1 // 2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Class for all pointer registers (including RSP) 170 reg_class any_reg(RAX, RAX_H, 171 RDX, RDX_H, 172 RBP, RBP_H, 173 RDI, RDI_H, 174 RSI, RSI_H, 175 RCX, RCX_H, 176 RBX, RBX_H, 177 RSP, RSP_H, 178 R8, R8_H, 179 R9, R9_H, 180 R10, R10_H, 181 R11, R11_H, 182 R12, R12_H, 183 R13, R13_H, 184 R14, R14_H, 185 R15, R15_H); 186 187 // Class for all pointer registers except RSP 188 reg_class ptr_reg(RAX, RAX_H, 189 RDX, RDX_H, 190 RBP, RBP_H, 191 RDI, RDI_H, 192 RSI, RSI_H, 193 RCX, RCX_H, 194 RBX, RBX_H, 195 R8, R8_H, 196 R9, R9_H, 197 R10, R10_H, 198 R11, R11_H, 199 R13, R13_H, 200 R14, R14_H); 201 202 // Class for all pointer registers except RAX and RSP 203 reg_class ptr_no_rax_reg(RDX, RDX_H, 204 RBP, RBP_H, 205 RDI, RDI_H, 206 RSI, RSI_H, 207 RCX, RCX_H, 208 RBX, RBX_H, 209 R8, R8_H, 210 R9, R9_H, 211 R10, R10_H, 212 R11, R11_H, 213 R13, R13_H, 214 R14, R14_H); 215 216 reg_class ptr_no_rbp_reg(RDX, RDX_H, 217 RAX, RAX_H, 218 RDI, RDI_H, 219 RSI, RSI_H, 220 RCX, RCX_H, 221 RBX, RBX_H, 222 R8, R8_H, 223 R9, R9_H, 224 R10, R10_H, 225 R11, R11_H, 226 R13, R13_H, 227 R14, R14_H); 228 229 // Class for all pointer registers except RAX, RBX and RSP 230 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 231 RBP, RBP_H, 232 RDI, RDI_H, 233 RSI, RSI_H, 234 RCX, RCX_H, 235 R8, R8_H, 236 R9, R9_H, 237 R10, R10_H, 238 R11, R11_H, 239 R13, R13_H, 240 R14, R14_H); 241 242 // Singleton class for RAX pointer register 243 reg_class ptr_rax_reg(RAX, RAX_H); 244 245 // Singleton class for RBX pointer register 246 reg_class ptr_rbx_reg(RBX, RBX_H); 247 248 // Singleton class for RSI pointer register 249 reg_class ptr_rsi_reg(RSI, RSI_H); 250 251 // Singleton class for RDI pointer register 252 reg_class ptr_rdi_reg(RDI, RDI_H); 253 254 // Singleton class for RBP pointer register 255 reg_class ptr_rbp_reg(RBP, RBP_H); 256 257 // Singleton class for stack pointer 258 reg_class ptr_rsp_reg(RSP, RSP_H); 259 260 // Singleton class for TLS pointer 261 reg_class ptr_r15_reg(R15, R15_H); 262 263 // Class for all long registers (except RSP) 264 reg_class long_reg(RAX, RAX_H, 265 RDX, RDX_H, 266 RBP, RBP_H, 267 RDI, RDI_H, 268 RSI, RSI_H, 269 RCX, RCX_H, 270 RBX, RBX_H, 271 R8, R8_H, 272 R9, R9_H, 273 R10, R10_H, 274 R11, R11_H, 275 R13, R13_H, 276 R14, R14_H); 277 278 // Class for all long registers except RAX, RDX (and RSP) 279 reg_class long_no_rax_rdx_reg(RBP, RBP_H, 280 RDI, RDI_H, 281 RSI, RSI_H, 282 RCX, RCX_H, 283 RBX, RBX_H, 284 R8, R8_H, 285 R9, R9_H, 286 R10, R10_H, 287 R11, R11_H, 288 R13, R13_H, 289 R14, R14_H); 290 291 // Class for all long registers except RCX (and RSP) 292 reg_class long_no_rcx_reg(RBP, RBP_H, 293 RDI, RDI_H, 294 RSI, RSI_H, 295 RAX, RAX_H, 296 RDX, RDX_H, 297 RBX, RBX_H, 298 R8, R8_H, 299 R9, R9_H, 300 R10, R10_H, 301 R11, R11_H, 302 R13, R13_H, 303 R14, R14_H); 304 305 // Class for all long registers except RAX (and RSP) 306 reg_class long_no_rax_reg(RBP, RBP_H, 307 RDX, RDX_H, 308 RDI, RDI_H, 309 RSI, RSI_H, 310 RCX, RCX_H, 311 RBX, RBX_H, 312 R8, R8_H, 313 R9, R9_H, 314 R10, R10_H, 315 R11, R11_H, 316 R13, R13_H, 317 R14, R14_H); 318 319 // Singleton class for RAX long register 320 reg_class long_rax_reg(RAX, RAX_H); 321 322 // Singleton class for RCX long register 323 reg_class long_rcx_reg(RCX, RCX_H); 324 325 // Singleton class for RDX long register 326 reg_class long_rdx_reg(RDX, RDX_H); 327 328 // Class for all int registers (except RSP) 329 reg_class int_reg(RAX, 330 RDX, 331 RBP, 332 RDI, 333 RSI, 334 RCX, 335 RBX, 336 R8, 337 R9, 338 R10, 339 R11, 340 R13, 341 R14); 342 343 // Class for all int registers except RCX (and RSP) 344 reg_class int_no_rcx_reg(RAX, 345 RDX, 346 RBP, 347 RDI, 348 RSI, 349 RBX, 350 R8, 351 R9, 352 R10, 353 R11, 354 R13, 355 R14); 356 357 // Class for all int registers except RAX, RDX (and RSP) 358 reg_class int_no_rax_rdx_reg(RBP, 359 RDI, 360 RSI, 361 RCX, 362 RBX, 363 R8, 364 R9, 365 R10, 366 R11, 367 R13, 368 R14); 369 370 // Singleton class for RAX int register 371 reg_class int_rax_reg(RAX); 372 373 // Singleton class for RBX int register 374 reg_class int_rbx_reg(RBX); 375 376 // Singleton class for RCX int register 377 reg_class int_rcx_reg(RCX); 378 379 // Singleton class for RCX int register 380 reg_class int_rdx_reg(RDX); 381 382 // Singleton class for RCX int register 383 reg_class int_rdi_reg(RDI); 384 385 // Singleton class for instruction pointer 386 // reg_class ip_reg(RIP); 387 388 %} 389 390 //----------SOURCE BLOCK------------------------------------------------------- 391 // This is a block of C++ code which provides values, functions, and 392 // definitions necessary in the rest of the architecture description 393 source %{ 394 #define RELOC_IMM64 Assembler::imm_operand 395 #define RELOC_DISP32 Assembler::disp32_operand 396 397 #define __ _masm. 398 399 static int preserve_SP_size() { 400 return 3; // rex.w, op, rm(reg/reg) 401 } 402 static int clear_avx_size() { 403 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper 404 } 405 406 // !!!!! Special hack to get all types of calls to specify the byte offset 407 // from the start of the call to the point where the return address 408 // will point. 409 int MachCallStaticJavaNode::ret_addr_offset() 410 { 411 int offset = 5; // 5 bytes from start of call to where return address points 412 offset += clear_avx_size(); 413 if (_method_handle_invoke) 414 offset += preserve_SP_size(); 415 return offset; 416 } 417 418 int MachCallDynamicJavaNode::ret_addr_offset() 419 { 420 int offset = 15; // 15 bytes from start of call to where return address points 421 offset += clear_avx_size(); 422 return offset; 423 } 424 425 int MachCallRuntimeNode::ret_addr_offset() { 426 int offset = 13; // movq r10,#addr; callq (r10) 427 offset += clear_avx_size(); 428 return offset; 429 } 430 431 // Indicate if the safepoint node needs the polling page as an input, 432 // it does if the polling page is more than disp32 away. 433 bool SafePointNode::needs_polling_address_input() 434 { 435 return Assembler::is_polling_page_far(); 436 } 437 438 // 439 // Compute padding required for nodes which need alignment 440 // 441 442 // The address of the call instruction needs to be 4-byte aligned to 443 // ensure that it does not span a cache line so that it can be patched. 444 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 445 { 446 current_offset += clear_avx_size(); // skip vzeroupper 447 current_offset += 1; // skip call opcode byte 448 return round_to(current_offset, alignment_required()) - current_offset; 449 } 450 451 // The address of the call instruction needs to be 4-byte aligned to 452 // ensure that it does not span a cache line so that it can be patched. 453 int CallStaticJavaHandleNode::compute_padding(int current_offset) const 454 { 455 current_offset += preserve_SP_size(); // skip mov rbp, rsp 456 current_offset += clear_avx_size(); // skip vzeroupper 457 current_offset += 1; // skip call opcode byte 458 return round_to(current_offset, alignment_required()) - current_offset; 459 } 460 461 // The address of the call instruction needs to be 4-byte aligned to 462 // ensure that it does not span a cache line so that it can be patched. 463 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 464 { 465 current_offset += clear_avx_size(); // skip vzeroupper 466 current_offset += 11; // skip movq instruction + call opcode byte 467 return round_to(current_offset, alignment_required()) - current_offset; 468 } 469 470 // EMIT_RM() 471 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 472 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 473 cbuf.insts()->emit_int8(c); 474 } 475 476 // EMIT_CC() 477 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 478 unsigned char c = (unsigned char) (f1 | f2); 479 cbuf.insts()->emit_int8(c); 480 } 481 482 // EMIT_OPCODE() 483 void emit_opcode(CodeBuffer &cbuf, int code) { 484 cbuf.insts()->emit_int8((unsigned char) code); 485 } 486 487 // EMIT_OPCODE() w/ relocation information 488 void emit_opcode(CodeBuffer &cbuf, 489 int code, relocInfo::relocType reloc, int offset, int format) 490 { 491 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 492 emit_opcode(cbuf, code); 493 } 494 495 // EMIT_D8() 496 void emit_d8(CodeBuffer &cbuf, int d8) { 497 cbuf.insts()->emit_int8((unsigned char) d8); 498 } 499 500 // EMIT_D16() 501 void emit_d16(CodeBuffer &cbuf, int d16) { 502 cbuf.insts()->emit_int16(d16); 503 } 504 505 // EMIT_D32() 506 void emit_d32(CodeBuffer &cbuf, int d32) { 507 cbuf.insts()->emit_int32(d32); 508 } 509 510 // EMIT_D64() 511 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 512 cbuf.insts()->emit_int64(d64); 513 } 514 515 // emit 32 bit value and construct relocation entry from relocInfo::relocType 516 void emit_d32_reloc(CodeBuffer& cbuf, 517 int d32, 518 relocInfo::relocType reloc, 519 int format) 520 { 521 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 522 cbuf.relocate(cbuf.insts_mark(), reloc, format); 523 cbuf.insts()->emit_int32(d32); 524 } 525 526 // emit 32 bit value and construct relocation entry from RelocationHolder 527 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 528 #ifdef ASSERT 529 if (rspec.reloc()->type() == relocInfo::oop_type && 530 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 531 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 532 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 533 } 534 #endif 535 cbuf.relocate(cbuf.insts_mark(), rspec, format); 536 cbuf.insts()->emit_int32(d32); 537 } 538 539 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 540 address next_ip = cbuf.insts_end() + 4; 541 emit_d32_reloc(cbuf, (int) (addr - next_ip), 542 external_word_Relocation::spec(addr), 543 RELOC_DISP32); 544 } 545 546 547 // emit 64 bit value and construct relocation entry from relocInfo::relocType 548 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 549 cbuf.relocate(cbuf.insts_mark(), reloc, format); 550 cbuf.insts()->emit_int64(d64); 551 } 552 553 // emit 64 bit value and construct relocation entry from RelocationHolder 554 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 555 #ifdef ASSERT 556 if (rspec.reloc()->type() == relocInfo::oop_type && 557 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 558 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 559 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 560 "cannot embed scavengable oops in code"); 561 } 562 #endif 563 cbuf.relocate(cbuf.insts_mark(), rspec, format); 564 cbuf.insts()->emit_int64(d64); 565 } 566 567 // Access stack slot for load or store 568 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 569 { 570 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 571 if (-0x80 <= disp && disp < 0x80) { 572 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 573 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 574 emit_d8(cbuf, disp); // Displacement // R/M byte 575 } else { 576 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 577 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 578 emit_d32(cbuf, disp); // Displacement // R/M byte 579 } 580 } 581 582 // rRegI ereg, memory mem) %{ // emit_reg_mem 583 void encode_RegMem(CodeBuffer &cbuf, 584 int reg, 585 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 586 { 587 assert(disp_reloc == relocInfo::none, "cannot have disp"); 588 int regenc = reg & 7; 589 int baseenc = base & 7; 590 int indexenc = index & 7; 591 592 // There is no index & no scale, use form without SIB byte 593 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 594 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 595 if (disp == 0 && base != RBP_enc && base != R13_enc) { 596 emit_rm(cbuf, 0x0, regenc, baseenc); // * 597 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 598 // If 8-bit displacement, mode 0x1 599 emit_rm(cbuf, 0x1, regenc, baseenc); // * 600 emit_d8(cbuf, disp); 601 } else { 602 // If 32-bit displacement 603 if (base == -1) { // Special flag for absolute address 604 emit_rm(cbuf, 0x0, regenc, 0x5); // * 605 if (disp_reloc != relocInfo::none) { 606 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 607 } else { 608 emit_d32(cbuf, disp); 609 } 610 } else { 611 // Normal base + offset 612 emit_rm(cbuf, 0x2, regenc, baseenc); // * 613 if (disp_reloc != relocInfo::none) { 614 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 615 } else { 616 emit_d32(cbuf, disp); 617 } 618 } 619 } 620 } else { 621 // Else, encode with the SIB byte 622 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 623 if (disp == 0 && base != RBP_enc && base != R13_enc) { 624 // If no displacement 625 emit_rm(cbuf, 0x0, regenc, 0x4); // * 626 emit_rm(cbuf, scale, indexenc, baseenc); 627 } else { 628 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 629 // If 8-bit displacement, mode 0x1 630 emit_rm(cbuf, 0x1, regenc, 0x4); // * 631 emit_rm(cbuf, scale, indexenc, baseenc); 632 emit_d8(cbuf, disp); 633 } else { 634 // If 32-bit displacement 635 if (base == 0x04 ) { 636 emit_rm(cbuf, 0x2, regenc, 0x4); 637 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 638 } else { 639 emit_rm(cbuf, 0x2, regenc, 0x4); 640 emit_rm(cbuf, scale, indexenc, baseenc); // * 641 } 642 if (disp_reloc != relocInfo::none) { 643 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 644 } else { 645 emit_d32(cbuf, disp); 646 } 647 } 648 } 649 } 650 } 651 652 // This could be in MacroAssembler but it's fairly C2 specific 653 void emit_cmpfp_fixup(MacroAssembler& _masm) { 654 Label exit; 655 __ jccb(Assembler::noParity, exit); 656 __ pushf(); 657 // 658 // comiss/ucomiss instructions set ZF,PF,CF flags and 659 // zero OF,AF,SF for NaN values. 660 // Fixup flags by zeroing ZF,PF so that compare of NaN 661 // values returns 'less than' result (CF is set). 662 // Leave the rest of flags unchanged. 663 // 664 // 7 6 5 4 3 2 1 0 665 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 666 // 0 0 1 0 1 0 1 1 (0x2B) 667 // 668 __ andq(Address(rsp, 0), 0xffffff2b); 669 __ popf(); 670 __ bind(exit); 671 } 672 673 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 674 Label done; 675 __ movl(dst, -1); 676 __ jcc(Assembler::parity, done); 677 __ jcc(Assembler::below, done); 678 __ setb(Assembler::notEqual, dst); 679 __ movzbl(dst, dst); 680 __ bind(done); 681 } 682 683 684 //============================================================================= 685 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 686 687 int Compile::ConstantTable::calculate_table_base_offset() const { 688 return 0; // absolute addressing, no offset 689 } 690 691 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 692 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 693 ShouldNotReachHere(); 694 } 695 696 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 697 // Empty encoding 698 } 699 700 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 701 return 0; 702 } 703 704 #ifndef PRODUCT 705 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 706 st->print("# MachConstantBaseNode (empty encoding)"); 707 } 708 #endif 709 710 711 //============================================================================= 712 #ifndef PRODUCT 713 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 714 Compile* C = ra_->C; 715 716 int framesize = C->frame_slots() << LogBytesPerInt; 717 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 718 // Remove wordSize for return addr which is already pushed. 719 framesize -= wordSize; 720 721 if (C->need_stack_bang(framesize)) { 722 framesize -= wordSize; 723 st->print("# stack bang"); 724 st->print("\n\t"); 725 st->print("pushq rbp\t# Save rbp"); 726 if (framesize) { 727 st->print("\n\t"); 728 st->print("subq rsp, #%d\t# Create frame",framesize); 729 } 730 } else { 731 st->print("subq rsp, #%d\t# Create frame",framesize); 732 st->print("\n\t"); 733 framesize -= wordSize; 734 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 735 } 736 737 if (VerifyStackAtCalls) { 738 st->print("\n\t"); 739 framesize -= wordSize; 740 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 741 #ifdef ASSERT 742 st->print("\n\t"); 743 st->print("# stack alignment check"); 744 #endif 745 } 746 st->cr(); 747 } 748 #endif 749 750 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 751 Compile* C = ra_->C; 752 MacroAssembler _masm(&cbuf); 753 754 int framesize = C->frame_slots() << LogBytesPerInt; 755 756 __ verified_entry(framesize, C->need_stack_bang(framesize), false); 757 758 C->set_frame_complete(cbuf.insts_size()); 759 760 if (C->has_mach_constant_base_node()) { 761 // NOTE: We set the table base offset here because users might be 762 // emitted before MachConstantBaseNode. 763 Compile::ConstantTable& constant_table = C->constant_table(); 764 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 765 } 766 } 767 768 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 769 { 770 return MachNode::size(ra_); // too many variables; just compute it 771 // the hard way 772 } 773 774 int MachPrologNode::reloc() const 775 { 776 return 0; // a large enough number 777 } 778 779 //============================================================================= 780 #ifndef PRODUCT 781 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 782 { 783 Compile* C = ra_->C; 784 if (C->max_vector_size() > 16) { 785 st->print("vzeroupper"); 786 st->cr(); st->print("\t"); 787 } 788 789 int framesize = C->frame_slots() << LogBytesPerInt; 790 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 791 // Remove word for return adr already pushed 792 // and RBP 793 framesize -= 2*wordSize; 794 795 if (framesize) { 796 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 797 st->print("\t"); 798 } 799 800 st->print_cr("popq rbp"); 801 if (do_polling() && C->is_method_compilation()) { 802 st->print("\t"); 803 if (Assembler::is_polling_page_far()) { 804 st->print_cr("movq rscratch1, #polling_page_address\n\t" 805 "testl rax, [rscratch1]\t" 806 "# Safepoint: poll for GC"); 807 } else { 808 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 809 "# Safepoint: poll for GC"); 810 } 811 } 812 } 813 #endif 814 815 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 816 { 817 Compile* C = ra_->C; 818 if (C->max_vector_size() > 16) { 819 // Clear upper bits of YMM registers when current compiled code uses 820 // wide vectors to avoid AVX <-> SSE transition penalty during call. 821 MacroAssembler _masm(&cbuf); 822 __ vzeroupper(); 823 } 824 825 int framesize = C->frame_slots() << LogBytesPerInt; 826 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 827 // Remove word for return adr already pushed 828 // and RBP 829 framesize -= 2*wordSize; 830 831 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 832 833 if (framesize) { 834 emit_opcode(cbuf, Assembler::REX_W); 835 if (framesize < 0x80) { 836 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 837 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 838 emit_d8(cbuf, framesize); 839 } else { 840 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 841 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 842 emit_d32(cbuf, framesize); 843 } 844 } 845 846 // popq rbp 847 emit_opcode(cbuf, 0x58 | RBP_enc); 848 849 if (do_polling() && C->is_method_compilation()) { 850 MacroAssembler _masm(&cbuf); 851 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 852 if (Assembler::is_polling_page_far()) { 853 __ lea(rscratch1, polling_page); 854 __ relocate(relocInfo::poll_return_type); 855 __ testl(rax, Address(rscratch1, 0)); 856 } else { 857 __ testl(rax, polling_page); 858 } 859 } 860 } 861 862 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 863 { 864 return MachNode::size(ra_); // too many variables; just compute it 865 // the hard way 866 } 867 868 int MachEpilogNode::reloc() const 869 { 870 return 2; // a large enough number 871 } 872 873 const Pipeline* MachEpilogNode::pipeline() const 874 { 875 return MachNode::pipeline_class(); 876 } 877 878 int MachEpilogNode::safepoint_offset() const 879 { 880 return 0; 881 } 882 883 //============================================================================= 884 885 enum RC { 886 rc_bad, 887 rc_int, 888 rc_float, 889 rc_stack 890 }; 891 892 static enum RC rc_class(OptoReg::Name reg) 893 { 894 if( !OptoReg::is_valid(reg) ) return rc_bad; 895 896 if (OptoReg::is_stack(reg)) return rc_stack; 897 898 VMReg r = OptoReg::as_VMReg(reg); 899 900 if (r->is_Register()) return rc_int; 901 902 assert(r->is_XMMRegister(), "must be"); 903 return rc_float; 904 } 905 906 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 907 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 908 int src_hi, int dst_hi, uint ireg, outputStream* st); 909 910 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 911 int stack_offset, int reg, uint ireg, outputStream* st); 912 913 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 914 int dst_offset, uint ireg, outputStream* st) { 915 if (cbuf) { 916 MacroAssembler _masm(cbuf); 917 switch (ireg) { 918 case Op_VecS: 919 __ movq(Address(rsp, -8), rax); 920 __ movl(rax, Address(rsp, src_offset)); 921 __ movl(Address(rsp, dst_offset), rax); 922 __ movq(rax, Address(rsp, -8)); 923 break; 924 case Op_VecD: 925 __ pushq(Address(rsp, src_offset)); 926 __ popq (Address(rsp, dst_offset)); 927 break; 928 case Op_VecX: 929 __ pushq(Address(rsp, src_offset)); 930 __ popq (Address(rsp, dst_offset)); 931 __ pushq(Address(rsp, src_offset+8)); 932 __ popq (Address(rsp, dst_offset+8)); 933 break; 934 case Op_VecY: 935 __ vmovdqu(Address(rsp, -32), xmm0); 936 __ vmovdqu(xmm0, Address(rsp, src_offset)); 937 __ vmovdqu(Address(rsp, dst_offset), xmm0); 938 __ vmovdqu(xmm0, Address(rsp, -32)); 939 break; 940 default: 941 ShouldNotReachHere(); 942 } 943 #ifndef PRODUCT 944 } else { 945 switch (ireg) { 946 case Op_VecS: 947 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 948 "movl rax, [rsp + #%d]\n\t" 949 "movl [rsp + #%d], rax\n\t" 950 "movq rax, [rsp - #8]", 951 src_offset, dst_offset); 952 break; 953 case Op_VecD: 954 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 955 "popq [rsp + #%d]", 956 src_offset, dst_offset); 957 break; 958 case Op_VecX: 959 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 960 "popq [rsp + #%d]\n\t" 961 "pushq [rsp + #%d]\n\t" 962 "popq [rsp + #%d]", 963 src_offset, dst_offset, src_offset+8, dst_offset+8); 964 break; 965 case Op_VecY: 966 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 967 "vmovdqu xmm0, [rsp + #%d]\n\t" 968 "vmovdqu [rsp + #%d], xmm0\n\t" 969 "vmovdqu xmm0, [rsp - #32]", 970 src_offset, dst_offset); 971 break; 972 default: 973 ShouldNotReachHere(); 974 } 975 #endif 976 } 977 } 978 979 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 980 PhaseRegAlloc* ra_, 981 bool do_size, 982 outputStream* st) const { 983 assert(cbuf != NULL || st != NULL, "sanity"); 984 // Get registers to move 985 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 986 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 987 OptoReg::Name dst_second = ra_->get_reg_second(this); 988 OptoReg::Name dst_first = ra_->get_reg_first(this); 989 990 enum RC src_second_rc = rc_class(src_second); 991 enum RC src_first_rc = rc_class(src_first); 992 enum RC dst_second_rc = rc_class(dst_second); 993 enum RC dst_first_rc = rc_class(dst_first); 994 995 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 996 "must move at least 1 register" ); 997 998 if (src_first == dst_first && src_second == dst_second) { 999 // Self copy, no move 1000 return 0; 1001 } 1002 if (bottom_type()->isa_vect() != NULL) { 1003 uint ireg = ideal_reg(); 1004 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1005 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); 1006 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1007 // mem -> mem 1008 int src_offset = ra_->reg2offset(src_first); 1009 int dst_offset = ra_->reg2offset(dst_first); 1010 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1011 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1012 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1013 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1014 int stack_offset = ra_->reg2offset(dst_first); 1015 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1016 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1017 int stack_offset = ra_->reg2offset(src_first); 1018 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1019 } else { 1020 ShouldNotReachHere(); 1021 } 1022 return 0; 1023 } 1024 if (src_first_rc == rc_stack) { 1025 // mem -> 1026 if (dst_first_rc == rc_stack) { 1027 // mem -> mem 1028 assert(src_second != dst_first, "overlap"); 1029 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1030 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1031 // 64-bit 1032 int src_offset = ra_->reg2offset(src_first); 1033 int dst_offset = ra_->reg2offset(dst_first); 1034 if (cbuf) { 1035 MacroAssembler _masm(cbuf); 1036 __ pushq(Address(rsp, src_offset)); 1037 __ popq (Address(rsp, dst_offset)); 1038 #ifndef PRODUCT 1039 } else { 1040 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1041 "popq [rsp + #%d]", 1042 src_offset, dst_offset); 1043 #endif 1044 } 1045 } else { 1046 // 32-bit 1047 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1048 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1049 // No pushl/popl, so: 1050 int src_offset = ra_->reg2offset(src_first); 1051 int dst_offset = ra_->reg2offset(dst_first); 1052 if (cbuf) { 1053 MacroAssembler _masm(cbuf); 1054 __ movq(Address(rsp, -8), rax); 1055 __ movl(rax, Address(rsp, src_offset)); 1056 __ movl(Address(rsp, dst_offset), rax); 1057 __ movq(rax, Address(rsp, -8)); 1058 #ifndef PRODUCT 1059 } else { 1060 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1061 "movl rax, [rsp + #%d]\n\t" 1062 "movl [rsp + #%d], rax\n\t" 1063 "movq rax, [rsp - #8]", 1064 src_offset, dst_offset); 1065 #endif 1066 } 1067 } 1068 return 0; 1069 } else if (dst_first_rc == rc_int) { 1070 // mem -> gpr 1071 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1072 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1073 // 64-bit 1074 int offset = ra_->reg2offset(src_first); 1075 if (cbuf) { 1076 MacroAssembler _masm(cbuf); 1077 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1078 #ifndef PRODUCT 1079 } else { 1080 st->print("movq %s, [rsp + #%d]\t# spill", 1081 Matcher::regName[dst_first], 1082 offset); 1083 #endif 1084 } 1085 } else { 1086 // 32-bit 1087 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1088 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1089 int offset = ra_->reg2offset(src_first); 1090 if (cbuf) { 1091 MacroAssembler _masm(cbuf); 1092 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1093 #ifndef PRODUCT 1094 } else { 1095 st->print("movl %s, [rsp + #%d]\t# spill", 1096 Matcher::regName[dst_first], 1097 offset); 1098 #endif 1099 } 1100 } 1101 return 0; 1102 } else if (dst_first_rc == rc_float) { 1103 // mem-> xmm 1104 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1105 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1106 // 64-bit 1107 int offset = ra_->reg2offset(src_first); 1108 if (cbuf) { 1109 MacroAssembler _masm(cbuf); 1110 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1111 #ifndef PRODUCT 1112 } else { 1113 st->print("%s %s, [rsp + #%d]\t# spill", 1114 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1115 Matcher::regName[dst_first], 1116 offset); 1117 #endif 1118 } 1119 } else { 1120 // 32-bit 1121 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1122 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1123 int offset = ra_->reg2offset(src_first); 1124 if (cbuf) { 1125 MacroAssembler _masm(cbuf); 1126 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1127 #ifndef PRODUCT 1128 } else { 1129 st->print("movss %s, [rsp + #%d]\t# spill", 1130 Matcher::regName[dst_first], 1131 offset); 1132 #endif 1133 } 1134 } 1135 return 0; 1136 } 1137 } else if (src_first_rc == rc_int) { 1138 // gpr -> 1139 if (dst_first_rc == rc_stack) { 1140 // gpr -> mem 1141 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1142 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1143 // 64-bit 1144 int offset = ra_->reg2offset(dst_first); 1145 if (cbuf) { 1146 MacroAssembler _masm(cbuf); 1147 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1148 #ifndef PRODUCT 1149 } else { 1150 st->print("movq [rsp + #%d], %s\t# spill", 1151 offset, 1152 Matcher::regName[src_first]); 1153 #endif 1154 } 1155 } else { 1156 // 32-bit 1157 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1158 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1159 int offset = ra_->reg2offset(dst_first); 1160 if (cbuf) { 1161 MacroAssembler _masm(cbuf); 1162 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1163 #ifndef PRODUCT 1164 } else { 1165 st->print("movl [rsp + #%d], %s\t# spill", 1166 offset, 1167 Matcher::regName[src_first]); 1168 #endif 1169 } 1170 } 1171 return 0; 1172 } else if (dst_first_rc == rc_int) { 1173 // gpr -> gpr 1174 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1175 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1176 // 64-bit 1177 if (cbuf) { 1178 MacroAssembler _masm(cbuf); 1179 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1180 as_Register(Matcher::_regEncode[src_first])); 1181 #ifndef PRODUCT 1182 } else { 1183 st->print("movq %s, %s\t# spill", 1184 Matcher::regName[dst_first], 1185 Matcher::regName[src_first]); 1186 #endif 1187 } 1188 return 0; 1189 } else { 1190 // 32-bit 1191 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1192 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1193 if (cbuf) { 1194 MacroAssembler _masm(cbuf); 1195 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1196 as_Register(Matcher::_regEncode[src_first])); 1197 #ifndef PRODUCT 1198 } else { 1199 st->print("movl %s, %s\t# spill", 1200 Matcher::regName[dst_first], 1201 Matcher::regName[src_first]); 1202 #endif 1203 } 1204 return 0; 1205 } 1206 } else if (dst_first_rc == rc_float) { 1207 // gpr -> xmm 1208 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1209 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1210 // 64-bit 1211 if (cbuf) { 1212 MacroAssembler _masm(cbuf); 1213 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1214 #ifndef PRODUCT 1215 } else { 1216 st->print("movdq %s, %s\t# spill", 1217 Matcher::regName[dst_first], 1218 Matcher::regName[src_first]); 1219 #endif 1220 } 1221 } else { 1222 // 32-bit 1223 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1224 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1225 if (cbuf) { 1226 MacroAssembler _masm(cbuf); 1227 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1228 #ifndef PRODUCT 1229 } else { 1230 st->print("movdl %s, %s\t# spill", 1231 Matcher::regName[dst_first], 1232 Matcher::regName[src_first]); 1233 #endif 1234 } 1235 } 1236 return 0; 1237 } 1238 } else if (src_first_rc == rc_float) { 1239 // xmm -> 1240 if (dst_first_rc == rc_stack) { 1241 // xmm -> mem 1242 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1243 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1244 // 64-bit 1245 int offset = ra_->reg2offset(dst_first); 1246 if (cbuf) { 1247 MacroAssembler _masm(cbuf); 1248 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1249 #ifndef PRODUCT 1250 } else { 1251 st->print("movsd [rsp + #%d], %s\t# spill", 1252 offset, 1253 Matcher::regName[src_first]); 1254 #endif 1255 } 1256 } else { 1257 // 32-bit 1258 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1259 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1260 int offset = ra_->reg2offset(dst_first); 1261 if (cbuf) { 1262 MacroAssembler _masm(cbuf); 1263 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1264 #ifndef PRODUCT 1265 } else { 1266 st->print("movss [rsp + #%d], %s\t# spill", 1267 offset, 1268 Matcher::regName[src_first]); 1269 #endif 1270 } 1271 } 1272 return 0; 1273 } else if (dst_first_rc == rc_int) { 1274 // xmm -> gpr 1275 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1276 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1277 // 64-bit 1278 if (cbuf) { 1279 MacroAssembler _masm(cbuf); 1280 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1281 #ifndef PRODUCT 1282 } else { 1283 st->print("movdq %s, %s\t# spill", 1284 Matcher::regName[dst_first], 1285 Matcher::regName[src_first]); 1286 #endif 1287 } 1288 } else { 1289 // 32-bit 1290 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1291 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1292 if (cbuf) { 1293 MacroAssembler _masm(cbuf); 1294 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1295 #ifndef PRODUCT 1296 } else { 1297 st->print("movdl %s, %s\t# spill", 1298 Matcher::regName[dst_first], 1299 Matcher::regName[src_first]); 1300 #endif 1301 } 1302 } 1303 return 0; 1304 } else if (dst_first_rc == rc_float) { 1305 // xmm -> xmm 1306 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1307 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1308 // 64-bit 1309 if (cbuf) { 1310 MacroAssembler _masm(cbuf); 1311 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1312 #ifndef PRODUCT 1313 } else { 1314 st->print("%s %s, %s\t# spill", 1315 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1316 Matcher::regName[dst_first], 1317 Matcher::regName[src_first]); 1318 #endif 1319 } 1320 } else { 1321 // 32-bit 1322 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1323 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1324 if (cbuf) { 1325 MacroAssembler _masm(cbuf); 1326 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1327 #ifndef PRODUCT 1328 } else { 1329 st->print("%s %s, %s\t# spill", 1330 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1331 Matcher::regName[dst_first], 1332 Matcher::regName[src_first]); 1333 #endif 1334 } 1335 } 1336 return 0; 1337 } 1338 } 1339 1340 assert(0," foo "); 1341 Unimplemented(); 1342 return 0; 1343 } 1344 1345 #ifndef PRODUCT 1346 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1347 implementation(NULL, ra_, false, st); 1348 } 1349 #endif 1350 1351 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1352 implementation(&cbuf, ra_, false, NULL); 1353 } 1354 1355 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1356 return MachNode::size(ra_); 1357 } 1358 1359 //============================================================================= 1360 #ifndef PRODUCT 1361 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1362 { 1363 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1364 int reg = ra_->get_reg_first(this); 1365 st->print("leaq %s, [rsp + #%d]\t# box lock", 1366 Matcher::regName[reg], offset); 1367 } 1368 #endif 1369 1370 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1371 { 1372 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1373 int reg = ra_->get_encode(this); 1374 if (offset >= 0x80) { 1375 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1376 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1377 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1378 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1379 emit_d32(cbuf, offset); 1380 } else { 1381 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1382 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1383 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1384 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1385 emit_d8(cbuf, offset); 1386 } 1387 } 1388 1389 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1390 { 1391 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1392 return (offset < 0x80) ? 5 : 8; // REX 1393 } 1394 1395 //============================================================================= 1396 #ifndef PRODUCT 1397 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1398 { 1399 if (UseCompressedClassPointers) { 1400 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1401 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1402 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1403 } else { 1404 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1405 "# Inline cache check"); 1406 } 1407 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1408 st->print_cr("\tnop\t# nops to align entry point"); 1409 } 1410 #endif 1411 1412 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1413 { 1414 MacroAssembler masm(&cbuf); 1415 uint insts_size = cbuf.insts_size(); 1416 if (UseCompressedClassPointers) { 1417 masm.load_klass(rscratch1, j_rarg0); 1418 masm.cmpptr(rax, rscratch1); 1419 } else { 1420 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1421 } 1422 1423 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1424 1425 /* WARNING these NOPs are critical so that verified entry point is properly 1426 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1427 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1428 if (OptoBreakpoint) { 1429 // Leave space for int3 1430 nops_cnt -= 1; 1431 } 1432 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1433 if (nops_cnt > 0) 1434 masm.nop(nops_cnt); 1435 } 1436 1437 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1438 { 1439 return MachNode::size(ra_); // too many variables; just compute it 1440 // the hard way 1441 } 1442 1443 1444 //============================================================================= 1445 uint size_exception_handler() 1446 { 1447 // NativeCall instruction size is the same as NativeJump. 1448 // Note that this value is also credited (in output.cpp) to 1449 // the size of the code section. 1450 return NativeJump::instruction_size; 1451 } 1452 1453 // Emit exception handler code. 1454 int emit_exception_handler(CodeBuffer& cbuf) 1455 { 1456 1457 // Note that the code buffer's insts_mark is always relative to insts. 1458 // That's why we must use the macroassembler to generate a handler. 1459 MacroAssembler _masm(&cbuf); 1460 address base = 1461 __ start_a_stub(size_exception_handler()); 1462 if (base == NULL) return 0; // CodeBuffer::expand failed 1463 int offset = __ offset(); 1464 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1465 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1466 __ end_a_stub(); 1467 return offset; 1468 } 1469 1470 uint size_deopt_handler() 1471 { 1472 // three 5 byte instructions 1473 return 15; 1474 } 1475 1476 // Emit deopt handler code. 1477 int emit_deopt_handler(CodeBuffer& cbuf) 1478 { 1479 1480 // Note that the code buffer's insts_mark is always relative to insts. 1481 // That's why we must use the macroassembler to generate a handler. 1482 MacroAssembler _masm(&cbuf); 1483 address base = 1484 __ start_a_stub(size_deopt_handler()); 1485 if (base == NULL) return 0; // CodeBuffer::expand failed 1486 int offset = __ offset(); 1487 address the_pc = (address) __ pc(); 1488 Label next; 1489 // push a "the_pc" on the stack without destroying any registers 1490 // as they all may be live. 1491 1492 // push address of "next" 1493 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1494 __ bind(next); 1495 // adjust it so it matches "the_pc" 1496 __ subptr(Address(rsp, 0), __ offset() - offset); 1497 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1498 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1499 __ end_a_stub(); 1500 return offset; 1501 } 1502 1503 int Matcher::regnum_to_fpu_offset(int regnum) 1504 { 1505 return regnum - 32; // The FP registers are in the second chunk 1506 } 1507 1508 // This is UltraSparc specific, true just means we have fast l2f conversion 1509 const bool Matcher::convL2FSupported(void) { 1510 return true; 1511 } 1512 1513 // Is this branch offset short enough that a short branch can be used? 1514 // 1515 // NOTE: If the platform does not provide any short branch variants, then 1516 // this method should return false for offset 0. 1517 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1518 // The passed offset is relative to address of the branch. 1519 // On 86 a branch displacement is calculated relative to address 1520 // of a next instruction. 1521 offset -= br_size; 1522 1523 // the short version of jmpConUCF2 contains multiple branches, 1524 // making the reach slightly less 1525 if (rule == jmpConUCF2_rule) 1526 return (-126 <= offset && offset <= 125); 1527 return (-128 <= offset && offset <= 127); 1528 } 1529 1530 const bool Matcher::isSimpleConstant64(jlong value) { 1531 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1532 //return value == (int) value; // Cf. storeImmL and immL32. 1533 1534 // Probably always true, even if a temp register is required. 1535 return true; 1536 } 1537 1538 // The ecx parameter to rep stosq for the ClearArray node is in words. 1539 const bool Matcher::init_array_count_is_in_bytes = false; 1540 1541 // Threshold size for cleararray. 1542 const int Matcher::init_array_short_size = 8 * BytesPerLong; 1543 1544 // No additional cost for CMOVL. 1545 const int Matcher::long_cmove_cost() { return 0; } 1546 1547 // No CMOVF/CMOVD with SSE2 1548 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1549 1550 // Does the CPU require late expand (see block.cpp for description of late expand)? 1551 const bool Matcher::require_postalloc_expand = false; 1552 1553 // Should the Matcher clone shifts on addressing modes, expecting them 1554 // to be subsumed into complex addressing expressions or compute them 1555 // into registers? True for Intel but false for most RISCs 1556 const bool Matcher::clone_shift_expressions = true; 1557 1558 // Do we need to mask the count passed to shift instructions or does 1559 // the cpu only look at the lower 5/6 bits anyway? 1560 const bool Matcher::need_masked_shift_count = false; 1561 1562 bool Matcher::narrow_oop_use_complex_address() { 1563 assert(UseCompressedOops, "only for compressed oops code"); 1564 return (LogMinObjAlignmentInBytes <= 3); 1565 } 1566 1567 bool Matcher::narrow_klass_use_complex_address() { 1568 assert(UseCompressedClassPointers, "only for compressed klass code"); 1569 return (LogKlassAlignmentInBytes <= 3); 1570 } 1571 1572 // Is it better to copy float constants, or load them directly from 1573 // memory? Intel can load a float constant from a direct address, 1574 // requiring no extra registers. Most RISCs will have to materialize 1575 // an address into a register first, so they would do better to copy 1576 // the constant from stack. 1577 const bool Matcher::rematerialize_float_constants = true; // XXX 1578 1579 // If CPU can load and store mis-aligned doubles directly then no 1580 // fixup is needed. Else we split the double into 2 integer pieces 1581 // and move it piece-by-piece. Only happens when passing doubles into 1582 // C code as the Java calling convention forces doubles to be aligned. 1583 const bool Matcher::misaligned_doubles_ok = true; 1584 1585 // No-op on amd64 1586 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1587 1588 // Advertise here if the CPU requires explicit rounding operations to 1589 // implement the UseStrictFP mode. 1590 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1591 1592 // Are floats conerted to double when stored to stack during deoptimization? 1593 // On x64 it is stored without convertion so we can use normal access. 1594 bool Matcher::float_in_double() { return false; } 1595 1596 // Do ints take an entire long register or just half? 1597 const bool Matcher::int_in_long = true; 1598 1599 // Return whether or not this register is ever used as an argument. 1600 // This function is used on startup to build the trampoline stubs in 1601 // generateOptoStub. Registers not mentioned will be killed by the VM 1602 // call in the trampoline, and arguments in those registers not be 1603 // available to the callee. 1604 bool Matcher::can_be_java_arg(int reg) 1605 { 1606 return 1607 reg == RDI_num || reg == RDI_H_num || 1608 reg == RSI_num || reg == RSI_H_num || 1609 reg == RDX_num || reg == RDX_H_num || 1610 reg == RCX_num || reg == RCX_H_num || 1611 reg == R8_num || reg == R8_H_num || 1612 reg == R9_num || reg == R9_H_num || 1613 reg == R12_num || reg == R12_H_num || 1614 reg == XMM0_num || reg == XMM0b_num || 1615 reg == XMM1_num || reg == XMM1b_num || 1616 reg == XMM2_num || reg == XMM2b_num || 1617 reg == XMM3_num || reg == XMM3b_num || 1618 reg == XMM4_num || reg == XMM4b_num || 1619 reg == XMM5_num || reg == XMM5b_num || 1620 reg == XMM6_num || reg == XMM6b_num || 1621 reg == XMM7_num || reg == XMM7b_num; 1622 } 1623 1624 bool Matcher::is_spillable_arg(int reg) 1625 { 1626 return can_be_java_arg(reg); 1627 } 1628 1629 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1630 // In 64 bit mode a code which use multiply when 1631 // devisor is constant is faster than hardware 1632 // DIV instruction (it uses MulHiL). 1633 return false; 1634 } 1635 1636 // Register for DIVI projection of divmodI 1637 RegMask Matcher::divI_proj_mask() { 1638 return INT_RAX_REG_mask(); 1639 } 1640 1641 // Register for MODI projection of divmodI 1642 RegMask Matcher::modI_proj_mask() { 1643 return INT_RDX_REG_mask(); 1644 } 1645 1646 // Register for DIVL projection of divmodL 1647 RegMask Matcher::divL_proj_mask() { 1648 return LONG_RAX_REG_mask(); 1649 } 1650 1651 // Register for MODL projection of divmodL 1652 RegMask Matcher::modL_proj_mask() { 1653 return LONG_RDX_REG_mask(); 1654 } 1655 1656 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1657 return PTR_RBP_REG_mask(); 1658 } 1659 1660 %} 1661 1662 //----------ENCODING BLOCK----------------------------------------------------- 1663 // This block specifies the encoding classes used by the compiler to 1664 // output byte streams. Encoding classes are parameterized macros 1665 // used by Machine Instruction Nodes in order to generate the bit 1666 // encoding of the instruction. Operands specify their base encoding 1667 // interface with the interface keyword. There are currently 1668 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1669 // COND_INTER. REG_INTER causes an operand to generate a function 1670 // which returns its register number when queried. CONST_INTER causes 1671 // an operand to generate a function which returns the value of the 1672 // constant when queried. MEMORY_INTER causes an operand to generate 1673 // four functions which return the Base Register, the Index Register, 1674 // the Scale Value, and the Offset Value of the operand when queried. 1675 // COND_INTER causes an operand to generate six functions which return 1676 // the encoding code (ie - encoding bits for the instruction) 1677 // associated with each basic boolean condition for a conditional 1678 // instruction. 1679 // 1680 // Instructions specify two basic values for encoding. Again, a 1681 // function is available to check if the constant displacement is an 1682 // oop. They use the ins_encode keyword to specify their encoding 1683 // classes (which must be a sequence of enc_class names, and their 1684 // parameters, specified in the encoding block), and they use the 1685 // opcode keyword to specify, in order, their primary, secondary, and 1686 // tertiary opcode. Only the opcode sections which a particular 1687 // instruction needs for encoding need to be specified. 1688 encode %{ 1689 // Build emit functions for each basic byte or larger field in the 1690 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1691 // from C++ code in the enc_class source block. Emit functions will 1692 // live in the main source block for now. In future, we can 1693 // generalize this by adding a syntax that specifies the sizes of 1694 // fields in an order, so that the adlc can build the emit functions 1695 // automagically 1696 1697 // Emit primary opcode 1698 enc_class OpcP 1699 %{ 1700 emit_opcode(cbuf, $primary); 1701 %} 1702 1703 // Emit secondary opcode 1704 enc_class OpcS 1705 %{ 1706 emit_opcode(cbuf, $secondary); 1707 %} 1708 1709 // Emit tertiary opcode 1710 enc_class OpcT 1711 %{ 1712 emit_opcode(cbuf, $tertiary); 1713 %} 1714 1715 // Emit opcode directly 1716 enc_class Opcode(immI d8) 1717 %{ 1718 emit_opcode(cbuf, $d8$$constant); 1719 %} 1720 1721 // Emit size prefix 1722 enc_class SizePrefix 1723 %{ 1724 emit_opcode(cbuf, 0x66); 1725 %} 1726 1727 enc_class reg(rRegI reg) 1728 %{ 1729 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1730 %} 1731 1732 enc_class reg_reg(rRegI dst, rRegI src) 1733 %{ 1734 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1735 %} 1736 1737 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1738 %{ 1739 emit_opcode(cbuf, $opcode$$constant); 1740 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1741 %} 1742 1743 enc_class cdql_enc(no_rax_rdx_RegI div) 1744 %{ 1745 // Full implementation of Java idiv and irem; checks for 1746 // special case as described in JVM spec., p.243 & p.271. 1747 // 1748 // normal case special case 1749 // 1750 // input : rax: dividend min_int 1751 // reg: divisor -1 1752 // 1753 // output: rax: quotient (= rax idiv reg) min_int 1754 // rdx: remainder (= rax irem reg) 0 1755 // 1756 // Code sequnce: 1757 // 1758 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1759 // 5: 75 07/08 jne e <normal> 1760 // 7: 33 d2 xor %edx,%edx 1761 // [div >= 8 -> offset + 1] 1762 // [REX_B] 1763 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1764 // c: 74 03/04 je 11 <done> 1765 // 000000000000000e <normal>: 1766 // e: 99 cltd 1767 // [div >= 8 -> offset + 1] 1768 // [REX_B] 1769 // f: f7 f9 idiv $div 1770 // 0000000000000011 <done>: 1771 1772 // cmp $0x80000000,%eax 1773 emit_opcode(cbuf, 0x3d); 1774 emit_d8(cbuf, 0x00); 1775 emit_d8(cbuf, 0x00); 1776 emit_d8(cbuf, 0x00); 1777 emit_d8(cbuf, 0x80); 1778 1779 // jne e <normal> 1780 emit_opcode(cbuf, 0x75); 1781 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1782 1783 // xor %edx,%edx 1784 emit_opcode(cbuf, 0x33); 1785 emit_d8(cbuf, 0xD2); 1786 1787 // cmp $0xffffffffffffffff,%ecx 1788 if ($div$$reg >= 8) { 1789 emit_opcode(cbuf, Assembler::REX_B); 1790 } 1791 emit_opcode(cbuf, 0x83); 1792 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1793 emit_d8(cbuf, 0xFF); 1794 1795 // je 11 <done> 1796 emit_opcode(cbuf, 0x74); 1797 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1798 1799 // <normal> 1800 // cltd 1801 emit_opcode(cbuf, 0x99); 1802 1803 // idivl (note: must be emitted by the user of this rule) 1804 // <done> 1805 %} 1806 1807 enc_class cdqq_enc(no_rax_rdx_RegL div) 1808 %{ 1809 // Full implementation of Java ldiv and lrem; checks for 1810 // special case as described in JVM spec., p.243 & p.271. 1811 // 1812 // normal case special case 1813 // 1814 // input : rax: dividend min_long 1815 // reg: divisor -1 1816 // 1817 // output: rax: quotient (= rax idiv reg) min_long 1818 // rdx: remainder (= rax irem reg) 0 1819 // 1820 // Code sequnce: 1821 // 1822 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1823 // 7: 00 00 80 1824 // a: 48 39 d0 cmp %rdx,%rax 1825 // d: 75 08 jne 17 <normal> 1826 // f: 33 d2 xor %edx,%edx 1827 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1828 // 15: 74 05 je 1c <done> 1829 // 0000000000000017 <normal>: 1830 // 17: 48 99 cqto 1831 // 19: 48 f7 f9 idiv $div 1832 // 000000000000001c <done>: 1833 1834 // mov $0x8000000000000000,%rdx 1835 emit_opcode(cbuf, Assembler::REX_W); 1836 emit_opcode(cbuf, 0xBA); 1837 emit_d8(cbuf, 0x00); 1838 emit_d8(cbuf, 0x00); 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, 0x80); 1845 1846 // cmp %rdx,%rax 1847 emit_opcode(cbuf, Assembler::REX_W); 1848 emit_opcode(cbuf, 0x39); 1849 emit_d8(cbuf, 0xD0); 1850 1851 // jne 17 <normal> 1852 emit_opcode(cbuf, 0x75); 1853 emit_d8(cbuf, 0x08); 1854 1855 // xor %edx,%edx 1856 emit_opcode(cbuf, 0x33); 1857 emit_d8(cbuf, 0xD2); 1858 1859 // cmp $0xffffffffffffffff,$div 1860 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1861 emit_opcode(cbuf, 0x83); 1862 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1863 emit_d8(cbuf, 0xFF); 1864 1865 // je 1e <done> 1866 emit_opcode(cbuf, 0x74); 1867 emit_d8(cbuf, 0x05); 1868 1869 // <normal> 1870 // cqto 1871 emit_opcode(cbuf, Assembler::REX_W); 1872 emit_opcode(cbuf, 0x99); 1873 1874 // idivq (note: must be emitted by the user of this rule) 1875 // <done> 1876 %} 1877 1878 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1879 enc_class OpcSE(immI imm) 1880 %{ 1881 // Emit primary opcode and set sign-extend bit 1882 // Check for 8-bit immediate, and set sign extend bit in opcode 1883 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1884 emit_opcode(cbuf, $primary | 0x02); 1885 } else { 1886 // 32-bit immediate 1887 emit_opcode(cbuf, $primary); 1888 } 1889 %} 1890 1891 enc_class OpcSErm(rRegI dst, immI imm) 1892 %{ 1893 // OpcSEr/m 1894 int dstenc = $dst$$reg; 1895 if (dstenc >= 8) { 1896 emit_opcode(cbuf, Assembler::REX_B); 1897 dstenc -= 8; 1898 } 1899 // Emit primary opcode and set sign-extend bit 1900 // Check for 8-bit immediate, and set sign extend bit in opcode 1901 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1902 emit_opcode(cbuf, $primary | 0x02); 1903 } else { 1904 // 32-bit immediate 1905 emit_opcode(cbuf, $primary); 1906 } 1907 // Emit r/m byte with secondary opcode, after primary opcode. 1908 emit_rm(cbuf, 0x3, $secondary, dstenc); 1909 %} 1910 1911 enc_class OpcSErm_wide(rRegL dst, immI imm) 1912 %{ 1913 // OpcSEr/m 1914 int dstenc = $dst$$reg; 1915 if (dstenc < 8) { 1916 emit_opcode(cbuf, Assembler::REX_W); 1917 } else { 1918 emit_opcode(cbuf, Assembler::REX_WB); 1919 dstenc -= 8; 1920 } 1921 // Emit primary opcode and set sign-extend bit 1922 // Check for 8-bit immediate, and set sign extend bit in opcode 1923 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1924 emit_opcode(cbuf, $primary | 0x02); 1925 } else { 1926 // 32-bit immediate 1927 emit_opcode(cbuf, $primary); 1928 } 1929 // Emit r/m byte with secondary opcode, after primary opcode. 1930 emit_rm(cbuf, 0x3, $secondary, dstenc); 1931 %} 1932 1933 enc_class Con8or32(immI imm) 1934 %{ 1935 // Check for 8-bit immediate, and set sign extend bit in opcode 1936 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1937 $$$emit8$imm$$constant; 1938 } else { 1939 // 32-bit immediate 1940 $$$emit32$imm$$constant; 1941 } 1942 %} 1943 1944 enc_class opc2_reg(rRegI dst) 1945 %{ 1946 // BSWAP 1947 emit_cc(cbuf, $secondary, $dst$$reg); 1948 %} 1949 1950 enc_class opc3_reg(rRegI dst) 1951 %{ 1952 // BSWAP 1953 emit_cc(cbuf, $tertiary, $dst$$reg); 1954 %} 1955 1956 enc_class reg_opc(rRegI div) 1957 %{ 1958 // INC, DEC, IDIV, IMOD, JMP indirect, ... 1959 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 1960 %} 1961 1962 enc_class enc_cmov(cmpOp cop) 1963 %{ 1964 // CMOV 1965 $$$emit8$primary; 1966 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1967 %} 1968 1969 enc_class enc_PartialSubtypeCheck() 1970 %{ 1971 Register Rrdi = as_Register(RDI_enc); // result register 1972 Register Rrax = as_Register(RAX_enc); // super class 1973 Register Rrcx = as_Register(RCX_enc); // killed 1974 Register Rrsi = as_Register(RSI_enc); // sub class 1975 Label miss; 1976 const bool set_cond_codes = true; 1977 1978 MacroAssembler _masm(&cbuf); 1979 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1980 NULL, &miss, 1981 /*set_cond_codes:*/ true); 1982 if ($primary) { 1983 __ xorptr(Rrdi, Rrdi); 1984 } 1985 __ bind(miss); 1986 %} 1987 1988 enc_class clear_avx %{ 1989 debug_only(int off0 = cbuf.insts_size()); 1990 if (ra_->C->max_vector_size() > 16) { 1991 // Clear upper bits of YMM registers when current compiled code uses 1992 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1993 MacroAssembler _masm(&cbuf); 1994 __ vzeroupper(); 1995 } 1996 debug_only(int off1 = cbuf.insts_size()); 1997 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1998 %} 1999 2000 enc_class Java_To_Runtime(method meth) %{ 2001 // No relocation needed 2002 MacroAssembler _masm(&cbuf); 2003 __ mov64(r10, (int64_t) $meth$$method); 2004 __ call(r10); 2005 %} 2006 2007 enc_class Java_To_Interpreter(method meth) 2008 %{ 2009 // CALL Java_To_Interpreter 2010 // This is the instruction starting address for relocation info. 2011 cbuf.set_insts_mark(); 2012 $$$emit8$primary; 2013 // CALL directly to the runtime 2014 emit_d32_reloc(cbuf, 2015 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2016 runtime_call_Relocation::spec(), 2017 RELOC_DISP32); 2018 %} 2019 2020 enc_class Java_Static_Call(method meth) 2021 %{ 2022 // JAVA STATIC CALL 2023 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2024 // determine who we intended to call. 2025 cbuf.set_insts_mark(); 2026 $$$emit8$primary; 2027 2028 if (!_method) { 2029 emit_d32_reloc(cbuf, 2030 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2031 runtime_call_Relocation::spec(), 2032 RELOC_DISP32); 2033 } else if (_optimized_virtual) { 2034 emit_d32_reloc(cbuf, 2035 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2036 opt_virtual_call_Relocation::spec(), 2037 RELOC_DISP32); 2038 } else { 2039 emit_d32_reloc(cbuf, 2040 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2041 static_call_Relocation::spec(), 2042 RELOC_DISP32); 2043 } 2044 if (_method) { 2045 // Emit stub for static call. 2046 CompiledStaticCall::emit_to_interp_stub(cbuf); 2047 } 2048 %} 2049 2050 enc_class Java_Dynamic_Call(method meth) %{ 2051 MacroAssembler _masm(&cbuf); 2052 __ ic_call((address)$meth$$method); 2053 %} 2054 2055 enc_class Java_Compiled_Call(method meth) 2056 %{ 2057 // JAVA COMPILED CALL 2058 int disp = in_bytes(Method:: from_compiled_offset()); 2059 2060 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2061 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2062 2063 // callq *disp(%rax) 2064 cbuf.set_insts_mark(); 2065 $$$emit8$primary; 2066 if (disp < 0x80) { 2067 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2068 emit_d8(cbuf, disp); // Displacement 2069 } else { 2070 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2071 emit_d32(cbuf, disp); // Displacement 2072 } 2073 %} 2074 2075 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2076 %{ 2077 // SAL, SAR, SHR 2078 int dstenc = $dst$$reg; 2079 if (dstenc >= 8) { 2080 emit_opcode(cbuf, Assembler::REX_B); 2081 dstenc -= 8; 2082 } 2083 $$$emit8$primary; 2084 emit_rm(cbuf, 0x3, $secondary, dstenc); 2085 $$$emit8$shift$$constant; 2086 %} 2087 2088 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2089 %{ 2090 // SAL, SAR, SHR 2091 int dstenc = $dst$$reg; 2092 if (dstenc < 8) { 2093 emit_opcode(cbuf, Assembler::REX_W); 2094 } else { 2095 emit_opcode(cbuf, Assembler::REX_WB); 2096 dstenc -= 8; 2097 } 2098 $$$emit8$primary; 2099 emit_rm(cbuf, 0x3, $secondary, dstenc); 2100 $$$emit8$shift$$constant; 2101 %} 2102 2103 enc_class load_immI(rRegI dst, immI src) 2104 %{ 2105 int dstenc = $dst$$reg; 2106 if (dstenc >= 8) { 2107 emit_opcode(cbuf, Assembler::REX_B); 2108 dstenc -= 8; 2109 } 2110 emit_opcode(cbuf, 0xB8 | dstenc); 2111 $$$emit32$src$$constant; 2112 %} 2113 2114 enc_class load_immL(rRegL dst, immL src) 2115 %{ 2116 int dstenc = $dst$$reg; 2117 if (dstenc < 8) { 2118 emit_opcode(cbuf, Assembler::REX_W); 2119 } else { 2120 emit_opcode(cbuf, Assembler::REX_WB); 2121 dstenc -= 8; 2122 } 2123 emit_opcode(cbuf, 0xB8 | dstenc); 2124 emit_d64(cbuf, $src$$constant); 2125 %} 2126 2127 enc_class load_immUL32(rRegL dst, immUL32 src) 2128 %{ 2129 // same as load_immI, but this time we care about zeroes in the high word 2130 int dstenc = $dst$$reg; 2131 if (dstenc >= 8) { 2132 emit_opcode(cbuf, Assembler::REX_B); 2133 dstenc -= 8; 2134 } 2135 emit_opcode(cbuf, 0xB8 | dstenc); 2136 $$$emit32$src$$constant; 2137 %} 2138 2139 enc_class load_immL32(rRegL dst, immL32 src) 2140 %{ 2141 int dstenc = $dst$$reg; 2142 if (dstenc < 8) { 2143 emit_opcode(cbuf, Assembler::REX_W); 2144 } else { 2145 emit_opcode(cbuf, Assembler::REX_WB); 2146 dstenc -= 8; 2147 } 2148 emit_opcode(cbuf, 0xC7); 2149 emit_rm(cbuf, 0x03, 0x00, dstenc); 2150 $$$emit32$src$$constant; 2151 %} 2152 2153 enc_class load_immP31(rRegP dst, immP32 src) 2154 %{ 2155 // same as load_immI, but this time we care about zeroes in the high word 2156 int dstenc = $dst$$reg; 2157 if (dstenc >= 8) { 2158 emit_opcode(cbuf, Assembler::REX_B); 2159 dstenc -= 8; 2160 } 2161 emit_opcode(cbuf, 0xB8 | dstenc); 2162 $$$emit32$src$$constant; 2163 %} 2164 2165 enc_class load_immP(rRegP dst, immP src) 2166 %{ 2167 int dstenc = $dst$$reg; 2168 if (dstenc < 8) { 2169 emit_opcode(cbuf, Assembler::REX_W); 2170 } else { 2171 emit_opcode(cbuf, Assembler::REX_WB); 2172 dstenc -= 8; 2173 } 2174 emit_opcode(cbuf, 0xB8 | dstenc); 2175 // This next line should be generated from ADLC 2176 if ($src->constant_reloc() != relocInfo::none) { 2177 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2178 } else { 2179 emit_d64(cbuf, $src$$constant); 2180 } 2181 %} 2182 2183 enc_class Con32(immI src) 2184 %{ 2185 // Output immediate 2186 $$$emit32$src$$constant; 2187 %} 2188 2189 enc_class Con32F_as_bits(immF src) 2190 %{ 2191 // Output Float immediate bits 2192 jfloat jf = $src$$constant; 2193 jint jf_as_bits = jint_cast(jf); 2194 emit_d32(cbuf, jf_as_bits); 2195 %} 2196 2197 enc_class Con16(immI src) 2198 %{ 2199 // Output immediate 2200 $$$emit16$src$$constant; 2201 %} 2202 2203 // How is this different from Con32??? XXX 2204 enc_class Con_d32(immI src) 2205 %{ 2206 emit_d32(cbuf,$src$$constant); 2207 %} 2208 2209 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2210 // Output immediate memory reference 2211 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2212 emit_d32(cbuf, 0x00); 2213 %} 2214 2215 enc_class lock_prefix() 2216 %{ 2217 if (os::is_MP()) { 2218 emit_opcode(cbuf, 0xF0); // lock 2219 } 2220 %} 2221 2222 enc_class REX_mem(memory mem) 2223 %{ 2224 if ($mem$$base >= 8) { 2225 if ($mem$$index < 8) { 2226 emit_opcode(cbuf, Assembler::REX_B); 2227 } else { 2228 emit_opcode(cbuf, Assembler::REX_XB); 2229 } 2230 } else { 2231 if ($mem$$index >= 8) { 2232 emit_opcode(cbuf, Assembler::REX_X); 2233 } 2234 } 2235 %} 2236 2237 enc_class REX_mem_wide(memory mem) 2238 %{ 2239 if ($mem$$base >= 8) { 2240 if ($mem$$index < 8) { 2241 emit_opcode(cbuf, Assembler::REX_WB); 2242 } else { 2243 emit_opcode(cbuf, Assembler::REX_WXB); 2244 } 2245 } else { 2246 if ($mem$$index < 8) { 2247 emit_opcode(cbuf, Assembler::REX_W); 2248 } else { 2249 emit_opcode(cbuf, Assembler::REX_WX); 2250 } 2251 } 2252 %} 2253 2254 // for byte regs 2255 enc_class REX_breg(rRegI reg) 2256 %{ 2257 if ($reg$$reg >= 4) { 2258 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2259 } 2260 %} 2261 2262 // for byte regs 2263 enc_class REX_reg_breg(rRegI dst, rRegI src) 2264 %{ 2265 if ($dst$$reg < 8) { 2266 if ($src$$reg >= 4) { 2267 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2268 } 2269 } else { 2270 if ($src$$reg < 8) { 2271 emit_opcode(cbuf, Assembler::REX_R); 2272 } else { 2273 emit_opcode(cbuf, Assembler::REX_RB); 2274 } 2275 } 2276 %} 2277 2278 // for byte regs 2279 enc_class REX_breg_mem(rRegI reg, memory mem) 2280 %{ 2281 if ($reg$$reg < 8) { 2282 if ($mem$$base < 8) { 2283 if ($mem$$index >= 8) { 2284 emit_opcode(cbuf, Assembler::REX_X); 2285 } else if ($reg$$reg >= 4) { 2286 emit_opcode(cbuf, Assembler::REX); 2287 } 2288 } else { 2289 if ($mem$$index < 8) { 2290 emit_opcode(cbuf, Assembler::REX_B); 2291 } else { 2292 emit_opcode(cbuf, Assembler::REX_XB); 2293 } 2294 } 2295 } else { 2296 if ($mem$$base < 8) { 2297 if ($mem$$index < 8) { 2298 emit_opcode(cbuf, Assembler::REX_R); 2299 } else { 2300 emit_opcode(cbuf, Assembler::REX_RX); 2301 } 2302 } else { 2303 if ($mem$$index < 8) { 2304 emit_opcode(cbuf, Assembler::REX_RB); 2305 } else { 2306 emit_opcode(cbuf, Assembler::REX_RXB); 2307 } 2308 } 2309 } 2310 %} 2311 2312 enc_class REX_reg(rRegI reg) 2313 %{ 2314 if ($reg$$reg >= 8) { 2315 emit_opcode(cbuf, Assembler::REX_B); 2316 } 2317 %} 2318 2319 enc_class REX_reg_wide(rRegI reg) 2320 %{ 2321 if ($reg$$reg < 8) { 2322 emit_opcode(cbuf, Assembler::REX_W); 2323 } else { 2324 emit_opcode(cbuf, Assembler::REX_WB); 2325 } 2326 %} 2327 2328 enc_class REX_reg_reg(rRegI dst, rRegI src) 2329 %{ 2330 if ($dst$$reg < 8) { 2331 if ($src$$reg >= 8) { 2332 emit_opcode(cbuf, Assembler::REX_B); 2333 } 2334 } else { 2335 if ($src$$reg < 8) { 2336 emit_opcode(cbuf, Assembler::REX_R); 2337 } else { 2338 emit_opcode(cbuf, Assembler::REX_RB); 2339 } 2340 } 2341 %} 2342 2343 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2344 %{ 2345 if ($dst$$reg < 8) { 2346 if ($src$$reg < 8) { 2347 emit_opcode(cbuf, Assembler::REX_W); 2348 } else { 2349 emit_opcode(cbuf, Assembler::REX_WB); 2350 } 2351 } else { 2352 if ($src$$reg < 8) { 2353 emit_opcode(cbuf, Assembler::REX_WR); 2354 } else { 2355 emit_opcode(cbuf, Assembler::REX_WRB); 2356 } 2357 } 2358 %} 2359 2360 enc_class REX_reg_mem(rRegI reg, memory mem) 2361 %{ 2362 if ($reg$$reg < 8) { 2363 if ($mem$$base < 8) { 2364 if ($mem$$index >= 8) { 2365 emit_opcode(cbuf, Assembler::REX_X); 2366 } 2367 } else { 2368 if ($mem$$index < 8) { 2369 emit_opcode(cbuf, Assembler::REX_B); 2370 } else { 2371 emit_opcode(cbuf, Assembler::REX_XB); 2372 } 2373 } 2374 } else { 2375 if ($mem$$base < 8) { 2376 if ($mem$$index < 8) { 2377 emit_opcode(cbuf, Assembler::REX_R); 2378 } else { 2379 emit_opcode(cbuf, Assembler::REX_RX); 2380 } 2381 } else { 2382 if ($mem$$index < 8) { 2383 emit_opcode(cbuf, Assembler::REX_RB); 2384 } else { 2385 emit_opcode(cbuf, Assembler::REX_RXB); 2386 } 2387 } 2388 } 2389 %} 2390 2391 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2392 %{ 2393 if ($reg$$reg < 8) { 2394 if ($mem$$base < 8) { 2395 if ($mem$$index < 8) { 2396 emit_opcode(cbuf, Assembler::REX_W); 2397 } else { 2398 emit_opcode(cbuf, Assembler::REX_WX); 2399 } 2400 } else { 2401 if ($mem$$index < 8) { 2402 emit_opcode(cbuf, Assembler::REX_WB); 2403 } else { 2404 emit_opcode(cbuf, Assembler::REX_WXB); 2405 } 2406 } 2407 } else { 2408 if ($mem$$base < 8) { 2409 if ($mem$$index < 8) { 2410 emit_opcode(cbuf, Assembler::REX_WR); 2411 } else { 2412 emit_opcode(cbuf, Assembler::REX_WRX); 2413 } 2414 } else { 2415 if ($mem$$index < 8) { 2416 emit_opcode(cbuf, Assembler::REX_WRB); 2417 } else { 2418 emit_opcode(cbuf, Assembler::REX_WRXB); 2419 } 2420 } 2421 } 2422 %} 2423 2424 enc_class reg_mem(rRegI ereg, memory mem) 2425 %{ 2426 // High registers handle in encode_RegMem 2427 int reg = $ereg$$reg; 2428 int base = $mem$$base; 2429 int index = $mem$$index; 2430 int scale = $mem$$scale; 2431 int disp = $mem$$disp; 2432 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2433 2434 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2435 %} 2436 2437 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2438 %{ 2439 int rm_byte_opcode = $rm_opcode$$constant; 2440 2441 // High registers handle in encode_RegMem 2442 int base = $mem$$base; 2443 int index = $mem$$index; 2444 int scale = $mem$$scale; 2445 int displace = $mem$$disp; 2446 2447 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2448 // working with static 2449 // globals 2450 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2451 disp_reloc); 2452 %} 2453 2454 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2455 %{ 2456 int reg_encoding = $dst$$reg; 2457 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2458 int index = 0x04; // 0x04 indicates no index 2459 int scale = 0x00; // 0x00 indicates no scale 2460 int displace = $src1$$constant; // 0x00 indicates no displacement 2461 relocInfo::relocType disp_reloc = relocInfo::none; 2462 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2463 disp_reloc); 2464 %} 2465 2466 enc_class neg_reg(rRegI dst) 2467 %{ 2468 int dstenc = $dst$$reg; 2469 if (dstenc >= 8) { 2470 emit_opcode(cbuf, Assembler::REX_B); 2471 dstenc -= 8; 2472 } 2473 // NEG $dst 2474 emit_opcode(cbuf, 0xF7); 2475 emit_rm(cbuf, 0x3, 0x03, dstenc); 2476 %} 2477 2478 enc_class neg_reg_wide(rRegI dst) 2479 %{ 2480 int dstenc = $dst$$reg; 2481 if (dstenc < 8) { 2482 emit_opcode(cbuf, Assembler::REX_W); 2483 } else { 2484 emit_opcode(cbuf, Assembler::REX_WB); 2485 dstenc -= 8; 2486 } 2487 // NEG $dst 2488 emit_opcode(cbuf, 0xF7); 2489 emit_rm(cbuf, 0x3, 0x03, dstenc); 2490 %} 2491 2492 enc_class setLT_reg(rRegI dst) 2493 %{ 2494 int dstenc = $dst$$reg; 2495 if (dstenc >= 8) { 2496 emit_opcode(cbuf, Assembler::REX_B); 2497 dstenc -= 8; 2498 } else if (dstenc >= 4) { 2499 emit_opcode(cbuf, Assembler::REX); 2500 } 2501 // SETLT $dst 2502 emit_opcode(cbuf, 0x0F); 2503 emit_opcode(cbuf, 0x9C); 2504 emit_rm(cbuf, 0x3, 0x0, dstenc); 2505 %} 2506 2507 enc_class setNZ_reg(rRegI dst) 2508 %{ 2509 int dstenc = $dst$$reg; 2510 if (dstenc >= 8) { 2511 emit_opcode(cbuf, Assembler::REX_B); 2512 dstenc -= 8; 2513 } else if (dstenc >= 4) { 2514 emit_opcode(cbuf, Assembler::REX); 2515 } 2516 // SETNZ $dst 2517 emit_opcode(cbuf, 0x0F); 2518 emit_opcode(cbuf, 0x95); 2519 emit_rm(cbuf, 0x3, 0x0, dstenc); 2520 %} 2521 2522 2523 // Compare the lonogs and set -1, 0, or 1 into dst 2524 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2525 %{ 2526 int src1enc = $src1$$reg; 2527 int src2enc = $src2$$reg; 2528 int dstenc = $dst$$reg; 2529 2530 // cmpq $src1, $src2 2531 if (src1enc < 8) { 2532 if (src2enc < 8) { 2533 emit_opcode(cbuf, Assembler::REX_W); 2534 } else { 2535 emit_opcode(cbuf, Assembler::REX_WB); 2536 } 2537 } else { 2538 if (src2enc < 8) { 2539 emit_opcode(cbuf, Assembler::REX_WR); 2540 } else { 2541 emit_opcode(cbuf, Assembler::REX_WRB); 2542 } 2543 } 2544 emit_opcode(cbuf, 0x3B); 2545 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2546 2547 // movl $dst, -1 2548 if (dstenc >= 8) { 2549 emit_opcode(cbuf, Assembler::REX_B); 2550 } 2551 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2552 emit_d32(cbuf, -1); 2553 2554 // jl,s done 2555 emit_opcode(cbuf, 0x7C); 2556 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2557 2558 // setne $dst 2559 if (dstenc >= 4) { 2560 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2561 } 2562 emit_opcode(cbuf, 0x0F); 2563 emit_opcode(cbuf, 0x95); 2564 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2565 2566 // movzbl $dst, $dst 2567 if (dstenc >= 4) { 2568 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2569 } 2570 emit_opcode(cbuf, 0x0F); 2571 emit_opcode(cbuf, 0xB6); 2572 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2573 %} 2574 2575 enc_class Push_ResultXD(regD dst) %{ 2576 MacroAssembler _masm(&cbuf); 2577 __ fstp_d(Address(rsp, 0)); 2578 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2579 __ addptr(rsp, 8); 2580 %} 2581 2582 enc_class Push_SrcXD(regD src) %{ 2583 MacroAssembler _masm(&cbuf); 2584 __ subptr(rsp, 8); 2585 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2586 __ fld_d(Address(rsp, 0)); 2587 %} 2588 2589 2590 enc_class enc_rethrow() 2591 %{ 2592 cbuf.set_insts_mark(); 2593 emit_opcode(cbuf, 0xE9); // jmp entry 2594 emit_d32_reloc(cbuf, 2595 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2596 runtime_call_Relocation::spec(), 2597 RELOC_DISP32); 2598 %} 2599 2600 %} 2601 2602 2603 2604 //----------FRAME-------------------------------------------------------------- 2605 // Definition of frame structure and management information. 2606 // 2607 // S T A C K L A Y O U T Allocators stack-slot number 2608 // | (to get allocators register number 2609 // G Owned by | | v add OptoReg::stack0()) 2610 // r CALLER | | 2611 // o | +--------+ pad to even-align allocators stack-slot 2612 // w V | pad0 | numbers; owned by CALLER 2613 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2614 // h ^ | in | 5 2615 // | | args | 4 Holes in incoming args owned by SELF 2616 // | | | | 3 2617 // | | +--------+ 2618 // V | | old out| Empty on Intel, window on Sparc 2619 // | old |preserve| Must be even aligned. 2620 // | SP-+--------+----> Matcher::_old_SP, even aligned 2621 // | | in | 3 area for Intel ret address 2622 // Owned by |preserve| Empty on Sparc. 2623 // SELF +--------+ 2624 // | | pad2 | 2 pad to align old SP 2625 // | +--------+ 1 2626 // | | locks | 0 2627 // | +--------+----> OptoReg::stack0(), even aligned 2628 // | | pad1 | 11 pad to align new SP 2629 // | +--------+ 2630 // | | | 10 2631 // | | spills | 9 spills 2632 // V | | 8 (pad0 slot for callee) 2633 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2634 // ^ | out | 7 2635 // | | args | 6 Holes in outgoing args owned by CALLEE 2636 // Owned by +--------+ 2637 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2638 // | new |preserve| Must be even-aligned. 2639 // | SP-+--------+----> Matcher::_new_SP, even aligned 2640 // | | | 2641 // 2642 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2643 // known from SELF's arguments and the Java calling convention. 2644 // Region 6-7 is determined per call site. 2645 // Note 2: If the calling convention leaves holes in the incoming argument 2646 // area, those holes are owned by SELF. Holes in the outgoing area 2647 // are owned by the CALLEE. Holes should not be nessecary in the 2648 // incoming area, as the Java calling convention is completely under 2649 // the control of the AD file. Doubles can be sorted and packed to 2650 // avoid holes. Holes in the outgoing arguments may be nessecary for 2651 // varargs C calling conventions. 2652 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2653 // even aligned with pad0 as needed. 2654 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2655 // region 6-11 is even aligned; it may be padded out more so that 2656 // the region from SP to FP meets the minimum stack alignment. 2657 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2658 // alignment. Region 11, pad1, may be dynamically extended so that 2659 // SP meets the minimum alignment. 2660 2661 frame 2662 %{ 2663 // What direction does stack grow in (assumed to be same for C & Java) 2664 stack_direction(TOWARDS_LOW); 2665 2666 // These three registers define part of the calling convention 2667 // between compiled code and the interpreter. 2668 inline_cache_reg(RAX); // Inline Cache Register 2669 interpreter_method_oop_reg(RBX); // Method Oop Register when 2670 // calling interpreter 2671 2672 // Optional: name the operand used by cisc-spilling to access 2673 // [stack_pointer + offset] 2674 cisc_spilling_operand_name(indOffset32); 2675 2676 // Number of stack slots consumed by locking an object 2677 sync_stack_slots(2); 2678 2679 // Compiled code's Frame Pointer 2680 frame_pointer(RSP); 2681 2682 // Interpreter stores its frame pointer in a register which is 2683 // stored to the stack by I2CAdaptors. 2684 // I2CAdaptors convert from interpreted java to compiled java. 2685 interpreter_frame_pointer(RBP); 2686 2687 // Stack alignment requirement 2688 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2689 2690 // Number of stack slots between incoming argument block and the start of 2691 // a new frame. The PROLOG must add this many slots to the stack. The 2692 // EPILOG must remove this many slots. amd64 needs two slots for 2693 // return address. 2694 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2695 2696 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2697 // for calls to C. Supports the var-args backing area for register parms. 2698 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2699 2700 // The after-PROLOG location of the return address. Location of 2701 // return address specifies a type (REG or STACK) and a number 2702 // representing the register number (i.e. - use a register name) or 2703 // stack slot. 2704 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2705 // Otherwise, it is above the locks and verification slot and alignment word 2706 return_addr(STACK - 2 + 2707 round_to((Compile::current()->in_preserve_stack_slots() + 2708 Compile::current()->fixed_slots()), 2709 stack_alignment_in_slots())); 2710 2711 // Body of function which returns an integer array locating 2712 // arguments either in registers or in stack slots. Passed an array 2713 // of ideal registers called "sig" and a "length" count. Stack-slot 2714 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2715 // arguments for a CALLEE. Incoming stack arguments are 2716 // automatically biased by the preserve_stack_slots field above. 2717 2718 calling_convention 2719 %{ 2720 // No difference between ingoing/outgoing just pass false 2721 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2722 %} 2723 2724 c_calling_convention 2725 %{ 2726 // This is obviously always outgoing 2727 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2728 %} 2729 2730 // Location of compiled Java return values. Same as C for now. 2731 return_value 2732 %{ 2733 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2734 "only return normal values"); 2735 2736 static const int lo[Op_RegL + 1] = { 2737 0, 2738 0, 2739 RAX_num, // Op_RegN 2740 RAX_num, // Op_RegI 2741 RAX_num, // Op_RegP 2742 XMM0_num, // Op_RegF 2743 XMM0_num, // Op_RegD 2744 RAX_num // Op_RegL 2745 }; 2746 static const int hi[Op_RegL + 1] = { 2747 0, 2748 0, 2749 OptoReg::Bad, // Op_RegN 2750 OptoReg::Bad, // Op_RegI 2751 RAX_H_num, // Op_RegP 2752 OptoReg::Bad, // Op_RegF 2753 XMM0b_num, // Op_RegD 2754 RAX_H_num // Op_RegL 2755 }; 2756 // Excluded flags and vector registers. 2757 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type"); 2758 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2759 %} 2760 %} 2761 2762 //----------ATTRIBUTES--------------------------------------------------------- 2763 //----------Operand Attributes------------------------------------------------- 2764 op_attrib op_cost(0); // Required cost attribute 2765 2766 //----------Instruction Attributes--------------------------------------------- 2767 ins_attrib ins_cost(100); // Required cost attribute 2768 ins_attrib ins_size(8); // Required size attribute (in bits) 2769 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2770 // a non-matching short branch variant 2771 // of some long branch? 2772 ins_attrib ins_alignment(1); // Required alignment attribute (must 2773 // be a power of 2) specifies the 2774 // alignment that some part of the 2775 // instruction (not necessarily the 2776 // start) requires. If > 1, a 2777 // compute_padding() function must be 2778 // provided for the instruction 2779 2780 //----------OPERANDS----------------------------------------------------------- 2781 // Operand definitions must precede instruction definitions for correct parsing 2782 // in the ADLC because operands constitute user defined types which are used in 2783 // instruction definitions. 2784 2785 //----------Simple Operands---------------------------------------------------- 2786 // Immediate Operands 2787 // Integer Immediate 2788 operand immI() 2789 %{ 2790 match(ConI); 2791 2792 op_cost(10); 2793 format %{ %} 2794 interface(CONST_INTER); 2795 %} 2796 2797 // Constant for test vs zero 2798 operand immI0() 2799 %{ 2800 predicate(n->get_int() == 0); 2801 match(ConI); 2802 2803 op_cost(0); 2804 format %{ %} 2805 interface(CONST_INTER); 2806 %} 2807 2808 // Constant for increment 2809 operand immI1() 2810 %{ 2811 predicate(n->get_int() == 1); 2812 match(ConI); 2813 2814 op_cost(0); 2815 format %{ %} 2816 interface(CONST_INTER); 2817 %} 2818 2819 // Constant for decrement 2820 operand immI_M1() 2821 %{ 2822 predicate(n->get_int() == -1); 2823 match(ConI); 2824 2825 op_cost(0); 2826 format %{ %} 2827 interface(CONST_INTER); 2828 %} 2829 2830 // Valid scale values for addressing modes 2831 operand immI2() 2832 %{ 2833 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2834 match(ConI); 2835 2836 format %{ %} 2837 interface(CONST_INTER); 2838 %} 2839 2840 operand immI8() 2841 %{ 2842 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2843 match(ConI); 2844 2845 op_cost(5); 2846 format %{ %} 2847 interface(CONST_INTER); 2848 %} 2849 2850 operand immI16() 2851 %{ 2852 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2853 match(ConI); 2854 2855 op_cost(10); 2856 format %{ %} 2857 interface(CONST_INTER); 2858 %} 2859 2860 // Int Immediate non-negative 2861 operand immU31() 2862 %{ 2863 predicate(n->get_int() >= 0); 2864 match(ConI); 2865 2866 op_cost(0); 2867 format %{ %} 2868 interface(CONST_INTER); 2869 %} 2870 2871 // Constant for long shifts 2872 operand immI_32() 2873 %{ 2874 predicate( n->get_int() == 32 ); 2875 match(ConI); 2876 2877 op_cost(0); 2878 format %{ %} 2879 interface(CONST_INTER); 2880 %} 2881 2882 // Constant for long shifts 2883 operand immI_64() 2884 %{ 2885 predicate( n->get_int() == 64 ); 2886 match(ConI); 2887 2888 op_cost(0); 2889 format %{ %} 2890 interface(CONST_INTER); 2891 %} 2892 2893 // Pointer Immediate 2894 operand immP() 2895 %{ 2896 match(ConP); 2897 2898 op_cost(10); 2899 format %{ %} 2900 interface(CONST_INTER); 2901 %} 2902 2903 // NULL Pointer Immediate 2904 operand immP0() 2905 %{ 2906 predicate(n->get_ptr() == 0); 2907 match(ConP); 2908 2909 op_cost(5); 2910 format %{ %} 2911 interface(CONST_INTER); 2912 %} 2913 2914 // Pointer Immediate 2915 operand immN() %{ 2916 match(ConN); 2917 2918 op_cost(10); 2919 format %{ %} 2920 interface(CONST_INTER); 2921 %} 2922 2923 operand immNKlass() %{ 2924 match(ConNKlass); 2925 2926 op_cost(10); 2927 format %{ %} 2928 interface(CONST_INTER); 2929 %} 2930 2931 // NULL Pointer Immediate 2932 operand immN0() %{ 2933 predicate(n->get_narrowcon() == 0); 2934 match(ConN); 2935 2936 op_cost(5); 2937 format %{ %} 2938 interface(CONST_INTER); 2939 %} 2940 2941 operand immP31() 2942 %{ 2943 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2944 && (n->get_ptr() >> 31) == 0); 2945 match(ConP); 2946 2947 op_cost(5); 2948 format %{ %} 2949 interface(CONST_INTER); 2950 %} 2951 2952 2953 // Long Immediate 2954 operand immL() 2955 %{ 2956 match(ConL); 2957 2958 op_cost(20); 2959 format %{ %} 2960 interface(CONST_INTER); 2961 %} 2962 2963 // Long Immediate 8-bit 2964 operand immL8() 2965 %{ 2966 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2967 match(ConL); 2968 2969 op_cost(5); 2970 format %{ %} 2971 interface(CONST_INTER); 2972 %} 2973 2974 // Long Immediate 32-bit unsigned 2975 operand immUL32() 2976 %{ 2977 predicate(n->get_long() == (unsigned int) (n->get_long())); 2978 match(ConL); 2979 2980 op_cost(10); 2981 format %{ %} 2982 interface(CONST_INTER); 2983 %} 2984 2985 // Long Immediate 32-bit signed 2986 operand immL32() 2987 %{ 2988 predicate(n->get_long() == (int) (n->get_long())); 2989 match(ConL); 2990 2991 op_cost(15); 2992 format %{ %} 2993 interface(CONST_INTER); 2994 %} 2995 2996 // Long Immediate zero 2997 operand immL0() 2998 %{ 2999 predicate(n->get_long() == 0L); 3000 match(ConL); 3001 3002 op_cost(10); 3003 format %{ %} 3004 interface(CONST_INTER); 3005 %} 3006 3007 // Constant for increment 3008 operand immL1() 3009 %{ 3010 predicate(n->get_long() == 1); 3011 match(ConL); 3012 3013 format %{ %} 3014 interface(CONST_INTER); 3015 %} 3016 3017 // Constant for decrement 3018 operand immL_M1() 3019 %{ 3020 predicate(n->get_long() == -1); 3021 match(ConL); 3022 3023 format %{ %} 3024 interface(CONST_INTER); 3025 %} 3026 3027 // Long Immediate: the value 10 3028 operand immL10() 3029 %{ 3030 predicate(n->get_long() == 10); 3031 match(ConL); 3032 3033 format %{ %} 3034 interface(CONST_INTER); 3035 %} 3036 3037 // Long immediate from 0 to 127. 3038 // Used for a shorter form of long mul by 10. 3039 operand immL_127() 3040 %{ 3041 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3042 match(ConL); 3043 3044 op_cost(10); 3045 format %{ %} 3046 interface(CONST_INTER); 3047 %} 3048 3049 // Long Immediate: low 32-bit mask 3050 operand immL_32bits() 3051 %{ 3052 predicate(n->get_long() == 0xFFFFFFFFL); 3053 match(ConL); 3054 op_cost(20); 3055 3056 format %{ %} 3057 interface(CONST_INTER); 3058 %} 3059 3060 // Float Immediate zero 3061 operand immF0() 3062 %{ 3063 predicate(jint_cast(n->getf()) == 0); 3064 match(ConF); 3065 3066 op_cost(5); 3067 format %{ %} 3068 interface(CONST_INTER); 3069 %} 3070 3071 // Float Immediate 3072 operand immF() 3073 %{ 3074 match(ConF); 3075 3076 op_cost(15); 3077 format %{ %} 3078 interface(CONST_INTER); 3079 %} 3080 3081 // Double Immediate zero 3082 operand immD0() 3083 %{ 3084 predicate(jlong_cast(n->getd()) == 0); 3085 match(ConD); 3086 3087 op_cost(5); 3088 format %{ %} 3089 interface(CONST_INTER); 3090 %} 3091 3092 // Double Immediate 3093 operand immD() 3094 %{ 3095 match(ConD); 3096 3097 op_cost(15); 3098 format %{ %} 3099 interface(CONST_INTER); 3100 %} 3101 3102 // Immediates for special shifts (sign extend) 3103 3104 // Constants for increment 3105 operand immI_16() 3106 %{ 3107 predicate(n->get_int() == 16); 3108 match(ConI); 3109 3110 format %{ %} 3111 interface(CONST_INTER); 3112 %} 3113 3114 operand immI_24() 3115 %{ 3116 predicate(n->get_int() == 24); 3117 match(ConI); 3118 3119 format %{ %} 3120 interface(CONST_INTER); 3121 %} 3122 3123 // Constant for byte-wide masking 3124 operand immI_255() 3125 %{ 3126 predicate(n->get_int() == 255); 3127 match(ConI); 3128 3129 format %{ %} 3130 interface(CONST_INTER); 3131 %} 3132 3133 // Constant for short-wide masking 3134 operand immI_65535() 3135 %{ 3136 predicate(n->get_int() == 65535); 3137 match(ConI); 3138 3139 format %{ %} 3140 interface(CONST_INTER); 3141 %} 3142 3143 // Constant for byte-wide masking 3144 operand immL_255() 3145 %{ 3146 predicate(n->get_long() == 255); 3147 match(ConL); 3148 3149 format %{ %} 3150 interface(CONST_INTER); 3151 %} 3152 3153 // Constant for short-wide masking 3154 operand immL_65535() 3155 %{ 3156 predicate(n->get_long() == 65535); 3157 match(ConL); 3158 3159 format %{ %} 3160 interface(CONST_INTER); 3161 %} 3162 3163 // Register Operands 3164 // Integer Register 3165 operand rRegI() 3166 %{ 3167 constraint(ALLOC_IN_RC(int_reg)); 3168 match(RegI); 3169 3170 match(rax_RegI); 3171 match(rbx_RegI); 3172 match(rcx_RegI); 3173 match(rdx_RegI); 3174 match(rdi_RegI); 3175 3176 format %{ %} 3177 interface(REG_INTER); 3178 %} 3179 3180 // Special Registers 3181 operand rax_RegI() 3182 %{ 3183 constraint(ALLOC_IN_RC(int_rax_reg)); 3184 match(RegI); 3185 match(rRegI); 3186 3187 format %{ "RAX" %} 3188 interface(REG_INTER); 3189 %} 3190 3191 // Special Registers 3192 operand rbx_RegI() 3193 %{ 3194 constraint(ALLOC_IN_RC(int_rbx_reg)); 3195 match(RegI); 3196 match(rRegI); 3197 3198 format %{ "RBX" %} 3199 interface(REG_INTER); 3200 %} 3201 3202 operand rcx_RegI() 3203 %{ 3204 constraint(ALLOC_IN_RC(int_rcx_reg)); 3205 match(RegI); 3206 match(rRegI); 3207 3208 format %{ "RCX" %} 3209 interface(REG_INTER); 3210 %} 3211 3212 operand rdx_RegI() 3213 %{ 3214 constraint(ALLOC_IN_RC(int_rdx_reg)); 3215 match(RegI); 3216 match(rRegI); 3217 3218 format %{ "RDX" %} 3219 interface(REG_INTER); 3220 %} 3221 3222 operand rdi_RegI() 3223 %{ 3224 constraint(ALLOC_IN_RC(int_rdi_reg)); 3225 match(RegI); 3226 match(rRegI); 3227 3228 format %{ "RDI" %} 3229 interface(REG_INTER); 3230 %} 3231 3232 operand no_rcx_RegI() 3233 %{ 3234 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3235 match(RegI); 3236 match(rax_RegI); 3237 match(rbx_RegI); 3238 match(rdx_RegI); 3239 match(rdi_RegI); 3240 3241 format %{ %} 3242 interface(REG_INTER); 3243 %} 3244 3245 operand no_rax_rdx_RegI() 3246 %{ 3247 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3248 match(RegI); 3249 match(rbx_RegI); 3250 match(rcx_RegI); 3251 match(rdi_RegI); 3252 3253 format %{ %} 3254 interface(REG_INTER); 3255 %} 3256 3257 // Pointer Register 3258 operand any_RegP() 3259 %{ 3260 constraint(ALLOC_IN_RC(any_reg)); 3261 match(RegP); 3262 match(rax_RegP); 3263 match(rbx_RegP); 3264 match(rdi_RegP); 3265 match(rsi_RegP); 3266 match(rbp_RegP); 3267 match(r15_RegP); 3268 match(rRegP); 3269 3270 format %{ %} 3271 interface(REG_INTER); 3272 %} 3273 3274 operand rRegP() 3275 %{ 3276 constraint(ALLOC_IN_RC(ptr_reg)); 3277 match(RegP); 3278 match(rax_RegP); 3279 match(rbx_RegP); 3280 match(rdi_RegP); 3281 match(rsi_RegP); 3282 match(rbp_RegP); 3283 match(r15_RegP); // See Q&A below about r15_RegP. 3284 3285 format %{ %} 3286 interface(REG_INTER); 3287 %} 3288 3289 operand rRegN() %{ 3290 constraint(ALLOC_IN_RC(int_reg)); 3291 match(RegN); 3292 3293 format %{ %} 3294 interface(REG_INTER); 3295 %} 3296 3297 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3298 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3299 // It's fine for an instruction input which expects rRegP to match a r15_RegP. 3300 // The output of an instruction is controlled by the allocator, which respects 3301 // register class masks, not match rules. Unless an instruction mentions 3302 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3303 // by the allocator as an input. 3304 3305 operand no_rax_RegP() 3306 %{ 3307 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3308 match(RegP); 3309 match(rbx_RegP); 3310 match(rsi_RegP); 3311 match(rdi_RegP); 3312 3313 format %{ %} 3314 interface(REG_INTER); 3315 %} 3316 3317 operand no_rbp_RegP() 3318 %{ 3319 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 3320 match(RegP); 3321 match(rbx_RegP); 3322 match(rsi_RegP); 3323 match(rdi_RegP); 3324 3325 format %{ %} 3326 interface(REG_INTER); 3327 %} 3328 3329 operand no_rax_rbx_RegP() 3330 %{ 3331 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3332 match(RegP); 3333 match(rsi_RegP); 3334 match(rdi_RegP); 3335 3336 format %{ %} 3337 interface(REG_INTER); 3338 %} 3339 3340 // Special Registers 3341 // Return a pointer value 3342 operand rax_RegP() 3343 %{ 3344 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3345 match(RegP); 3346 match(rRegP); 3347 3348 format %{ %} 3349 interface(REG_INTER); 3350 %} 3351 3352 // Special Registers 3353 // Return a compressed pointer value 3354 operand rax_RegN() 3355 %{ 3356 constraint(ALLOC_IN_RC(int_rax_reg)); 3357 match(RegN); 3358 match(rRegN); 3359 3360 format %{ %} 3361 interface(REG_INTER); 3362 %} 3363 3364 // Used in AtomicAdd 3365 operand rbx_RegP() 3366 %{ 3367 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3368 match(RegP); 3369 match(rRegP); 3370 3371 format %{ %} 3372 interface(REG_INTER); 3373 %} 3374 3375 operand rsi_RegP() 3376 %{ 3377 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3378 match(RegP); 3379 match(rRegP); 3380 3381 format %{ %} 3382 interface(REG_INTER); 3383 %} 3384 3385 // Used in rep stosq 3386 operand rdi_RegP() 3387 %{ 3388 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3389 match(RegP); 3390 match(rRegP); 3391 3392 format %{ %} 3393 interface(REG_INTER); 3394 %} 3395 3396 operand rbp_RegP() 3397 %{ 3398 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3399 match(RegP); 3400 match(rRegP); 3401 3402 format %{ %} 3403 interface(REG_INTER); 3404 %} 3405 3406 operand r15_RegP() 3407 %{ 3408 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3409 match(RegP); 3410 match(rRegP); 3411 3412 format %{ %} 3413 interface(REG_INTER); 3414 %} 3415 3416 operand rRegL() 3417 %{ 3418 constraint(ALLOC_IN_RC(long_reg)); 3419 match(RegL); 3420 match(rax_RegL); 3421 match(rdx_RegL); 3422 3423 format %{ %} 3424 interface(REG_INTER); 3425 %} 3426 3427 // Special Registers 3428 operand no_rax_rdx_RegL() 3429 %{ 3430 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3431 match(RegL); 3432 match(rRegL); 3433 3434 format %{ %} 3435 interface(REG_INTER); 3436 %} 3437 3438 operand no_rax_RegL() 3439 %{ 3440 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3441 match(RegL); 3442 match(rRegL); 3443 match(rdx_RegL); 3444 3445 format %{ %} 3446 interface(REG_INTER); 3447 %} 3448 3449 operand no_rcx_RegL() 3450 %{ 3451 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3452 match(RegL); 3453 match(rRegL); 3454 3455 format %{ %} 3456 interface(REG_INTER); 3457 %} 3458 3459 operand rax_RegL() 3460 %{ 3461 constraint(ALLOC_IN_RC(long_rax_reg)); 3462 match(RegL); 3463 match(rRegL); 3464 3465 format %{ "RAX" %} 3466 interface(REG_INTER); 3467 %} 3468 3469 operand rcx_RegL() 3470 %{ 3471 constraint(ALLOC_IN_RC(long_rcx_reg)); 3472 match(RegL); 3473 match(rRegL); 3474 3475 format %{ %} 3476 interface(REG_INTER); 3477 %} 3478 3479 operand rdx_RegL() 3480 %{ 3481 constraint(ALLOC_IN_RC(long_rdx_reg)); 3482 match(RegL); 3483 match(rRegL); 3484 3485 format %{ %} 3486 interface(REG_INTER); 3487 %} 3488 3489 // Flags register, used as output of compare instructions 3490 operand rFlagsReg() 3491 %{ 3492 constraint(ALLOC_IN_RC(int_flags)); 3493 match(RegFlags); 3494 3495 format %{ "RFLAGS" %} 3496 interface(REG_INTER); 3497 %} 3498 3499 // Flags register, used as output of FLOATING POINT compare instructions 3500 operand rFlagsRegU() 3501 %{ 3502 constraint(ALLOC_IN_RC(int_flags)); 3503 match(RegFlags); 3504 3505 format %{ "RFLAGS_U" %} 3506 interface(REG_INTER); 3507 %} 3508 3509 operand rFlagsRegUCF() %{ 3510 constraint(ALLOC_IN_RC(int_flags)); 3511 match(RegFlags); 3512 predicate(false); 3513 3514 format %{ "RFLAGS_U_CF" %} 3515 interface(REG_INTER); 3516 %} 3517 3518 // Float register operands 3519 operand regF() 3520 %{ 3521 constraint(ALLOC_IN_RC(float_reg)); 3522 match(RegF); 3523 3524 format %{ %} 3525 interface(REG_INTER); 3526 %} 3527 3528 // Double register operands 3529 operand regD() 3530 %{ 3531 constraint(ALLOC_IN_RC(double_reg)); 3532 match(RegD); 3533 3534 format %{ %} 3535 interface(REG_INTER); 3536 %} 3537 3538 //----------Memory Operands---------------------------------------------------- 3539 // Direct Memory Operand 3540 // operand direct(immP addr) 3541 // %{ 3542 // match(addr); 3543 3544 // format %{ "[$addr]" %} 3545 // interface(MEMORY_INTER) %{ 3546 // base(0xFFFFFFFF); 3547 // index(0x4); 3548 // scale(0x0); 3549 // disp($addr); 3550 // %} 3551 // %} 3552 3553 // Indirect Memory Operand 3554 operand indirect(any_RegP reg) 3555 %{ 3556 constraint(ALLOC_IN_RC(ptr_reg)); 3557 match(reg); 3558 3559 format %{ "[$reg]" %} 3560 interface(MEMORY_INTER) %{ 3561 base($reg); 3562 index(0x4); 3563 scale(0x0); 3564 disp(0x0); 3565 %} 3566 %} 3567 3568 // Indirect Memory Plus Short Offset Operand 3569 operand indOffset8(any_RegP reg, immL8 off) 3570 %{ 3571 constraint(ALLOC_IN_RC(ptr_reg)); 3572 match(AddP reg off); 3573 3574 format %{ "[$reg + $off (8-bit)]" %} 3575 interface(MEMORY_INTER) %{ 3576 base($reg); 3577 index(0x4); 3578 scale(0x0); 3579 disp($off); 3580 %} 3581 %} 3582 3583 // Indirect Memory Plus Long Offset Operand 3584 operand indOffset32(any_RegP reg, immL32 off) 3585 %{ 3586 constraint(ALLOC_IN_RC(ptr_reg)); 3587 match(AddP reg off); 3588 3589 format %{ "[$reg + $off (32-bit)]" %} 3590 interface(MEMORY_INTER) %{ 3591 base($reg); 3592 index(0x4); 3593 scale(0x0); 3594 disp($off); 3595 %} 3596 %} 3597 3598 // Indirect Memory Plus Index Register Plus Offset Operand 3599 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3600 %{ 3601 constraint(ALLOC_IN_RC(ptr_reg)); 3602 match(AddP (AddP reg lreg) off); 3603 3604 op_cost(10); 3605 format %{"[$reg + $off + $lreg]" %} 3606 interface(MEMORY_INTER) %{ 3607 base($reg); 3608 index($lreg); 3609 scale(0x0); 3610 disp($off); 3611 %} 3612 %} 3613 3614 // Indirect Memory Plus Index Register Plus Offset Operand 3615 operand indIndex(any_RegP reg, rRegL lreg) 3616 %{ 3617 constraint(ALLOC_IN_RC(ptr_reg)); 3618 match(AddP reg lreg); 3619 3620 op_cost(10); 3621 format %{"[$reg + $lreg]" %} 3622 interface(MEMORY_INTER) %{ 3623 base($reg); 3624 index($lreg); 3625 scale(0x0); 3626 disp(0x0); 3627 %} 3628 %} 3629 3630 // Indirect Memory Times Scale Plus Index Register 3631 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3632 %{ 3633 constraint(ALLOC_IN_RC(ptr_reg)); 3634 match(AddP reg (LShiftL lreg scale)); 3635 3636 op_cost(10); 3637 format %{"[$reg + $lreg << $scale]" %} 3638 interface(MEMORY_INTER) %{ 3639 base($reg); 3640 index($lreg); 3641 scale($scale); 3642 disp(0x0); 3643 %} 3644 %} 3645 3646 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3647 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3648 %{ 3649 constraint(ALLOC_IN_RC(ptr_reg)); 3650 match(AddP (AddP reg (LShiftL lreg scale)) off); 3651 3652 op_cost(10); 3653 format %{"[$reg + $off + $lreg << $scale]" %} 3654 interface(MEMORY_INTER) %{ 3655 base($reg); 3656 index($lreg); 3657 scale($scale); 3658 disp($off); 3659 %} 3660 %} 3661 3662 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3663 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3664 %{ 3665 constraint(ALLOC_IN_RC(ptr_reg)); 3666 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3667 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3668 3669 op_cost(10); 3670 format %{"[$reg + $off + $idx << $scale]" %} 3671 interface(MEMORY_INTER) %{ 3672 base($reg); 3673 index($idx); 3674 scale($scale); 3675 disp($off); 3676 %} 3677 %} 3678 3679 // Indirect Narrow Oop Plus Offset Operand 3680 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3681 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3682 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3683 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3684 constraint(ALLOC_IN_RC(ptr_reg)); 3685 match(AddP (DecodeN reg) off); 3686 3687 op_cost(10); 3688 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3689 interface(MEMORY_INTER) %{ 3690 base(0xc); // R12 3691 index($reg); 3692 scale(0x3); 3693 disp($off); 3694 %} 3695 %} 3696 3697 // Indirect Memory Operand 3698 operand indirectNarrow(rRegN reg) 3699 %{ 3700 predicate(Universe::narrow_oop_shift() == 0); 3701 constraint(ALLOC_IN_RC(ptr_reg)); 3702 match(DecodeN reg); 3703 3704 format %{ "[$reg]" %} 3705 interface(MEMORY_INTER) %{ 3706 base($reg); 3707 index(0x4); 3708 scale(0x0); 3709 disp(0x0); 3710 %} 3711 %} 3712 3713 // Indirect Memory Plus Short Offset Operand 3714 operand indOffset8Narrow(rRegN reg, immL8 off) 3715 %{ 3716 predicate(Universe::narrow_oop_shift() == 0); 3717 constraint(ALLOC_IN_RC(ptr_reg)); 3718 match(AddP (DecodeN reg) off); 3719 3720 format %{ "[$reg + $off (8-bit)]" %} 3721 interface(MEMORY_INTER) %{ 3722 base($reg); 3723 index(0x4); 3724 scale(0x0); 3725 disp($off); 3726 %} 3727 %} 3728 3729 // Indirect Memory Plus Long Offset Operand 3730 operand indOffset32Narrow(rRegN reg, immL32 off) 3731 %{ 3732 predicate(Universe::narrow_oop_shift() == 0); 3733 constraint(ALLOC_IN_RC(ptr_reg)); 3734 match(AddP (DecodeN reg) off); 3735 3736 format %{ "[$reg + $off (32-bit)]" %} 3737 interface(MEMORY_INTER) %{ 3738 base($reg); 3739 index(0x4); 3740 scale(0x0); 3741 disp($off); 3742 %} 3743 %} 3744 3745 // Indirect Memory Plus Index Register Plus Offset Operand 3746 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3747 %{ 3748 predicate(Universe::narrow_oop_shift() == 0); 3749 constraint(ALLOC_IN_RC(ptr_reg)); 3750 match(AddP (AddP (DecodeN reg) lreg) off); 3751 3752 op_cost(10); 3753 format %{"[$reg + $off + $lreg]" %} 3754 interface(MEMORY_INTER) %{ 3755 base($reg); 3756 index($lreg); 3757 scale(0x0); 3758 disp($off); 3759 %} 3760 %} 3761 3762 // Indirect Memory Plus Index Register Plus Offset Operand 3763 operand indIndexNarrow(rRegN reg, rRegL lreg) 3764 %{ 3765 predicate(Universe::narrow_oop_shift() == 0); 3766 constraint(ALLOC_IN_RC(ptr_reg)); 3767 match(AddP (DecodeN reg) lreg); 3768 3769 op_cost(10); 3770 format %{"[$reg + $lreg]" %} 3771 interface(MEMORY_INTER) %{ 3772 base($reg); 3773 index($lreg); 3774 scale(0x0); 3775 disp(0x0); 3776 %} 3777 %} 3778 3779 // Indirect Memory Times Scale Plus Index Register 3780 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3781 %{ 3782 predicate(Universe::narrow_oop_shift() == 0); 3783 constraint(ALLOC_IN_RC(ptr_reg)); 3784 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3785 3786 op_cost(10); 3787 format %{"[$reg + $lreg << $scale]" %} 3788 interface(MEMORY_INTER) %{ 3789 base($reg); 3790 index($lreg); 3791 scale($scale); 3792 disp(0x0); 3793 %} 3794 %} 3795 3796 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3797 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3798 %{ 3799 predicate(Universe::narrow_oop_shift() == 0); 3800 constraint(ALLOC_IN_RC(ptr_reg)); 3801 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3802 3803 op_cost(10); 3804 format %{"[$reg + $off + $lreg << $scale]" %} 3805 interface(MEMORY_INTER) %{ 3806 base($reg); 3807 index($lreg); 3808 scale($scale); 3809 disp($off); 3810 %} 3811 %} 3812 3813 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3814 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3815 %{ 3816 constraint(ALLOC_IN_RC(ptr_reg)); 3817 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3818 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3819 3820 op_cost(10); 3821 format %{"[$reg + $off + $idx << $scale]" %} 3822 interface(MEMORY_INTER) %{ 3823 base($reg); 3824 index($idx); 3825 scale($scale); 3826 disp($off); 3827 %} 3828 %} 3829 3830 //----------Special Memory Operands-------------------------------------------- 3831 // Stack Slot Operand - This operand is used for loading and storing temporary 3832 // values on the stack where a match requires a value to 3833 // flow through memory. 3834 operand stackSlotP(sRegP reg) 3835 %{ 3836 constraint(ALLOC_IN_RC(stack_slots)); 3837 // No match rule because this operand is only generated in matching 3838 3839 format %{ "[$reg]" %} 3840 interface(MEMORY_INTER) %{ 3841 base(0x4); // RSP 3842 index(0x4); // No Index 3843 scale(0x0); // No Scale 3844 disp($reg); // Stack Offset 3845 %} 3846 %} 3847 3848 operand stackSlotI(sRegI reg) 3849 %{ 3850 constraint(ALLOC_IN_RC(stack_slots)); 3851 // No match rule because this operand is only generated in matching 3852 3853 format %{ "[$reg]" %} 3854 interface(MEMORY_INTER) %{ 3855 base(0x4); // RSP 3856 index(0x4); // No Index 3857 scale(0x0); // No Scale 3858 disp($reg); // Stack Offset 3859 %} 3860 %} 3861 3862 operand stackSlotF(sRegF reg) 3863 %{ 3864 constraint(ALLOC_IN_RC(stack_slots)); 3865 // No match rule because this operand is only generated in matching 3866 3867 format %{ "[$reg]" %} 3868 interface(MEMORY_INTER) %{ 3869 base(0x4); // RSP 3870 index(0x4); // No Index 3871 scale(0x0); // No Scale 3872 disp($reg); // Stack Offset 3873 %} 3874 %} 3875 3876 operand stackSlotD(sRegD reg) 3877 %{ 3878 constraint(ALLOC_IN_RC(stack_slots)); 3879 // No match rule because this operand is only generated in matching 3880 3881 format %{ "[$reg]" %} 3882 interface(MEMORY_INTER) %{ 3883 base(0x4); // RSP 3884 index(0x4); // No Index 3885 scale(0x0); // No Scale 3886 disp($reg); // Stack Offset 3887 %} 3888 %} 3889 operand stackSlotL(sRegL reg) 3890 %{ 3891 constraint(ALLOC_IN_RC(stack_slots)); 3892 // No match rule because this operand is only generated in matching 3893 3894 format %{ "[$reg]" %} 3895 interface(MEMORY_INTER) %{ 3896 base(0x4); // RSP 3897 index(0x4); // No Index 3898 scale(0x0); // No Scale 3899 disp($reg); // Stack Offset 3900 %} 3901 %} 3902 3903 //----------Conditional Branch Operands---------------------------------------- 3904 // Comparison Op - This is the operation of the comparison, and is limited to 3905 // the following set of codes: 3906 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3907 // 3908 // Other attributes of the comparison, such as unsignedness, are specified 3909 // by the comparison instruction that sets a condition code flags register. 3910 // That result is represented by a flags operand whose subtype is appropriate 3911 // to the unsignedness (etc.) of the comparison. 3912 // 3913 // Later, the instruction which matches both the Comparison Op (a Bool) and 3914 // the flags (produced by the Cmp) specifies the coding of the comparison op 3915 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3916 3917 // Comparision Code 3918 operand cmpOp() 3919 %{ 3920 match(Bool); 3921 3922 format %{ "" %} 3923 interface(COND_INTER) %{ 3924 equal(0x4, "e"); 3925 not_equal(0x5, "ne"); 3926 less(0xC, "l"); 3927 greater_equal(0xD, "ge"); 3928 less_equal(0xE, "le"); 3929 greater(0xF, "g"); 3930 overflow(0x0, "o"); 3931 no_overflow(0x1, "no"); 3932 %} 3933 %} 3934 3935 // Comparison Code, unsigned compare. Used by FP also, with 3936 // C2 (unordered) turned into GT or LT already. The other bits 3937 // C0 and C3 are turned into Carry & Zero flags. 3938 operand cmpOpU() 3939 %{ 3940 match(Bool); 3941 3942 format %{ "" %} 3943 interface(COND_INTER) %{ 3944 equal(0x4, "e"); 3945 not_equal(0x5, "ne"); 3946 less(0x2, "b"); 3947 greater_equal(0x3, "nb"); 3948 less_equal(0x6, "be"); 3949 greater(0x7, "nbe"); 3950 overflow(0x0, "o"); 3951 no_overflow(0x1, "no"); 3952 %} 3953 %} 3954 3955 3956 // Floating comparisons that don't require any fixup for the unordered case 3957 operand cmpOpUCF() %{ 3958 match(Bool); 3959 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3960 n->as_Bool()->_test._test == BoolTest::ge || 3961 n->as_Bool()->_test._test == BoolTest::le || 3962 n->as_Bool()->_test._test == BoolTest::gt); 3963 format %{ "" %} 3964 interface(COND_INTER) %{ 3965 equal(0x4, "e"); 3966 not_equal(0x5, "ne"); 3967 less(0x2, "b"); 3968 greater_equal(0x3, "nb"); 3969 less_equal(0x6, "be"); 3970 greater(0x7, "nbe"); 3971 overflow(0x0, "o"); 3972 no_overflow(0x1, "no"); 3973 %} 3974 %} 3975 3976 3977 // Floating comparisons that can be fixed up with extra conditional jumps 3978 operand cmpOpUCF2() %{ 3979 match(Bool); 3980 predicate(n->as_Bool()->_test._test == BoolTest::ne || 3981 n->as_Bool()->_test._test == BoolTest::eq); 3982 format %{ "" %} 3983 interface(COND_INTER) %{ 3984 equal(0x4, "e"); 3985 not_equal(0x5, "ne"); 3986 less(0x2, "b"); 3987 greater_equal(0x3, "nb"); 3988 less_equal(0x6, "be"); 3989 greater(0x7, "nbe"); 3990 overflow(0x0, "o"); 3991 no_overflow(0x1, "no"); 3992 %} 3993 %} 3994 3995 3996 //----------OPERAND CLASSES---------------------------------------------------- 3997 // Operand Classes are groups of operands that are used as to simplify 3998 // instruction definitions by not requiring the AD writer to specify separate 3999 // instructions for every form of operand when the instruction accepts 4000 // multiple operand types with the same basic encoding and format. The classic 4001 // case of this is memory operands. 4002 4003 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4004 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 4005 indCompressedOopOffset, 4006 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4007 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4008 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); 4009 4010 //----------PIPELINE----------------------------------------------------------- 4011 // Rules which define the behavior of the target architectures pipeline. 4012 pipeline %{ 4013 4014 //----------ATTRIBUTES--------------------------------------------------------- 4015 attributes %{ 4016 variable_size_instructions; // Fixed size instructions 4017 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4018 instruction_unit_size = 1; // An instruction is 1 bytes long 4019 instruction_fetch_unit_size = 16; // The processor fetches one line 4020 instruction_fetch_units = 1; // of 16 bytes 4021 4022 // List of nop instructions 4023 nops( MachNop ); 4024 %} 4025 4026 //----------RESOURCES---------------------------------------------------------- 4027 // Resources are the functional units available to the machine 4028 4029 // Generic P2/P3 pipeline 4030 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4031 // 3 instructions decoded per cycle. 4032 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4033 // 3 ALU op, only ALU0 handles mul instructions. 4034 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4035 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4036 BR, FPU, 4037 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4038 4039 //----------PIPELINE DESCRIPTION----------------------------------------------- 4040 // Pipeline Description specifies the stages in the machine's pipeline 4041 4042 // Generic P2/P3 pipeline 4043 pipe_desc(S0, S1, S2, S3, S4, S5); 4044 4045 //----------PIPELINE CLASSES--------------------------------------------------- 4046 // Pipeline Classes describe the stages in which input and output are 4047 // referenced by the hardware pipeline. 4048 4049 // Naming convention: ialu or fpu 4050 // Then: _reg 4051 // Then: _reg if there is a 2nd register 4052 // Then: _long if it's a pair of instructions implementing a long 4053 // Then: _fat if it requires the big decoder 4054 // Or: _mem if it requires the big decoder and a memory unit. 4055 4056 // Integer ALU reg operation 4057 pipe_class ialu_reg(rRegI dst) 4058 %{ 4059 single_instruction; 4060 dst : S4(write); 4061 dst : S3(read); 4062 DECODE : S0; // any decoder 4063 ALU : S3; // any alu 4064 %} 4065 4066 // Long ALU reg operation 4067 pipe_class ialu_reg_long(rRegL dst) 4068 %{ 4069 instruction_count(2); 4070 dst : S4(write); 4071 dst : S3(read); 4072 DECODE : S0(2); // any 2 decoders 4073 ALU : S3(2); // both alus 4074 %} 4075 4076 // Integer ALU reg operation using big decoder 4077 pipe_class ialu_reg_fat(rRegI dst) 4078 %{ 4079 single_instruction; 4080 dst : S4(write); 4081 dst : S3(read); 4082 D0 : S0; // big decoder only 4083 ALU : S3; // any alu 4084 %} 4085 4086 // Long ALU reg operation using big decoder 4087 pipe_class ialu_reg_long_fat(rRegL dst) 4088 %{ 4089 instruction_count(2); 4090 dst : S4(write); 4091 dst : S3(read); 4092 D0 : S0(2); // big decoder only; twice 4093 ALU : S3(2); // any 2 alus 4094 %} 4095 4096 // Integer ALU reg-reg operation 4097 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4098 %{ 4099 single_instruction; 4100 dst : S4(write); 4101 src : S3(read); 4102 DECODE : S0; // any decoder 4103 ALU : S3; // any alu 4104 %} 4105 4106 // Long ALU reg-reg operation 4107 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4108 %{ 4109 instruction_count(2); 4110 dst : S4(write); 4111 src : S3(read); 4112 DECODE : S0(2); // any 2 decoders 4113 ALU : S3(2); // both alus 4114 %} 4115 4116 // Integer ALU reg-reg operation 4117 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4118 %{ 4119 single_instruction; 4120 dst : S4(write); 4121 src : S3(read); 4122 D0 : S0; // big decoder only 4123 ALU : S3; // any alu 4124 %} 4125 4126 // Long ALU reg-reg operation 4127 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4128 %{ 4129 instruction_count(2); 4130 dst : S4(write); 4131 src : S3(read); 4132 D0 : S0(2); // big decoder only; twice 4133 ALU : S3(2); // both alus 4134 %} 4135 4136 // Integer ALU reg-mem operation 4137 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4138 %{ 4139 single_instruction; 4140 dst : S5(write); 4141 mem : S3(read); 4142 D0 : S0; // big decoder only 4143 ALU : S4; // any alu 4144 MEM : S3; // any mem 4145 %} 4146 4147 // Integer mem operation (prefetch) 4148 pipe_class ialu_mem(memory mem) 4149 %{ 4150 single_instruction; 4151 mem : S3(read); 4152 D0 : S0; // big decoder only 4153 MEM : S3; // any mem 4154 %} 4155 4156 // Integer Store to Memory 4157 pipe_class ialu_mem_reg(memory mem, rRegI src) 4158 %{ 4159 single_instruction; 4160 mem : S3(read); 4161 src : S5(read); 4162 D0 : S0; // big decoder only 4163 ALU : S4; // any alu 4164 MEM : S3; 4165 %} 4166 4167 // // Long Store to Memory 4168 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4169 // %{ 4170 // instruction_count(2); 4171 // mem : S3(read); 4172 // src : S5(read); 4173 // D0 : S0(2); // big decoder only; twice 4174 // ALU : S4(2); // any 2 alus 4175 // MEM : S3(2); // Both mems 4176 // %} 4177 4178 // Integer Store to Memory 4179 pipe_class ialu_mem_imm(memory mem) 4180 %{ 4181 single_instruction; 4182 mem : S3(read); 4183 D0 : S0; // big decoder only 4184 ALU : S4; // any alu 4185 MEM : S3; 4186 %} 4187 4188 // Integer ALU0 reg-reg operation 4189 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4190 %{ 4191 single_instruction; 4192 dst : S4(write); 4193 src : S3(read); 4194 D0 : S0; // Big decoder only 4195 ALU0 : S3; // only alu0 4196 %} 4197 4198 // Integer ALU0 reg-mem operation 4199 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4200 %{ 4201 single_instruction; 4202 dst : S5(write); 4203 mem : S3(read); 4204 D0 : S0; // big decoder only 4205 ALU0 : S4; // ALU0 only 4206 MEM : S3; // any mem 4207 %} 4208 4209 // Integer ALU reg-reg operation 4210 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4211 %{ 4212 single_instruction; 4213 cr : S4(write); 4214 src1 : S3(read); 4215 src2 : S3(read); 4216 DECODE : S0; // any decoder 4217 ALU : S3; // any alu 4218 %} 4219 4220 // Integer ALU reg-imm operation 4221 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4222 %{ 4223 single_instruction; 4224 cr : S4(write); 4225 src1 : S3(read); 4226 DECODE : S0; // any decoder 4227 ALU : S3; // any alu 4228 %} 4229 4230 // Integer ALU reg-mem operation 4231 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4232 %{ 4233 single_instruction; 4234 cr : S4(write); 4235 src1 : S3(read); 4236 src2 : S3(read); 4237 D0 : S0; // big decoder only 4238 ALU : S4; // any alu 4239 MEM : S3; 4240 %} 4241 4242 // Conditional move reg-reg 4243 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4244 %{ 4245 instruction_count(4); 4246 y : S4(read); 4247 q : S3(read); 4248 p : S3(read); 4249 DECODE : S0(4); // any decoder 4250 %} 4251 4252 // Conditional move reg-reg 4253 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4254 %{ 4255 single_instruction; 4256 dst : S4(write); 4257 src : S3(read); 4258 cr : S3(read); 4259 DECODE : S0; // any decoder 4260 %} 4261 4262 // Conditional move reg-mem 4263 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4264 %{ 4265 single_instruction; 4266 dst : S4(write); 4267 src : S3(read); 4268 cr : S3(read); 4269 DECODE : S0; // any decoder 4270 MEM : S3; 4271 %} 4272 4273 // Conditional move reg-reg long 4274 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4275 %{ 4276 single_instruction; 4277 dst : S4(write); 4278 src : S3(read); 4279 cr : S3(read); 4280 DECODE : S0(2); // any 2 decoders 4281 %} 4282 4283 // XXX 4284 // // Conditional move double reg-reg 4285 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4286 // %{ 4287 // single_instruction; 4288 // dst : S4(write); 4289 // src : S3(read); 4290 // cr : S3(read); 4291 // DECODE : S0; // any decoder 4292 // %} 4293 4294 // Float reg-reg operation 4295 pipe_class fpu_reg(regD dst) 4296 %{ 4297 instruction_count(2); 4298 dst : S3(read); 4299 DECODE : S0(2); // any 2 decoders 4300 FPU : S3; 4301 %} 4302 4303 // Float reg-reg operation 4304 pipe_class fpu_reg_reg(regD dst, regD src) 4305 %{ 4306 instruction_count(2); 4307 dst : S4(write); 4308 src : S3(read); 4309 DECODE : S0(2); // any 2 decoders 4310 FPU : S3; 4311 %} 4312 4313 // Float reg-reg operation 4314 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4315 %{ 4316 instruction_count(3); 4317 dst : S4(write); 4318 src1 : S3(read); 4319 src2 : S3(read); 4320 DECODE : S0(3); // any 3 decoders 4321 FPU : S3(2); 4322 %} 4323 4324 // Float reg-reg operation 4325 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4326 %{ 4327 instruction_count(4); 4328 dst : S4(write); 4329 src1 : S3(read); 4330 src2 : S3(read); 4331 src3 : S3(read); 4332 DECODE : S0(4); // any 3 decoders 4333 FPU : S3(2); 4334 %} 4335 4336 // Float reg-reg operation 4337 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4338 %{ 4339 instruction_count(4); 4340 dst : S4(write); 4341 src1 : S3(read); 4342 src2 : S3(read); 4343 src3 : S3(read); 4344 DECODE : S1(3); // any 3 decoders 4345 D0 : S0; // Big decoder only 4346 FPU : S3(2); 4347 MEM : S3; 4348 %} 4349 4350 // Float reg-mem operation 4351 pipe_class fpu_reg_mem(regD dst, memory mem) 4352 %{ 4353 instruction_count(2); 4354 dst : S5(write); 4355 mem : S3(read); 4356 D0 : S0; // big decoder only 4357 DECODE : S1; // any decoder for FPU POP 4358 FPU : S4; 4359 MEM : S3; // any mem 4360 %} 4361 4362 // Float reg-mem operation 4363 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4364 %{ 4365 instruction_count(3); 4366 dst : S5(write); 4367 src1 : S3(read); 4368 mem : S3(read); 4369 D0 : S0; // big decoder only 4370 DECODE : S1(2); // any decoder for FPU POP 4371 FPU : S4; 4372 MEM : S3; // any mem 4373 %} 4374 4375 // Float mem-reg operation 4376 pipe_class fpu_mem_reg(memory mem, regD src) 4377 %{ 4378 instruction_count(2); 4379 src : S5(read); 4380 mem : S3(read); 4381 DECODE : S0; // any decoder for FPU PUSH 4382 D0 : S1; // big decoder only 4383 FPU : S4; 4384 MEM : S3; // any mem 4385 %} 4386 4387 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4388 %{ 4389 instruction_count(3); 4390 src1 : S3(read); 4391 src2 : S3(read); 4392 mem : S3(read); 4393 DECODE : S0(2); // any decoder for FPU PUSH 4394 D0 : S1; // big decoder only 4395 FPU : S4; 4396 MEM : S3; // any mem 4397 %} 4398 4399 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4400 %{ 4401 instruction_count(3); 4402 src1 : S3(read); 4403 src2 : S3(read); 4404 mem : S4(read); 4405 DECODE : S0; // any decoder for FPU PUSH 4406 D0 : S0(2); // big decoder only 4407 FPU : S4; 4408 MEM : S3(2); // any mem 4409 %} 4410 4411 pipe_class fpu_mem_mem(memory dst, memory src1) 4412 %{ 4413 instruction_count(2); 4414 src1 : S3(read); 4415 dst : S4(read); 4416 D0 : S0(2); // big decoder only 4417 MEM : S3(2); // any mem 4418 %} 4419 4420 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4421 %{ 4422 instruction_count(3); 4423 src1 : S3(read); 4424 src2 : S3(read); 4425 dst : S4(read); 4426 D0 : S0(3); // big decoder only 4427 FPU : S4; 4428 MEM : S3(3); // any mem 4429 %} 4430 4431 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4432 %{ 4433 instruction_count(3); 4434 src1 : S4(read); 4435 mem : S4(read); 4436 DECODE : S0; // any decoder for FPU PUSH 4437 D0 : S0(2); // big decoder only 4438 FPU : S4; 4439 MEM : S3(2); // any mem 4440 %} 4441 4442 // Float load constant 4443 pipe_class fpu_reg_con(regD dst) 4444 %{ 4445 instruction_count(2); 4446 dst : S5(write); 4447 D0 : S0; // big decoder only for the load 4448 DECODE : S1; // any decoder for FPU POP 4449 FPU : S4; 4450 MEM : S3; // any mem 4451 %} 4452 4453 // Float load constant 4454 pipe_class fpu_reg_reg_con(regD dst, regD src) 4455 %{ 4456 instruction_count(3); 4457 dst : S5(write); 4458 src : S3(read); 4459 D0 : S0; // big decoder only for the load 4460 DECODE : S1(2); // any decoder for FPU POP 4461 FPU : S4; 4462 MEM : S3; // any mem 4463 %} 4464 4465 // UnConditional branch 4466 pipe_class pipe_jmp(label labl) 4467 %{ 4468 single_instruction; 4469 BR : S3; 4470 %} 4471 4472 // Conditional branch 4473 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4474 %{ 4475 single_instruction; 4476 cr : S1(read); 4477 BR : S3; 4478 %} 4479 4480 // Allocation idiom 4481 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4482 %{ 4483 instruction_count(1); force_serialization; 4484 fixed_latency(6); 4485 heap_ptr : S3(read); 4486 DECODE : S0(3); 4487 D0 : S2; 4488 MEM : S3; 4489 ALU : S3(2); 4490 dst : S5(write); 4491 BR : S5; 4492 %} 4493 4494 // Generic big/slow expanded idiom 4495 pipe_class pipe_slow() 4496 %{ 4497 instruction_count(10); multiple_bundles; force_serialization; 4498 fixed_latency(100); 4499 D0 : S0(2); 4500 MEM : S3(2); 4501 %} 4502 4503 // The real do-nothing guy 4504 pipe_class empty() 4505 %{ 4506 instruction_count(0); 4507 %} 4508 4509 // Define the class for the Nop node 4510 define 4511 %{ 4512 MachNop = empty; 4513 %} 4514 4515 %} 4516 4517 //----------INSTRUCTIONS------------------------------------------------------- 4518 // 4519 // match -- States which machine-independent subtree may be replaced 4520 // by this instruction. 4521 // ins_cost -- The estimated cost of this instruction is used by instruction 4522 // selection to identify a minimum cost tree of machine 4523 // instructions that matches a tree of machine-independent 4524 // instructions. 4525 // format -- A string providing the disassembly for this instruction. 4526 // The value of an instruction's operand may be inserted 4527 // by referring to it with a '$' prefix. 4528 // opcode -- Three instruction opcodes may be provided. These are referred 4529 // to within an encode class as $primary, $secondary, and $tertiary 4530 // rrspectively. The primary opcode is commonly used to 4531 // indicate the type of machine instruction, while secondary 4532 // and tertiary are often used for prefix options or addressing 4533 // modes. 4534 // ins_encode -- A list of encode classes with parameters. The encode class 4535 // name must have been defined in an 'enc_class' specification 4536 // in the encode section of the architecture description. 4537 4538 4539 //----------Load/Store/Move Instructions--------------------------------------- 4540 //----------Load Instructions-------------------------------------------------- 4541 4542 // Load Byte (8 bit signed) 4543 instruct loadB(rRegI dst, memory mem) 4544 %{ 4545 match(Set dst (LoadB mem)); 4546 4547 ins_cost(125); 4548 format %{ "movsbl $dst, $mem\t# byte" %} 4549 4550 ins_encode %{ 4551 __ movsbl($dst$$Register, $mem$$Address); 4552 %} 4553 4554 ins_pipe(ialu_reg_mem); 4555 %} 4556 4557 // Load Byte (8 bit signed) into Long Register 4558 instruct loadB2L(rRegL dst, memory mem) 4559 %{ 4560 match(Set dst (ConvI2L (LoadB mem))); 4561 4562 ins_cost(125); 4563 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4564 4565 ins_encode %{ 4566 __ movsbq($dst$$Register, $mem$$Address); 4567 %} 4568 4569 ins_pipe(ialu_reg_mem); 4570 %} 4571 4572 // Load Unsigned Byte (8 bit UNsigned) 4573 instruct loadUB(rRegI dst, memory mem) 4574 %{ 4575 match(Set dst (LoadUB mem)); 4576 4577 ins_cost(125); 4578 format %{ "movzbl $dst, $mem\t# ubyte" %} 4579 4580 ins_encode %{ 4581 __ movzbl($dst$$Register, $mem$$Address); 4582 %} 4583 4584 ins_pipe(ialu_reg_mem); 4585 %} 4586 4587 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4588 instruct loadUB2L(rRegL dst, memory mem) 4589 %{ 4590 match(Set dst (ConvI2L (LoadUB mem))); 4591 4592 ins_cost(125); 4593 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4594 4595 ins_encode %{ 4596 __ movzbq($dst$$Register, $mem$$Address); 4597 %} 4598 4599 ins_pipe(ialu_reg_mem); 4600 %} 4601 4602 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 4603 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 4604 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4605 effect(KILL cr); 4606 4607 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 4608 "andl $dst, $mask" %} 4609 ins_encode %{ 4610 Register Rdst = $dst$$Register; 4611 __ movzbq(Rdst, $mem$$Address); 4612 __ andl(Rdst, $mask$$constant); 4613 %} 4614 ins_pipe(ialu_reg_mem); 4615 %} 4616 4617 // Load Short (16 bit signed) 4618 instruct loadS(rRegI dst, memory mem) 4619 %{ 4620 match(Set dst (LoadS mem)); 4621 4622 ins_cost(125); 4623 format %{ "movswl $dst, $mem\t# short" %} 4624 4625 ins_encode %{ 4626 __ movswl($dst$$Register, $mem$$Address); 4627 %} 4628 4629 ins_pipe(ialu_reg_mem); 4630 %} 4631 4632 // Load Short (16 bit signed) to Byte (8 bit signed) 4633 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4634 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4635 4636 ins_cost(125); 4637 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4638 ins_encode %{ 4639 __ movsbl($dst$$Register, $mem$$Address); 4640 %} 4641 ins_pipe(ialu_reg_mem); 4642 %} 4643 4644 // Load Short (16 bit signed) into Long Register 4645 instruct loadS2L(rRegL dst, memory mem) 4646 %{ 4647 match(Set dst (ConvI2L (LoadS mem))); 4648 4649 ins_cost(125); 4650 format %{ "movswq $dst, $mem\t# short -> long" %} 4651 4652 ins_encode %{ 4653 __ movswq($dst$$Register, $mem$$Address); 4654 %} 4655 4656 ins_pipe(ialu_reg_mem); 4657 %} 4658 4659 // Load Unsigned Short/Char (16 bit UNsigned) 4660 instruct loadUS(rRegI dst, memory mem) 4661 %{ 4662 match(Set dst (LoadUS mem)); 4663 4664 ins_cost(125); 4665 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4666 4667 ins_encode %{ 4668 __ movzwl($dst$$Register, $mem$$Address); 4669 %} 4670 4671 ins_pipe(ialu_reg_mem); 4672 %} 4673 4674 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4675 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4676 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4677 4678 ins_cost(125); 4679 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4680 ins_encode %{ 4681 __ movsbl($dst$$Register, $mem$$Address); 4682 %} 4683 ins_pipe(ialu_reg_mem); 4684 %} 4685 4686 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4687 instruct loadUS2L(rRegL dst, memory mem) 4688 %{ 4689 match(Set dst (ConvI2L (LoadUS mem))); 4690 4691 ins_cost(125); 4692 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4693 4694 ins_encode %{ 4695 __ movzwq($dst$$Register, $mem$$Address); 4696 %} 4697 4698 ins_pipe(ialu_reg_mem); 4699 %} 4700 4701 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4702 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4703 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4704 4705 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4706 ins_encode %{ 4707 __ movzbq($dst$$Register, $mem$$Address); 4708 %} 4709 ins_pipe(ialu_reg_mem); 4710 %} 4711 4712 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 4713 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 4714 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4715 effect(KILL cr); 4716 4717 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 4718 "andl $dst, $mask" %} 4719 ins_encode %{ 4720 Register Rdst = $dst$$Register; 4721 __ movzwq(Rdst, $mem$$Address); 4722 __ andl(Rdst, $mask$$constant); 4723 %} 4724 ins_pipe(ialu_reg_mem); 4725 %} 4726 4727 // Load Integer 4728 instruct loadI(rRegI dst, memory mem) 4729 %{ 4730 match(Set dst (LoadI mem)); 4731 4732 ins_cost(125); 4733 format %{ "movl $dst, $mem\t# int" %} 4734 4735 ins_encode %{ 4736 __ movl($dst$$Register, $mem$$Address); 4737 %} 4738 4739 ins_pipe(ialu_reg_mem); 4740 %} 4741 4742 // Load Integer (32 bit signed) to Byte (8 bit signed) 4743 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4744 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4745 4746 ins_cost(125); 4747 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4748 ins_encode %{ 4749 __ movsbl($dst$$Register, $mem$$Address); 4750 %} 4751 ins_pipe(ialu_reg_mem); 4752 %} 4753 4754 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4755 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4756 match(Set dst (AndI (LoadI mem) mask)); 4757 4758 ins_cost(125); 4759 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4760 ins_encode %{ 4761 __ movzbl($dst$$Register, $mem$$Address); 4762 %} 4763 ins_pipe(ialu_reg_mem); 4764 %} 4765 4766 // Load Integer (32 bit signed) to Short (16 bit signed) 4767 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4768 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4769 4770 ins_cost(125); 4771 format %{ "movswl $dst, $mem\t# int -> short" %} 4772 ins_encode %{ 4773 __ movswl($dst$$Register, $mem$$Address); 4774 %} 4775 ins_pipe(ialu_reg_mem); 4776 %} 4777 4778 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4779 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4780 match(Set dst (AndI (LoadI mem) mask)); 4781 4782 ins_cost(125); 4783 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4784 ins_encode %{ 4785 __ movzwl($dst$$Register, $mem$$Address); 4786 %} 4787 ins_pipe(ialu_reg_mem); 4788 %} 4789 4790 // Load Integer into Long Register 4791 instruct loadI2L(rRegL dst, memory mem) 4792 %{ 4793 match(Set dst (ConvI2L (LoadI mem))); 4794 4795 ins_cost(125); 4796 format %{ "movslq $dst, $mem\t# int -> long" %} 4797 4798 ins_encode %{ 4799 __ movslq($dst$$Register, $mem$$Address); 4800 %} 4801 4802 ins_pipe(ialu_reg_mem); 4803 %} 4804 4805 // Load Integer with mask 0xFF into Long Register 4806 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4807 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4808 4809 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4810 ins_encode %{ 4811 __ movzbq($dst$$Register, $mem$$Address); 4812 %} 4813 ins_pipe(ialu_reg_mem); 4814 %} 4815 4816 // Load Integer with mask 0xFFFF into Long Register 4817 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4818 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4819 4820 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4821 ins_encode %{ 4822 __ movzwq($dst$$Register, $mem$$Address); 4823 %} 4824 ins_pipe(ialu_reg_mem); 4825 %} 4826 4827 // Load Integer with a 31-bit mask into Long Register 4828 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4829 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4830 effect(KILL cr); 4831 4832 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4833 "andl $dst, $mask" %} 4834 ins_encode %{ 4835 Register Rdst = $dst$$Register; 4836 __ movl(Rdst, $mem$$Address); 4837 __ andl(Rdst, $mask$$constant); 4838 %} 4839 ins_pipe(ialu_reg_mem); 4840 %} 4841 4842 // Load Unsigned Integer into Long Register 4843 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4844 %{ 4845 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4846 4847 ins_cost(125); 4848 format %{ "movl $dst, $mem\t# uint -> long" %} 4849 4850 ins_encode %{ 4851 __ movl($dst$$Register, $mem$$Address); 4852 %} 4853 4854 ins_pipe(ialu_reg_mem); 4855 %} 4856 4857 // Load Long 4858 instruct loadL(rRegL dst, memory mem) 4859 %{ 4860 match(Set dst (LoadL mem)); 4861 4862 ins_cost(125); 4863 format %{ "movq $dst, $mem\t# long" %} 4864 4865 ins_encode %{ 4866 __ movq($dst$$Register, $mem$$Address); 4867 %} 4868 4869 ins_pipe(ialu_reg_mem); // XXX 4870 %} 4871 4872 // Load Range 4873 instruct loadRange(rRegI dst, memory mem) 4874 %{ 4875 match(Set dst (LoadRange mem)); 4876 4877 ins_cost(125); // XXX 4878 format %{ "movl $dst, $mem\t# range" %} 4879 opcode(0x8B); 4880 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 4881 ins_pipe(ialu_reg_mem); 4882 %} 4883 4884 // Load Pointer 4885 instruct loadP(rRegP dst, memory mem) 4886 %{ 4887 match(Set dst (LoadP mem)); 4888 4889 ins_cost(125); // XXX 4890 format %{ "movq $dst, $mem\t# ptr" %} 4891 opcode(0x8B); 4892 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 4893 ins_pipe(ialu_reg_mem); // XXX 4894 %} 4895 4896 // Load Compressed Pointer 4897 instruct loadN(rRegN dst, memory mem) 4898 %{ 4899 match(Set dst (LoadN mem)); 4900 4901 ins_cost(125); // XXX 4902 format %{ "movl $dst, $mem\t# compressed ptr" %} 4903 ins_encode %{ 4904 __ movl($dst$$Register, $mem$$Address); 4905 %} 4906 ins_pipe(ialu_reg_mem); // XXX 4907 %} 4908 4909 4910 // Load Klass Pointer 4911 instruct loadKlass(rRegP dst, memory mem) 4912 %{ 4913 match(Set dst (LoadKlass mem)); 4914 4915 ins_cost(125); // XXX 4916 format %{ "movq $dst, $mem\t# class" %} 4917 opcode(0x8B); 4918 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 4919 ins_pipe(ialu_reg_mem); // XXX 4920 %} 4921 4922 // Load narrow Klass Pointer 4923 instruct loadNKlass(rRegN dst, memory mem) 4924 %{ 4925 match(Set dst (LoadNKlass mem)); 4926 4927 ins_cost(125); // XXX 4928 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4929 ins_encode %{ 4930 __ movl($dst$$Register, $mem$$Address); 4931 %} 4932 ins_pipe(ialu_reg_mem); // XXX 4933 %} 4934 4935 // Load Float 4936 instruct loadF(regF dst, memory mem) 4937 %{ 4938 match(Set dst (LoadF mem)); 4939 4940 ins_cost(145); // XXX 4941 format %{ "movss $dst, $mem\t# float" %} 4942 ins_encode %{ 4943 __ movflt($dst$$XMMRegister, $mem$$Address); 4944 %} 4945 ins_pipe(pipe_slow); // XXX 4946 %} 4947 4948 // Load Double 4949 instruct loadD_partial(regD dst, memory mem) 4950 %{ 4951 predicate(!UseXmmLoadAndClearUpper); 4952 match(Set dst (LoadD mem)); 4953 4954 ins_cost(145); // XXX 4955 format %{ "movlpd $dst, $mem\t# double" %} 4956 ins_encode %{ 4957 __ movdbl($dst$$XMMRegister, $mem$$Address); 4958 %} 4959 ins_pipe(pipe_slow); // XXX 4960 %} 4961 4962 instruct loadD(regD dst, memory mem) 4963 %{ 4964 predicate(UseXmmLoadAndClearUpper); 4965 match(Set dst (LoadD mem)); 4966 4967 ins_cost(145); // XXX 4968 format %{ "movsd $dst, $mem\t# double" %} 4969 ins_encode %{ 4970 __ movdbl($dst$$XMMRegister, $mem$$Address); 4971 %} 4972 ins_pipe(pipe_slow); // XXX 4973 %} 4974 4975 // Load Effective Address 4976 instruct leaP8(rRegP dst, indOffset8 mem) 4977 %{ 4978 match(Set dst mem); 4979 4980 ins_cost(110); // XXX 4981 format %{ "leaq $dst, $mem\t# ptr 8" %} 4982 opcode(0x8D); 4983 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 4984 ins_pipe(ialu_reg_reg_fat); 4985 %} 4986 4987 instruct leaP32(rRegP dst, indOffset32 mem) 4988 %{ 4989 match(Set dst mem); 4990 4991 ins_cost(110); 4992 format %{ "leaq $dst, $mem\t# ptr 32" %} 4993 opcode(0x8D); 4994 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 4995 ins_pipe(ialu_reg_reg_fat); 4996 %} 4997 4998 // instruct leaPIdx(rRegP dst, indIndex mem) 4999 // %{ 5000 // match(Set dst mem); 5001 5002 // ins_cost(110); 5003 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5004 // opcode(0x8D); 5005 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5006 // ins_pipe(ialu_reg_reg_fat); 5007 // %} 5008 5009 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5010 %{ 5011 match(Set dst mem); 5012 5013 ins_cost(110); 5014 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5015 opcode(0x8D); 5016 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5017 ins_pipe(ialu_reg_reg_fat); 5018 %} 5019 5020 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5021 %{ 5022 match(Set dst mem); 5023 5024 ins_cost(110); 5025 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5026 opcode(0x8D); 5027 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5028 ins_pipe(ialu_reg_reg_fat); 5029 %} 5030 5031 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5032 %{ 5033 match(Set dst mem); 5034 5035 ins_cost(110); 5036 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5037 opcode(0x8D); 5038 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5039 ins_pipe(ialu_reg_reg_fat); 5040 %} 5041 5042 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5043 %{ 5044 match(Set dst mem); 5045 5046 ins_cost(110); 5047 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5048 opcode(0x8D); 5049 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5050 ins_pipe(ialu_reg_reg_fat); 5051 %} 5052 5053 // Load Effective Address which uses Narrow (32-bits) oop 5054 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5055 %{ 5056 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5057 match(Set dst mem); 5058 5059 ins_cost(110); 5060 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5061 opcode(0x8D); 5062 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5063 ins_pipe(ialu_reg_reg_fat); 5064 %} 5065 5066 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5067 %{ 5068 predicate(Universe::narrow_oop_shift() == 0); 5069 match(Set dst mem); 5070 5071 ins_cost(110); // XXX 5072 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5073 opcode(0x8D); 5074 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5075 ins_pipe(ialu_reg_reg_fat); 5076 %} 5077 5078 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5079 %{ 5080 predicate(Universe::narrow_oop_shift() == 0); 5081 match(Set dst mem); 5082 5083 ins_cost(110); 5084 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5085 opcode(0x8D); 5086 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5087 ins_pipe(ialu_reg_reg_fat); 5088 %} 5089 5090 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5091 %{ 5092 predicate(Universe::narrow_oop_shift() == 0); 5093 match(Set dst mem); 5094 5095 ins_cost(110); 5096 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5097 opcode(0x8D); 5098 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5099 ins_pipe(ialu_reg_reg_fat); 5100 %} 5101 5102 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5103 %{ 5104 predicate(Universe::narrow_oop_shift() == 0); 5105 match(Set dst mem); 5106 5107 ins_cost(110); 5108 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5109 opcode(0x8D); 5110 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5111 ins_pipe(ialu_reg_reg_fat); 5112 %} 5113 5114 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5115 %{ 5116 predicate(Universe::narrow_oop_shift() == 0); 5117 match(Set dst mem); 5118 5119 ins_cost(110); 5120 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5121 opcode(0x8D); 5122 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5123 ins_pipe(ialu_reg_reg_fat); 5124 %} 5125 5126 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5127 %{ 5128 predicate(Universe::narrow_oop_shift() == 0); 5129 match(Set dst mem); 5130 5131 ins_cost(110); 5132 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5133 opcode(0x8D); 5134 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5135 ins_pipe(ialu_reg_reg_fat); 5136 %} 5137 5138 instruct loadConI(rRegI dst, immI src) 5139 %{ 5140 match(Set dst src); 5141 5142 format %{ "movl $dst, $src\t# int" %} 5143 ins_encode(load_immI(dst, src)); 5144 ins_pipe(ialu_reg_fat); // XXX 5145 %} 5146 5147 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5148 %{ 5149 match(Set dst src); 5150 effect(KILL cr); 5151 5152 ins_cost(50); 5153 format %{ "xorl $dst, $dst\t# int" %} 5154 opcode(0x33); /* + rd */ 5155 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5156 ins_pipe(ialu_reg); 5157 %} 5158 5159 instruct loadConL(rRegL dst, immL src) 5160 %{ 5161 match(Set dst src); 5162 5163 ins_cost(150); 5164 format %{ "movq $dst, $src\t# long" %} 5165 ins_encode(load_immL(dst, src)); 5166 ins_pipe(ialu_reg); 5167 %} 5168 5169 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5170 %{ 5171 match(Set dst src); 5172 effect(KILL cr); 5173 5174 ins_cost(50); 5175 format %{ "xorl $dst, $dst\t# long" %} 5176 opcode(0x33); /* + rd */ 5177 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5178 ins_pipe(ialu_reg); // XXX 5179 %} 5180 5181 instruct loadConUL32(rRegL dst, immUL32 src) 5182 %{ 5183 match(Set dst src); 5184 5185 ins_cost(60); 5186 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5187 ins_encode(load_immUL32(dst, src)); 5188 ins_pipe(ialu_reg); 5189 %} 5190 5191 instruct loadConL32(rRegL dst, immL32 src) 5192 %{ 5193 match(Set dst src); 5194 5195 ins_cost(70); 5196 format %{ "movq $dst, $src\t# long (32-bit)" %} 5197 ins_encode(load_immL32(dst, src)); 5198 ins_pipe(ialu_reg); 5199 %} 5200 5201 instruct loadConP(rRegP dst, immP con) %{ 5202 match(Set dst con); 5203 5204 format %{ "movq $dst, $con\t# ptr" %} 5205 ins_encode(load_immP(dst, con)); 5206 ins_pipe(ialu_reg_fat); // XXX 5207 %} 5208 5209 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5210 %{ 5211 match(Set dst src); 5212 effect(KILL cr); 5213 5214 ins_cost(50); 5215 format %{ "xorl $dst, $dst\t# ptr" %} 5216 opcode(0x33); /* + rd */ 5217 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5218 ins_pipe(ialu_reg); 5219 %} 5220 5221 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5222 %{ 5223 match(Set dst src); 5224 effect(KILL cr); 5225 5226 ins_cost(60); 5227 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5228 ins_encode(load_immP31(dst, src)); 5229 ins_pipe(ialu_reg); 5230 %} 5231 5232 instruct loadConF(regF dst, immF con) %{ 5233 match(Set dst con); 5234 ins_cost(125); 5235 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5236 ins_encode %{ 5237 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5238 %} 5239 ins_pipe(pipe_slow); 5240 %} 5241 5242 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5243 match(Set dst src); 5244 effect(KILL cr); 5245 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5246 ins_encode %{ 5247 __ xorq($dst$$Register, $dst$$Register); 5248 %} 5249 ins_pipe(ialu_reg); 5250 %} 5251 5252 instruct loadConN(rRegN dst, immN src) %{ 5253 match(Set dst src); 5254 5255 ins_cost(125); 5256 format %{ "movl $dst, $src\t# compressed ptr" %} 5257 ins_encode %{ 5258 address con = (address)$src$$constant; 5259 if (con == NULL) { 5260 ShouldNotReachHere(); 5261 } else { 5262 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5263 } 5264 %} 5265 ins_pipe(ialu_reg_fat); // XXX 5266 %} 5267 5268 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5269 match(Set dst src); 5270 5271 ins_cost(125); 5272 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5273 ins_encode %{ 5274 address con = (address)$src$$constant; 5275 if (con == NULL) { 5276 ShouldNotReachHere(); 5277 } else { 5278 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5279 } 5280 %} 5281 ins_pipe(ialu_reg_fat); // XXX 5282 %} 5283 5284 instruct loadConF0(regF dst, immF0 src) 5285 %{ 5286 match(Set dst src); 5287 ins_cost(100); 5288 5289 format %{ "xorps $dst, $dst\t# float 0.0" %} 5290 ins_encode %{ 5291 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5292 %} 5293 ins_pipe(pipe_slow); 5294 %} 5295 5296 // Use the same format since predicate() can not be used here. 5297 instruct loadConD(regD dst, immD con) %{ 5298 match(Set dst con); 5299 ins_cost(125); 5300 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5301 ins_encode %{ 5302 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5303 %} 5304 ins_pipe(pipe_slow); 5305 %} 5306 5307 instruct loadConD0(regD dst, immD0 src) 5308 %{ 5309 match(Set dst src); 5310 ins_cost(100); 5311 5312 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5313 ins_encode %{ 5314 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5315 %} 5316 ins_pipe(pipe_slow); 5317 %} 5318 5319 instruct loadSSI(rRegI dst, stackSlotI src) 5320 %{ 5321 match(Set dst src); 5322 5323 ins_cost(125); 5324 format %{ "movl $dst, $src\t# int stk" %} 5325 opcode(0x8B); 5326 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5327 ins_pipe(ialu_reg_mem); 5328 %} 5329 5330 instruct loadSSL(rRegL dst, stackSlotL src) 5331 %{ 5332 match(Set dst src); 5333 5334 ins_cost(125); 5335 format %{ "movq $dst, $src\t# long stk" %} 5336 opcode(0x8B); 5337 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5338 ins_pipe(ialu_reg_mem); 5339 %} 5340 5341 instruct loadSSP(rRegP dst, stackSlotP src) 5342 %{ 5343 match(Set dst src); 5344 5345 ins_cost(125); 5346 format %{ "movq $dst, $src\t# ptr stk" %} 5347 opcode(0x8B); 5348 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5349 ins_pipe(ialu_reg_mem); 5350 %} 5351 5352 instruct loadSSF(regF dst, stackSlotF src) 5353 %{ 5354 match(Set dst src); 5355 5356 ins_cost(125); 5357 format %{ "movss $dst, $src\t# float stk" %} 5358 ins_encode %{ 5359 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5360 %} 5361 ins_pipe(pipe_slow); // XXX 5362 %} 5363 5364 // Use the same format since predicate() can not be used here. 5365 instruct loadSSD(regD dst, stackSlotD src) 5366 %{ 5367 match(Set dst src); 5368 5369 ins_cost(125); 5370 format %{ "movsd $dst, $src\t# double stk" %} 5371 ins_encode %{ 5372 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5373 %} 5374 ins_pipe(pipe_slow); // XXX 5375 %} 5376 5377 // Prefetch instructions. 5378 // Must be safe to execute with invalid address (cannot fault). 5379 5380 instruct prefetchr( memory mem ) %{ 5381 predicate(ReadPrefetchInstr==3); 5382 match(PrefetchRead mem); 5383 ins_cost(125); 5384 5385 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 5386 ins_encode %{ 5387 __ prefetchr($mem$$Address); 5388 %} 5389 ins_pipe(ialu_mem); 5390 %} 5391 5392 instruct prefetchrNTA( memory mem ) %{ 5393 predicate(ReadPrefetchInstr==0); 5394 match(PrefetchRead mem); 5395 ins_cost(125); 5396 5397 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 5398 ins_encode %{ 5399 __ prefetchnta($mem$$Address); 5400 %} 5401 ins_pipe(ialu_mem); 5402 %} 5403 5404 instruct prefetchrT0( memory mem ) %{ 5405 predicate(ReadPrefetchInstr==1); 5406 match(PrefetchRead mem); 5407 ins_cost(125); 5408 5409 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 5410 ins_encode %{ 5411 __ prefetcht0($mem$$Address); 5412 %} 5413 ins_pipe(ialu_mem); 5414 %} 5415 5416 instruct prefetchrT2( memory mem ) %{ 5417 predicate(ReadPrefetchInstr==2); 5418 match(PrefetchRead mem); 5419 ins_cost(125); 5420 5421 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 5422 ins_encode %{ 5423 __ prefetcht2($mem$$Address); 5424 %} 5425 ins_pipe(ialu_mem); 5426 %} 5427 5428 instruct prefetchwNTA( memory mem ) %{ 5429 match(PrefetchWrite mem); 5430 ins_cost(125); 5431 5432 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 5433 ins_encode %{ 5434 __ prefetchnta($mem$$Address); 5435 %} 5436 ins_pipe(ialu_mem); 5437 %} 5438 5439 // Prefetch instructions for allocation. 5440 5441 instruct prefetchAlloc( memory mem ) %{ 5442 predicate(AllocatePrefetchInstr==3); 5443 match(PrefetchAllocation mem); 5444 ins_cost(125); 5445 5446 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5447 ins_encode %{ 5448 __ prefetchw($mem$$Address); 5449 %} 5450 ins_pipe(ialu_mem); 5451 %} 5452 5453 instruct prefetchAllocNTA( memory mem ) %{ 5454 predicate(AllocatePrefetchInstr==0); 5455 match(PrefetchAllocation mem); 5456 ins_cost(125); 5457 5458 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5459 ins_encode %{ 5460 __ prefetchnta($mem$$Address); 5461 %} 5462 ins_pipe(ialu_mem); 5463 %} 5464 5465 instruct prefetchAllocT0( memory mem ) %{ 5466 predicate(AllocatePrefetchInstr==1); 5467 match(PrefetchAllocation mem); 5468 ins_cost(125); 5469 5470 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5471 ins_encode %{ 5472 __ prefetcht0($mem$$Address); 5473 %} 5474 ins_pipe(ialu_mem); 5475 %} 5476 5477 instruct prefetchAllocT2( memory mem ) %{ 5478 predicate(AllocatePrefetchInstr==2); 5479 match(PrefetchAllocation mem); 5480 ins_cost(125); 5481 5482 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5483 ins_encode %{ 5484 __ prefetcht2($mem$$Address); 5485 %} 5486 ins_pipe(ialu_mem); 5487 %} 5488 5489 //----------Store Instructions------------------------------------------------- 5490 5491 // Store Byte 5492 instruct storeB(memory mem, rRegI src) 5493 %{ 5494 match(Set mem (StoreB mem src)); 5495 5496 ins_cost(125); // XXX 5497 format %{ "movb $mem, $src\t# byte" %} 5498 opcode(0x88); 5499 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5500 ins_pipe(ialu_mem_reg); 5501 %} 5502 5503 // Store Char/Short 5504 instruct storeC(memory mem, rRegI src) 5505 %{ 5506 match(Set mem (StoreC mem src)); 5507 5508 ins_cost(125); // XXX 5509 format %{ "movw $mem, $src\t# char/short" %} 5510 opcode(0x89); 5511 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5512 ins_pipe(ialu_mem_reg); 5513 %} 5514 5515 // Store Integer 5516 instruct storeI(memory mem, rRegI src) 5517 %{ 5518 match(Set mem (StoreI mem src)); 5519 5520 ins_cost(125); // XXX 5521 format %{ "movl $mem, $src\t# int" %} 5522 opcode(0x89); 5523 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5524 ins_pipe(ialu_mem_reg); 5525 %} 5526 5527 // Store Long 5528 instruct storeL(memory mem, rRegL src) 5529 %{ 5530 match(Set mem (StoreL mem src)); 5531 5532 ins_cost(125); // XXX 5533 format %{ "movq $mem, $src\t# long" %} 5534 opcode(0x89); 5535 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5536 ins_pipe(ialu_mem_reg); // XXX 5537 %} 5538 5539 // Store Pointer 5540 instruct storeP(memory mem, any_RegP src) 5541 %{ 5542 match(Set mem (StoreP mem src)); 5543 5544 ins_cost(125); // XXX 5545 format %{ "movq $mem, $src\t# ptr" %} 5546 opcode(0x89); 5547 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5548 ins_pipe(ialu_mem_reg); 5549 %} 5550 5551 instruct storeImmP0(memory mem, immP0 zero) 5552 %{ 5553 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5554 match(Set mem (StoreP mem zero)); 5555 5556 ins_cost(125); // XXX 5557 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5558 ins_encode %{ 5559 __ movq($mem$$Address, r12); 5560 %} 5561 ins_pipe(ialu_mem_reg); 5562 %} 5563 5564 // Store NULL Pointer, mark word, or other simple pointer constant. 5565 instruct storeImmP(memory mem, immP31 src) 5566 %{ 5567 match(Set mem (StoreP mem src)); 5568 5569 ins_cost(150); // XXX 5570 format %{ "movq $mem, $src\t# ptr" %} 5571 opcode(0xC7); /* C7 /0 */ 5572 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5573 ins_pipe(ialu_mem_imm); 5574 %} 5575 5576 // Store Compressed Pointer 5577 instruct storeN(memory mem, rRegN src) 5578 %{ 5579 match(Set mem (StoreN mem src)); 5580 5581 ins_cost(125); // XXX 5582 format %{ "movl $mem, $src\t# compressed ptr" %} 5583 ins_encode %{ 5584 __ movl($mem$$Address, $src$$Register); 5585 %} 5586 ins_pipe(ialu_mem_reg); 5587 %} 5588 5589 instruct storeNKlass(memory mem, rRegN src) 5590 %{ 5591 match(Set mem (StoreNKlass mem src)); 5592 5593 ins_cost(125); // XXX 5594 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5595 ins_encode %{ 5596 __ movl($mem$$Address, $src$$Register); 5597 %} 5598 ins_pipe(ialu_mem_reg); 5599 %} 5600 5601 instruct storeImmN0(memory mem, immN0 zero) 5602 %{ 5603 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5604 match(Set mem (StoreN mem zero)); 5605 5606 ins_cost(125); // XXX 5607 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5608 ins_encode %{ 5609 __ movl($mem$$Address, r12); 5610 %} 5611 ins_pipe(ialu_mem_reg); 5612 %} 5613 5614 instruct storeImmN(memory mem, immN src) 5615 %{ 5616 match(Set mem (StoreN mem src)); 5617 5618 ins_cost(150); // XXX 5619 format %{ "movl $mem, $src\t# compressed ptr" %} 5620 ins_encode %{ 5621 address con = (address)$src$$constant; 5622 if (con == NULL) { 5623 __ movl($mem$$Address, (int32_t)0); 5624 } else { 5625 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5626 } 5627 %} 5628 ins_pipe(ialu_mem_imm); 5629 %} 5630 5631 instruct storeImmNKlass(memory mem, immNKlass src) 5632 %{ 5633 match(Set mem (StoreNKlass mem src)); 5634 5635 ins_cost(150); // XXX 5636 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5637 ins_encode %{ 5638 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5639 %} 5640 ins_pipe(ialu_mem_imm); 5641 %} 5642 5643 // Store Integer Immediate 5644 instruct storeImmI0(memory mem, immI0 zero) 5645 %{ 5646 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5647 match(Set mem (StoreI mem zero)); 5648 5649 ins_cost(125); // XXX 5650 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5651 ins_encode %{ 5652 __ movl($mem$$Address, r12); 5653 %} 5654 ins_pipe(ialu_mem_reg); 5655 %} 5656 5657 instruct storeImmI(memory mem, immI src) 5658 %{ 5659 match(Set mem (StoreI mem src)); 5660 5661 ins_cost(150); 5662 format %{ "movl $mem, $src\t# int" %} 5663 opcode(0xC7); /* C7 /0 */ 5664 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5665 ins_pipe(ialu_mem_imm); 5666 %} 5667 5668 // Store Long Immediate 5669 instruct storeImmL0(memory mem, immL0 zero) 5670 %{ 5671 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5672 match(Set mem (StoreL mem zero)); 5673 5674 ins_cost(125); // XXX 5675 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5676 ins_encode %{ 5677 __ movq($mem$$Address, r12); 5678 %} 5679 ins_pipe(ialu_mem_reg); 5680 %} 5681 5682 instruct storeImmL(memory mem, immL32 src) 5683 %{ 5684 match(Set mem (StoreL mem src)); 5685 5686 ins_cost(150); 5687 format %{ "movq $mem, $src\t# long" %} 5688 opcode(0xC7); /* C7 /0 */ 5689 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5690 ins_pipe(ialu_mem_imm); 5691 %} 5692 5693 // Store Short/Char Immediate 5694 instruct storeImmC0(memory mem, immI0 zero) 5695 %{ 5696 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5697 match(Set mem (StoreC mem zero)); 5698 5699 ins_cost(125); // XXX 5700 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5701 ins_encode %{ 5702 __ movw($mem$$Address, r12); 5703 %} 5704 ins_pipe(ialu_mem_reg); 5705 %} 5706 5707 instruct storeImmI16(memory mem, immI16 src) 5708 %{ 5709 predicate(UseStoreImmI16); 5710 match(Set mem (StoreC mem src)); 5711 5712 ins_cost(150); 5713 format %{ "movw $mem, $src\t# short/char" %} 5714 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5715 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5716 ins_pipe(ialu_mem_imm); 5717 %} 5718 5719 // Store Byte Immediate 5720 instruct storeImmB0(memory mem, immI0 zero) 5721 %{ 5722 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5723 match(Set mem (StoreB mem zero)); 5724 5725 ins_cost(125); // XXX 5726 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5727 ins_encode %{ 5728 __ movb($mem$$Address, r12); 5729 %} 5730 ins_pipe(ialu_mem_reg); 5731 %} 5732 5733 instruct storeImmB(memory mem, immI8 src) 5734 %{ 5735 match(Set mem (StoreB mem src)); 5736 5737 ins_cost(150); // XXX 5738 format %{ "movb $mem, $src\t# byte" %} 5739 opcode(0xC6); /* C6 /0 */ 5740 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5741 ins_pipe(ialu_mem_imm); 5742 %} 5743 5744 // Store CMS card-mark Immediate 5745 instruct storeImmCM0_reg(memory mem, immI0 zero) 5746 %{ 5747 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5748 match(Set mem (StoreCM mem zero)); 5749 5750 ins_cost(125); // XXX 5751 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5752 ins_encode %{ 5753 __ movb($mem$$Address, r12); 5754 %} 5755 ins_pipe(ialu_mem_reg); 5756 %} 5757 5758 instruct storeImmCM0(memory mem, immI0 src) 5759 %{ 5760 match(Set mem (StoreCM mem src)); 5761 5762 ins_cost(150); // XXX 5763 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5764 opcode(0xC6); /* C6 /0 */ 5765 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5766 ins_pipe(ialu_mem_imm); 5767 %} 5768 5769 // Store Float 5770 instruct storeF(memory mem, regF src) 5771 %{ 5772 match(Set mem (StoreF mem src)); 5773 5774 ins_cost(95); // XXX 5775 format %{ "movss $mem, $src\t# float" %} 5776 ins_encode %{ 5777 __ movflt($mem$$Address, $src$$XMMRegister); 5778 %} 5779 ins_pipe(pipe_slow); // XXX 5780 %} 5781 5782 // Store immediate Float value (it is faster than store from XMM register) 5783 instruct storeF0(memory mem, immF0 zero) 5784 %{ 5785 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5786 match(Set mem (StoreF mem zero)); 5787 5788 ins_cost(25); // XXX 5789 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5790 ins_encode %{ 5791 __ movl($mem$$Address, r12); 5792 %} 5793 ins_pipe(ialu_mem_reg); 5794 %} 5795 5796 instruct storeF_imm(memory mem, immF src) 5797 %{ 5798 match(Set mem (StoreF mem src)); 5799 5800 ins_cost(50); 5801 format %{ "movl $mem, $src\t# float" %} 5802 opcode(0xC7); /* C7 /0 */ 5803 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5804 ins_pipe(ialu_mem_imm); 5805 %} 5806 5807 // Store Double 5808 instruct storeD(memory mem, regD src) 5809 %{ 5810 match(Set mem (StoreD mem src)); 5811 5812 ins_cost(95); // XXX 5813 format %{ "movsd $mem, $src\t# double" %} 5814 ins_encode %{ 5815 __ movdbl($mem$$Address, $src$$XMMRegister); 5816 %} 5817 ins_pipe(pipe_slow); // XXX 5818 %} 5819 5820 // Store immediate double 0.0 (it is faster than store from XMM register) 5821 instruct storeD0_imm(memory mem, immD0 src) 5822 %{ 5823 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 5824 match(Set mem (StoreD mem src)); 5825 5826 ins_cost(50); 5827 format %{ "movq $mem, $src\t# double 0." %} 5828 opcode(0xC7); /* C7 /0 */ 5829 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5830 ins_pipe(ialu_mem_imm); 5831 %} 5832 5833 instruct storeD0(memory mem, immD0 zero) 5834 %{ 5835 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5836 match(Set mem (StoreD mem zero)); 5837 5838 ins_cost(25); // XXX 5839 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5840 ins_encode %{ 5841 __ movq($mem$$Address, r12); 5842 %} 5843 ins_pipe(ialu_mem_reg); 5844 %} 5845 5846 instruct storeSSI(stackSlotI dst, rRegI src) 5847 %{ 5848 match(Set dst src); 5849 5850 ins_cost(100); 5851 format %{ "movl $dst, $src\t# int stk" %} 5852 opcode(0x89); 5853 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 5854 ins_pipe( ialu_mem_reg ); 5855 %} 5856 5857 instruct storeSSL(stackSlotL dst, rRegL src) 5858 %{ 5859 match(Set dst src); 5860 5861 ins_cost(100); 5862 format %{ "movq $dst, $src\t# long stk" %} 5863 opcode(0x89); 5864 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 5865 ins_pipe(ialu_mem_reg); 5866 %} 5867 5868 instruct storeSSP(stackSlotP dst, rRegP src) 5869 %{ 5870 match(Set dst src); 5871 5872 ins_cost(100); 5873 format %{ "movq $dst, $src\t# ptr stk" %} 5874 opcode(0x89); 5875 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 5876 ins_pipe(ialu_mem_reg); 5877 %} 5878 5879 instruct storeSSF(stackSlotF dst, regF src) 5880 %{ 5881 match(Set dst src); 5882 5883 ins_cost(95); // XXX 5884 format %{ "movss $dst, $src\t# float stk" %} 5885 ins_encode %{ 5886 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5887 %} 5888 ins_pipe(pipe_slow); // XXX 5889 %} 5890 5891 instruct storeSSD(stackSlotD dst, regD src) 5892 %{ 5893 match(Set dst src); 5894 5895 ins_cost(95); // XXX 5896 format %{ "movsd $dst, $src\t# double stk" %} 5897 ins_encode %{ 5898 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5899 %} 5900 ins_pipe(pipe_slow); // XXX 5901 %} 5902 5903 //----------BSWAP Instructions------------------------------------------------- 5904 instruct bytes_reverse_int(rRegI dst) %{ 5905 match(Set dst (ReverseBytesI dst)); 5906 5907 format %{ "bswapl $dst" %} 5908 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 5909 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 5910 ins_pipe( ialu_reg ); 5911 %} 5912 5913 instruct bytes_reverse_long(rRegL dst) %{ 5914 match(Set dst (ReverseBytesL dst)); 5915 5916 format %{ "bswapq $dst" %} 5917 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 5918 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 5919 ins_pipe( ialu_reg); 5920 %} 5921 5922 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5923 match(Set dst (ReverseBytesUS dst)); 5924 effect(KILL cr); 5925 5926 format %{ "bswapl $dst\n\t" 5927 "shrl $dst,16\n\t" %} 5928 ins_encode %{ 5929 __ bswapl($dst$$Register); 5930 __ shrl($dst$$Register, 16); 5931 %} 5932 ins_pipe( ialu_reg ); 5933 %} 5934 5935 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5936 match(Set dst (ReverseBytesS dst)); 5937 effect(KILL cr); 5938 5939 format %{ "bswapl $dst\n\t" 5940 "sar $dst,16\n\t" %} 5941 ins_encode %{ 5942 __ bswapl($dst$$Register); 5943 __ sarl($dst$$Register, 16); 5944 %} 5945 ins_pipe( ialu_reg ); 5946 %} 5947 5948 //---------- Zeros Count Instructions ------------------------------------------ 5949 5950 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5951 predicate(UseCountLeadingZerosInstruction); 5952 match(Set dst (CountLeadingZerosI src)); 5953 effect(KILL cr); 5954 5955 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5956 ins_encode %{ 5957 __ lzcntl($dst$$Register, $src$$Register); 5958 %} 5959 ins_pipe(ialu_reg); 5960 %} 5961 5962 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5963 predicate(!UseCountLeadingZerosInstruction); 5964 match(Set dst (CountLeadingZerosI src)); 5965 effect(KILL cr); 5966 5967 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5968 "jnz skip\n\t" 5969 "movl $dst, -1\n" 5970 "skip:\n\t" 5971 "negl $dst\n\t" 5972 "addl $dst, 31" %} 5973 ins_encode %{ 5974 Register Rdst = $dst$$Register; 5975 Register Rsrc = $src$$Register; 5976 Label skip; 5977 __ bsrl(Rdst, Rsrc); 5978 __ jccb(Assembler::notZero, skip); 5979 __ movl(Rdst, -1); 5980 __ bind(skip); 5981 __ negl(Rdst); 5982 __ addl(Rdst, BitsPerInt - 1); 5983 %} 5984 ins_pipe(ialu_reg); 5985 %} 5986 5987 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5988 predicate(UseCountLeadingZerosInstruction); 5989 match(Set dst (CountLeadingZerosL src)); 5990 effect(KILL cr); 5991 5992 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5993 ins_encode %{ 5994 __ lzcntq($dst$$Register, $src$$Register); 5995 %} 5996 ins_pipe(ialu_reg); 5997 %} 5998 5999 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6000 predicate(!UseCountLeadingZerosInstruction); 6001 match(Set dst (CountLeadingZerosL src)); 6002 effect(KILL cr); 6003 6004 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6005 "jnz skip\n\t" 6006 "movl $dst, -1\n" 6007 "skip:\n\t" 6008 "negl $dst\n\t" 6009 "addl $dst, 63" %} 6010 ins_encode %{ 6011 Register Rdst = $dst$$Register; 6012 Register Rsrc = $src$$Register; 6013 Label skip; 6014 __ bsrq(Rdst, Rsrc); 6015 __ jccb(Assembler::notZero, skip); 6016 __ movl(Rdst, -1); 6017 __ bind(skip); 6018 __ negl(Rdst); 6019 __ addl(Rdst, BitsPerLong - 1); 6020 %} 6021 ins_pipe(ialu_reg); 6022 %} 6023 6024 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6025 predicate(UseCountTrailingZerosInstruction); 6026 match(Set dst (CountTrailingZerosI src)); 6027 effect(KILL cr); 6028 6029 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6030 ins_encode %{ 6031 __ tzcntl($dst$$Register, $src$$Register); 6032 %} 6033 ins_pipe(ialu_reg); 6034 %} 6035 6036 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6037 predicate(!UseCountTrailingZerosInstruction); 6038 match(Set dst (CountTrailingZerosI src)); 6039 effect(KILL cr); 6040 6041 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6042 "jnz done\n\t" 6043 "movl $dst, 32\n" 6044 "done:" %} 6045 ins_encode %{ 6046 Register Rdst = $dst$$Register; 6047 Label done; 6048 __ bsfl(Rdst, $src$$Register); 6049 __ jccb(Assembler::notZero, done); 6050 __ movl(Rdst, BitsPerInt); 6051 __ bind(done); 6052 %} 6053 ins_pipe(ialu_reg); 6054 %} 6055 6056 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6057 predicate(UseCountTrailingZerosInstruction); 6058 match(Set dst (CountTrailingZerosL src)); 6059 effect(KILL cr); 6060 6061 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6062 ins_encode %{ 6063 __ tzcntq($dst$$Register, $src$$Register); 6064 %} 6065 ins_pipe(ialu_reg); 6066 %} 6067 6068 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6069 predicate(!UseCountTrailingZerosInstruction); 6070 match(Set dst (CountTrailingZerosL src)); 6071 effect(KILL cr); 6072 6073 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6074 "jnz done\n\t" 6075 "movl $dst, 64\n" 6076 "done:" %} 6077 ins_encode %{ 6078 Register Rdst = $dst$$Register; 6079 Label done; 6080 __ bsfq(Rdst, $src$$Register); 6081 __ jccb(Assembler::notZero, done); 6082 __ movl(Rdst, BitsPerLong); 6083 __ bind(done); 6084 %} 6085 ins_pipe(ialu_reg); 6086 %} 6087 6088 6089 //---------- Population Count Instructions ------------------------------------- 6090 6091 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6092 predicate(UsePopCountInstruction); 6093 match(Set dst (PopCountI src)); 6094 effect(KILL cr); 6095 6096 format %{ "popcnt $dst, $src" %} 6097 ins_encode %{ 6098 __ popcntl($dst$$Register, $src$$Register); 6099 %} 6100 ins_pipe(ialu_reg); 6101 %} 6102 6103 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6104 predicate(UsePopCountInstruction); 6105 match(Set dst (PopCountI (LoadI mem))); 6106 effect(KILL cr); 6107 6108 format %{ "popcnt $dst, $mem" %} 6109 ins_encode %{ 6110 __ popcntl($dst$$Register, $mem$$Address); 6111 %} 6112 ins_pipe(ialu_reg); 6113 %} 6114 6115 // Note: Long.bitCount(long) returns an int. 6116 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6117 predicate(UsePopCountInstruction); 6118 match(Set dst (PopCountL src)); 6119 effect(KILL cr); 6120 6121 format %{ "popcnt $dst, $src" %} 6122 ins_encode %{ 6123 __ popcntq($dst$$Register, $src$$Register); 6124 %} 6125 ins_pipe(ialu_reg); 6126 %} 6127 6128 // Note: Long.bitCount(long) returns an int. 6129 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6130 predicate(UsePopCountInstruction); 6131 match(Set dst (PopCountL (LoadL mem))); 6132 effect(KILL cr); 6133 6134 format %{ "popcnt $dst, $mem" %} 6135 ins_encode %{ 6136 __ popcntq($dst$$Register, $mem$$Address); 6137 %} 6138 ins_pipe(ialu_reg); 6139 %} 6140 6141 6142 //----------MemBar Instructions----------------------------------------------- 6143 // Memory barrier flavors 6144 6145 instruct membar_acquire() 6146 %{ 6147 match(MemBarAcquire); 6148 match(LoadFence); 6149 ins_cost(0); 6150 6151 size(0); 6152 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6153 ins_encode(); 6154 ins_pipe(empty); 6155 %} 6156 6157 instruct membar_acquire_lock() 6158 %{ 6159 match(MemBarAcquireLock); 6160 ins_cost(0); 6161 6162 size(0); 6163 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6164 ins_encode(); 6165 ins_pipe(empty); 6166 %} 6167 6168 instruct membar_release() 6169 %{ 6170 match(MemBarRelease); 6171 match(StoreFence); 6172 ins_cost(0); 6173 6174 size(0); 6175 format %{ "MEMBAR-release ! (empty encoding)" %} 6176 ins_encode(); 6177 ins_pipe(empty); 6178 %} 6179 6180 instruct membar_release_lock() 6181 %{ 6182 match(MemBarReleaseLock); 6183 ins_cost(0); 6184 6185 size(0); 6186 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6187 ins_encode(); 6188 ins_pipe(empty); 6189 %} 6190 6191 instruct membar_volatile(rFlagsReg cr) %{ 6192 match(MemBarVolatile); 6193 effect(KILL cr); 6194 ins_cost(400); 6195 6196 format %{ 6197 $$template 6198 if (os::is_MP()) { 6199 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6200 } else { 6201 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6202 } 6203 %} 6204 ins_encode %{ 6205 __ membar(Assembler::StoreLoad); 6206 %} 6207 ins_pipe(pipe_slow); 6208 %} 6209 6210 instruct unnecessary_membar_volatile() 6211 %{ 6212 match(MemBarVolatile); 6213 predicate(Matcher::post_store_load_barrier(n)); 6214 ins_cost(0); 6215 6216 size(0); 6217 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6218 ins_encode(); 6219 ins_pipe(empty); 6220 %} 6221 6222 instruct membar_storestore() %{ 6223 match(MemBarStoreStore); 6224 ins_cost(0); 6225 6226 size(0); 6227 format %{ "MEMBAR-storestore (empty encoding)" %} 6228 ins_encode( ); 6229 ins_pipe(empty); 6230 %} 6231 6232 //----------Move Instructions-------------------------------------------------- 6233 6234 instruct castX2P(rRegP dst, rRegL src) 6235 %{ 6236 match(Set dst (CastX2P src)); 6237 6238 format %{ "movq $dst, $src\t# long->ptr" %} 6239 ins_encode %{ 6240 if ($dst$$reg != $src$$reg) { 6241 __ movptr($dst$$Register, $src$$Register); 6242 } 6243 %} 6244 ins_pipe(ialu_reg_reg); // XXX 6245 %} 6246 6247 instruct castP2X(rRegL dst, rRegP src) 6248 %{ 6249 match(Set dst (CastP2X src)); 6250 6251 format %{ "movq $dst, $src\t# ptr -> long" %} 6252 ins_encode %{ 6253 if ($dst$$reg != $src$$reg) { 6254 __ movptr($dst$$Register, $src$$Register); 6255 } 6256 %} 6257 ins_pipe(ialu_reg_reg); // XXX 6258 %} 6259 6260 // Convert oop into int for vectors alignment masking 6261 instruct convP2I(rRegI dst, rRegP src) 6262 %{ 6263 match(Set dst (ConvL2I (CastP2X src))); 6264 6265 format %{ "movl $dst, $src\t# ptr -> int" %} 6266 ins_encode %{ 6267 __ movl($dst$$Register, $src$$Register); 6268 %} 6269 ins_pipe(ialu_reg_reg); // XXX 6270 %} 6271 6272 // Convert compressed oop into int for vectors alignment masking 6273 // in case of 32bit oops (heap < 4Gb). 6274 instruct convN2I(rRegI dst, rRegN src) 6275 %{ 6276 predicate(Universe::narrow_oop_shift() == 0); 6277 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6278 6279 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6280 ins_encode %{ 6281 __ movl($dst$$Register, $src$$Register); 6282 %} 6283 ins_pipe(ialu_reg_reg); // XXX 6284 %} 6285 6286 // Convert oop pointer into compressed form 6287 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6288 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6289 match(Set dst (EncodeP src)); 6290 effect(KILL cr); 6291 format %{ "encode_heap_oop $dst,$src" %} 6292 ins_encode %{ 6293 Register s = $src$$Register; 6294 Register d = $dst$$Register; 6295 if (s != d) { 6296 __ movq(d, s); 6297 } 6298 __ encode_heap_oop(d); 6299 %} 6300 ins_pipe(ialu_reg_long); 6301 %} 6302 6303 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6304 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6305 match(Set dst (EncodeP src)); 6306 effect(KILL cr); 6307 format %{ "encode_heap_oop_not_null $dst,$src" %} 6308 ins_encode %{ 6309 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6310 %} 6311 ins_pipe(ialu_reg_long); 6312 %} 6313 6314 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6315 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6316 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6317 match(Set dst (DecodeN src)); 6318 effect(KILL cr); 6319 format %{ "decode_heap_oop $dst,$src" %} 6320 ins_encode %{ 6321 Register s = $src$$Register; 6322 Register d = $dst$$Register; 6323 if (s != d) { 6324 __ movq(d, s); 6325 } 6326 __ decode_heap_oop(d); 6327 %} 6328 ins_pipe(ialu_reg_long); 6329 %} 6330 6331 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6332 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6333 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6334 match(Set dst (DecodeN src)); 6335 effect(KILL cr); 6336 format %{ "decode_heap_oop_not_null $dst,$src" %} 6337 ins_encode %{ 6338 Register s = $src$$Register; 6339 Register d = $dst$$Register; 6340 if (s != d) { 6341 __ decode_heap_oop_not_null(d, s); 6342 } else { 6343 __ decode_heap_oop_not_null(d); 6344 } 6345 %} 6346 ins_pipe(ialu_reg_long); 6347 %} 6348 6349 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6350 match(Set dst (EncodePKlass src)); 6351 effect(KILL cr); 6352 format %{ "encode_klass_not_null $dst,$src" %} 6353 ins_encode %{ 6354 __ encode_klass_not_null($dst$$Register, $src$$Register); 6355 %} 6356 ins_pipe(ialu_reg_long); 6357 %} 6358 6359 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6360 match(Set dst (DecodeNKlass src)); 6361 effect(KILL cr); 6362 format %{ "decode_klass_not_null $dst,$src" %} 6363 ins_encode %{ 6364 Register s = $src$$Register; 6365 Register d = $dst$$Register; 6366 if (s != d) { 6367 __ decode_klass_not_null(d, s); 6368 } else { 6369 __ decode_klass_not_null(d); 6370 } 6371 %} 6372 ins_pipe(ialu_reg_long); 6373 %} 6374 6375 6376 //----------Conditional Move--------------------------------------------------- 6377 // Jump 6378 // dummy instruction for generating temp registers 6379 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6380 match(Jump (LShiftL switch_val shift)); 6381 ins_cost(350); 6382 predicate(false); 6383 effect(TEMP dest); 6384 6385 format %{ "leaq $dest, [$constantaddress]\n\t" 6386 "jmp [$dest + $switch_val << $shift]\n\t" %} 6387 ins_encode %{ 6388 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6389 // to do that and the compiler is using that register as one it can allocate. 6390 // So we build it all by hand. 6391 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6392 // ArrayAddress dispatch(table, index); 6393 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6394 __ lea($dest$$Register, $constantaddress); 6395 __ jmp(dispatch); 6396 %} 6397 ins_pipe(pipe_jmp); 6398 %} 6399 6400 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6401 match(Jump (AddL (LShiftL switch_val shift) offset)); 6402 ins_cost(350); 6403 effect(TEMP dest); 6404 6405 format %{ "leaq $dest, [$constantaddress]\n\t" 6406 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6407 ins_encode %{ 6408 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6409 // to do that and the compiler is using that register as one it can allocate. 6410 // So we build it all by hand. 6411 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6412 // ArrayAddress dispatch(table, index); 6413 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6414 __ lea($dest$$Register, $constantaddress); 6415 __ jmp(dispatch); 6416 %} 6417 ins_pipe(pipe_jmp); 6418 %} 6419 6420 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6421 match(Jump switch_val); 6422 ins_cost(350); 6423 effect(TEMP dest); 6424 6425 format %{ "leaq $dest, [$constantaddress]\n\t" 6426 "jmp [$dest + $switch_val]\n\t" %} 6427 ins_encode %{ 6428 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6429 // to do that and the compiler is using that register as one it can allocate. 6430 // So we build it all by hand. 6431 // Address index(noreg, switch_reg, Address::times_1); 6432 // ArrayAddress dispatch(table, index); 6433 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6434 __ lea($dest$$Register, $constantaddress); 6435 __ jmp(dispatch); 6436 %} 6437 ins_pipe(pipe_jmp); 6438 %} 6439 6440 // Conditional move 6441 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6442 %{ 6443 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6444 6445 ins_cost(200); // XXX 6446 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6447 opcode(0x0F, 0x40); 6448 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6449 ins_pipe(pipe_cmov_reg); 6450 %} 6451 6452 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6453 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6454 6455 ins_cost(200); // XXX 6456 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6457 opcode(0x0F, 0x40); 6458 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6459 ins_pipe(pipe_cmov_reg); 6460 %} 6461 6462 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6463 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6464 ins_cost(200); 6465 expand %{ 6466 cmovI_regU(cop, cr, dst, src); 6467 %} 6468 %} 6469 6470 // Conditional move 6471 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6472 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6473 6474 ins_cost(250); // XXX 6475 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6476 opcode(0x0F, 0x40); 6477 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6478 ins_pipe(pipe_cmov_mem); 6479 %} 6480 6481 // Conditional move 6482 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6483 %{ 6484 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6485 6486 ins_cost(250); // XXX 6487 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6488 opcode(0x0F, 0x40); 6489 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6490 ins_pipe(pipe_cmov_mem); 6491 %} 6492 6493 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6494 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6495 ins_cost(250); 6496 expand %{ 6497 cmovI_memU(cop, cr, dst, src); 6498 %} 6499 %} 6500 6501 // Conditional move 6502 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6503 %{ 6504 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6505 6506 ins_cost(200); // XXX 6507 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6508 opcode(0x0F, 0x40); 6509 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6510 ins_pipe(pipe_cmov_reg); 6511 %} 6512 6513 // Conditional move 6514 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6515 %{ 6516 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6517 6518 ins_cost(200); // XXX 6519 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6520 opcode(0x0F, 0x40); 6521 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6522 ins_pipe(pipe_cmov_reg); 6523 %} 6524 6525 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6526 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6527 ins_cost(200); 6528 expand %{ 6529 cmovN_regU(cop, cr, dst, src); 6530 %} 6531 %} 6532 6533 // Conditional move 6534 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6535 %{ 6536 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6537 6538 ins_cost(200); // XXX 6539 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6540 opcode(0x0F, 0x40); 6541 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6542 ins_pipe(pipe_cmov_reg); // XXX 6543 %} 6544 6545 // Conditional move 6546 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6547 %{ 6548 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6549 6550 ins_cost(200); // XXX 6551 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6552 opcode(0x0F, 0x40); 6553 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6554 ins_pipe(pipe_cmov_reg); // XXX 6555 %} 6556 6557 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6558 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6559 ins_cost(200); 6560 expand %{ 6561 cmovP_regU(cop, cr, dst, src); 6562 %} 6563 %} 6564 6565 // DISABLED: Requires the ADLC to emit a bottom_type call that 6566 // correctly meets the two pointer arguments; one is an incoming 6567 // register but the other is a memory operand. ALSO appears to 6568 // be buggy with implicit null checks. 6569 // 6570 //// Conditional move 6571 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6572 //%{ 6573 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6574 // ins_cost(250); 6575 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6576 // opcode(0x0F,0x40); 6577 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6578 // ins_pipe( pipe_cmov_mem ); 6579 //%} 6580 // 6581 //// Conditional move 6582 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6583 //%{ 6584 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6585 // ins_cost(250); 6586 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6587 // opcode(0x0F,0x40); 6588 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6589 // ins_pipe( pipe_cmov_mem ); 6590 //%} 6591 6592 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6593 %{ 6594 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6595 6596 ins_cost(200); // XXX 6597 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6598 opcode(0x0F, 0x40); 6599 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6600 ins_pipe(pipe_cmov_reg); // XXX 6601 %} 6602 6603 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6604 %{ 6605 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6606 6607 ins_cost(200); // XXX 6608 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6609 opcode(0x0F, 0x40); 6610 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6611 ins_pipe(pipe_cmov_mem); // XXX 6612 %} 6613 6614 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6615 %{ 6616 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6617 6618 ins_cost(200); // XXX 6619 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6620 opcode(0x0F, 0x40); 6621 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6622 ins_pipe(pipe_cmov_reg); // XXX 6623 %} 6624 6625 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6626 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6627 ins_cost(200); 6628 expand %{ 6629 cmovL_regU(cop, cr, dst, src); 6630 %} 6631 %} 6632 6633 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6634 %{ 6635 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6636 6637 ins_cost(200); // XXX 6638 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6639 opcode(0x0F, 0x40); 6640 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6641 ins_pipe(pipe_cmov_mem); // XXX 6642 %} 6643 6644 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6645 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6646 ins_cost(200); 6647 expand %{ 6648 cmovL_memU(cop, cr, dst, src); 6649 %} 6650 %} 6651 6652 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6653 %{ 6654 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6655 6656 ins_cost(200); // XXX 6657 format %{ "jn$cop skip\t# signed cmove float\n\t" 6658 "movss $dst, $src\n" 6659 "skip:" %} 6660 ins_encode %{ 6661 Label Lskip; 6662 // Invert sense of branch from sense of CMOV 6663 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6664 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6665 __ bind(Lskip); 6666 %} 6667 ins_pipe(pipe_slow); 6668 %} 6669 6670 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6671 // %{ 6672 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6673 6674 // ins_cost(200); // XXX 6675 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6676 // "movss $dst, $src\n" 6677 // "skip:" %} 6678 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6679 // ins_pipe(pipe_slow); 6680 // %} 6681 6682 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6683 %{ 6684 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6685 6686 ins_cost(200); // XXX 6687 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6688 "movss $dst, $src\n" 6689 "skip:" %} 6690 ins_encode %{ 6691 Label Lskip; 6692 // Invert sense of branch from sense of CMOV 6693 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6694 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6695 __ bind(Lskip); 6696 %} 6697 ins_pipe(pipe_slow); 6698 %} 6699 6700 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6701 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6702 ins_cost(200); 6703 expand %{ 6704 cmovF_regU(cop, cr, dst, src); 6705 %} 6706 %} 6707 6708 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6709 %{ 6710 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6711 6712 ins_cost(200); // XXX 6713 format %{ "jn$cop skip\t# signed cmove double\n\t" 6714 "movsd $dst, $src\n" 6715 "skip:" %} 6716 ins_encode %{ 6717 Label Lskip; 6718 // Invert sense of branch from sense of CMOV 6719 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6720 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6721 __ bind(Lskip); 6722 %} 6723 ins_pipe(pipe_slow); 6724 %} 6725 6726 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6727 %{ 6728 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6729 6730 ins_cost(200); // XXX 6731 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6732 "movsd $dst, $src\n" 6733 "skip:" %} 6734 ins_encode %{ 6735 Label Lskip; 6736 // Invert sense of branch from sense of CMOV 6737 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6738 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6739 __ bind(Lskip); 6740 %} 6741 ins_pipe(pipe_slow); 6742 %} 6743 6744 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6745 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6746 ins_cost(200); 6747 expand %{ 6748 cmovD_regU(cop, cr, dst, src); 6749 %} 6750 %} 6751 6752 //----------Arithmetic Instructions-------------------------------------------- 6753 //----------Addition Instructions---------------------------------------------- 6754 6755 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6756 %{ 6757 match(Set dst (AddI dst src)); 6758 effect(KILL cr); 6759 6760 format %{ "addl $dst, $src\t# int" %} 6761 opcode(0x03); 6762 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6763 ins_pipe(ialu_reg_reg); 6764 %} 6765 6766 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6767 %{ 6768 match(Set dst (AddI dst src)); 6769 effect(KILL cr); 6770 6771 format %{ "addl $dst, $src\t# int" %} 6772 opcode(0x81, 0x00); /* /0 id */ 6773 ins_encode(OpcSErm(dst, src), Con8or32(src)); 6774 ins_pipe( ialu_reg ); 6775 %} 6776 6777 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6778 %{ 6779 match(Set dst (AddI dst (LoadI src))); 6780 effect(KILL cr); 6781 6782 ins_cost(125); // XXX 6783 format %{ "addl $dst, $src\t# int" %} 6784 opcode(0x03); 6785 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6786 ins_pipe(ialu_reg_mem); 6787 %} 6788 6789 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6790 %{ 6791 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6792 effect(KILL cr); 6793 6794 ins_cost(150); // XXX 6795 format %{ "addl $dst, $src\t# int" %} 6796 opcode(0x01); /* Opcode 01 /r */ 6797 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6798 ins_pipe(ialu_mem_reg); 6799 %} 6800 6801 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6802 %{ 6803 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6804 effect(KILL cr); 6805 6806 ins_cost(125); // XXX 6807 format %{ "addl $dst, $src\t# int" %} 6808 opcode(0x81); /* Opcode 81 /0 id */ 6809 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 6810 ins_pipe(ialu_mem_imm); 6811 %} 6812 6813 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 6814 %{ 6815 predicate(UseIncDec); 6816 match(Set dst (AddI dst src)); 6817 effect(KILL cr); 6818 6819 format %{ "incl $dst\t# int" %} 6820 opcode(0xFF, 0x00); // FF /0 6821 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6822 ins_pipe(ialu_reg); 6823 %} 6824 6825 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 6826 %{ 6827 predicate(UseIncDec); 6828 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6829 effect(KILL cr); 6830 6831 ins_cost(125); // XXX 6832 format %{ "incl $dst\t# int" %} 6833 opcode(0xFF); /* Opcode FF /0 */ 6834 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 6835 ins_pipe(ialu_mem_imm); 6836 %} 6837 6838 // XXX why does that use AddI 6839 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6840 %{ 6841 predicate(UseIncDec); 6842 match(Set dst (AddI dst src)); 6843 effect(KILL cr); 6844 6845 format %{ "decl $dst\t# int" %} 6846 opcode(0xFF, 0x01); // FF /1 6847 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6848 ins_pipe(ialu_reg); 6849 %} 6850 6851 // XXX why does that use AddI 6852 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6853 %{ 6854 predicate(UseIncDec); 6855 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6856 effect(KILL cr); 6857 6858 ins_cost(125); // XXX 6859 format %{ "decl $dst\t# int" %} 6860 opcode(0xFF); /* Opcode FF /1 */ 6861 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 6862 ins_pipe(ialu_mem_imm); 6863 %} 6864 6865 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 6866 %{ 6867 match(Set dst (AddI src0 src1)); 6868 6869 ins_cost(110); 6870 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 6871 opcode(0x8D); /* 0x8D /r */ 6872 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 6873 ins_pipe(ialu_reg_reg); 6874 %} 6875 6876 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6877 %{ 6878 match(Set dst (AddL dst src)); 6879 effect(KILL cr); 6880 6881 format %{ "addq $dst, $src\t# long" %} 6882 opcode(0x03); 6883 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 6884 ins_pipe(ialu_reg_reg); 6885 %} 6886 6887 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6888 %{ 6889 match(Set dst (AddL dst src)); 6890 effect(KILL cr); 6891 6892 format %{ "addq $dst, $src\t# long" %} 6893 opcode(0x81, 0x00); /* /0 id */ 6894 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 6895 ins_pipe( ialu_reg ); 6896 %} 6897 6898 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6899 %{ 6900 match(Set dst (AddL dst (LoadL src))); 6901 effect(KILL cr); 6902 6903 ins_cost(125); // XXX 6904 format %{ "addq $dst, $src\t# long" %} 6905 opcode(0x03); 6906 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6907 ins_pipe(ialu_reg_mem); 6908 %} 6909 6910 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6911 %{ 6912 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6913 effect(KILL cr); 6914 6915 ins_cost(150); // XXX 6916 format %{ "addq $dst, $src\t# long" %} 6917 opcode(0x01); /* Opcode 01 /r */ 6918 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6919 ins_pipe(ialu_mem_reg); 6920 %} 6921 6922 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6923 %{ 6924 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6925 effect(KILL cr); 6926 6927 ins_cost(125); // XXX 6928 format %{ "addq $dst, $src\t# long" %} 6929 opcode(0x81); /* Opcode 81 /0 id */ 6930 ins_encode(REX_mem_wide(dst), 6931 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 6932 ins_pipe(ialu_mem_imm); 6933 %} 6934 6935 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6936 %{ 6937 predicate(UseIncDec); 6938 match(Set dst (AddL dst src)); 6939 effect(KILL cr); 6940 6941 format %{ "incq $dst\t# long" %} 6942 opcode(0xFF, 0x00); // FF /0 6943 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 6944 ins_pipe(ialu_reg); 6945 %} 6946 6947 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6948 %{ 6949 predicate(UseIncDec); 6950 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6951 effect(KILL cr); 6952 6953 ins_cost(125); // XXX 6954 format %{ "incq $dst\t# long" %} 6955 opcode(0xFF); /* Opcode FF /0 */ 6956 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 6957 ins_pipe(ialu_mem_imm); 6958 %} 6959 6960 // XXX why does that use AddL 6961 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6962 %{ 6963 predicate(UseIncDec); 6964 match(Set dst (AddL dst src)); 6965 effect(KILL cr); 6966 6967 format %{ "decq $dst\t# long" %} 6968 opcode(0xFF, 0x01); // FF /1 6969 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 6970 ins_pipe(ialu_reg); 6971 %} 6972 6973 // XXX why does that use AddL 6974 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6975 %{ 6976 predicate(UseIncDec); 6977 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6978 effect(KILL cr); 6979 6980 ins_cost(125); // XXX 6981 format %{ "decq $dst\t# long" %} 6982 opcode(0xFF); /* Opcode FF /1 */ 6983 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 6984 ins_pipe(ialu_mem_imm); 6985 %} 6986 6987 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 6988 %{ 6989 match(Set dst (AddL src0 src1)); 6990 6991 ins_cost(110); 6992 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 6993 opcode(0x8D); /* 0x8D /r */ 6994 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 6995 ins_pipe(ialu_reg_reg); 6996 %} 6997 6998 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6999 %{ 7000 match(Set dst (AddP dst src)); 7001 effect(KILL cr); 7002 7003 format %{ "addq $dst, $src\t# ptr" %} 7004 opcode(0x03); 7005 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7006 ins_pipe(ialu_reg_reg); 7007 %} 7008 7009 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7010 %{ 7011 match(Set dst (AddP dst src)); 7012 effect(KILL cr); 7013 7014 format %{ "addq $dst, $src\t# ptr" %} 7015 opcode(0x81, 0x00); /* /0 id */ 7016 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7017 ins_pipe( ialu_reg ); 7018 %} 7019 7020 // XXX addP mem ops ???? 7021 7022 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7023 %{ 7024 match(Set dst (AddP src0 src1)); 7025 7026 ins_cost(110); 7027 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7028 opcode(0x8D); /* 0x8D /r */ 7029 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7030 ins_pipe(ialu_reg_reg); 7031 %} 7032 7033 instruct checkCastPP(rRegP dst) 7034 %{ 7035 match(Set dst (CheckCastPP dst)); 7036 7037 size(0); 7038 format %{ "# checkcastPP of $dst" %} 7039 ins_encode(/* empty encoding */); 7040 ins_pipe(empty); 7041 %} 7042 7043 instruct castPP(rRegP dst) 7044 %{ 7045 match(Set dst (CastPP dst)); 7046 7047 size(0); 7048 format %{ "# castPP of $dst" %} 7049 ins_encode(/* empty encoding */); 7050 ins_pipe(empty); 7051 %} 7052 7053 instruct castII(rRegI dst) 7054 %{ 7055 match(Set dst (CastII dst)); 7056 7057 size(0); 7058 format %{ "# castII of $dst" %} 7059 ins_encode(/* empty encoding */); 7060 ins_cost(0); 7061 ins_pipe(empty); 7062 %} 7063 7064 // LoadP-locked same as a regular LoadP when used with compare-swap 7065 instruct loadPLocked(rRegP dst, memory mem) 7066 %{ 7067 match(Set dst (LoadPLocked mem)); 7068 7069 ins_cost(125); // XXX 7070 format %{ "movq $dst, $mem\t# ptr locked" %} 7071 opcode(0x8B); 7072 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7073 ins_pipe(ialu_reg_mem); // XXX 7074 %} 7075 7076 // Conditional-store of the updated heap-top. 7077 // Used during allocation of the shared heap. 7078 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7079 7080 instruct storePConditional(memory heap_top_ptr, 7081 rax_RegP oldval, rRegP newval, 7082 rFlagsReg cr) 7083 %{ 7084 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7085 7086 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7087 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7088 opcode(0x0F, 0xB1); 7089 ins_encode(lock_prefix, 7090 REX_reg_mem_wide(newval, heap_top_ptr), 7091 OpcP, OpcS, 7092 reg_mem(newval, heap_top_ptr)); 7093 ins_pipe(pipe_cmpxchg); 7094 %} 7095 7096 // Conditional-store of an int value. 7097 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7098 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7099 %{ 7100 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7101 effect(KILL oldval); 7102 7103 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7104 opcode(0x0F, 0xB1); 7105 ins_encode(lock_prefix, 7106 REX_reg_mem(newval, mem), 7107 OpcP, OpcS, 7108 reg_mem(newval, mem)); 7109 ins_pipe(pipe_cmpxchg); 7110 %} 7111 7112 // Conditional-store of a long value. 7113 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7114 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7115 %{ 7116 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7117 effect(KILL oldval); 7118 7119 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7120 opcode(0x0F, 0xB1); 7121 ins_encode(lock_prefix, 7122 REX_reg_mem_wide(newval, mem), 7123 OpcP, OpcS, 7124 reg_mem(newval, mem)); 7125 ins_pipe(pipe_cmpxchg); 7126 %} 7127 7128 7129 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7130 instruct compareAndSwapP(rRegI res, 7131 memory mem_ptr, 7132 rax_RegP oldval, rRegP newval, 7133 rFlagsReg cr) 7134 %{ 7135 predicate(VM_Version::supports_cx8()); 7136 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7137 effect(KILL cr, KILL oldval); 7138 7139 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7140 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7141 "sete $res\n\t" 7142 "movzbl $res, $res" %} 7143 opcode(0x0F, 0xB1); 7144 ins_encode(lock_prefix, 7145 REX_reg_mem_wide(newval, mem_ptr), 7146 OpcP, OpcS, 7147 reg_mem(newval, mem_ptr), 7148 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7149 REX_reg_breg(res, res), // movzbl 7150 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7151 ins_pipe( pipe_cmpxchg ); 7152 %} 7153 7154 instruct compareAndSwapL(rRegI res, 7155 memory mem_ptr, 7156 rax_RegL oldval, rRegL newval, 7157 rFlagsReg cr) 7158 %{ 7159 predicate(VM_Version::supports_cx8()); 7160 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7161 effect(KILL cr, KILL oldval); 7162 7163 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7164 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7165 "sete $res\n\t" 7166 "movzbl $res, $res" %} 7167 opcode(0x0F, 0xB1); 7168 ins_encode(lock_prefix, 7169 REX_reg_mem_wide(newval, mem_ptr), 7170 OpcP, OpcS, 7171 reg_mem(newval, mem_ptr), 7172 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7173 REX_reg_breg(res, res), // movzbl 7174 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7175 ins_pipe( pipe_cmpxchg ); 7176 %} 7177 7178 instruct compareAndSwapI(rRegI res, 7179 memory mem_ptr, 7180 rax_RegI oldval, rRegI newval, 7181 rFlagsReg cr) 7182 %{ 7183 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7184 effect(KILL cr, KILL oldval); 7185 7186 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7187 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7188 "sete $res\n\t" 7189 "movzbl $res, $res" %} 7190 opcode(0x0F, 0xB1); 7191 ins_encode(lock_prefix, 7192 REX_reg_mem(newval, mem_ptr), 7193 OpcP, OpcS, 7194 reg_mem(newval, mem_ptr), 7195 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7196 REX_reg_breg(res, res), // movzbl 7197 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7198 ins_pipe( pipe_cmpxchg ); 7199 %} 7200 7201 7202 instruct compareAndSwapN(rRegI res, 7203 memory mem_ptr, 7204 rax_RegN oldval, rRegN newval, 7205 rFlagsReg cr) %{ 7206 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7207 effect(KILL cr, KILL oldval); 7208 7209 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7210 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7211 "sete $res\n\t" 7212 "movzbl $res, $res" %} 7213 opcode(0x0F, 0xB1); 7214 ins_encode(lock_prefix, 7215 REX_reg_mem(newval, mem_ptr), 7216 OpcP, OpcS, 7217 reg_mem(newval, mem_ptr), 7218 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7219 REX_reg_breg(res, res), // movzbl 7220 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7221 ins_pipe( pipe_cmpxchg ); 7222 %} 7223 7224 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7225 predicate(n->as_LoadStore()->result_not_used()); 7226 match(Set dummy (GetAndAddI mem add)); 7227 effect(KILL cr); 7228 format %{ "ADDL [$mem],$add" %} 7229 ins_encode %{ 7230 if (os::is_MP()) { __ lock(); } 7231 __ addl($mem$$Address, $add$$constant); 7232 %} 7233 ins_pipe( pipe_cmpxchg ); 7234 %} 7235 7236 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7237 match(Set newval (GetAndAddI mem newval)); 7238 effect(KILL cr); 7239 format %{ "XADDL [$mem],$newval" %} 7240 ins_encode %{ 7241 if (os::is_MP()) { __ lock(); } 7242 __ xaddl($mem$$Address, $newval$$Register); 7243 %} 7244 ins_pipe( pipe_cmpxchg ); 7245 %} 7246 7247 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7248 predicate(n->as_LoadStore()->result_not_used()); 7249 match(Set dummy (GetAndAddL mem add)); 7250 effect(KILL cr); 7251 format %{ "ADDQ [$mem],$add" %} 7252 ins_encode %{ 7253 if (os::is_MP()) { __ lock(); } 7254 __ addq($mem$$Address, $add$$constant); 7255 %} 7256 ins_pipe( pipe_cmpxchg ); 7257 %} 7258 7259 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7260 match(Set newval (GetAndAddL mem newval)); 7261 effect(KILL cr); 7262 format %{ "XADDQ [$mem],$newval" %} 7263 ins_encode %{ 7264 if (os::is_MP()) { __ lock(); } 7265 __ xaddq($mem$$Address, $newval$$Register); 7266 %} 7267 ins_pipe( pipe_cmpxchg ); 7268 %} 7269 7270 instruct xchgI( memory mem, rRegI newval) %{ 7271 match(Set newval (GetAndSetI mem newval)); 7272 format %{ "XCHGL $newval,[$mem]" %} 7273 ins_encode %{ 7274 __ xchgl($newval$$Register, $mem$$Address); 7275 %} 7276 ins_pipe( pipe_cmpxchg ); 7277 %} 7278 7279 instruct xchgL( memory mem, rRegL newval) %{ 7280 match(Set newval (GetAndSetL mem newval)); 7281 format %{ "XCHGL $newval,[$mem]" %} 7282 ins_encode %{ 7283 __ xchgq($newval$$Register, $mem$$Address); 7284 %} 7285 ins_pipe( pipe_cmpxchg ); 7286 %} 7287 7288 instruct xchgP( memory mem, rRegP newval) %{ 7289 match(Set newval (GetAndSetP mem newval)); 7290 format %{ "XCHGQ $newval,[$mem]" %} 7291 ins_encode %{ 7292 __ xchgq($newval$$Register, $mem$$Address); 7293 %} 7294 ins_pipe( pipe_cmpxchg ); 7295 %} 7296 7297 instruct xchgN( memory mem, rRegN newval) %{ 7298 match(Set newval (GetAndSetN mem newval)); 7299 format %{ "XCHGL $newval,$mem]" %} 7300 ins_encode %{ 7301 __ xchgl($newval$$Register, $mem$$Address); 7302 %} 7303 ins_pipe( pipe_cmpxchg ); 7304 %} 7305 7306 //----------Subtraction Instructions------------------------------------------- 7307 7308 // Integer Subtraction Instructions 7309 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7310 %{ 7311 match(Set dst (SubI dst src)); 7312 effect(KILL cr); 7313 7314 format %{ "subl $dst, $src\t# int" %} 7315 opcode(0x2B); 7316 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7317 ins_pipe(ialu_reg_reg); 7318 %} 7319 7320 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7321 %{ 7322 match(Set dst (SubI dst src)); 7323 effect(KILL cr); 7324 7325 format %{ "subl $dst, $src\t# int" %} 7326 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7327 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7328 ins_pipe(ialu_reg); 7329 %} 7330 7331 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7332 %{ 7333 match(Set dst (SubI dst (LoadI src))); 7334 effect(KILL cr); 7335 7336 ins_cost(125); 7337 format %{ "subl $dst, $src\t# int" %} 7338 opcode(0x2B); 7339 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7340 ins_pipe(ialu_reg_mem); 7341 %} 7342 7343 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7344 %{ 7345 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7346 effect(KILL cr); 7347 7348 ins_cost(150); 7349 format %{ "subl $dst, $src\t# int" %} 7350 opcode(0x29); /* Opcode 29 /r */ 7351 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7352 ins_pipe(ialu_mem_reg); 7353 %} 7354 7355 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7356 %{ 7357 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7358 effect(KILL cr); 7359 7360 ins_cost(125); // XXX 7361 format %{ "subl $dst, $src\t# int" %} 7362 opcode(0x81); /* Opcode 81 /5 id */ 7363 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7364 ins_pipe(ialu_mem_imm); 7365 %} 7366 7367 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7368 %{ 7369 match(Set dst (SubL dst src)); 7370 effect(KILL cr); 7371 7372 format %{ "subq $dst, $src\t# long" %} 7373 opcode(0x2B); 7374 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7375 ins_pipe(ialu_reg_reg); 7376 %} 7377 7378 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7379 %{ 7380 match(Set dst (SubL dst src)); 7381 effect(KILL cr); 7382 7383 format %{ "subq $dst, $src\t# long" %} 7384 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7385 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7386 ins_pipe(ialu_reg); 7387 %} 7388 7389 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7390 %{ 7391 match(Set dst (SubL dst (LoadL src))); 7392 effect(KILL cr); 7393 7394 ins_cost(125); 7395 format %{ "subq $dst, $src\t# long" %} 7396 opcode(0x2B); 7397 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7398 ins_pipe(ialu_reg_mem); 7399 %} 7400 7401 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7402 %{ 7403 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7404 effect(KILL cr); 7405 7406 ins_cost(150); 7407 format %{ "subq $dst, $src\t# long" %} 7408 opcode(0x29); /* Opcode 29 /r */ 7409 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7410 ins_pipe(ialu_mem_reg); 7411 %} 7412 7413 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7414 %{ 7415 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7416 effect(KILL cr); 7417 7418 ins_cost(125); // XXX 7419 format %{ "subq $dst, $src\t# long" %} 7420 opcode(0x81); /* Opcode 81 /5 id */ 7421 ins_encode(REX_mem_wide(dst), 7422 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7423 ins_pipe(ialu_mem_imm); 7424 %} 7425 7426 // Subtract from a pointer 7427 // XXX hmpf??? 7428 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7429 %{ 7430 match(Set dst (AddP dst (SubI zero src))); 7431 effect(KILL cr); 7432 7433 format %{ "subq $dst, $src\t# ptr - int" %} 7434 opcode(0x2B); 7435 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7436 ins_pipe(ialu_reg_reg); 7437 %} 7438 7439 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7440 %{ 7441 match(Set dst (SubI zero dst)); 7442 effect(KILL cr); 7443 7444 format %{ "negl $dst\t# int" %} 7445 opcode(0xF7, 0x03); // Opcode F7 /3 7446 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7447 ins_pipe(ialu_reg); 7448 %} 7449 7450 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7451 %{ 7452 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7453 effect(KILL cr); 7454 7455 format %{ "negl $dst\t# int" %} 7456 opcode(0xF7, 0x03); // Opcode F7 /3 7457 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7458 ins_pipe(ialu_reg); 7459 %} 7460 7461 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7462 %{ 7463 match(Set dst (SubL zero dst)); 7464 effect(KILL cr); 7465 7466 format %{ "negq $dst\t# long" %} 7467 opcode(0xF7, 0x03); // Opcode F7 /3 7468 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7469 ins_pipe(ialu_reg); 7470 %} 7471 7472 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7473 %{ 7474 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7475 effect(KILL cr); 7476 7477 format %{ "negq $dst\t# long" %} 7478 opcode(0xF7, 0x03); // Opcode F7 /3 7479 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7480 ins_pipe(ialu_reg); 7481 %} 7482 7483 //----------Multiplication/Division Instructions------------------------------- 7484 // Integer Multiplication Instructions 7485 // Multiply Register 7486 7487 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7488 %{ 7489 match(Set dst (MulI dst src)); 7490 effect(KILL cr); 7491 7492 ins_cost(300); 7493 format %{ "imull $dst, $src\t# int" %} 7494 opcode(0x0F, 0xAF); 7495 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7496 ins_pipe(ialu_reg_reg_alu0); 7497 %} 7498 7499 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7500 %{ 7501 match(Set dst (MulI src imm)); 7502 effect(KILL cr); 7503 7504 ins_cost(300); 7505 format %{ "imull $dst, $src, $imm\t# int" %} 7506 opcode(0x69); /* 69 /r id */ 7507 ins_encode(REX_reg_reg(dst, src), 7508 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7509 ins_pipe(ialu_reg_reg_alu0); 7510 %} 7511 7512 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7513 %{ 7514 match(Set dst (MulI dst (LoadI src))); 7515 effect(KILL cr); 7516 7517 ins_cost(350); 7518 format %{ "imull $dst, $src\t# int" %} 7519 opcode(0x0F, 0xAF); 7520 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7521 ins_pipe(ialu_reg_mem_alu0); 7522 %} 7523 7524 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7525 %{ 7526 match(Set dst (MulI (LoadI src) imm)); 7527 effect(KILL cr); 7528 7529 ins_cost(300); 7530 format %{ "imull $dst, $src, $imm\t# int" %} 7531 opcode(0x69); /* 69 /r id */ 7532 ins_encode(REX_reg_mem(dst, src), 7533 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7534 ins_pipe(ialu_reg_mem_alu0); 7535 %} 7536 7537 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7538 %{ 7539 match(Set dst (MulL dst src)); 7540 effect(KILL cr); 7541 7542 ins_cost(300); 7543 format %{ "imulq $dst, $src\t# long" %} 7544 opcode(0x0F, 0xAF); 7545 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7546 ins_pipe(ialu_reg_reg_alu0); 7547 %} 7548 7549 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7550 %{ 7551 match(Set dst (MulL src imm)); 7552 effect(KILL cr); 7553 7554 ins_cost(300); 7555 format %{ "imulq $dst, $src, $imm\t# long" %} 7556 opcode(0x69); /* 69 /r id */ 7557 ins_encode(REX_reg_reg_wide(dst, src), 7558 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7559 ins_pipe(ialu_reg_reg_alu0); 7560 %} 7561 7562 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7563 %{ 7564 match(Set dst (MulL dst (LoadL src))); 7565 effect(KILL cr); 7566 7567 ins_cost(350); 7568 format %{ "imulq $dst, $src\t# long" %} 7569 opcode(0x0F, 0xAF); 7570 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7571 ins_pipe(ialu_reg_mem_alu0); 7572 %} 7573 7574 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7575 %{ 7576 match(Set dst (MulL (LoadL src) imm)); 7577 effect(KILL cr); 7578 7579 ins_cost(300); 7580 format %{ "imulq $dst, $src, $imm\t# long" %} 7581 opcode(0x69); /* 69 /r id */ 7582 ins_encode(REX_reg_mem_wide(dst, src), 7583 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7584 ins_pipe(ialu_reg_mem_alu0); 7585 %} 7586 7587 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7588 %{ 7589 match(Set dst (MulHiL src rax)); 7590 effect(USE_KILL rax, KILL cr); 7591 7592 ins_cost(300); 7593 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7594 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7595 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7596 ins_pipe(ialu_reg_reg_alu0); 7597 %} 7598 7599 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7600 rFlagsReg cr) 7601 %{ 7602 match(Set rax (DivI rax div)); 7603 effect(KILL rdx, KILL cr); 7604 7605 ins_cost(30*100+10*100); // XXX 7606 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7607 "jne,s normal\n\t" 7608 "xorl rdx, rdx\n\t" 7609 "cmpl $div, -1\n\t" 7610 "je,s done\n" 7611 "normal: cdql\n\t" 7612 "idivl $div\n" 7613 "done:" %} 7614 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7615 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7616 ins_pipe(ialu_reg_reg_alu0); 7617 %} 7618 7619 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7620 rFlagsReg cr) 7621 %{ 7622 match(Set rax (DivL rax div)); 7623 effect(KILL rdx, KILL cr); 7624 7625 ins_cost(30*100+10*100); // XXX 7626 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7627 "cmpq rax, rdx\n\t" 7628 "jne,s normal\n\t" 7629 "xorl rdx, rdx\n\t" 7630 "cmpq $div, -1\n\t" 7631 "je,s done\n" 7632 "normal: cdqq\n\t" 7633 "idivq $div\n" 7634 "done:" %} 7635 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7636 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7637 ins_pipe(ialu_reg_reg_alu0); 7638 %} 7639 7640 // Integer DIVMOD with Register, both quotient and mod results 7641 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7642 rFlagsReg cr) 7643 %{ 7644 match(DivModI rax div); 7645 effect(KILL cr); 7646 7647 ins_cost(30*100+10*100); // XXX 7648 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7649 "jne,s normal\n\t" 7650 "xorl rdx, rdx\n\t" 7651 "cmpl $div, -1\n\t" 7652 "je,s done\n" 7653 "normal: cdql\n\t" 7654 "idivl $div\n" 7655 "done:" %} 7656 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7657 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7658 ins_pipe(pipe_slow); 7659 %} 7660 7661 // Long DIVMOD with Register, both quotient and mod results 7662 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7663 rFlagsReg cr) 7664 %{ 7665 match(DivModL rax div); 7666 effect(KILL cr); 7667 7668 ins_cost(30*100+10*100); // XXX 7669 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7670 "cmpq rax, rdx\n\t" 7671 "jne,s normal\n\t" 7672 "xorl rdx, rdx\n\t" 7673 "cmpq $div, -1\n\t" 7674 "je,s done\n" 7675 "normal: cdqq\n\t" 7676 "idivq $div\n" 7677 "done:" %} 7678 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7679 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7680 ins_pipe(pipe_slow); 7681 %} 7682 7683 //----------- DivL-By-Constant-Expansions-------------------------------------- 7684 // DivI cases are handled by the compiler 7685 7686 // Magic constant, reciprocal of 10 7687 instruct loadConL_0x6666666666666667(rRegL dst) 7688 %{ 7689 effect(DEF dst); 7690 7691 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 7692 ins_encode(load_immL(dst, 0x6666666666666667)); 7693 ins_pipe(ialu_reg); 7694 %} 7695 7696 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7697 %{ 7698 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 7699 7700 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 7701 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7702 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7703 ins_pipe(ialu_reg_reg_alu0); 7704 %} 7705 7706 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 7707 %{ 7708 effect(USE_DEF dst, KILL cr); 7709 7710 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 7711 opcode(0xC1, 0x7); /* C1 /7 ib */ 7712 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 7713 ins_pipe(ialu_reg); 7714 %} 7715 7716 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 7717 %{ 7718 effect(USE_DEF dst, KILL cr); 7719 7720 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 7721 opcode(0xC1, 0x7); /* C1 /7 ib */ 7722 ins_encode(reg_opc_imm_wide(dst, 0x2)); 7723 ins_pipe(ialu_reg); 7724 %} 7725 7726 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 7727 %{ 7728 match(Set dst (DivL src div)); 7729 7730 ins_cost((5+8)*100); 7731 expand %{ 7732 rax_RegL rax; // Killed temp 7733 rFlagsReg cr; // Killed 7734 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 7735 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 7736 sarL_rReg_63(src, cr); // sarq src, 63 7737 sarL_rReg_2(dst, cr); // sarq rdx, 2 7738 subL_rReg(dst, src, cr); // subl rdx, src 7739 %} 7740 %} 7741 7742 //----------------------------------------------------------------------------- 7743 7744 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7745 rFlagsReg cr) 7746 %{ 7747 match(Set rdx (ModI rax div)); 7748 effect(KILL rax, KILL cr); 7749 7750 ins_cost(300); // XXX 7751 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7752 "jne,s normal\n\t" 7753 "xorl rdx, rdx\n\t" 7754 "cmpl $div, -1\n\t" 7755 "je,s done\n" 7756 "normal: cdql\n\t" 7757 "idivl $div\n" 7758 "done:" %} 7759 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7760 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7761 ins_pipe(ialu_reg_reg_alu0); 7762 %} 7763 7764 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7765 rFlagsReg cr) 7766 %{ 7767 match(Set rdx (ModL rax div)); 7768 effect(KILL rax, KILL cr); 7769 7770 ins_cost(300); // XXX 7771 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7772 "cmpq rax, rdx\n\t" 7773 "jne,s normal\n\t" 7774 "xorl rdx, rdx\n\t" 7775 "cmpq $div, -1\n\t" 7776 "je,s done\n" 7777 "normal: cdqq\n\t" 7778 "idivq $div\n" 7779 "done:" %} 7780 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7781 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7782 ins_pipe(ialu_reg_reg_alu0); 7783 %} 7784 7785 // Integer Shift Instructions 7786 // Shift Left by one 7787 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7788 %{ 7789 match(Set dst (LShiftI dst shift)); 7790 effect(KILL cr); 7791 7792 format %{ "sall $dst, $shift" %} 7793 opcode(0xD1, 0x4); /* D1 /4 */ 7794 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7795 ins_pipe(ialu_reg); 7796 %} 7797 7798 // Shift Left by one 7799 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7800 %{ 7801 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7802 effect(KILL cr); 7803 7804 format %{ "sall $dst, $shift\t" %} 7805 opcode(0xD1, 0x4); /* D1 /4 */ 7806 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7807 ins_pipe(ialu_mem_imm); 7808 %} 7809 7810 // Shift Left by 8-bit immediate 7811 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7812 %{ 7813 match(Set dst (LShiftI dst shift)); 7814 effect(KILL cr); 7815 7816 format %{ "sall $dst, $shift" %} 7817 opcode(0xC1, 0x4); /* C1 /4 ib */ 7818 ins_encode(reg_opc_imm(dst, shift)); 7819 ins_pipe(ialu_reg); 7820 %} 7821 7822 // Shift Left by 8-bit immediate 7823 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7824 %{ 7825 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7826 effect(KILL cr); 7827 7828 format %{ "sall $dst, $shift" %} 7829 opcode(0xC1, 0x4); /* C1 /4 ib */ 7830 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7831 ins_pipe(ialu_mem_imm); 7832 %} 7833 7834 // Shift Left by variable 7835 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7836 %{ 7837 match(Set dst (LShiftI dst shift)); 7838 effect(KILL cr); 7839 7840 format %{ "sall $dst, $shift" %} 7841 opcode(0xD3, 0x4); /* D3 /4 */ 7842 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7843 ins_pipe(ialu_reg_reg); 7844 %} 7845 7846 // Shift Left by variable 7847 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7848 %{ 7849 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7850 effect(KILL cr); 7851 7852 format %{ "sall $dst, $shift" %} 7853 opcode(0xD3, 0x4); /* D3 /4 */ 7854 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7855 ins_pipe(ialu_mem_reg); 7856 %} 7857 7858 // Arithmetic shift right by one 7859 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7860 %{ 7861 match(Set dst (RShiftI dst shift)); 7862 effect(KILL cr); 7863 7864 format %{ "sarl $dst, $shift" %} 7865 opcode(0xD1, 0x7); /* D1 /7 */ 7866 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7867 ins_pipe(ialu_reg); 7868 %} 7869 7870 // Arithmetic shift right by one 7871 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7872 %{ 7873 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7874 effect(KILL cr); 7875 7876 format %{ "sarl $dst, $shift" %} 7877 opcode(0xD1, 0x7); /* D1 /7 */ 7878 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7879 ins_pipe(ialu_mem_imm); 7880 %} 7881 7882 // Arithmetic Shift Right by 8-bit immediate 7883 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7884 %{ 7885 match(Set dst (RShiftI dst shift)); 7886 effect(KILL cr); 7887 7888 format %{ "sarl $dst, $shift" %} 7889 opcode(0xC1, 0x7); /* C1 /7 ib */ 7890 ins_encode(reg_opc_imm(dst, shift)); 7891 ins_pipe(ialu_mem_imm); 7892 %} 7893 7894 // Arithmetic Shift Right by 8-bit immediate 7895 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7896 %{ 7897 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7898 effect(KILL cr); 7899 7900 format %{ "sarl $dst, $shift" %} 7901 opcode(0xC1, 0x7); /* C1 /7 ib */ 7902 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7903 ins_pipe(ialu_mem_imm); 7904 %} 7905 7906 // Arithmetic Shift Right by variable 7907 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7908 %{ 7909 match(Set dst (RShiftI dst shift)); 7910 effect(KILL cr); 7911 7912 format %{ "sarl $dst, $shift" %} 7913 opcode(0xD3, 0x7); /* D3 /7 */ 7914 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7915 ins_pipe(ialu_reg_reg); 7916 %} 7917 7918 // Arithmetic Shift Right by variable 7919 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7920 %{ 7921 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7922 effect(KILL cr); 7923 7924 format %{ "sarl $dst, $shift" %} 7925 opcode(0xD3, 0x7); /* D3 /7 */ 7926 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7927 ins_pipe(ialu_mem_reg); 7928 %} 7929 7930 // Logical shift right by one 7931 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7932 %{ 7933 match(Set dst (URShiftI dst shift)); 7934 effect(KILL cr); 7935 7936 format %{ "shrl $dst, $shift" %} 7937 opcode(0xD1, 0x5); /* D1 /5 */ 7938 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7939 ins_pipe(ialu_reg); 7940 %} 7941 7942 // Logical shift right by one 7943 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7944 %{ 7945 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 7946 effect(KILL cr); 7947 7948 format %{ "shrl $dst, $shift" %} 7949 opcode(0xD1, 0x5); /* D1 /5 */ 7950 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7951 ins_pipe(ialu_mem_imm); 7952 %} 7953 7954 // Logical Shift Right by 8-bit immediate 7955 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7956 %{ 7957 match(Set dst (URShiftI dst shift)); 7958 effect(KILL cr); 7959 7960 format %{ "shrl $dst, $shift" %} 7961 opcode(0xC1, 0x5); /* C1 /5 ib */ 7962 ins_encode(reg_opc_imm(dst, shift)); 7963 ins_pipe(ialu_reg); 7964 %} 7965 7966 // Logical Shift Right by 8-bit immediate 7967 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7968 %{ 7969 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 7970 effect(KILL cr); 7971 7972 format %{ "shrl $dst, $shift" %} 7973 opcode(0xC1, 0x5); /* C1 /5 ib */ 7974 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7975 ins_pipe(ialu_mem_imm); 7976 %} 7977 7978 // Logical Shift Right by variable 7979 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7980 %{ 7981 match(Set dst (URShiftI dst shift)); 7982 effect(KILL cr); 7983 7984 format %{ "shrl $dst, $shift" %} 7985 opcode(0xD3, 0x5); /* D3 /5 */ 7986 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7987 ins_pipe(ialu_reg_reg); 7988 %} 7989 7990 // Logical Shift Right by variable 7991 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7992 %{ 7993 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 7994 effect(KILL cr); 7995 7996 format %{ "shrl $dst, $shift" %} 7997 opcode(0xD3, 0x5); /* D3 /5 */ 7998 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7999 ins_pipe(ialu_mem_reg); 8000 %} 8001 8002 // Long Shift Instructions 8003 // Shift Left by one 8004 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8005 %{ 8006 match(Set dst (LShiftL dst shift)); 8007 effect(KILL cr); 8008 8009 format %{ "salq $dst, $shift" %} 8010 opcode(0xD1, 0x4); /* D1 /4 */ 8011 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8012 ins_pipe(ialu_reg); 8013 %} 8014 8015 // Shift Left by one 8016 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8017 %{ 8018 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8019 effect(KILL cr); 8020 8021 format %{ "salq $dst, $shift" %} 8022 opcode(0xD1, 0x4); /* D1 /4 */ 8023 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8024 ins_pipe(ialu_mem_imm); 8025 %} 8026 8027 // Shift Left by 8-bit immediate 8028 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8029 %{ 8030 match(Set dst (LShiftL dst shift)); 8031 effect(KILL cr); 8032 8033 format %{ "salq $dst, $shift" %} 8034 opcode(0xC1, 0x4); /* C1 /4 ib */ 8035 ins_encode(reg_opc_imm_wide(dst, shift)); 8036 ins_pipe(ialu_reg); 8037 %} 8038 8039 // Shift Left by 8-bit immediate 8040 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8041 %{ 8042 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8043 effect(KILL cr); 8044 8045 format %{ "salq $dst, $shift" %} 8046 opcode(0xC1, 0x4); /* C1 /4 ib */ 8047 ins_encode(REX_mem_wide(dst), OpcP, 8048 RM_opc_mem(secondary, dst), Con8or32(shift)); 8049 ins_pipe(ialu_mem_imm); 8050 %} 8051 8052 // Shift Left by variable 8053 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8054 %{ 8055 match(Set dst (LShiftL dst shift)); 8056 effect(KILL cr); 8057 8058 format %{ "salq $dst, $shift" %} 8059 opcode(0xD3, 0x4); /* D3 /4 */ 8060 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8061 ins_pipe(ialu_reg_reg); 8062 %} 8063 8064 // Shift Left by variable 8065 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8066 %{ 8067 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8068 effect(KILL cr); 8069 8070 format %{ "salq $dst, $shift" %} 8071 opcode(0xD3, 0x4); /* D3 /4 */ 8072 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8073 ins_pipe(ialu_mem_reg); 8074 %} 8075 8076 // Arithmetic shift right by one 8077 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8078 %{ 8079 match(Set dst (RShiftL dst shift)); 8080 effect(KILL cr); 8081 8082 format %{ "sarq $dst, $shift" %} 8083 opcode(0xD1, 0x7); /* D1 /7 */ 8084 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8085 ins_pipe(ialu_reg); 8086 %} 8087 8088 // Arithmetic shift right by one 8089 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8090 %{ 8091 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8092 effect(KILL cr); 8093 8094 format %{ "sarq $dst, $shift" %} 8095 opcode(0xD1, 0x7); /* D1 /7 */ 8096 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8097 ins_pipe(ialu_mem_imm); 8098 %} 8099 8100 // Arithmetic Shift Right by 8-bit immediate 8101 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8102 %{ 8103 match(Set dst (RShiftL dst shift)); 8104 effect(KILL cr); 8105 8106 format %{ "sarq $dst, $shift" %} 8107 opcode(0xC1, 0x7); /* C1 /7 ib */ 8108 ins_encode(reg_opc_imm_wide(dst, shift)); 8109 ins_pipe(ialu_mem_imm); 8110 %} 8111 8112 // Arithmetic Shift Right by 8-bit immediate 8113 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8114 %{ 8115 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8116 effect(KILL cr); 8117 8118 format %{ "sarq $dst, $shift" %} 8119 opcode(0xC1, 0x7); /* C1 /7 ib */ 8120 ins_encode(REX_mem_wide(dst), OpcP, 8121 RM_opc_mem(secondary, dst), Con8or32(shift)); 8122 ins_pipe(ialu_mem_imm); 8123 %} 8124 8125 // Arithmetic Shift Right by variable 8126 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8127 %{ 8128 match(Set dst (RShiftL dst shift)); 8129 effect(KILL cr); 8130 8131 format %{ "sarq $dst, $shift" %} 8132 opcode(0xD3, 0x7); /* D3 /7 */ 8133 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8134 ins_pipe(ialu_reg_reg); 8135 %} 8136 8137 // Arithmetic Shift Right by variable 8138 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8139 %{ 8140 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8141 effect(KILL cr); 8142 8143 format %{ "sarq $dst, $shift" %} 8144 opcode(0xD3, 0x7); /* D3 /7 */ 8145 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8146 ins_pipe(ialu_mem_reg); 8147 %} 8148 8149 // Logical shift right by one 8150 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8151 %{ 8152 match(Set dst (URShiftL dst shift)); 8153 effect(KILL cr); 8154 8155 format %{ "shrq $dst, $shift" %} 8156 opcode(0xD1, 0x5); /* D1 /5 */ 8157 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8158 ins_pipe(ialu_reg); 8159 %} 8160 8161 // Logical shift right by one 8162 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8163 %{ 8164 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8165 effect(KILL cr); 8166 8167 format %{ "shrq $dst, $shift" %} 8168 opcode(0xD1, 0x5); /* D1 /5 */ 8169 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8170 ins_pipe(ialu_mem_imm); 8171 %} 8172 8173 // Logical Shift Right by 8-bit immediate 8174 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8175 %{ 8176 match(Set dst (URShiftL dst shift)); 8177 effect(KILL cr); 8178 8179 format %{ "shrq $dst, $shift" %} 8180 opcode(0xC1, 0x5); /* C1 /5 ib */ 8181 ins_encode(reg_opc_imm_wide(dst, shift)); 8182 ins_pipe(ialu_reg); 8183 %} 8184 8185 8186 // Logical Shift Right by 8-bit immediate 8187 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8188 %{ 8189 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8190 effect(KILL cr); 8191 8192 format %{ "shrq $dst, $shift" %} 8193 opcode(0xC1, 0x5); /* C1 /5 ib */ 8194 ins_encode(REX_mem_wide(dst), OpcP, 8195 RM_opc_mem(secondary, dst), Con8or32(shift)); 8196 ins_pipe(ialu_mem_imm); 8197 %} 8198 8199 // Logical Shift Right by variable 8200 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8201 %{ 8202 match(Set dst (URShiftL dst shift)); 8203 effect(KILL cr); 8204 8205 format %{ "shrq $dst, $shift" %} 8206 opcode(0xD3, 0x5); /* D3 /5 */ 8207 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8208 ins_pipe(ialu_reg_reg); 8209 %} 8210 8211 // Logical Shift Right by variable 8212 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8213 %{ 8214 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8215 effect(KILL cr); 8216 8217 format %{ "shrq $dst, $shift" %} 8218 opcode(0xD3, 0x5); /* D3 /5 */ 8219 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8220 ins_pipe(ialu_mem_reg); 8221 %} 8222 8223 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8224 // This idiom is used by the compiler for the i2b bytecode. 8225 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8226 %{ 8227 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8228 8229 format %{ "movsbl $dst, $src\t# i2b" %} 8230 opcode(0x0F, 0xBE); 8231 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8232 ins_pipe(ialu_reg_reg); 8233 %} 8234 8235 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8236 // This idiom is used by the compiler the i2s bytecode. 8237 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8238 %{ 8239 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8240 8241 format %{ "movswl $dst, $src\t# i2s" %} 8242 opcode(0x0F, 0xBF); 8243 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8244 ins_pipe(ialu_reg_reg); 8245 %} 8246 8247 // ROL/ROR instructions 8248 8249 // ROL expand 8250 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8251 effect(KILL cr, USE_DEF dst); 8252 8253 format %{ "roll $dst" %} 8254 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8255 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8256 ins_pipe(ialu_reg); 8257 %} 8258 8259 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8260 effect(USE_DEF dst, USE shift, KILL cr); 8261 8262 format %{ "roll $dst, $shift" %} 8263 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8264 ins_encode( reg_opc_imm(dst, shift) ); 8265 ins_pipe(ialu_reg); 8266 %} 8267 8268 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8269 %{ 8270 effect(USE_DEF dst, USE shift, KILL cr); 8271 8272 format %{ "roll $dst, $shift" %} 8273 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8274 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8275 ins_pipe(ialu_reg_reg); 8276 %} 8277 // end of ROL expand 8278 8279 // Rotate Left by one 8280 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8281 %{ 8282 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8283 8284 expand %{ 8285 rolI_rReg_imm1(dst, cr); 8286 %} 8287 %} 8288 8289 // Rotate Left by 8-bit immediate 8290 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8291 %{ 8292 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8293 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8294 8295 expand %{ 8296 rolI_rReg_imm8(dst, lshift, cr); 8297 %} 8298 %} 8299 8300 // Rotate Left by variable 8301 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8302 %{ 8303 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8304 8305 expand %{ 8306 rolI_rReg_CL(dst, shift, cr); 8307 %} 8308 %} 8309 8310 // Rotate Left by variable 8311 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8312 %{ 8313 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8314 8315 expand %{ 8316 rolI_rReg_CL(dst, shift, cr); 8317 %} 8318 %} 8319 8320 // ROR expand 8321 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8322 %{ 8323 effect(USE_DEF dst, KILL cr); 8324 8325 format %{ "rorl $dst" %} 8326 opcode(0xD1, 0x1); /* D1 /1 */ 8327 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8328 ins_pipe(ialu_reg); 8329 %} 8330 8331 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8332 %{ 8333 effect(USE_DEF dst, USE shift, KILL cr); 8334 8335 format %{ "rorl $dst, $shift" %} 8336 opcode(0xC1, 0x1); /* C1 /1 ib */ 8337 ins_encode(reg_opc_imm(dst, shift)); 8338 ins_pipe(ialu_reg); 8339 %} 8340 8341 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8342 %{ 8343 effect(USE_DEF dst, USE shift, KILL cr); 8344 8345 format %{ "rorl $dst, $shift" %} 8346 opcode(0xD3, 0x1); /* D3 /1 */ 8347 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8348 ins_pipe(ialu_reg_reg); 8349 %} 8350 // end of ROR expand 8351 8352 // Rotate Right by one 8353 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8354 %{ 8355 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8356 8357 expand %{ 8358 rorI_rReg_imm1(dst, cr); 8359 %} 8360 %} 8361 8362 // Rotate Right by 8-bit immediate 8363 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8364 %{ 8365 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8366 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8367 8368 expand %{ 8369 rorI_rReg_imm8(dst, rshift, cr); 8370 %} 8371 %} 8372 8373 // Rotate Right by variable 8374 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8375 %{ 8376 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8377 8378 expand %{ 8379 rorI_rReg_CL(dst, shift, cr); 8380 %} 8381 %} 8382 8383 // Rotate Right by variable 8384 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8385 %{ 8386 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8387 8388 expand %{ 8389 rorI_rReg_CL(dst, shift, cr); 8390 %} 8391 %} 8392 8393 // for long rotate 8394 // ROL expand 8395 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8396 effect(USE_DEF dst, KILL cr); 8397 8398 format %{ "rolq $dst" %} 8399 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8400 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8401 ins_pipe(ialu_reg); 8402 %} 8403 8404 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8405 effect(USE_DEF dst, USE shift, KILL cr); 8406 8407 format %{ "rolq $dst, $shift" %} 8408 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8409 ins_encode( reg_opc_imm_wide(dst, shift) ); 8410 ins_pipe(ialu_reg); 8411 %} 8412 8413 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8414 %{ 8415 effect(USE_DEF dst, USE shift, KILL cr); 8416 8417 format %{ "rolq $dst, $shift" %} 8418 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8419 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8420 ins_pipe(ialu_reg_reg); 8421 %} 8422 // end of ROL expand 8423 8424 // Rotate Left by one 8425 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8426 %{ 8427 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8428 8429 expand %{ 8430 rolL_rReg_imm1(dst, cr); 8431 %} 8432 %} 8433 8434 // Rotate Left by 8-bit immediate 8435 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8436 %{ 8437 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8438 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8439 8440 expand %{ 8441 rolL_rReg_imm8(dst, lshift, cr); 8442 %} 8443 %} 8444 8445 // Rotate Left by variable 8446 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8447 %{ 8448 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8449 8450 expand %{ 8451 rolL_rReg_CL(dst, shift, cr); 8452 %} 8453 %} 8454 8455 // Rotate Left by variable 8456 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8457 %{ 8458 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8459 8460 expand %{ 8461 rolL_rReg_CL(dst, shift, cr); 8462 %} 8463 %} 8464 8465 // ROR expand 8466 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8467 %{ 8468 effect(USE_DEF dst, KILL cr); 8469 8470 format %{ "rorq $dst" %} 8471 opcode(0xD1, 0x1); /* D1 /1 */ 8472 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8473 ins_pipe(ialu_reg); 8474 %} 8475 8476 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8477 %{ 8478 effect(USE_DEF dst, USE shift, KILL cr); 8479 8480 format %{ "rorq $dst, $shift" %} 8481 opcode(0xC1, 0x1); /* C1 /1 ib */ 8482 ins_encode(reg_opc_imm_wide(dst, shift)); 8483 ins_pipe(ialu_reg); 8484 %} 8485 8486 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8487 %{ 8488 effect(USE_DEF dst, USE shift, KILL cr); 8489 8490 format %{ "rorq $dst, $shift" %} 8491 opcode(0xD3, 0x1); /* D3 /1 */ 8492 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8493 ins_pipe(ialu_reg_reg); 8494 %} 8495 // end of ROR expand 8496 8497 // Rotate Right by one 8498 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8499 %{ 8500 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8501 8502 expand %{ 8503 rorL_rReg_imm1(dst, cr); 8504 %} 8505 %} 8506 8507 // Rotate Right by 8-bit immediate 8508 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8509 %{ 8510 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8511 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8512 8513 expand %{ 8514 rorL_rReg_imm8(dst, rshift, cr); 8515 %} 8516 %} 8517 8518 // Rotate Right by variable 8519 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8520 %{ 8521 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8522 8523 expand %{ 8524 rorL_rReg_CL(dst, shift, cr); 8525 %} 8526 %} 8527 8528 // Rotate Right by variable 8529 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8530 %{ 8531 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8532 8533 expand %{ 8534 rorL_rReg_CL(dst, shift, cr); 8535 %} 8536 %} 8537 8538 // Logical Instructions 8539 8540 // Integer Logical Instructions 8541 8542 // And Instructions 8543 // And Register with Register 8544 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8545 %{ 8546 match(Set dst (AndI dst src)); 8547 effect(KILL cr); 8548 8549 format %{ "andl $dst, $src\t# int" %} 8550 opcode(0x23); 8551 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8552 ins_pipe(ialu_reg_reg); 8553 %} 8554 8555 // And Register with Immediate 255 8556 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8557 %{ 8558 match(Set dst (AndI dst src)); 8559 8560 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8561 opcode(0x0F, 0xB6); 8562 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8563 ins_pipe(ialu_reg); 8564 %} 8565 8566 // And Register with Immediate 255 and promote to long 8567 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8568 %{ 8569 match(Set dst (ConvI2L (AndI src mask))); 8570 8571 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8572 opcode(0x0F, 0xB6); 8573 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8574 ins_pipe(ialu_reg); 8575 %} 8576 8577 // And Register with Immediate 65535 8578 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8579 %{ 8580 match(Set dst (AndI dst src)); 8581 8582 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8583 opcode(0x0F, 0xB7); 8584 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8585 ins_pipe(ialu_reg); 8586 %} 8587 8588 // And Register with Immediate 65535 and promote to long 8589 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8590 %{ 8591 match(Set dst (ConvI2L (AndI src mask))); 8592 8593 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8594 opcode(0x0F, 0xB7); 8595 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8596 ins_pipe(ialu_reg); 8597 %} 8598 8599 // And Register with Immediate 8600 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8601 %{ 8602 match(Set dst (AndI dst src)); 8603 effect(KILL cr); 8604 8605 format %{ "andl $dst, $src\t# int" %} 8606 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8607 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8608 ins_pipe(ialu_reg); 8609 %} 8610 8611 // And Register with Memory 8612 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8613 %{ 8614 match(Set dst (AndI dst (LoadI src))); 8615 effect(KILL cr); 8616 8617 ins_cost(125); 8618 format %{ "andl $dst, $src\t# int" %} 8619 opcode(0x23); 8620 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8621 ins_pipe(ialu_reg_mem); 8622 %} 8623 8624 // And Memory with Register 8625 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8626 %{ 8627 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8628 effect(KILL cr); 8629 8630 ins_cost(150); 8631 format %{ "andl $dst, $src\t# int" %} 8632 opcode(0x21); /* Opcode 21 /r */ 8633 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8634 ins_pipe(ialu_mem_reg); 8635 %} 8636 8637 // And Memory with Immediate 8638 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8639 %{ 8640 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8641 effect(KILL cr); 8642 8643 ins_cost(125); 8644 format %{ "andl $dst, $src\t# int" %} 8645 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8646 ins_encode(REX_mem(dst), OpcSE(src), 8647 RM_opc_mem(secondary, dst), Con8or32(src)); 8648 ins_pipe(ialu_mem_imm); 8649 %} 8650 8651 // BMI1 instructions 8652 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8653 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8654 predicate(UseBMI1Instructions); 8655 effect(KILL cr); 8656 8657 ins_cost(125); 8658 format %{ "andnl $dst, $src1, $src2" %} 8659 8660 ins_encode %{ 8661 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8662 %} 8663 ins_pipe(ialu_reg_mem); 8664 %} 8665 8666 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8667 match(Set dst (AndI (XorI src1 minus_1) src2)); 8668 predicate(UseBMI1Instructions); 8669 effect(KILL cr); 8670 8671 format %{ "andnl $dst, $src1, $src2" %} 8672 8673 ins_encode %{ 8674 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8675 %} 8676 ins_pipe(ialu_reg); 8677 %} 8678 8679 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 8680 match(Set dst (AndI (SubI imm_zero src) src)); 8681 predicate(UseBMI1Instructions); 8682 effect(KILL cr); 8683 8684 format %{ "blsil $dst, $src" %} 8685 8686 ins_encode %{ 8687 __ blsil($dst$$Register, $src$$Register); 8688 %} 8689 ins_pipe(ialu_reg); 8690 %} 8691 8692 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 8693 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8694 predicate(UseBMI1Instructions); 8695 effect(KILL cr); 8696 8697 ins_cost(125); 8698 format %{ "blsil $dst, $src" %} 8699 8700 ins_encode %{ 8701 __ blsil($dst$$Register, $src$$Address); 8702 %} 8703 ins_pipe(ialu_reg_mem); 8704 %} 8705 8706 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8707 %{ 8708 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8709 predicate(UseBMI1Instructions); 8710 effect(KILL cr); 8711 8712 ins_cost(125); 8713 format %{ "blsmskl $dst, $src" %} 8714 8715 ins_encode %{ 8716 __ blsmskl($dst$$Register, $src$$Address); 8717 %} 8718 ins_pipe(ialu_reg_mem); 8719 %} 8720 8721 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8722 %{ 8723 match(Set dst (XorI (AddI src minus_1) src)); 8724 predicate(UseBMI1Instructions); 8725 effect(KILL cr); 8726 8727 format %{ "blsmskl $dst, $src" %} 8728 8729 ins_encode %{ 8730 __ blsmskl($dst$$Register, $src$$Register); 8731 %} 8732 8733 ins_pipe(ialu_reg); 8734 %} 8735 8736 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8737 %{ 8738 match(Set dst (AndI (AddI src minus_1) src) ); 8739 predicate(UseBMI1Instructions); 8740 effect(KILL cr); 8741 8742 format %{ "blsrl $dst, $src" %} 8743 8744 ins_encode %{ 8745 __ blsrl($dst$$Register, $src$$Register); 8746 %} 8747 8748 ins_pipe(ialu_reg_mem); 8749 %} 8750 8751 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8752 %{ 8753 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8754 predicate(UseBMI1Instructions); 8755 effect(KILL cr); 8756 8757 ins_cost(125); 8758 format %{ "blsrl $dst, $src" %} 8759 8760 ins_encode %{ 8761 __ blsrl($dst$$Register, $src$$Address); 8762 %} 8763 8764 ins_pipe(ialu_reg); 8765 %} 8766 8767 // Or Instructions 8768 // Or Register with Register 8769 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8770 %{ 8771 match(Set dst (OrI dst src)); 8772 effect(KILL cr); 8773 8774 format %{ "orl $dst, $src\t# int" %} 8775 opcode(0x0B); 8776 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8777 ins_pipe(ialu_reg_reg); 8778 %} 8779 8780 // Or Register with Immediate 8781 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8782 %{ 8783 match(Set dst (OrI dst src)); 8784 effect(KILL cr); 8785 8786 format %{ "orl $dst, $src\t# int" %} 8787 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 8788 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8789 ins_pipe(ialu_reg); 8790 %} 8791 8792 // Or Register with Memory 8793 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8794 %{ 8795 match(Set dst (OrI dst (LoadI src))); 8796 effect(KILL cr); 8797 8798 ins_cost(125); 8799 format %{ "orl $dst, $src\t# int" %} 8800 opcode(0x0B); 8801 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8802 ins_pipe(ialu_reg_mem); 8803 %} 8804 8805 // Or Memory with Register 8806 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8807 %{ 8808 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8809 effect(KILL cr); 8810 8811 ins_cost(150); 8812 format %{ "orl $dst, $src\t# int" %} 8813 opcode(0x09); /* Opcode 09 /r */ 8814 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8815 ins_pipe(ialu_mem_reg); 8816 %} 8817 8818 // Or Memory with Immediate 8819 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 8820 %{ 8821 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8822 effect(KILL cr); 8823 8824 ins_cost(125); 8825 format %{ "orl $dst, $src\t# int" %} 8826 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 8827 ins_encode(REX_mem(dst), OpcSE(src), 8828 RM_opc_mem(secondary, dst), Con8or32(src)); 8829 ins_pipe(ialu_mem_imm); 8830 %} 8831 8832 // Xor Instructions 8833 // Xor Register with Register 8834 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8835 %{ 8836 match(Set dst (XorI dst src)); 8837 effect(KILL cr); 8838 8839 format %{ "xorl $dst, $src\t# int" %} 8840 opcode(0x33); 8841 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8842 ins_pipe(ialu_reg_reg); 8843 %} 8844 8845 // Xor Register with Immediate -1 8846 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 8847 match(Set dst (XorI dst imm)); 8848 8849 format %{ "not $dst" %} 8850 ins_encode %{ 8851 __ notl($dst$$Register); 8852 %} 8853 ins_pipe(ialu_reg); 8854 %} 8855 8856 // Xor Register with Immediate 8857 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8858 %{ 8859 match(Set dst (XorI dst src)); 8860 effect(KILL cr); 8861 8862 format %{ "xorl $dst, $src\t# int" %} 8863 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 8864 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8865 ins_pipe(ialu_reg); 8866 %} 8867 8868 // Xor Register with Memory 8869 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8870 %{ 8871 match(Set dst (XorI dst (LoadI src))); 8872 effect(KILL cr); 8873 8874 ins_cost(125); 8875 format %{ "xorl $dst, $src\t# int" %} 8876 opcode(0x33); 8877 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8878 ins_pipe(ialu_reg_mem); 8879 %} 8880 8881 // Xor Memory with Register 8882 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8883 %{ 8884 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 8885 effect(KILL cr); 8886 8887 ins_cost(150); 8888 format %{ "xorl $dst, $src\t# int" %} 8889 opcode(0x31); /* Opcode 31 /r */ 8890 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8891 ins_pipe(ialu_mem_reg); 8892 %} 8893 8894 // Xor Memory with Immediate 8895 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 8896 %{ 8897 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 8898 effect(KILL cr); 8899 8900 ins_cost(125); 8901 format %{ "xorl $dst, $src\t# int" %} 8902 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 8903 ins_encode(REX_mem(dst), OpcSE(src), 8904 RM_opc_mem(secondary, dst), Con8or32(src)); 8905 ins_pipe(ialu_mem_imm); 8906 %} 8907 8908 8909 // Long Logical Instructions 8910 8911 // And Instructions 8912 // And Register with Register 8913 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8914 %{ 8915 match(Set dst (AndL dst src)); 8916 effect(KILL cr); 8917 8918 format %{ "andq $dst, $src\t# long" %} 8919 opcode(0x23); 8920 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8921 ins_pipe(ialu_reg_reg); 8922 %} 8923 8924 // And Register with Immediate 255 8925 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 8926 %{ 8927 match(Set dst (AndL dst src)); 8928 8929 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 8930 opcode(0x0F, 0xB6); 8931 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8932 ins_pipe(ialu_reg); 8933 %} 8934 8935 // And Register with Immediate 65535 8936 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 8937 %{ 8938 match(Set dst (AndL dst src)); 8939 8940 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 8941 opcode(0x0F, 0xB7); 8942 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8943 ins_pipe(ialu_reg); 8944 %} 8945 8946 // And Register with Immediate 8947 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 8948 %{ 8949 match(Set dst (AndL dst src)); 8950 effect(KILL cr); 8951 8952 format %{ "andq $dst, $src\t# long" %} 8953 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8954 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8955 ins_pipe(ialu_reg); 8956 %} 8957 8958 // And Register with Memory 8959 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8960 %{ 8961 match(Set dst (AndL dst (LoadL src))); 8962 effect(KILL cr); 8963 8964 ins_cost(125); 8965 format %{ "andq $dst, $src\t# long" %} 8966 opcode(0x23); 8967 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8968 ins_pipe(ialu_reg_mem); 8969 %} 8970 8971 // And Memory with Register 8972 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8973 %{ 8974 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 8975 effect(KILL cr); 8976 8977 ins_cost(150); 8978 format %{ "andq $dst, $src\t# long" %} 8979 opcode(0x21); /* Opcode 21 /r */ 8980 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8981 ins_pipe(ialu_mem_reg); 8982 %} 8983 8984 // And Memory with Immediate 8985 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8986 %{ 8987 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 8988 effect(KILL cr); 8989 8990 ins_cost(125); 8991 format %{ "andq $dst, $src\t# long" %} 8992 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8993 ins_encode(REX_mem_wide(dst), OpcSE(src), 8994 RM_opc_mem(secondary, dst), Con8or32(src)); 8995 ins_pipe(ialu_mem_imm); 8996 %} 8997 8998 // BMI1 instructions 8999 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9000 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9001 predicate(UseBMI1Instructions); 9002 effect(KILL cr); 9003 9004 ins_cost(125); 9005 format %{ "andnq $dst, $src1, $src2" %} 9006 9007 ins_encode %{ 9008 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9009 %} 9010 ins_pipe(ialu_reg_mem); 9011 %} 9012 9013 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9014 match(Set dst (AndL (XorL src1 minus_1) src2)); 9015 predicate(UseBMI1Instructions); 9016 effect(KILL cr); 9017 9018 format %{ "andnq $dst, $src1, $src2" %} 9019 9020 ins_encode %{ 9021 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9022 %} 9023 ins_pipe(ialu_reg_mem); 9024 %} 9025 9026 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9027 match(Set dst (AndL (SubL imm_zero src) src)); 9028 predicate(UseBMI1Instructions); 9029 effect(KILL cr); 9030 9031 format %{ "blsiq $dst, $src" %} 9032 9033 ins_encode %{ 9034 __ blsiq($dst$$Register, $src$$Register); 9035 %} 9036 ins_pipe(ialu_reg); 9037 %} 9038 9039 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9040 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9041 predicate(UseBMI1Instructions); 9042 effect(KILL cr); 9043 9044 ins_cost(125); 9045 format %{ "blsiq $dst, $src" %} 9046 9047 ins_encode %{ 9048 __ blsiq($dst$$Register, $src$$Address); 9049 %} 9050 ins_pipe(ialu_reg_mem); 9051 %} 9052 9053 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9054 %{ 9055 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9056 predicate(UseBMI1Instructions); 9057 effect(KILL cr); 9058 9059 ins_cost(125); 9060 format %{ "blsmskq $dst, $src" %} 9061 9062 ins_encode %{ 9063 __ blsmskq($dst$$Register, $src$$Address); 9064 %} 9065 ins_pipe(ialu_reg_mem); 9066 %} 9067 9068 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9069 %{ 9070 match(Set dst (XorL (AddL src minus_1) src)); 9071 predicate(UseBMI1Instructions); 9072 effect(KILL cr); 9073 9074 format %{ "blsmskq $dst, $src" %} 9075 9076 ins_encode %{ 9077 __ blsmskq($dst$$Register, $src$$Register); 9078 %} 9079 9080 ins_pipe(ialu_reg); 9081 %} 9082 9083 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9084 %{ 9085 match(Set dst (AndL (AddL src minus_1) src) ); 9086 predicate(UseBMI1Instructions); 9087 effect(KILL cr); 9088 9089 format %{ "blsrq $dst, $src" %} 9090 9091 ins_encode %{ 9092 __ blsrq($dst$$Register, $src$$Register); 9093 %} 9094 9095 ins_pipe(ialu_reg); 9096 %} 9097 9098 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9099 %{ 9100 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9101 predicate(UseBMI1Instructions); 9102 effect(KILL cr); 9103 9104 ins_cost(125); 9105 format %{ "blsrq $dst, $src" %} 9106 9107 ins_encode %{ 9108 __ blsrq($dst$$Register, $src$$Address); 9109 %} 9110 9111 ins_pipe(ialu_reg); 9112 %} 9113 9114 // Or Instructions 9115 // Or Register with Register 9116 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9117 %{ 9118 match(Set dst (OrL dst src)); 9119 effect(KILL cr); 9120 9121 format %{ "orq $dst, $src\t# long" %} 9122 opcode(0x0B); 9123 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9124 ins_pipe(ialu_reg_reg); 9125 %} 9126 9127 // Use any_RegP to match R15 (TLS register) without spilling. 9128 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9129 match(Set dst (OrL dst (CastP2X src))); 9130 effect(KILL cr); 9131 9132 format %{ "orq $dst, $src\t# long" %} 9133 opcode(0x0B); 9134 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9135 ins_pipe(ialu_reg_reg); 9136 %} 9137 9138 9139 // Or Register with Immediate 9140 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9141 %{ 9142 match(Set dst (OrL dst src)); 9143 effect(KILL cr); 9144 9145 format %{ "orq $dst, $src\t# long" %} 9146 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9147 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9148 ins_pipe(ialu_reg); 9149 %} 9150 9151 // Or Register with Memory 9152 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9153 %{ 9154 match(Set dst (OrL dst (LoadL src))); 9155 effect(KILL cr); 9156 9157 ins_cost(125); 9158 format %{ "orq $dst, $src\t# long" %} 9159 opcode(0x0B); 9160 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9161 ins_pipe(ialu_reg_mem); 9162 %} 9163 9164 // Or Memory with Register 9165 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9166 %{ 9167 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9168 effect(KILL cr); 9169 9170 ins_cost(150); 9171 format %{ "orq $dst, $src\t# long" %} 9172 opcode(0x09); /* Opcode 09 /r */ 9173 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9174 ins_pipe(ialu_mem_reg); 9175 %} 9176 9177 // Or Memory with Immediate 9178 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9179 %{ 9180 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9181 effect(KILL cr); 9182 9183 ins_cost(125); 9184 format %{ "orq $dst, $src\t# long" %} 9185 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9186 ins_encode(REX_mem_wide(dst), OpcSE(src), 9187 RM_opc_mem(secondary, dst), Con8or32(src)); 9188 ins_pipe(ialu_mem_imm); 9189 %} 9190 9191 // Xor Instructions 9192 // Xor Register with Register 9193 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9194 %{ 9195 match(Set dst (XorL dst src)); 9196 effect(KILL cr); 9197 9198 format %{ "xorq $dst, $src\t# long" %} 9199 opcode(0x33); 9200 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9201 ins_pipe(ialu_reg_reg); 9202 %} 9203 9204 // Xor Register with Immediate -1 9205 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9206 match(Set dst (XorL dst imm)); 9207 9208 format %{ "notq $dst" %} 9209 ins_encode %{ 9210 __ notq($dst$$Register); 9211 %} 9212 ins_pipe(ialu_reg); 9213 %} 9214 9215 // Xor Register with Immediate 9216 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9217 %{ 9218 match(Set dst (XorL dst src)); 9219 effect(KILL cr); 9220 9221 format %{ "xorq $dst, $src\t# long" %} 9222 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9223 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9224 ins_pipe(ialu_reg); 9225 %} 9226 9227 // Xor Register with Memory 9228 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9229 %{ 9230 match(Set dst (XorL dst (LoadL src))); 9231 effect(KILL cr); 9232 9233 ins_cost(125); 9234 format %{ "xorq $dst, $src\t# long" %} 9235 opcode(0x33); 9236 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9237 ins_pipe(ialu_reg_mem); 9238 %} 9239 9240 // Xor Memory with Register 9241 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9242 %{ 9243 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9244 effect(KILL cr); 9245 9246 ins_cost(150); 9247 format %{ "xorq $dst, $src\t# long" %} 9248 opcode(0x31); /* Opcode 31 /r */ 9249 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9250 ins_pipe(ialu_mem_reg); 9251 %} 9252 9253 // Xor Memory with Immediate 9254 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9255 %{ 9256 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9257 effect(KILL cr); 9258 9259 ins_cost(125); 9260 format %{ "xorq $dst, $src\t# long" %} 9261 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9262 ins_encode(REX_mem_wide(dst), OpcSE(src), 9263 RM_opc_mem(secondary, dst), Con8or32(src)); 9264 ins_pipe(ialu_mem_imm); 9265 %} 9266 9267 // Convert Int to Boolean 9268 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9269 %{ 9270 match(Set dst (Conv2B src)); 9271 effect(KILL cr); 9272 9273 format %{ "testl $src, $src\t# ci2b\n\t" 9274 "setnz $dst\n\t" 9275 "movzbl $dst, $dst" %} 9276 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9277 setNZ_reg(dst), 9278 REX_reg_breg(dst, dst), // movzbl 9279 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9280 ins_pipe(pipe_slow); // XXX 9281 %} 9282 9283 // Convert Pointer to Boolean 9284 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9285 %{ 9286 match(Set dst (Conv2B src)); 9287 effect(KILL cr); 9288 9289 format %{ "testq $src, $src\t# cp2b\n\t" 9290 "setnz $dst\n\t" 9291 "movzbl $dst, $dst" %} 9292 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9293 setNZ_reg(dst), 9294 REX_reg_breg(dst, dst), // movzbl 9295 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9296 ins_pipe(pipe_slow); // XXX 9297 %} 9298 9299 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9300 %{ 9301 match(Set dst (CmpLTMask p q)); 9302 effect(KILL cr); 9303 9304 ins_cost(400); 9305 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9306 "setlt $dst\n\t" 9307 "movzbl $dst, $dst\n\t" 9308 "negl $dst" %} 9309 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9310 setLT_reg(dst), 9311 REX_reg_breg(dst, dst), // movzbl 9312 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9313 neg_reg(dst)); 9314 ins_pipe(pipe_slow); 9315 %} 9316 9317 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9318 %{ 9319 match(Set dst (CmpLTMask dst zero)); 9320 effect(KILL cr); 9321 9322 ins_cost(100); 9323 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9324 ins_encode %{ 9325 __ sarl($dst$$Register, 31); 9326 %} 9327 ins_pipe(ialu_reg); 9328 %} 9329 9330 /* Better to save a register than avoid a branch */ 9331 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9332 %{ 9333 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9334 effect(KILL cr); 9335 ins_cost(300); 9336 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9337 "jge done\n\t" 9338 "addl $p,$y\n" 9339 "done: " %} 9340 ins_encode %{ 9341 Register Rp = $p$$Register; 9342 Register Rq = $q$$Register; 9343 Register Ry = $y$$Register; 9344 Label done; 9345 __ subl(Rp, Rq); 9346 __ jccb(Assembler::greaterEqual, done); 9347 __ addl(Rp, Ry); 9348 __ bind(done); 9349 %} 9350 ins_pipe(pipe_cmplt); 9351 %} 9352 9353 /* Better to save a register than avoid a branch */ 9354 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9355 %{ 9356 match(Set y (AndI (CmpLTMask p q) y)); 9357 effect(KILL cr); 9358 9359 ins_cost(300); 9360 9361 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9362 "jlt done\n\t" 9363 "xorl $y, $y\n" 9364 "done: " %} 9365 ins_encode %{ 9366 Register Rp = $p$$Register; 9367 Register Rq = $q$$Register; 9368 Register Ry = $y$$Register; 9369 Label done; 9370 __ cmpl(Rp, Rq); 9371 __ jccb(Assembler::less, done); 9372 __ xorl(Ry, Ry); 9373 __ bind(done); 9374 %} 9375 ins_pipe(pipe_cmplt); 9376 %} 9377 9378 9379 //---------- FP Instructions------------------------------------------------ 9380 9381 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9382 %{ 9383 match(Set cr (CmpF src1 src2)); 9384 9385 ins_cost(145); 9386 format %{ "ucomiss $src1, $src2\n\t" 9387 "jnp,s exit\n\t" 9388 "pushfq\t# saw NaN, set CF\n\t" 9389 "andq [rsp], #0xffffff2b\n\t" 9390 "popfq\n" 9391 "exit:" %} 9392 ins_encode %{ 9393 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9394 emit_cmpfp_fixup(_masm); 9395 %} 9396 ins_pipe(pipe_slow); 9397 %} 9398 9399 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9400 match(Set cr (CmpF src1 src2)); 9401 9402 ins_cost(100); 9403 format %{ "ucomiss $src1, $src2" %} 9404 ins_encode %{ 9405 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9406 %} 9407 ins_pipe(pipe_slow); 9408 %} 9409 9410 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9411 %{ 9412 match(Set cr (CmpF src1 (LoadF src2))); 9413 9414 ins_cost(145); 9415 format %{ "ucomiss $src1, $src2\n\t" 9416 "jnp,s exit\n\t" 9417 "pushfq\t# saw NaN, set CF\n\t" 9418 "andq [rsp], #0xffffff2b\n\t" 9419 "popfq\n" 9420 "exit:" %} 9421 ins_encode %{ 9422 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9423 emit_cmpfp_fixup(_masm); 9424 %} 9425 ins_pipe(pipe_slow); 9426 %} 9427 9428 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9429 match(Set cr (CmpF src1 (LoadF src2))); 9430 9431 ins_cost(100); 9432 format %{ "ucomiss $src1, $src2" %} 9433 ins_encode %{ 9434 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9435 %} 9436 ins_pipe(pipe_slow); 9437 %} 9438 9439 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9440 match(Set cr (CmpF src con)); 9441 9442 ins_cost(145); 9443 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9444 "jnp,s exit\n\t" 9445 "pushfq\t# saw NaN, set CF\n\t" 9446 "andq [rsp], #0xffffff2b\n\t" 9447 "popfq\n" 9448 "exit:" %} 9449 ins_encode %{ 9450 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9451 emit_cmpfp_fixup(_masm); 9452 %} 9453 ins_pipe(pipe_slow); 9454 %} 9455 9456 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9457 match(Set cr (CmpF src con)); 9458 ins_cost(100); 9459 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9460 ins_encode %{ 9461 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9462 %} 9463 ins_pipe(pipe_slow); 9464 %} 9465 9466 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9467 %{ 9468 match(Set cr (CmpD src1 src2)); 9469 9470 ins_cost(145); 9471 format %{ "ucomisd $src1, $src2\n\t" 9472 "jnp,s exit\n\t" 9473 "pushfq\t# saw NaN, set CF\n\t" 9474 "andq [rsp], #0xffffff2b\n\t" 9475 "popfq\n" 9476 "exit:" %} 9477 ins_encode %{ 9478 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9479 emit_cmpfp_fixup(_masm); 9480 %} 9481 ins_pipe(pipe_slow); 9482 %} 9483 9484 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9485 match(Set cr (CmpD src1 src2)); 9486 9487 ins_cost(100); 9488 format %{ "ucomisd $src1, $src2 test" %} 9489 ins_encode %{ 9490 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9491 %} 9492 ins_pipe(pipe_slow); 9493 %} 9494 9495 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9496 %{ 9497 match(Set cr (CmpD src1 (LoadD src2))); 9498 9499 ins_cost(145); 9500 format %{ "ucomisd $src1, $src2\n\t" 9501 "jnp,s exit\n\t" 9502 "pushfq\t# saw NaN, set CF\n\t" 9503 "andq [rsp], #0xffffff2b\n\t" 9504 "popfq\n" 9505 "exit:" %} 9506 ins_encode %{ 9507 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9508 emit_cmpfp_fixup(_masm); 9509 %} 9510 ins_pipe(pipe_slow); 9511 %} 9512 9513 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9514 match(Set cr (CmpD src1 (LoadD src2))); 9515 9516 ins_cost(100); 9517 format %{ "ucomisd $src1, $src2" %} 9518 ins_encode %{ 9519 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9520 %} 9521 ins_pipe(pipe_slow); 9522 %} 9523 9524 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9525 match(Set cr (CmpD src con)); 9526 9527 ins_cost(145); 9528 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9529 "jnp,s exit\n\t" 9530 "pushfq\t# saw NaN, set CF\n\t" 9531 "andq [rsp], #0xffffff2b\n\t" 9532 "popfq\n" 9533 "exit:" %} 9534 ins_encode %{ 9535 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9536 emit_cmpfp_fixup(_masm); 9537 %} 9538 ins_pipe(pipe_slow); 9539 %} 9540 9541 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9542 match(Set cr (CmpD src con)); 9543 ins_cost(100); 9544 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9545 ins_encode %{ 9546 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9547 %} 9548 ins_pipe(pipe_slow); 9549 %} 9550 9551 // Compare into -1,0,1 9552 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9553 %{ 9554 match(Set dst (CmpF3 src1 src2)); 9555 effect(KILL cr); 9556 9557 ins_cost(275); 9558 format %{ "ucomiss $src1, $src2\n\t" 9559 "movl $dst, #-1\n\t" 9560 "jp,s done\n\t" 9561 "jb,s done\n\t" 9562 "setne $dst\n\t" 9563 "movzbl $dst, $dst\n" 9564 "done:" %} 9565 ins_encode %{ 9566 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9567 emit_cmpfp3(_masm, $dst$$Register); 9568 %} 9569 ins_pipe(pipe_slow); 9570 %} 9571 9572 // Compare into -1,0,1 9573 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9574 %{ 9575 match(Set dst (CmpF3 src1 (LoadF src2))); 9576 effect(KILL cr); 9577 9578 ins_cost(275); 9579 format %{ "ucomiss $src1, $src2\n\t" 9580 "movl $dst, #-1\n\t" 9581 "jp,s done\n\t" 9582 "jb,s done\n\t" 9583 "setne $dst\n\t" 9584 "movzbl $dst, $dst\n" 9585 "done:" %} 9586 ins_encode %{ 9587 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9588 emit_cmpfp3(_masm, $dst$$Register); 9589 %} 9590 ins_pipe(pipe_slow); 9591 %} 9592 9593 // Compare into -1,0,1 9594 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9595 match(Set dst (CmpF3 src con)); 9596 effect(KILL cr); 9597 9598 ins_cost(275); 9599 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9600 "movl $dst, #-1\n\t" 9601 "jp,s done\n\t" 9602 "jb,s done\n\t" 9603 "setne $dst\n\t" 9604 "movzbl $dst, $dst\n" 9605 "done:" %} 9606 ins_encode %{ 9607 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9608 emit_cmpfp3(_masm, $dst$$Register); 9609 %} 9610 ins_pipe(pipe_slow); 9611 %} 9612 9613 // Compare into -1,0,1 9614 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9615 %{ 9616 match(Set dst (CmpD3 src1 src2)); 9617 effect(KILL cr); 9618 9619 ins_cost(275); 9620 format %{ "ucomisd $src1, $src2\n\t" 9621 "movl $dst, #-1\n\t" 9622 "jp,s done\n\t" 9623 "jb,s done\n\t" 9624 "setne $dst\n\t" 9625 "movzbl $dst, $dst\n" 9626 "done:" %} 9627 ins_encode %{ 9628 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9629 emit_cmpfp3(_masm, $dst$$Register); 9630 %} 9631 ins_pipe(pipe_slow); 9632 %} 9633 9634 // Compare into -1,0,1 9635 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9636 %{ 9637 match(Set dst (CmpD3 src1 (LoadD src2))); 9638 effect(KILL cr); 9639 9640 ins_cost(275); 9641 format %{ "ucomisd $src1, $src2\n\t" 9642 "movl $dst, #-1\n\t" 9643 "jp,s done\n\t" 9644 "jb,s done\n\t" 9645 "setne $dst\n\t" 9646 "movzbl $dst, $dst\n" 9647 "done:" %} 9648 ins_encode %{ 9649 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9650 emit_cmpfp3(_masm, $dst$$Register); 9651 %} 9652 ins_pipe(pipe_slow); 9653 %} 9654 9655 // Compare into -1,0,1 9656 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9657 match(Set dst (CmpD3 src con)); 9658 effect(KILL cr); 9659 9660 ins_cost(275); 9661 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9662 "movl $dst, #-1\n\t" 9663 "jp,s done\n\t" 9664 "jb,s done\n\t" 9665 "setne $dst\n\t" 9666 "movzbl $dst, $dst\n" 9667 "done:" %} 9668 ins_encode %{ 9669 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9670 emit_cmpfp3(_masm, $dst$$Register); 9671 %} 9672 ins_pipe(pipe_slow); 9673 %} 9674 9675 // -----------Trig and Trancendental Instructions------------------------------ 9676 instruct cosD_reg(regD dst) %{ 9677 match(Set dst (CosD dst)); 9678 9679 format %{ "dcos $dst\n\t" %} 9680 opcode(0xD9, 0xFF); 9681 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9682 ins_pipe( pipe_slow ); 9683 %} 9684 9685 instruct sinD_reg(regD dst) %{ 9686 match(Set dst (SinD dst)); 9687 9688 format %{ "dsin $dst\n\t" %} 9689 opcode(0xD9, 0xFE); 9690 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9691 ins_pipe( pipe_slow ); 9692 %} 9693 9694 instruct tanD_reg(regD dst) %{ 9695 match(Set dst (TanD dst)); 9696 9697 format %{ "dtan $dst\n\t" %} 9698 ins_encode( Push_SrcXD(dst), 9699 Opcode(0xD9), Opcode(0xF2), //fptan 9700 Opcode(0xDD), Opcode(0xD8), //fstp st 9701 Push_ResultXD(dst) ); 9702 ins_pipe( pipe_slow ); 9703 %} 9704 9705 instruct log10D_reg(regD dst) %{ 9706 // The source and result Double operands in XMM registers 9707 match(Set dst (Log10D dst)); 9708 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9709 // fyl2x ; compute log_10(2) * log_2(x) 9710 format %{ "fldlg2\t\t\t#Log10\n\t" 9711 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9712 %} 9713 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9714 Push_SrcXD(dst), 9715 Opcode(0xD9), Opcode(0xF1), // fyl2x 9716 Push_ResultXD(dst)); 9717 9718 ins_pipe( pipe_slow ); 9719 %} 9720 9721 instruct logD_reg(regD dst) %{ 9722 // The source and result Double operands in XMM registers 9723 match(Set dst (LogD dst)); 9724 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9725 // fyl2x ; compute log_e(2) * log_2(x) 9726 format %{ "fldln2\t\t\t#Log_e\n\t" 9727 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9728 %} 9729 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9730 Push_SrcXD(dst), 9731 Opcode(0xD9), Opcode(0xF1), // fyl2x 9732 Push_ResultXD(dst)); 9733 ins_pipe( pipe_slow ); 9734 %} 9735 9736 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9737 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9738 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9739 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9740 ins_encode %{ 9741 __ subptr(rsp, 8); 9742 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9743 __ fld_d(Address(rsp, 0)); 9744 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9745 __ fld_d(Address(rsp, 0)); 9746 __ fast_pow(); 9747 __ fstp_d(Address(rsp, 0)); 9748 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9749 __ addptr(rsp, 8); 9750 %} 9751 ins_pipe( pipe_slow ); 9752 %} 9753 9754 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9755 match(Set dst (ExpD src)); 9756 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 9757 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 9758 ins_encode %{ 9759 __ subptr(rsp, 8); 9760 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9761 __ fld_d(Address(rsp, 0)); 9762 __ fast_exp(); 9763 __ fstp_d(Address(rsp, 0)); 9764 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9765 __ addptr(rsp, 8); 9766 %} 9767 ins_pipe( pipe_slow ); 9768 %} 9769 9770 //----------Arithmetic Conversion Instructions--------------------------------- 9771 9772 instruct roundFloat_nop(regF dst) 9773 %{ 9774 match(Set dst (RoundFloat dst)); 9775 9776 ins_cost(0); 9777 ins_encode(); 9778 ins_pipe(empty); 9779 %} 9780 9781 instruct roundDouble_nop(regD dst) 9782 %{ 9783 match(Set dst (RoundDouble dst)); 9784 9785 ins_cost(0); 9786 ins_encode(); 9787 ins_pipe(empty); 9788 %} 9789 9790 instruct convF2D_reg_reg(regD dst, regF src) 9791 %{ 9792 match(Set dst (ConvF2D src)); 9793 9794 format %{ "cvtss2sd $dst, $src" %} 9795 ins_encode %{ 9796 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9797 %} 9798 ins_pipe(pipe_slow); // XXX 9799 %} 9800 9801 instruct convF2D_reg_mem(regD dst, memory src) 9802 %{ 9803 match(Set dst (ConvF2D (LoadF src))); 9804 9805 format %{ "cvtss2sd $dst, $src" %} 9806 ins_encode %{ 9807 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9808 %} 9809 ins_pipe(pipe_slow); // XXX 9810 %} 9811 9812 instruct convD2F_reg_reg(regF dst, regD src) 9813 %{ 9814 match(Set dst (ConvD2F src)); 9815 9816 format %{ "cvtsd2ss $dst, $src" %} 9817 ins_encode %{ 9818 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9819 %} 9820 ins_pipe(pipe_slow); // XXX 9821 %} 9822 9823 instruct convD2F_reg_mem(regF dst, memory src) 9824 %{ 9825 match(Set dst (ConvD2F (LoadD src))); 9826 9827 format %{ "cvtsd2ss $dst, $src" %} 9828 ins_encode %{ 9829 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9830 %} 9831 ins_pipe(pipe_slow); // XXX 9832 %} 9833 9834 // XXX do mem variants 9835 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9836 %{ 9837 match(Set dst (ConvF2I src)); 9838 effect(KILL cr); 9839 9840 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9841 "cmpl $dst, #0x80000000\n\t" 9842 "jne,s done\n\t" 9843 "subq rsp, #8\n\t" 9844 "movss [rsp], $src\n\t" 9845 "call f2i_fixup\n\t" 9846 "popq $dst\n" 9847 "done: "%} 9848 ins_encode %{ 9849 Label done; 9850 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9851 __ cmpl($dst$$Register, 0x80000000); 9852 __ jccb(Assembler::notEqual, done); 9853 __ subptr(rsp, 8); 9854 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9855 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9856 __ pop($dst$$Register); 9857 __ bind(done); 9858 %} 9859 ins_pipe(pipe_slow); 9860 %} 9861 9862 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9863 %{ 9864 match(Set dst (ConvF2L src)); 9865 effect(KILL cr); 9866 9867 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9868 "cmpq $dst, [0x8000000000000000]\n\t" 9869 "jne,s done\n\t" 9870 "subq rsp, #8\n\t" 9871 "movss [rsp], $src\n\t" 9872 "call f2l_fixup\n\t" 9873 "popq $dst\n" 9874 "done: "%} 9875 ins_encode %{ 9876 Label done; 9877 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 9878 __ cmp64($dst$$Register, 9879 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9880 __ jccb(Assembler::notEqual, done); 9881 __ subptr(rsp, 8); 9882 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9883 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 9884 __ pop($dst$$Register); 9885 __ bind(done); 9886 %} 9887 ins_pipe(pipe_slow); 9888 %} 9889 9890 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 9891 %{ 9892 match(Set dst (ConvD2I src)); 9893 effect(KILL cr); 9894 9895 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 9896 "cmpl $dst, #0x80000000\n\t" 9897 "jne,s done\n\t" 9898 "subq rsp, #8\n\t" 9899 "movsd [rsp], $src\n\t" 9900 "call d2i_fixup\n\t" 9901 "popq $dst\n" 9902 "done: "%} 9903 ins_encode %{ 9904 Label done; 9905 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 9906 __ cmpl($dst$$Register, 0x80000000); 9907 __ jccb(Assembler::notEqual, done); 9908 __ subptr(rsp, 8); 9909 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9910 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 9911 __ pop($dst$$Register); 9912 __ bind(done); 9913 %} 9914 ins_pipe(pipe_slow); 9915 %} 9916 9917 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 9918 %{ 9919 match(Set dst (ConvD2L src)); 9920 effect(KILL cr); 9921 9922 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 9923 "cmpq $dst, [0x8000000000000000]\n\t" 9924 "jne,s done\n\t" 9925 "subq rsp, #8\n\t" 9926 "movsd [rsp], $src\n\t" 9927 "call d2l_fixup\n\t" 9928 "popq $dst\n" 9929 "done: "%} 9930 ins_encode %{ 9931 Label done; 9932 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 9933 __ cmp64($dst$$Register, 9934 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9935 __ jccb(Assembler::notEqual, done); 9936 __ subptr(rsp, 8); 9937 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9938 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 9939 __ pop($dst$$Register); 9940 __ bind(done); 9941 %} 9942 ins_pipe(pipe_slow); 9943 %} 9944 9945 instruct convI2F_reg_reg(regF dst, rRegI src) 9946 %{ 9947 predicate(!UseXmmI2F); 9948 match(Set dst (ConvI2F src)); 9949 9950 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 9951 ins_encode %{ 9952 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 9953 %} 9954 ins_pipe(pipe_slow); // XXX 9955 %} 9956 9957 instruct convI2F_reg_mem(regF dst, memory src) 9958 %{ 9959 match(Set dst (ConvI2F (LoadI src))); 9960 9961 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 9962 ins_encode %{ 9963 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 9964 %} 9965 ins_pipe(pipe_slow); // XXX 9966 %} 9967 9968 instruct convI2D_reg_reg(regD dst, rRegI src) 9969 %{ 9970 predicate(!UseXmmI2D); 9971 match(Set dst (ConvI2D src)); 9972 9973 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 9974 ins_encode %{ 9975 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 9976 %} 9977 ins_pipe(pipe_slow); // XXX 9978 %} 9979 9980 instruct convI2D_reg_mem(regD dst, memory src) 9981 %{ 9982 match(Set dst (ConvI2D (LoadI src))); 9983 9984 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 9985 ins_encode %{ 9986 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 9987 %} 9988 ins_pipe(pipe_slow); // XXX 9989 %} 9990 9991 instruct convXI2F_reg(regF dst, rRegI src) 9992 %{ 9993 predicate(UseXmmI2F); 9994 match(Set dst (ConvI2F src)); 9995 9996 format %{ "movdl $dst, $src\n\t" 9997 "cvtdq2psl $dst, $dst\t# i2f" %} 9998 ins_encode %{ 9999 __ movdl($dst$$XMMRegister, $src$$Register); 10000 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10001 %} 10002 ins_pipe(pipe_slow); // XXX 10003 %} 10004 10005 instruct convXI2D_reg(regD dst, rRegI src) 10006 %{ 10007 predicate(UseXmmI2D); 10008 match(Set dst (ConvI2D src)); 10009 10010 format %{ "movdl $dst, $src\n\t" 10011 "cvtdq2pdl $dst, $dst\t# i2d" %} 10012 ins_encode %{ 10013 __ movdl($dst$$XMMRegister, $src$$Register); 10014 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10015 %} 10016 ins_pipe(pipe_slow); // XXX 10017 %} 10018 10019 instruct convL2F_reg_reg(regF dst, rRegL src) 10020 %{ 10021 match(Set dst (ConvL2F src)); 10022 10023 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10024 ins_encode %{ 10025 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10026 %} 10027 ins_pipe(pipe_slow); // XXX 10028 %} 10029 10030 instruct convL2F_reg_mem(regF dst, memory src) 10031 %{ 10032 match(Set dst (ConvL2F (LoadL src))); 10033 10034 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10035 ins_encode %{ 10036 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10037 %} 10038 ins_pipe(pipe_slow); // XXX 10039 %} 10040 10041 instruct convL2D_reg_reg(regD dst, rRegL src) 10042 %{ 10043 match(Set dst (ConvL2D src)); 10044 10045 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10046 ins_encode %{ 10047 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10048 %} 10049 ins_pipe(pipe_slow); // XXX 10050 %} 10051 10052 instruct convL2D_reg_mem(regD dst, memory src) 10053 %{ 10054 match(Set dst (ConvL2D (LoadL src))); 10055 10056 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10057 ins_encode %{ 10058 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10059 %} 10060 ins_pipe(pipe_slow); // XXX 10061 %} 10062 10063 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10064 %{ 10065 match(Set dst (ConvI2L src)); 10066 10067 ins_cost(125); 10068 format %{ "movslq $dst, $src\t# i2l" %} 10069 ins_encode %{ 10070 __ movslq($dst$$Register, $src$$Register); 10071 %} 10072 ins_pipe(ialu_reg_reg); 10073 %} 10074 10075 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10076 // %{ 10077 // match(Set dst (ConvI2L src)); 10078 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10079 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10080 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10081 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10082 // ((const TypeNode*) n)->type()->is_long()->_lo == 10083 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10084 10085 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10086 // ins_encode(enc_copy(dst, src)); 10087 // // opcode(0x63); // needs REX.W 10088 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10089 // ins_pipe(ialu_reg_reg); 10090 // %} 10091 10092 // Zero-extend convert int to long 10093 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10094 %{ 10095 match(Set dst (AndL (ConvI2L src) mask)); 10096 10097 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10098 ins_encode %{ 10099 if ($dst$$reg != $src$$reg) { 10100 __ movl($dst$$Register, $src$$Register); 10101 } 10102 %} 10103 ins_pipe(ialu_reg_reg); 10104 %} 10105 10106 // Zero-extend convert int to long 10107 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10108 %{ 10109 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10110 10111 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10112 ins_encode %{ 10113 __ movl($dst$$Register, $src$$Address); 10114 %} 10115 ins_pipe(ialu_reg_mem); 10116 %} 10117 10118 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10119 %{ 10120 match(Set dst (AndL src mask)); 10121 10122 format %{ "movl $dst, $src\t# zero-extend long" %} 10123 ins_encode %{ 10124 __ movl($dst$$Register, $src$$Register); 10125 %} 10126 ins_pipe(ialu_reg_reg); 10127 %} 10128 10129 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10130 %{ 10131 match(Set dst (ConvL2I src)); 10132 10133 format %{ "movl $dst, $src\t# l2i" %} 10134 ins_encode %{ 10135 __ movl($dst$$Register, $src$$Register); 10136 %} 10137 ins_pipe(ialu_reg_reg); 10138 %} 10139 10140 10141 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10142 match(Set dst (MoveF2I src)); 10143 effect(DEF dst, USE src); 10144 10145 ins_cost(125); 10146 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10147 ins_encode %{ 10148 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10149 %} 10150 ins_pipe(ialu_reg_mem); 10151 %} 10152 10153 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10154 match(Set dst (MoveI2F src)); 10155 effect(DEF dst, USE src); 10156 10157 ins_cost(125); 10158 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10159 ins_encode %{ 10160 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10161 %} 10162 ins_pipe(pipe_slow); 10163 %} 10164 10165 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10166 match(Set dst (MoveD2L src)); 10167 effect(DEF dst, USE src); 10168 10169 ins_cost(125); 10170 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10171 ins_encode %{ 10172 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10173 %} 10174 ins_pipe(ialu_reg_mem); 10175 %} 10176 10177 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10178 predicate(!UseXmmLoadAndClearUpper); 10179 match(Set dst (MoveL2D src)); 10180 effect(DEF dst, USE src); 10181 10182 ins_cost(125); 10183 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10184 ins_encode %{ 10185 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10186 %} 10187 ins_pipe(pipe_slow); 10188 %} 10189 10190 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10191 predicate(UseXmmLoadAndClearUpper); 10192 match(Set dst (MoveL2D src)); 10193 effect(DEF dst, USE src); 10194 10195 ins_cost(125); 10196 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10197 ins_encode %{ 10198 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10199 %} 10200 ins_pipe(pipe_slow); 10201 %} 10202 10203 10204 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10205 match(Set dst (MoveF2I src)); 10206 effect(DEF dst, USE src); 10207 10208 ins_cost(95); // XXX 10209 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10210 ins_encode %{ 10211 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10212 %} 10213 ins_pipe(pipe_slow); 10214 %} 10215 10216 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10217 match(Set dst (MoveI2F src)); 10218 effect(DEF dst, USE src); 10219 10220 ins_cost(100); 10221 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10222 ins_encode %{ 10223 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10224 %} 10225 ins_pipe( ialu_mem_reg ); 10226 %} 10227 10228 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10229 match(Set dst (MoveD2L src)); 10230 effect(DEF dst, USE src); 10231 10232 ins_cost(95); // XXX 10233 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10234 ins_encode %{ 10235 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10236 %} 10237 ins_pipe(pipe_slow); 10238 %} 10239 10240 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10241 match(Set dst (MoveL2D src)); 10242 effect(DEF dst, USE src); 10243 10244 ins_cost(100); 10245 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10246 ins_encode %{ 10247 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10248 %} 10249 ins_pipe(ialu_mem_reg); 10250 %} 10251 10252 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10253 match(Set dst (MoveF2I src)); 10254 effect(DEF dst, USE src); 10255 ins_cost(85); 10256 format %{ "movd $dst,$src\t# MoveF2I" %} 10257 ins_encode %{ 10258 __ movdl($dst$$Register, $src$$XMMRegister); 10259 %} 10260 ins_pipe( pipe_slow ); 10261 %} 10262 10263 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10264 match(Set dst (MoveD2L src)); 10265 effect(DEF dst, USE src); 10266 ins_cost(85); 10267 format %{ "movd $dst,$src\t# MoveD2L" %} 10268 ins_encode %{ 10269 __ movdq($dst$$Register, $src$$XMMRegister); 10270 %} 10271 ins_pipe( pipe_slow ); 10272 %} 10273 10274 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10275 match(Set dst (MoveI2F src)); 10276 effect(DEF dst, USE src); 10277 ins_cost(100); 10278 format %{ "movd $dst,$src\t# MoveI2F" %} 10279 ins_encode %{ 10280 __ movdl($dst$$XMMRegister, $src$$Register); 10281 %} 10282 ins_pipe( pipe_slow ); 10283 %} 10284 10285 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10286 match(Set dst (MoveL2D src)); 10287 effect(DEF dst, USE src); 10288 ins_cost(100); 10289 format %{ "movd $dst,$src\t# MoveL2D" %} 10290 ins_encode %{ 10291 __ movdq($dst$$XMMRegister, $src$$Register); 10292 %} 10293 ins_pipe( pipe_slow ); 10294 %} 10295 10296 10297 // ======================================================================= 10298 // fast clearing of an array 10299 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10300 rFlagsReg cr) 10301 %{ 10302 predicate(!UseFastStosb); 10303 match(Set dummy (ClearArray cnt base)); 10304 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10305 10306 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10307 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10308 ins_encode %{ 10309 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10310 %} 10311 ins_pipe(pipe_slow); 10312 %} 10313 10314 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10315 rFlagsReg cr) 10316 %{ 10317 predicate(UseFastStosb); 10318 match(Set dummy (ClearArray cnt base)); 10319 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10320 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10321 "shlq rcx,3\t# Convert doublewords to bytes\n\t" 10322 "rep stosb\t# Store rax to *rdi++ while rcx--" %} 10323 ins_encode %{ 10324 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10325 %} 10326 ins_pipe( pipe_slow ); 10327 %} 10328 10329 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10330 rax_RegI result, regD tmp1, rFlagsReg cr) 10331 %{ 10332 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10333 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10334 10335 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10336 ins_encode %{ 10337 __ string_compare($str1$$Register, $str2$$Register, 10338 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10339 $tmp1$$XMMRegister); 10340 %} 10341 ins_pipe( pipe_slow ); 10342 %} 10343 10344 // fast search of substring with known size. 10345 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10346 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10347 %{ 10348 predicate(UseSSE42Intrinsics); 10349 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10350 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10351 10352 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10353 ins_encode %{ 10354 int icnt2 = (int)$int_cnt2$$constant; 10355 if (icnt2 >= 8) { 10356 // IndexOf for constant substrings with size >= 8 elements 10357 // which don't need to be loaded through stack. 10358 __ string_indexofC8($str1$$Register, $str2$$Register, 10359 $cnt1$$Register, $cnt2$$Register, 10360 icnt2, $result$$Register, 10361 $vec$$XMMRegister, $tmp$$Register); 10362 } else { 10363 // Small strings are loaded through stack if they cross page boundary. 10364 __ string_indexof($str1$$Register, $str2$$Register, 10365 $cnt1$$Register, $cnt2$$Register, 10366 icnt2, $result$$Register, 10367 $vec$$XMMRegister, $tmp$$Register); 10368 } 10369 %} 10370 ins_pipe( pipe_slow ); 10371 %} 10372 10373 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10374 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10375 %{ 10376 predicate(UseSSE42Intrinsics); 10377 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10378 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10379 10380 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10381 ins_encode %{ 10382 __ string_indexof($str1$$Register, $str2$$Register, 10383 $cnt1$$Register, $cnt2$$Register, 10384 (-1), $result$$Register, 10385 $vec$$XMMRegister, $tmp$$Register); 10386 %} 10387 ins_pipe( pipe_slow ); 10388 %} 10389 10390 // fast string equals 10391 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10392 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10393 %{ 10394 match(Set result (StrEquals (Binary str1 str2) cnt)); 10395 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10396 10397 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10398 ins_encode %{ 10399 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10400 $cnt$$Register, $result$$Register, $tmp3$$Register, 10401 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10402 %} 10403 ins_pipe( pipe_slow ); 10404 %} 10405 10406 // fast array equals 10407 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10408 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10409 %{ 10410 match(Set result (AryEq ary1 ary2)); 10411 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10412 //ins_cost(300); 10413 10414 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10415 ins_encode %{ 10416 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10417 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10418 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10419 %} 10420 ins_pipe( pipe_slow ); 10421 %} 10422 10423 // encode char[] to byte[] in ISO_8859_1 10424 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10425 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10426 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10427 match(Set result (EncodeISOArray src (Binary dst len))); 10428 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10429 10430 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 10431 ins_encode %{ 10432 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 10433 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10434 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10435 %} 10436 ins_pipe( pipe_slow ); 10437 %} 10438 10439 //----------Overflow Math Instructions----------------------------------------- 10440 10441 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10442 %{ 10443 match(Set cr (OverflowAddI op1 op2)); 10444 effect(DEF cr, USE_KILL op1, USE op2); 10445 10446 format %{ "addl $op1, $op2\t# overflow check int" %} 10447 10448 ins_encode %{ 10449 __ addl($op1$$Register, $op2$$Register); 10450 %} 10451 ins_pipe(ialu_reg_reg); 10452 %} 10453 10454 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 10455 %{ 10456 match(Set cr (OverflowAddI op1 op2)); 10457 effect(DEF cr, USE_KILL op1, USE op2); 10458 10459 format %{ "addl $op1, $op2\t# overflow check int" %} 10460 10461 ins_encode %{ 10462 __ addl($op1$$Register, $op2$$constant); 10463 %} 10464 ins_pipe(ialu_reg_reg); 10465 %} 10466 10467 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10468 %{ 10469 match(Set cr (OverflowAddL op1 op2)); 10470 effect(DEF cr, USE_KILL op1, USE op2); 10471 10472 format %{ "addq $op1, $op2\t# overflow check long" %} 10473 ins_encode %{ 10474 __ addq($op1$$Register, $op2$$Register); 10475 %} 10476 ins_pipe(ialu_reg_reg); 10477 %} 10478 10479 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 10480 %{ 10481 match(Set cr (OverflowAddL op1 op2)); 10482 effect(DEF cr, USE_KILL op1, USE op2); 10483 10484 format %{ "addq $op1, $op2\t# overflow check long" %} 10485 ins_encode %{ 10486 __ addq($op1$$Register, $op2$$constant); 10487 %} 10488 ins_pipe(ialu_reg_reg); 10489 %} 10490 10491 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10492 %{ 10493 match(Set cr (OverflowSubI op1 op2)); 10494 10495 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10496 ins_encode %{ 10497 __ cmpl($op1$$Register, $op2$$Register); 10498 %} 10499 ins_pipe(ialu_reg_reg); 10500 %} 10501 10502 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10503 %{ 10504 match(Set cr (OverflowSubI op1 op2)); 10505 10506 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10507 ins_encode %{ 10508 __ cmpl($op1$$Register, $op2$$constant); 10509 %} 10510 ins_pipe(ialu_reg_reg); 10511 %} 10512 10513 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10514 %{ 10515 match(Set cr (OverflowSubL op1 op2)); 10516 10517 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10518 ins_encode %{ 10519 __ cmpq($op1$$Register, $op2$$Register); 10520 %} 10521 ins_pipe(ialu_reg_reg); 10522 %} 10523 10524 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10525 %{ 10526 match(Set cr (OverflowSubL op1 op2)); 10527 10528 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10529 ins_encode %{ 10530 __ cmpq($op1$$Register, $op2$$constant); 10531 %} 10532 ins_pipe(ialu_reg_reg); 10533 %} 10534 10535 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 10536 %{ 10537 match(Set cr (OverflowSubI zero op2)); 10538 effect(DEF cr, USE_KILL op2); 10539 10540 format %{ "negl $op2\t# overflow check int" %} 10541 ins_encode %{ 10542 __ negl($op2$$Register); 10543 %} 10544 ins_pipe(ialu_reg_reg); 10545 %} 10546 10547 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 10548 %{ 10549 match(Set cr (OverflowSubL zero op2)); 10550 effect(DEF cr, USE_KILL op2); 10551 10552 format %{ "negq $op2\t# overflow check long" %} 10553 ins_encode %{ 10554 __ negq($op2$$Register); 10555 %} 10556 ins_pipe(ialu_reg_reg); 10557 %} 10558 10559 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10560 %{ 10561 match(Set cr (OverflowMulI op1 op2)); 10562 effect(DEF cr, USE_KILL op1, USE op2); 10563 10564 format %{ "imull $op1, $op2\t# overflow check int" %} 10565 ins_encode %{ 10566 __ imull($op1$$Register, $op2$$Register); 10567 %} 10568 ins_pipe(ialu_reg_reg_alu0); 10569 %} 10570 10571 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 10572 %{ 10573 match(Set cr (OverflowMulI op1 op2)); 10574 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10575 10576 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 10577 ins_encode %{ 10578 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 10579 %} 10580 ins_pipe(ialu_reg_reg_alu0); 10581 %} 10582 10583 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10584 %{ 10585 match(Set cr (OverflowMulL op1 op2)); 10586 effect(DEF cr, USE_KILL op1, USE op2); 10587 10588 format %{ "imulq $op1, $op2\t# overflow check long" %} 10589 ins_encode %{ 10590 __ imulq($op1$$Register, $op2$$Register); 10591 %} 10592 ins_pipe(ialu_reg_reg_alu0); 10593 %} 10594 10595 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 10596 %{ 10597 match(Set cr (OverflowMulL op1 op2)); 10598 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10599 10600 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 10601 ins_encode %{ 10602 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 10603 %} 10604 ins_pipe(ialu_reg_reg_alu0); 10605 %} 10606 10607 10608 //----------Control Flow Instructions------------------------------------------ 10609 // Signed compare Instructions 10610 10611 // XXX more variants!! 10612 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10613 %{ 10614 match(Set cr (CmpI op1 op2)); 10615 effect(DEF cr, USE op1, USE op2); 10616 10617 format %{ "cmpl $op1, $op2" %} 10618 opcode(0x3B); /* Opcode 3B /r */ 10619 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10620 ins_pipe(ialu_cr_reg_reg); 10621 %} 10622 10623 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10624 %{ 10625 match(Set cr (CmpI op1 op2)); 10626 10627 format %{ "cmpl $op1, $op2" %} 10628 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10629 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10630 ins_pipe(ialu_cr_reg_imm); 10631 %} 10632 10633 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10634 %{ 10635 match(Set cr (CmpI op1 (LoadI op2))); 10636 10637 ins_cost(500); // XXX 10638 format %{ "cmpl $op1, $op2" %} 10639 opcode(0x3B); /* Opcode 3B /r */ 10640 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10641 ins_pipe(ialu_cr_reg_mem); 10642 %} 10643 10644 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10645 %{ 10646 match(Set cr (CmpI src zero)); 10647 10648 format %{ "testl $src, $src" %} 10649 opcode(0x85); 10650 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10651 ins_pipe(ialu_cr_reg_imm); 10652 %} 10653 10654 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10655 %{ 10656 match(Set cr (CmpI (AndI src con) zero)); 10657 10658 format %{ "testl $src, $con" %} 10659 opcode(0xF7, 0x00); 10660 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10661 ins_pipe(ialu_cr_reg_imm); 10662 %} 10663 10664 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10665 %{ 10666 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10667 10668 format %{ "testl $src, $mem" %} 10669 opcode(0x85); 10670 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10671 ins_pipe(ialu_cr_reg_mem); 10672 %} 10673 10674 // Unsigned compare Instructions; really, same as signed except they 10675 // produce an rFlagsRegU instead of rFlagsReg. 10676 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10677 %{ 10678 match(Set cr (CmpU op1 op2)); 10679 10680 format %{ "cmpl $op1, $op2\t# unsigned" %} 10681 opcode(0x3B); /* Opcode 3B /r */ 10682 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10683 ins_pipe(ialu_cr_reg_reg); 10684 %} 10685 10686 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10687 %{ 10688 match(Set cr (CmpU op1 op2)); 10689 10690 format %{ "cmpl $op1, $op2\t# unsigned" %} 10691 opcode(0x81,0x07); /* Opcode 81 /7 */ 10692 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10693 ins_pipe(ialu_cr_reg_imm); 10694 %} 10695 10696 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10697 %{ 10698 match(Set cr (CmpU op1 (LoadI op2))); 10699 10700 ins_cost(500); // XXX 10701 format %{ "cmpl $op1, $op2\t# unsigned" %} 10702 opcode(0x3B); /* Opcode 3B /r */ 10703 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10704 ins_pipe(ialu_cr_reg_mem); 10705 %} 10706 10707 // // // Cisc-spilled version of cmpU_rReg 10708 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10709 // //%{ 10710 // // match(Set cr (CmpU (LoadI op1) op2)); 10711 // // 10712 // // format %{ "CMPu $op1,$op2" %} 10713 // // ins_cost(500); 10714 // // opcode(0x39); /* Opcode 39 /r */ 10715 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10716 // //%} 10717 10718 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10719 %{ 10720 match(Set cr (CmpU src zero)); 10721 10722 format %{ "testl $src, $src\t# unsigned" %} 10723 opcode(0x85); 10724 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10725 ins_pipe(ialu_cr_reg_imm); 10726 %} 10727 10728 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10729 %{ 10730 match(Set cr (CmpP op1 op2)); 10731 10732 format %{ "cmpq $op1, $op2\t# ptr" %} 10733 opcode(0x3B); /* Opcode 3B /r */ 10734 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10735 ins_pipe(ialu_cr_reg_reg); 10736 %} 10737 10738 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10739 %{ 10740 match(Set cr (CmpP op1 (LoadP op2))); 10741 10742 ins_cost(500); // XXX 10743 format %{ "cmpq $op1, $op2\t# ptr" %} 10744 opcode(0x3B); /* Opcode 3B /r */ 10745 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10746 ins_pipe(ialu_cr_reg_mem); 10747 %} 10748 10749 // // // Cisc-spilled version of cmpP_rReg 10750 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10751 // //%{ 10752 // // match(Set cr (CmpP (LoadP op1) op2)); 10753 // // 10754 // // format %{ "CMPu $op1,$op2" %} 10755 // // ins_cost(500); 10756 // // opcode(0x39); /* Opcode 39 /r */ 10757 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10758 // //%} 10759 10760 // XXX this is generalized by compP_rReg_mem??? 10761 // Compare raw pointer (used in out-of-heap check). 10762 // Only works because non-oop pointers must be raw pointers 10763 // and raw pointers have no anti-dependencies. 10764 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10765 %{ 10766 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 10767 match(Set cr (CmpP op1 (LoadP op2))); 10768 10769 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10770 opcode(0x3B); /* Opcode 3B /r */ 10771 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10772 ins_pipe(ialu_cr_reg_mem); 10773 %} 10774 10775 // This will generate a signed flags result. This should be OK since 10776 // any compare to a zero should be eq/neq. 10777 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10778 %{ 10779 match(Set cr (CmpP src zero)); 10780 10781 format %{ "testq $src, $src\t# ptr" %} 10782 opcode(0x85); 10783 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10784 ins_pipe(ialu_cr_reg_imm); 10785 %} 10786 10787 // This will generate a signed flags result. This should be OK since 10788 // any compare to a zero should be eq/neq. 10789 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10790 %{ 10791 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10792 match(Set cr (CmpP (LoadP op) zero)); 10793 10794 ins_cost(500); // XXX 10795 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10796 opcode(0xF7); /* Opcode F7 /0 */ 10797 ins_encode(REX_mem_wide(op), 10798 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10799 ins_pipe(ialu_cr_reg_imm); 10800 %} 10801 10802 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10803 %{ 10804 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 10805 match(Set cr (CmpP (LoadP mem) zero)); 10806 10807 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10808 ins_encode %{ 10809 __ cmpq(r12, $mem$$Address); 10810 %} 10811 ins_pipe(ialu_cr_reg_mem); 10812 %} 10813 10814 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10815 %{ 10816 match(Set cr (CmpN op1 op2)); 10817 10818 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10819 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10820 ins_pipe(ialu_cr_reg_reg); 10821 %} 10822 10823 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10824 %{ 10825 match(Set cr (CmpN src (LoadN mem))); 10826 10827 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10828 ins_encode %{ 10829 __ cmpl($src$$Register, $mem$$Address); 10830 %} 10831 ins_pipe(ialu_cr_reg_mem); 10832 %} 10833 10834 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10835 match(Set cr (CmpN op1 op2)); 10836 10837 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10838 ins_encode %{ 10839 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10840 %} 10841 ins_pipe(ialu_cr_reg_imm); 10842 %} 10843 10844 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10845 %{ 10846 match(Set cr (CmpN src (LoadN mem))); 10847 10848 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10849 ins_encode %{ 10850 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10851 %} 10852 ins_pipe(ialu_cr_reg_mem); 10853 %} 10854 10855 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 10856 match(Set cr (CmpN op1 op2)); 10857 10858 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 10859 ins_encode %{ 10860 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 10861 %} 10862 ins_pipe(ialu_cr_reg_imm); 10863 %} 10864 10865 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 10866 %{ 10867 match(Set cr (CmpN src (LoadNKlass mem))); 10868 10869 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 10870 ins_encode %{ 10871 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 10872 %} 10873 ins_pipe(ialu_cr_reg_mem); 10874 %} 10875 10876 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 10877 match(Set cr (CmpN src zero)); 10878 10879 format %{ "testl $src, $src\t# compressed ptr" %} 10880 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 10881 ins_pipe(ialu_cr_reg_imm); 10882 %} 10883 10884 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 10885 %{ 10886 predicate(Universe::narrow_oop_base() != NULL); 10887 match(Set cr (CmpN (LoadN mem) zero)); 10888 10889 ins_cost(500); // XXX 10890 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 10891 ins_encode %{ 10892 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 10893 %} 10894 ins_pipe(ialu_cr_reg_mem); 10895 %} 10896 10897 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 10898 %{ 10899 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 10900 match(Set cr (CmpN (LoadN mem) zero)); 10901 10902 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 10903 ins_encode %{ 10904 __ cmpl(r12, $mem$$Address); 10905 %} 10906 ins_pipe(ialu_cr_reg_mem); 10907 %} 10908 10909 // Yanked all unsigned pointer compare operations. 10910 // Pointer compares are done with CmpP which is already unsigned. 10911 10912 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10913 %{ 10914 match(Set cr (CmpL op1 op2)); 10915 10916 format %{ "cmpq $op1, $op2" %} 10917 opcode(0x3B); /* Opcode 3B /r */ 10918 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10919 ins_pipe(ialu_cr_reg_reg); 10920 %} 10921 10922 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10923 %{ 10924 match(Set cr (CmpL op1 op2)); 10925 10926 format %{ "cmpq $op1, $op2" %} 10927 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10928 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 10929 ins_pipe(ialu_cr_reg_imm); 10930 %} 10931 10932 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 10933 %{ 10934 match(Set cr (CmpL op1 (LoadL op2))); 10935 10936 format %{ "cmpq $op1, $op2" %} 10937 opcode(0x3B); /* Opcode 3B /r */ 10938 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10939 ins_pipe(ialu_cr_reg_mem); 10940 %} 10941 10942 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 10943 %{ 10944 match(Set cr (CmpL src zero)); 10945 10946 format %{ "testq $src, $src" %} 10947 opcode(0x85); 10948 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10949 ins_pipe(ialu_cr_reg_imm); 10950 %} 10951 10952 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 10953 %{ 10954 match(Set cr (CmpL (AndL src con) zero)); 10955 10956 format %{ "testq $src, $con\t# long" %} 10957 opcode(0xF7, 0x00); 10958 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 10959 ins_pipe(ialu_cr_reg_imm); 10960 %} 10961 10962 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 10963 %{ 10964 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 10965 10966 format %{ "testq $src, $mem" %} 10967 opcode(0x85); 10968 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 10969 ins_pipe(ialu_cr_reg_mem); 10970 %} 10971 10972 // Manifest a CmpL result in an integer register. Very painful. 10973 // This is the test to avoid. 10974 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 10975 %{ 10976 match(Set dst (CmpL3 src1 src2)); 10977 effect(KILL flags); 10978 10979 ins_cost(275); // XXX 10980 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 10981 "movl $dst, -1\n\t" 10982 "jl,s done\n\t" 10983 "setne $dst\n\t" 10984 "movzbl $dst, $dst\n\t" 10985 "done:" %} 10986 ins_encode(cmpl3_flag(src1, src2, dst)); 10987 ins_pipe(pipe_slow); 10988 %} 10989 10990 //----------Max and Min-------------------------------------------------------- 10991 // Min Instructions 10992 10993 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 10994 %{ 10995 effect(USE_DEF dst, USE src, USE cr); 10996 10997 format %{ "cmovlgt $dst, $src\t# min" %} 10998 opcode(0x0F, 0x4F); 10999 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11000 ins_pipe(pipe_cmov_reg); 11001 %} 11002 11003 11004 instruct minI_rReg(rRegI dst, rRegI src) 11005 %{ 11006 match(Set dst (MinI dst src)); 11007 11008 ins_cost(200); 11009 expand %{ 11010 rFlagsReg cr; 11011 compI_rReg(cr, dst, src); 11012 cmovI_reg_g(dst, src, cr); 11013 %} 11014 %} 11015 11016 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11017 %{ 11018 effect(USE_DEF dst, USE src, USE cr); 11019 11020 format %{ "cmovllt $dst, $src\t# max" %} 11021 opcode(0x0F, 0x4C); 11022 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11023 ins_pipe(pipe_cmov_reg); 11024 %} 11025 11026 11027 instruct maxI_rReg(rRegI dst, rRegI src) 11028 %{ 11029 match(Set dst (MaxI dst src)); 11030 11031 ins_cost(200); 11032 expand %{ 11033 rFlagsReg cr; 11034 compI_rReg(cr, dst, src); 11035 cmovI_reg_l(dst, src, cr); 11036 %} 11037 %} 11038 11039 // ============================================================================ 11040 // Branch Instructions 11041 11042 // Jump Direct - Label defines a relative address from JMP+1 11043 instruct jmpDir(label labl) 11044 %{ 11045 match(Goto); 11046 effect(USE labl); 11047 11048 ins_cost(300); 11049 format %{ "jmp $labl" %} 11050 size(5); 11051 ins_encode %{ 11052 Label* L = $labl$$label; 11053 __ jmp(*L, false); // Always long jump 11054 %} 11055 ins_pipe(pipe_jmp); 11056 %} 11057 11058 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11059 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11060 %{ 11061 match(If cop cr); 11062 effect(USE labl); 11063 11064 ins_cost(300); 11065 format %{ "j$cop $labl" %} 11066 size(6); 11067 ins_encode %{ 11068 Label* L = $labl$$label; 11069 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11070 %} 11071 ins_pipe(pipe_jcc); 11072 %} 11073 11074 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11075 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11076 %{ 11077 match(CountedLoopEnd cop cr); 11078 effect(USE labl); 11079 11080 ins_cost(300); 11081 format %{ "j$cop $labl\t# loop end" %} 11082 size(6); 11083 ins_encode %{ 11084 Label* L = $labl$$label; 11085 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11086 %} 11087 ins_pipe(pipe_jcc); 11088 %} 11089 11090 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11091 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11092 match(CountedLoopEnd cop cmp); 11093 effect(USE labl); 11094 11095 ins_cost(300); 11096 format %{ "j$cop,u $labl\t# loop end" %} 11097 size(6); 11098 ins_encode %{ 11099 Label* L = $labl$$label; 11100 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11101 %} 11102 ins_pipe(pipe_jcc); 11103 %} 11104 11105 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11106 match(CountedLoopEnd cop cmp); 11107 effect(USE labl); 11108 11109 ins_cost(200); 11110 format %{ "j$cop,u $labl\t# loop end" %} 11111 size(6); 11112 ins_encode %{ 11113 Label* L = $labl$$label; 11114 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11115 %} 11116 ins_pipe(pipe_jcc); 11117 %} 11118 11119 // Jump Direct Conditional - using unsigned comparison 11120 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11121 match(If cop cmp); 11122 effect(USE labl); 11123 11124 ins_cost(300); 11125 format %{ "j$cop,u $labl" %} 11126 size(6); 11127 ins_encode %{ 11128 Label* L = $labl$$label; 11129 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11130 %} 11131 ins_pipe(pipe_jcc); 11132 %} 11133 11134 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11135 match(If cop cmp); 11136 effect(USE labl); 11137 11138 ins_cost(200); 11139 format %{ "j$cop,u $labl" %} 11140 size(6); 11141 ins_encode %{ 11142 Label* L = $labl$$label; 11143 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11144 %} 11145 ins_pipe(pipe_jcc); 11146 %} 11147 11148 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11149 match(If cop cmp); 11150 effect(USE labl); 11151 11152 ins_cost(200); 11153 format %{ $$template 11154 if ($cop$$cmpcode == Assembler::notEqual) { 11155 $$emit$$"jp,u $labl\n\t" 11156 $$emit$$"j$cop,u $labl" 11157 } else { 11158 $$emit$$"jp,u done\n\t" 11159 $$emit$$"j$cop,u $labl\n\t" 11160 $$emit$$"done:" 11161 } 11162 %} 11163 ins_encode %{ 11164 Label* l = $labl$$label; 11165 if ($cop$$cmpcode == Assembler::notEqual) { 11166 __ jcc(Assembler::parity, *l, false); 11167 __ jcc(Assembler::notEqual, *l, false); 11168 } else if ($cop$$cmpcode == Assembler::equal) { 11169 Label done; 11170 __ jccb(Assembler::parity, done); 11171 __ jcc(Assembler::equal, *l, false); 11172 __ bind(done); 11173 } else { 11174 ShouldNotReachHere(); 11175 } 11176 %} 11177 ins_pipe(pipe_jcc); 11178 %} 11179 11180 // ============================================================================ 11181 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11182 // superklass array for an instance of the superklass. Set a hidden 11183 // internal cache on a hit (cache is checked with exposed code in 11184 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11185 // encoding ALSO sets flags. 11186 11187 instruct partialSubtypeCheck(rdi_RegP result, 11188 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11189 rFlagsReg cr) 11190 %{ 11191 match(Set result (PartialSubtypeCheck sub super)); 11192 effect(KILL rcx, KILL cr); 11193 11194 ins_cost(1100); // slightly larger than the next version 11195 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11196 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11197 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11198 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11199 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11200 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11201 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11202 "miss:\t" %} 11203 11204 opcode(0x1); // Force a XOR of RDI 11205 ins_encode(enc_PartialSubtypeCheck()); 11206 ins_pipe(pipe_slow); 11207 %} 11208 11209 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11210 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11211 immP0 zero, 11212 rdi_RegP result) 11213 %{ 11214 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11215 effect(KILL rcx, KILL result); 11216 11217 ins_cost(1000); 11218 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11219 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11220 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11221 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11222 "jne,s miss\t\t# Missed: flags nz\n\t" 11223 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11224 "miss:\t" %} 11225 11226 opcode(0x0); // No need to XOR RDI 11227 ins_encode(enc_PartialSubtypeCheck()); 11228 ins_pipe(pipe_slow); 11229 %} 11230 11231 // ============================================================================ 11232 // Branch Instructions -- short offset versions 11233 // 11234 // These instructions are used to replace jumps of a long offset (the default 11235 // match) with jumps of a shorter offset. These instructions are all tagged 11236 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11237 // match rules in general matching. Instead, the ADLC generates a conversion 11238 // method in the MachNode which can be used to do in-place replacement of the 11239 // long variant with the shorter variant. The compiler will determine if a 11240 // branch can be taken by the is_short_branch_offset() predicate in the machine 11241 // specific code section of the file. 11242 11243 // Jump Direct - Label defines a relative address from JMP+1 11244 instruct jmpDir_short(label labl) %{ 11245 match(Goto); 11246 effect(USE labl); 11247 11248 ins_cost(300); 11249 format %{ "jmp,s $labl" %} 11250 size(2); 11251 ins_encode %{ 11252 Label* L = $labl$$label; 11253 __ jmpb(*L); 11254 %} 11255 ins_pipe(pipe_jmp); 11256 ins_short_branch(1); 11257 %} 11258 11259 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11260 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11261 match(If cop cr); 11262 effect(USE labl); 11263 11264 ins_cost(300); 11265 format %{ "j$cop,s $labl" %} 11266 size(2); 11267 ins_encode %{ 11268 Label* L = $labl$$label; 11269 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11270 %} 11271 ins_pipe(pipe_jcc); 11272 ins_short_branch(1); 11273 %} 11274 11275 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11276 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11277 match(CountedLoopEnd cop cr); 11278 effect(USE labl); 11279 11280 ins_cost(300); 11281 format %{ "j$cop,s $labl\t# loop end" %} 11282 size(2); 11283 ins_encode %{ 11284 Label* L = $labl$$label; 11285 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11286 %} 11287 ins_pipe(pipe_jcc); 11288 ins_short_branch(1); 11289 %} 11290 11291 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11292 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11293 match(CountedLoopEnd cop cmp); 11294 effect(USE labl); 11295 11296 ins_cost(300); 11297 format %{ "j$cop,us $labl\t# loop end" %} 11298 size(2); 11299 ins_encode %{ 11300 Label* L = $labl$$label; 11301 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11302 %} 11303 ins_pipe(pipe_jcc); 11304 ins_short_branch(1); 11305 %} 11306 11307 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11308 match(CountedLoopEnd cop cmp); 11309 effect(USE labl); 11310 11311 ins_cost(300); 11312 format %{ "j$cop,us $labl\t# loop end" %} 11313 size(2); 11314 ins_encode %{ 11315 Label* L = $labl$$label; 11316 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11317 %} 11318 ins_pipe(pipe_jcc); 11319 ins_short_branch(1); 11320 %} 11321 11322 // Jump Direct Conditional - using unsigned comparison 11323 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11324 match(If cop cmp); 11325 effect(USE labl); 11326 11327 ins_cost(300); 11328 format %{ "j$cop,us $labl" %} 11329 size(2); 11330 ins_encode %{ 11331 Label* L = $labl$$label; 11332 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11333 %} 11334 ins_pipe(pipe_jcc); 11335 ins_short_branch(1); 11336 %} 11337 11338 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11339 match(If cop cmp); 11340 effect(USE labl); 11341 11342 ins_cost(300); 11343 format %{ "j$cop,us $labl" %} 11344 size(2); 11345 ins_encode %{ 11346 Label* L = $labl$$label; 11347 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11348 %} 11349 ins_pipe(pipe_jcc); 11350 ins_short_branch(1); 11351 %} 11352 11353 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11354 match(If cop cmp); 11355 effect(USE labl); 11356 11357 ins_cost(300); 11358 format %{ $$template 11359 if ($cop$$cmpcode == Assembler::notEqual) { 11360 $$emit$$"jp,u,s $labl\n\t" 11361 $$emit$$"j$cop,u,s $labl" 11362 } else { 11363 $$emit$$"jp,u,s done\n\t" 11364 $$emit$$"j$cop,u,s $labl\n\t" 11365 $$emit$$"done:" 11366 } 11367 %} 11368 size(4); 11369 ins_encode %{ 11370 Label* l = $labl$$label; 11371 if ($cop$$cmpcode == Assembler::notEqual) { 11372 __ jccb(Assembler::parity, *l); 11373 __ jccb(Assembler::notEqual, *l); 11374 } else if ($cop$$cmpcode == Assembler::equal) { 11375 Label done; 11376 __ jccb(Assembler::parity, done); 11377 __ jccb(Assembler::equal, *l); 11378 __ bind(done); 11379 } else { 11380 ShouldNotReachHere(); 11381 } 11382 %} 11383 ins_pipe(pipe_jcc); 11384 ins_short_branch(1); 11385 %} 11386 11387 // ============================================================================ 11388 // inlined locking and unlocking 11389 11390 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 11391 match(Set cr (FastLock object box)); 11392 effect(TEMP tmp, TEMP scr, USE_KILL box); 11393 ins_cost(300); 11394 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11395 ins_encode %{ 11396 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register, _counters); 11397 %} 11398 ins_pipe(pipe_slow); 11399 %} 11400 11401 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 11402 match(Set cr (FastUnlock object box)); 11403 effect(TEMP tmp, USE_KILL box); 11404 ins_cost(300); 11405 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11406 ins_encode %{ 11407 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 11408 %} 11409 ins_pipe(pipe_slow); 11410 %} 11411 11412 11413 // ============================================================================ 11414 // Safepoint Instructions 11415 instruct safePoint_poll(rFlagsReg cr) 11416 %{ 11417 predicate(!Assembler::is_polling_page_far()); 11418 match(SafePoint); 11419 effect(KILL cr); 11420 11421 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11422 "# Safepoint: poll for GC" %} 11423 ins_cost(125); 11424 ins_encode %{ 11425 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11426 __ testl(rax, addr); 11427 %} 11428 ins_pipe(ialu_reg_mem); 11429 %} 11430 11431 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11432 %{ 11433 predicate(Assembler::is_polling_page_far()); 11434 match(SafePoint poll); 11435 effect(KILL cr, USE poll); 11436 11437 format %{ "testl rax, [$poll]\t" 11438 "# Safepoint: poll for GC" %} 11439 ins_cost(125); 11440 ins_encode %{ 11441 __ relocate(relocInfo::poll_type); 11442 __ testl(rax, Address($poll$$Register, 0)); 11443 %} 11444 ins_pipe(ialu_reg_mem); 11445 %} 11446 11447 // ============================================================================ 11448 // Procedure Call/Return Instructions 11449 // Call Java Static Instruction 11450 // Note: If this code changes, the corresponding ret_addr_offset() and 11451 // compute_padding() functions will have to be adjusted. 11452 instruct CallStaticJavaDirect(method meth) %{ 11453 match(CallStaticJava); 11454 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11455 effect(USE meth); 11456 11457 ins_cost(300); 11458 format %{ "call,static " %} 11459 opcode(0xE8); /* E8 cd */ 11460 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 11461 ins_pipe(pipe_slow); 11462 ins_alignment(4); 11463 %} 11464 11465 // Call Java Static Instruction (method handle version) 11466 // Note: If this code changes, the corresponding ret_addr_offset() and 11467 // compute_padding() functions will have to be adjusted. 11468 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 11469 match(CallStaticJava); 11470 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11471 effect(USE meth); 11472 // RBP is saved by all callees (for interpreter stack correction). 11473 // We use it here for a similar purpose, in {preserve,restore}_SP. 11474 11475 ins_cost(300); 11476 format %{ "call,static/MethodHandle " %} 11477 opcode(0xE8); /* E8 cd */ 11478 ins_encode(clear_avx, preserve_SP, 11479 Java_Static_Call(meth), 11480 restore_SP, 11481 call_epilog); 11482 ins_pipe(pipe_slow); 11483 ins_alignment(4); 11484 %} 11485 11486 // Call Java Dynamic Instruction 11487 // Note: If this code changes, the corresponding ret_addr_offset() and 11488 // compute_padding() functions will have to be adjusted. 11489 instruct CallDynamicJavaDirect(method meth) 11490 %{ 11491 match(CallDynamicJava); 11492 effect(USE meth); 11493 11494 ins_cost(300); 11495 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11496 "call,dynamic " %} 11497 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 11498 ins_pipe(pipe_slow); 11499 ins_alignment(4); 11500 %} 11501 11502 // Call Runtime Instruction 11503 instruct CallRuntimeDirect(method meth) 11504 %{ 11505 match(CallRuntime); 11506 effect(USE meth); 11507 11508 ins_cost(300); 11509 format %{ "call,runtime " %} 11510 ins_encode(clear_avx, Java_To_Runtime(meth)); 11511 ins_pipe(pipe_slow); 11512 %} 11513 11514 // Call runtime without safepoint 11515 instruct CallLeafDirect(method meth) 11516 %{ 11517 match(CallLeaf); 11518 effect(USE meth); 11519 11520 ins_cost(300); 11521 format %{ "call_leaf,runtime " %} 11522 ins_encode(clear_avx, Java_To_Runtime(meth)); 11523 ins_pipe(pipe_slow); 11524 %} 11525 11526 // Call runtime without safepoint 11527 instruct CallLeafNoFPDirect(method meth) 11528 %{ 11529 match(CallLeafNoFP); 11530 effect(USE meth); 11531 11532 ins_cost(300); 11533 format %{ "call_leaf_nofp,runtime " %} 11534 ins_encode(Java_To_Runtime(meth)); 11535 ins_pipe(pipe_slow); 11536 %} 11537 11538 // Return Instruction 11539 // Remove the return address & jump to it. 11540 // Notice: We always emit a nop after a ret to make sure there is room 11541 // for safepoint patching 11542 instruct Ret() 11543 %{ 11544 match(Return); 11545 11546 format %{ "ret" %} 11547 opcode(0xC3); 11548 ins_encode(OpcP); 11549 ins_pipe(pipe_jmp); 11550 %} 11551 11552 // Tail Call; Jump from runtime stub to Java code. 11553 // Also known as an 'interprocedural jump'. 11554 // Target of jump will eventually return to caller. 11555 // TailJump below removes the return address. 11556 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11557 %{ 11558 match(TailCall jump_target method_oop); 11559 11560 ins_cost(300); 11561 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11562 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11563 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11564 ins_pipe(pipe_jmp); 11565 %} 11566 11567 // Tail Jump; remove the return address; jump to target. 11568 // TailCall above leaves the return address around. 11569 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11570 %{ 11571 match(TailJump jump_target ex_oop); 11572 11573 ins_cost(300); 11574 format %{ "popq rdx\t# pop return address\n\t" 11575 "jmp $jump_target" %} 11576 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11577 ins_encode(Opcode(0x5a), // popq rdx 11578 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11579 ins_pipe(pipe_jmp); 11580 %} 11581 11582 // Create exception oop: created by stack-crawling runtime code. 11583 // Created exception is now available to this handler, and is setup 11584 // just prior to jumping to this handler. No code emitted. 11585 instruct CreateException(rax_RegP ex_oop) 11586 %{ 11587 match(Set ex_oop (CreateEx)); 11588 11589 size(0); 11590 // use the following format syntax 11591 format %{ "# exception oop is in rax; no code emitted" %} 11592 ins_encode(); 11593 ins_pipe(empty); 11594 %} 11595 11596 // Rethrow exception: 11597 // The exception oop will come in the first argument position. 11598 // Then JUMP (not call) to the rethrow stub code. 11599 instruct RethrowException() 11600 %{ 11601 match(Rethrow); 11602 11603 // use the following format syntax 11604 format %{ "jmp rethrow_stub" %} 11605 ins_encode(enc_rethrow); 11606 ins_pipe(pipe_jmp); 11607 %} 11608 11609 11610 // ============================================================================ 11611 // This name is KNOWN by the ADLC and cannot be changed. 11612 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11613 // for this guy. 11614 instruct tlsLoadP(r15_RegP dst) %{ 11615 match(Set dst (ThreadLocal)); 11616 effect(DEF dst); 11617 11618 size(0); 11619 format %{ "# TLS is in R15" %} 11620 ins_encode( /*empty encoding*/ ); 11621 ins_pipe(ialu_reg_reg); 11622 %} 11623 11624 11625 //----------PEEPHOLE RULES----------------------------------------------------- 11626 // These must follow all instruction definitions as they use the names 11627 // defined in the instructions definitions. 11628 // 11629 // peepmatch ( root_instr_name [preceding_instruction]* ); 11630 // 11631 // peepconstraint %{ 11632 // (instruction_number.operand_name relational_op instruction_number.operand_name 11633 // [, ...] ); 11634 // // instruction numbers are zero-based using left to right order in peepmatch 11635 // 11636 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11637 // // provide an instruction_number.operand_name for each operand that appears 11638 // // in the replacement instruction's match rule 11639 // 11640 // ---------VM FLAGS--------------------------------------------------------- 11641 // 11642 // All peephole optimizations can be turned off using -XX:-OptoPeephole 11643 // 11644 // Each peephole rule is given an identifying number starting with zero and 11645 // increasing by one in the order seen by the parser. An individual peephole 11646 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11647 // on the command-line. 11648 // 11649 // ---------CURRENT LIMITATIONS---------------------------------------------- 11650 // 11651 // Only match adjacent instructions in same basic block 11652 // Only equality constraints 11653 // Only constraints between operands, not (0.dest_reg == RAX_enc) 11654 // Only one replacement instruction 11655 // 11656 // ---------EXAMPLE---------------------------------------------------------- 11657 // 11658 // // pertinent parts of existing instructions in architecture description 11659 // instruct movI(rRegI dst, rRegI src) 11660 // %{ 11661 // match(Set dst (CopyI src)); 11662 // %} 11663 // 11664 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11665 // %{ 11666 // match(Set dst (AddI dst src)); 11667 // effect(KILL cr); 11668 // %} 11669 // 11670 // // Change (inc mov) to lea 11671 // peephole %{ 11672 // // increment preceeded by register-register move 11673 // peepmatch ( incI_rReg movI ); 11674 // // require that the destination register of the increment 11675 // // match the destination register of the move 11676 // peepconstraint ( 0.dst == 1.dst ); 11677 // // construct a replacement instruction that sets 11678 // // the destination to ( move's source register + one ) 11679 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11680 // %} 11681 // 11682 11683 // Implementation no longer uses movX instructions since 11684 // machine-independent system no longer uses CopyX nodes. 11685 // 11686 // peephole 11687 // %{ 11688 // peepmatch (incI_rReg movI); 11689 // peepconstraint (0.dst == 1.dst); 11690 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11691 // %} 11692 11693 // peephole 11694 // %{ 11695 // peepmatch (decI_rReg movI); 11696 // peepconstraint (0.dst == 1.dst); 11697 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11698 // %} 11699 11700 // peephole 11701 // %{ 11702 // peepmatch (addI_rReg_imm movI); 11703 // peepconstraint (0.dst == 1.dst); 11704 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11705 // %} 11706 11707 // peephole 11708 // %{ 11709 // peepmatch (incL_rReg movL); 11710 // peepconstraint (0.dst == 1.dst); 11711 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11712 // %} 11713 11714 // peephole 11715 // %{ 11716 // peepmatch (decL_rReg movL); 11717 // peepconstraint (0.dst == 1.dst); 11718 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11719 // %} 11720 11721 // peephole 11722 // %{ 11723 // peepmatch (addL_rReg_imm movL); 11724 // peepconstraint (0.dst == 1.dst); 11725 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11726 // %} 11727 11728 // peephole 11729 // %{ 11730 // peepmatch (addP_rReg_imm movP); 11731 // peepconstraint (0.dst == 1.dst); 11732 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11733 // %} 11734 11735 // // Change load of spilled value to only a spill 11736 // instruct storeI(memory mem, rRegI src) 11737 // %{ 11738 // match(Set mem (StoreI mem src)); 11739 // %} 11740 // 11741 // instruct loadI(rRegI dst, memory mem) 11742 // %{ 11743 // match(Set dst (LoadI mem)); 11744 // %} 11745 // 11746 11747 peephole 11748 %{ 11749 peepmatch (loadI storeI); 11750 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11751 peepreplace (storeI(1.mem 1.mem 1.src)); 11752 %} 11753 11754 peephole 11755 %{ 11756 peepmatch (loadL storeL); 11757 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11758 peepreplace (storeL(1.mem 1.mem 1.src)); 11759 %} 11760 11761 //----------SMARTSPILL RULES--------------------------------------------------- 11762 // These must follow all instruction definitions as they use the names 11763 // defined in the instructions definitions.