1 // 2 // Copyright (c) 2003, 2020, 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 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer/long registers 173 reg_class all_reg(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all int registers 191 reg_class all_int_reg(RAX 192 RDX, 193 RBP, 194 RDI, 195 RSI, 196 RCX, 197 RBX, 198 R8, 199 R9, 200 R10, 201 R11, 202 R12, 203 R13, 204 R14); 205 206 // Class for all pointer registers 207 reg_class any_reg %{ 208 return _ANY_REG_mask; 209 %} 210 211 // Class for all pointer registers (excluding RSP) 212 reg_class ptr_reg %{ 213 return _PTR_REG_mask; 214 %} 215 216 // Class for all pointer registers (excluding RSP and RBP) 217 reg_class ptr_reg_no_rbp %{ 218 return _PTR_REG_NO_RBP_mask; 219 %} 220 221 // Class for all pointer registers (excluding RAX and RSP) 222 reg_class ptr_no_rax_reg %{ 223 return _PTR_NO_RAX_REG_mask; 224 %} 225 226 // Class for all pointer registers (excluding RAX, RBX, and RSP) 227 reg_class ptr_no_rax_rbx_reg %{ 228 return _PTR_NO_RAX_RBX_REG_mask; 229 %} 230 231 // Class for all long registers (excluding RSP) 232 reg_class long_reg %{ 233 return _LONG_REG_mask; 234 %} 235 236 // Class for all long registers (excluding RAX, RDX and RSP) 237 reg_class long_no_rax_rdx_reg %{ 238 return _LONG_NO_RAX_RDX_REG_mask; 239 %} 240 241 // Class for all long registers (excluding RCX and RSP) 242 reg_class long_no_rcx_reg %{ 243 return _LONG_NO_RCX_REG_mask; 244 %} 245 246 // Class for all int registers (excluding RSP) 247 reg_class int_reg %{ 248 return _INT_REG_mask; 249 %} 250 251 // Class for all int registers (excluding RAX, RDX, and RSP) 252 reg_class int_no_rax_rdx_reg %{ 253 return _INT_NO_RAX_RDX_REG_mask; 254 %} 255 256 // Class for all int registers (excluding RCX and RSP) 257 reg_class int_no_rcx_reg %{ 258 return _INT_NO_RCX_REG_mask; 259 %} 260 261 // Singleton class for RAX pointer register 262 reg_class ptr_rax_reg(RAX, RAX_H); 263 264 // Singleton class for RBX pointer register 265 reg_class ptr_rbx_reg(RBX, RBX_H); 266 267 // Singleton class for RSI pointer register 268 reg_class ptr_rsi_reg(RSI, RSI_H); 269 270 // Singleton class for RBP pointer register 271 reg_class ptr_rbp_reg(RBP, RBP_H); 272 273 // Singleton class for RDI pointer register 274 reg_class ptr_rdi_reg(RDI, RDI_H); 275 276 // Singleton class for stack pointer 277 reg_class ptr_rsp_reg(RSP, RSP_H); 278 279 // Singleton class for TLS pointer 280 reg_class ptr_r15_reg(R15, R15_H); 281 282 // Singleton class for RAX long register 283 reg_class long_rax_reg(RAX, RAX_H); 284 285 // Singleton class for RCX long register 286 reg_class long_rcx_reg(RCX, RCX_H); 287 288 // Singleton class for RDX long register 289 reg_class long_rdx_reg(RDX, RDX_H); 290 291 // Singleton class for RAX int register 292 reg_class int_rax_reg(RAX); 293 294 // Singleton class for RBX int register 295 reg_class int_rbx_reg(RBX); 296 297 // Singleton class for RCX int register 298 reg_class int_rcx_reg(RCX); 299 300 // Singleton class for RCX int register 301 reg_class int_rdx_reg(RDX); 302 303 // Singleton class for RCX int register 304 reg_class int_rdi_reg(RDI); 305 306 // Singleton class for instruction pointer 307 // reg_class ip_reg(RIP); 308 309 %} 310 311 //----------SOURCE BLOCK------------------------------------------------------- 312 // This is a block of C++ code which provides values, functions, and 313 // definitions necessary in the rest of the architecture description 314 source_hpp %{ 315 316 extern RegMask _ANY_REG_mask; 317 extern RegMask _PTR_REG_mask; 318 extern RegMask _PTR_REG_NO_RBP_mask; 319 extern RegMask _PTR_NO_RAX_REG_mask; 320 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 321 extern RegMask _LONG_REG_mask; 322 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 323 extern RegMask _LONG_NO_RCX_REG_mask; 324 extern RegMask _INT_REG_mask; 325 extern RegMask _INT_NO_RAX_RDX_REG_mask; 326 extern RegMask _INT_NO_RCX_REG_mask; 327 328 extern RegMask _STACK_OR_PTR_REG_mask; 329 extern RegMask _STACK_OR_LONG_REG_mask; 330 extern RegMask _STACK_OR_INT_REG_mask; 331 332 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 333 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 334 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 335 336 %} 337 338 source %{ 339 #define RELOC_IMM64 Assembler::imm_operand 340 #define RELOC_DISP32 Assembler::disp32_operand 341 342 #define __ _masm. 343 344 RegMask _ANY_REG_mask; 345 RegMask _PTR_REG_mask; 346 RegMask _PTR_REG_NO_RBP_mask; 347 RegMask _PTR_NO_RAX_REG_mask; 348 RegMask _PTR_NO_RAX_RBX_REG_mask; 349 RegMask _LONG_REG_mask; 350 RegMask _LONG_NO_RAX_RDX_REG_mask; 351 RegMask _LONG_NO_RCX_REG_mask; 352 RegMask _INT_REG_mask; 353 RegMask _INT_NO_RAX_RDX_REG_mask; 354 RegMask _INT_NO_RCX_REG_mask; 355 RegMask _STACK_OR_PTR_REG_mask; 356 RegMask _STACK_OR_LONG_REG_mask; 357 RegMask _STACK_OR_INT_REG_mask; 358 359 static bool need_r12_heapbase() { 360 return UseCompressedOops; 361 } 362 363 void reg_mask_init() { 364 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 365 // We derive a number of subsets from it. 366 _ANY_REG_mask = _ALL_REG_mask; 367 368 if (PreserveFramePointer) { 369 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 370 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 371 } 372 if (need_r12_heapbase()) { 373 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 374 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 375 } 376 377 _PTR_REG_mask = _ANY_REG_mask; 378 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 379 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 380 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 381 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 382 383 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 384 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 385 386 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 387 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 388 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 389 390 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 391 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 392 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 393 394 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 395 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 396 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 397 398 _LONG_REG_mask = _PTR_REG_mask; 399 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 400 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 401 402 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 403 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 404 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 405 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 406 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 407 408 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 409 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 410 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 411 412 _INT_REG_mask = _ALL_INT_REG_mask; 413 if (PreserveFramePointer) { 414 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 415 } 416 if (need_r12_heapbase()) { 417 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 418 } 419 420 _STACK_OR_INT_REG_mask = _INT_REG_mask; 421 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 422 423 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 424 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 425 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 426 427 _INT_NO_RCX_REG_mask = _INT_REG_mask; 428 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 429 } 430 431 static bool generate_vzeroupper(Compile* C) { 432 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 433 } 434 435 static int clear_avx_size() { 436 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 437 } 438 439 // !!!!! Special hack to get all types of calls to specify the byte offset 440 // from the start of the call to the point where the return address 441 // will point. 442 int MachCallStaticJavaNode::ret_addr_offset() 443 { 444 int offset = 5; // 5 bytes from start of call to where return address points 445 offset += clear_avx_size(); 446 return offset; 447 } 448 449 int MachCallDynamicJavaNode::ret_addr_offset() 450 { 451 int offset = 15; // 15 bytes from start of call to where return address points 452 offset += clear_avx_size(); 453 return offset; 454 } 455 456 int MachCallRuntimeNode::ret_addr_offset() { 457 int offset = 13; // movq r10,#addr; callq (r10) 458 offset += clear_avx_size(); 459 return offset; 460 } 461 462 // 463 // Compute padding required for nodes which need alignment 464 // 465 466 // The address of the call instruction needs to be 4-byte aligned to 467 // ensure that it does not span a cache line so that it can be patched. 468 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 469 { 470 current_offset += clear_avx_size(); // skip vzeroupper 471 current_offset += 1; // skip call opcode byte 472 return align_up(current_offset, alignment_required()) - current_offset; 473 } 474 475 // The address of the call instruction needs to be 4-byte aligned to 476 // ensure that it does not span a cache line so that it can be patched. 477 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 478 { 479 current_offset += clear_avx_size(); // skip vzeroupper 480 current_offset += 11; // skip movq instruction + call opcode byte 481 return align_up(current_offset, alignment_required()) - current_offset; 482 } 483 484 // EMIT_RM() 485 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 486 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 487 cbuf.insts()->emit_int8(c); 488 } 489 490 // EMIT_CC() 491 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 492 unsigned char c = (unsigned char) (f1 | f2); 493 cbuf.insts()->emit_int8(c); 494 } 495 496 // EMIT_OPCODE() 497 void emit_opcode(CodeBuffer &cbuf, int code) { 498 cbuf.insts()->emit_int8((unsigned char) code); 499 } 500 501 // EMIT_OPCODE() w/ relocation information 502 void emit_opcode(CodeBuffer &cbuf, 503 int code, relocInfo::relocType reloc, int offset, int format) 504 { 505 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 506 emit_opcode(cbuf, code); 507 } 508 509 // EMIT_D8() 510 void emit_d8(CodeBuffer &cbuf, int d8) { 511 cbuf.insts()->emit_int8((unsigned char) d8); 512 } 513 514 // EMIT_D16() 515 void emit_d16(CodeBuffer &cbuf, int d16) { 516 cbuf.insts()->emit_int16(d16); 517 } 518 519 // EMIT_D32() 520 void emit_d32(CodeBuffer &cbuf, int d32) { 521 cbuf.insts()->emit_int32(d32); 522 } 523 524 // EMIT_D64() 525 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 526 cbuf.insts()->emit_int64(d64); 527 } 528 529 // emit 32 bit value and construct relocation entry from relocInfo::relocType 530 void emit_d32_reloc(CodeBuffer& cbuf, 531 int d32, 532 relocInfo::relocType reloc, 533 int format) 534 { 535 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 536 cbuf.relocate(cbuf.insts_mark(), reloc, format); 537 cbuf.insts()->emit_int32(d32); 538 } 539 540 // emit 32 bit value and construct relocation entry from RelocationHolder 541 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 542 #ifdef ASSERT 543 if (rspec.reloc()->type() == relocInfo::oop_type && 544 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 545 assert(Universe::heap()->is_in((address)(intptr_t)d32), "should be real oop"); 546 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)), "cannot embed broken oops in code"); 547 } 548 #endif 549 cbuf.relocate(cbuf.insts_mark(), rspec, format); 550 cbuf.insts()->emit_int32(d32); 551 } 552 553 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 554 address next_ip = cbuf.insts_end() + 4; 555 emit_d32_reloc(cbuf, (int) (addr - next_ip), 556 external_word_Relocation::spec(addr), 557 RELOC_DISP32); 558 } 559 560 561 // emit 64 bit value and construct relocation entry from relocInfo::relocType 562 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 563 cbuf.relocate(cbuf.insts_mark(), reloc, format); 564 cbuf.insts()->emit_int64(d64); 565 } 566 567 // emit 64 bit value and construct relocation entry from RelocationHolder 568 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 569 #ifdef ASSERT 570 if (rspec.reloc()->type() == relocInfo::oop_type && 571 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 572 assert(Universe::heap()->is_in((address)d64), "should be real oop"); 573 assert(oopDesc::is_oop(cast_to_oop(d64)), "cannot embed broken oops in code"); 574 } 575 #endif 576 cbuf.relocate(cbuf.insts_mark(), rspec, format); 577 cbuf.insts()->emit_int64(d64); 578 } 579 580 // Access stack slot for load or store 581 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 582 { 583 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 584 if (-0x80 <= disp && disp < 0x80) { 585 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 586 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 587 emit_d8(cbuf, disp); // Displacement // R/M byte 588 } else { 589 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 590 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 591 emit_d32(cbuf, disp); // Displacement // R/M byte 592 } 593 } 594 595 // rRegI ereg, memory mem) %{ // emit_reg_mem 596 void encode_RegMem(CodeBuffer &cbuf, 597 int reg, 598 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 599 { 600 assert(disp_reloc == relocInfo::none, "cannot have disp"); 601 int regenc = reg & 7; 602 int baseenc = base & 7; 603 int indexenc = index & 7; 604 605 // There is no index & no scale, use form without SIB byte 606 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 607 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 608 if (disp == 0 && base != RBP_enc && base != R13_enc) { 609 emit_rm(cbuf, 0x0, regenc, baseenc); // * 610 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 611 // If 8-bit displacement, mode 0x1 612 emit_rm(cbuf, 0x1, regenc, baseenc); // * 613 emit_d8(cbuf, disp); 614 } else { 615 // If 32-bit displacement 616 if (base == -1) { // Special flag for absolute address 617 emit_rm(cbuf, 0x0, regenc, 0x5); // * 618 if (disp_reloc != relocInfo::none) { 619 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 620 } else { 621 emit_d32(cbuf, disp); 622 } 623 } else { 624 // Normal base + offset 625 emit_rm(cbuf, 0x2, regenc, baseenc); // * 626 if (disp_reloc != relocInfo::none) { 627 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 628 } else { 629 emit_d32(cbuf, disp); 630 } 631 } 632 } 633 } else { 634 // Else, encode with the SIB byte 635 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 636 if (disp == 0 && base != RBP_enc && base != R13_enc) { 637 // If no displacement 638 emit_rm(cbuf, 0x0, regenc, 0x4); // * 639 emit_rm(cbuf, scale, indexenc, baseenc); 640 } else { 641 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 642 // If 8-bit displacement, mode 0x1 643 emit_rm(cbuf, 0x1, regenc, 0x4); // * 644 emit_rm(cbuf, scale, indexenc, baseenc); 645 emit_d8(cbuf, disp); 646 } else { 647 // If 32-bit displacement 648 if (base == 0x04 ) { 649 emit_rm(cbuf, 0x2, regenc, 0x4); 650 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 651 } else { 652 emit_rm(cbuf, 0x2, regenc, 0x4); 653 emit_rm(cbuf, scale, indexenc, baseenc); // * 654 } 655 if (disp_reloc != relocInfo::none) { 656 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 657 } else { 658 emit_d32(cbuf, disp); 659 } 660 } 661 } 662 } 663 } 664 665 // This could be in MacroAssembler but it's fairly C2 specific 666 void emit_cmpfp_fixup(MacroAssembler& _masm) { 667 Label exit; 668 __ jccb(Assembler::noParity, exit); 669 __ pushf(); 670 // 671 // comiss/ucomiss instructions set ZF,PF,CF flags and 672 // zero OF,AF,SF for NaN values. 673 // Fixup flags by zeroing ZF,PF so that compare of NaN 674 // values returns 'less than' result (CF is set). 675 // Leave the rest of flags unchanged. 676 // 677 // 7 6 5 4 3 2 1 0 678 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 679 // 0 0 1 0 1 0 1 1 (0x2B) 680 // 681 __ andq(Address(rsp, 0), 0xffffff2b); 682 __ popf(); 683 __ bind(exit); 684 } 685 686 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 687 Label done; 688 __ movl(dst, -1); 689 __ jcc(Assembler::parity, done); 690 __ jcc(Assembler::below, done); 691 __ setb(Assembler::notEqual, dst); 692 __ movzbl(dst, dst); 693 __ bind(done); 694 } 695 696 // Math.min() # Math.max() 697 // -------------------------- 698 // ucomis[s/d] # 699 // ja -> b # a 700 // jp -> NaN # NaN 701 // jb -> a # b 702 // je # 703 // |-jz -> a | b # a & b 704 // | -> a # 705 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst, 706 XMMRegister a, XMMRegister b, 707 XMMRegister xmmt, Register rt, 708 bool min, bool single) { 709 710 Label nan, zero, below, above, done; 711 712 if (single) 713 __ ucomiss(a, b); 714 else 715 __ ucomisd(a, b); 716 717 if (dst->encoding() != (min ? b : a)->encoding()) 718 __ jccb(Assembler::above, above); // CF=0 & ZF=0 719 else 720 __ jccb(Assembler::above, done); 721 722 __ jccb(Assembler::parity, nan); // PF=1 723 __ jccb(Assembler::below, below); // CF=1 724 725 // equal 726 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 727 if (single) { 728 __ ucomiss(a, xmmt); 729 __ jccb(Assembler::equal, zero); 730 731 __ movflt(dst, a); 732 __ jmp(done); 733 } 734 else { 735 __ ucomisd(a, xmmt); 736 __ jccb(Assembler::equal, zero); 737 738 __ movdbl(dst, a); 739 __ jmp(done); 740 } 741 742 __ bind(zero); 743 if (min) 744 __ vpor(dst, a, b, Assembler::AVX_128bit); 745 else 746 __ vpand(dst, a, b, Assembler::AVX_128bit); 747 748 __ jmp(done); 749 750 __ bind(above); 751 if (single) 752 __ movflt(dst, min ? b : a); 753 else 754 __ movdbl(dst, min ? b : a); 755 756 __ jmp(done); 757 758 __ bind(nan); 759 if (single) { 760 __ movl(rt, 0x7fc00000); // Float.NaN 761 __ movdl(dst, rt); 762 } 763 else { 764 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 765 __ movdq(dst, rt); 766 } 767 __ jmp(done); 768 769 __ bind(below); 770 if (single) 771 __ movflt(dst, min ? a : b); 772 else 773 __ movdbl(dst, min ? a : b); 774 775 __ bind(done); 776 } 777 778 //============================================================================= 779 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 780 781 int ConstantTable::calculate_table_base_offset() const { 782 return 0; // absolute addressing, no offset 783 } 784 785 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 786 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 787 ShouldNotReachHere(); 788 } 789 790 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 791 // Empty encoding 792 } 793 794 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 795 return 0; 796 } 797 798 #ifndef PRODUCT 799 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 800 st->print("# MachConstantBaseNode (empty encoding)"); 801 } 802 #endif 803 804 805 //============================================================================= 806 #ifndef PRODUCT 807 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 808 Compile* C = ra_->C; 809 810 int framesize = C->output()->frame_size_in_bytes(); 811 int bangsize = C->output()->bang_size_in_bytes(); 812 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 813 // Remove wordSize for return addr which is already pushed. 814 framesize -= wordSize; 815 816 if (C->output()->need_stack_bang(bangsize)) { 817 framesize -= wordSize; 818 st->print("# stack bang (%d bytes)", bangsize); 819 st->print("\n\t"); 820 st->print("pushq rbp\t# Save rbp"); 821 if (PreserveFramePointer) { 822 st->print("\n\t"); 823 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 824 } 825 if (framesize) { 826 st->print("\n\t"); 827 st->print("subq rsp, #%d\t# Create frame",framesize); 828 } 829 } else { 830 st->print("subq rsp, #%d\t# Create frame",framesize); 831 st->print("\n\t"); 832 framesize -= wordSize; 833 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 834 if (PreserveFramePointer) { 835 st->print("\n\t"); 836 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 837 if (framesize > 0) { 838 st->print("\n\t"); 839 st->print("addq rbp, #%d", framesize); 840 } 841 } 842 } 843 844 if (VerifyStackAtCalls) { 845 st->print("\n\t"); 846 framesize -= wordSize; 847 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 848 #ifdef ASSERT 849 st->print("\n\t"); 850 st->print("# stack alignment check"); 851 #endif 852 } 853 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 854 st->print("\n\t"); 855 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t"); 856 st->print("\n\t"); 857 st->print("je fast_entry\t"); 858 st->print("\n\t"); 859 st->print("call #nmethod_entry_barrier_stub\t"); 860 st->print("\n\tfast_entry:"); 861 } 862 st->cr(); 863 } 864 #endif 865 866 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 867 Compile* C = ra_->C; 868 MacroAssembler _masm(&cbuf); 869 870 int framesize = C->output()->frame_size_in_bytes(); 871 int bangsize = C->output()->bang_size_in_bytes(); 872 873 if (C->clinit_barrier_on_entry()) { 874 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 875 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 876 877 Label L_skip_barrier; 878 Register klass = rscratch1; 879 880 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 881 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 882 883 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 884 885 __ bind(L_skip_barrier); 886 } 887 888 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != NULL); 889 890 C->output()->set_frame_complete(cbuf.insts_size()); 891 892 if (C->has_mach_constant_base_node()) { 893 // NOTE: We set the table base offset here because users might be 894 // emitted before MachConstantBaseNode. 895 ConstantTable& constant_table = C->output()->constant_table(); 896 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 897 } 898 } 899 900 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 901 { 902 return MachNode::size(ra_); // too many variables; just compute it 903 // the hard way 904 } 905 906 int MachPrologNode::reloc() const 907 { 908 return 0; // a large enough number 909 } 910 911 //============================================================================= 912 #ifndef PRODUCT 913 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 914 { 915 Compile* C = ra_->C; 916 if (generate_vzeroupper(C)) { 917 st->print("vzeroupper"); 918 st->cr(); st->print("\t"); 919 } 920 921 int framesize = C->output()->frame_size_in_bytes(); 922 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 923 // Remove word for return adr already pushed 924 // and RBP 925 framesize -= 2*wordSize; 926 927 if (framesize) { 928 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 929 st->print("\t"); 930 } 931 932 st->print_cr("popq rbp"); 933 if (do_polling() && C->is_method_compilation()) { 934 st->print("\t"); 935 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 936 "testl rax, [rscratch1]\t" 937 "# Safepoint: poll for GC"); 938 } 939 } 940 #endif 941 942 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 943 { 944 Compile* C = ra_->C; 945 MacroAssembler _masm(&cbuf); 946 947 if (generate_vzeroupper(C)) { 948 // Clear upper bits of YMM registers when current compiled code uses 949 // wide vectors to avoid AVX <-> SSE transition penalty during call. 950 __ vzeroupper(); 951 } 952 953 int framesize = C->output()->frame_size_in_bytes(); 954 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 955 // Remove word for return adr already pushed 956 // and RBP 957 framesize -= 2*wordSize; 958 959 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 960 961 if (framesize) { 962 emit_opcode(cbuf, Assembler::REX_W); 963 if (framesize < 0x80) { 964 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 965 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 966 emit_d8(cbuf, framesize); 967 } else { 968 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 969 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 970 emit_d32(cbuf, framesize); 971 } 972 } 973 974 // popq rbp 975 emit_opcode(cbuf, 0x58 | RBP_enc); 976 977 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 978 __ reserved_stack_check(); 979 } 980 981 if (do_polling() && C->is_method_compilation()) { 982 MacroAssembler _masm(&cbuf); 983 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 984 __ relocate(relocInfo::poll_return_type); 985 __ testl(rax, Address(rscratch1, 0)); 986 } 987 } 988 989 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 990 { 991 return MachNode::size(ra_); // too many variables; just compute it 992 // the hard way 993 } 994 995 int MachEpilogNode::reloc() const 996 { 997 return 2; // a large enough number 998 } 999 1000 const Pipeline* MachEpilogNode::pipeline() const 1001 { 1002 return MachNode::pipeline_class(); 1003 } 1004 1005 //============================================================================= 1006 1007 enum RC { 1008 rc_bad, 1009 rc_int, 1010 rc_float, 1011 rc_stack 1012 }; 1013 1014 static enum RC rc_class(OptoReg::Name reg) 1015 { 1016 if( !OptoReg::is_valid(reg) ) return rc_bad; 1017 1018 if (OptoReg::is_stack(reg)) return rc_stack; 1019 1020 VMReg r = OptoReg::as_VMReg(reg); 1021 1022 if (r->is_Register()) return rc_int; 1023 1024 assert(r->is_XMMRegister(), "must be"); 1025 return rc_float; 1026 } 1027 1028 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1029 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1030 int src_hi, int dst_hi, uint ireg, outputStream* st); 1031 1032 int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1033 int stack_offset, int reg, uint ireg, outputStream* st); 1034 1035 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1036 int dst_offset, uint ireg, outputStream* st) { 1037 if (cbuf) { 1038 MacroAssembler _masm(cbuf); 1039 switch (ireg) { 1040 case Op_VecS: 1041 __ movq(Address(rsp, -8), rax); 1042 __ movl(rax, Address(rsp, src_offset)); 1043 __ movl(Address(rsp, dst_offset), rax); 1044 __ movq(rax, Address(rsp, -8)); 1045 break; 1046 case Op_VecD: 1047 __ pushq(Address(rsp, src_offset)); 1048 __ popq (Address(rsp, dst_offset)); 1049 break; 1050 case Op_VecX: 1051 __ pushq(Address(rsp, src_offset)); 1052 __ popq (Address(rsp, dst_offset)); 1053 __ pushq(Address(rsp, src_offset+8)); 1054 __ popq (Address(rsp, dst_offset+8)); 1055 break; 1056 case Op_VecY: 1057 __ vmovdqu(Address(rsp, -32), xmm0); 1058 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1059 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1060 __ vmovdqu(xmm0, Address(rsp, -32)); 1061 break; 1062 case Op_VecZ: 1063 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1064 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1065 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1066 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1067 break; 1068 default: 1069 ShouldNotReachHere(); 1070 } 1071 #ifndef PRODUCT 1072 } else { 1073 switch (ireg) { 1074 case Op_VecS: 1075 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1076 "movl rax, [rsp + #%d]\n\t" 1077 "movl [rsp + #%d], rax\n\t" 1078 "movq rax, [rsp - #8]", 1079 src_offset, dst_offset); 1080 break; 1081 case Op_VecD: 1082 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1083 "popq [rsp + #%d]", 1084 src_offset, dst_offset); 1085 break; 1086 case Op_VecX: 1087 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1088 "popq [rsp + #%d]\n\t" 1089 "pushq [rsp + #%d]\n\t" 1090 "popq [rsp + #%d]", 1091 src_offset, dst_offset, src_offset+8, dst_offset+8); 1092 break; 1093 case Op_VecY: 1094 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1095 "vmovdqu xmm0, [rsp + #%d]\n\t" 1096 "vmovdqu [rsp + #%d], xmm0\n\t" 1097 "vmovdqu xmm0, [rsp - #32]", 1098 src_offset, dst_offset); 1099 break; 1100 case Op_VecZ: 1101 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1102 "vmovdqu xmm0, [rsp + #%d]\n\t" 1103 "vmovdqu [rsp + #%d], xmm0\n\t" 1104 "vmovdqu xmm0, [rsp - #64]", 1105 src_offset, dst_offset); 1106 break; 1107 default: 1108 ShouldNotReachHere(); 1109 } 1110 #endif 1111 } 1112 } 1113 1114 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1115 PhaseRegAlloc* ra_, 1116 bool do_size, 1117 outputStream* st) const { 1118 assert(cbuf != NULL || st != NULL, "sanity"); 1119 // Get registers to move 1120 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1121 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1122 OptoReg::Name dst_second = ra_->get_reg_second(this); 1123 OptoReg::Name dst_first = ra_->get_reg_first(this); 1124 1125 enum RC src_second_rc = rc_class(src_second); 1126 enum RC src_first_rc = rc_class(src_first); 1127 enum RC dst_second_rc = rc_class(dst_second); 1128 enum RC dst_first_rc = rc_class(dst_first); 1129 1130 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1131 "must move at least 1 register" ); 1132 1133 if (src_first == dst_first && src_second == dst_second) { 1134 // Self copy, no move 1135 return 0; 1136 } 1137 if (bottom_type()->isa_vect() != NULL) { 1138 uint ireg = ideal_reg(); 1139 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1140 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1141 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1142 // mem -> mem 1143 int src_offset = ra_->reg2offset(src_first); 1144 int dst_offset = ra_->reg2offset(dst_first); 1145 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1146 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1147 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1148 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1149 int stack_offset = ra_->reg2offset(dst_first); 1150 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1151 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1152 int stack_offset = ra_->reg2offset(src_first); 1153 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1154 } else { 1155 ShouldNotReachHere(); 1156 } 1157 return 0; 1158 } 1159 if (src_first_rc == rc_stack) { 1160 // mem -> 1161 if (dst_first_rc == rc_stack) { 1162 // mem -> mem 1163 assert(src_second != dst_first, "overlap"); 1164 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1165 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1166 // 64-bit 1167 int src_offset = ra_->reg2offset(src_first); 1168 int dst_offset = ra_->reg2offset(dst_first); 1169 if (cbuf) { 1170 MacroAssembler _masm(cbuf); 1171 __ pushq(Address(rsp, src_offset)); 1172 __ popq (Address(rsp, dst_offset)); 1173 #ifndef PRODUCT 1174 } else { 1175 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1176 "popq [rsp + #%d]", 1177 src_offset, dst_offset); 1178 #endif 1179 } 1180 } else { 1181 // 32-bit 1182 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1183 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1184 // No pushl/popl, so: 1185 int src_offset = ra_->reg2offset(src_first); 1186 int dst_offset = ra_->reg2offset(dst_first); 1187 if (cbuf) { 1188 MacroAssembler _masm(cbuf); 1189 __ movq(Address(rsp, -8), rax); 1190 __ movl(rax, Address(rsp, src_offset)); 1191 __ movl(Address(rsp, dst_offset), rax); 1192 __ movq(rax, Address(rsp, -8)); 1193 #ifndef PRODUCT 1194 } else { 1195 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1196 "movl rax, [rsp + #%d]\n\t" 1197 "movl [rsp + #%d], rax\n\t" 1198 "movq rax, [rsp - #8]", 1199 src_offset, dst_offset); 1200 #endif 1201 } 1202 } 1203 return 0; 1204 } else if (dst_first_rc == rc_int) { 1205 // mem -> gpr 1206 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1207 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1208 // 64-bit 1209 int offset = ra_->reg2offset(src_first); 1210 if (cbuf) { 1211 MacroAssembler _masm(cbuf); 1212 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1213 #ifndef PRODUCT 1214 } else { 1215 st->print("movq %s, [rsp + #%d]\t# spill", 1216 Matcher::regName[dst_first], 1217 offset); 1218 #endif 1219 } 1220 } else { 1221 // 32-bit 1222 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1223 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1224 int offset = ra_->reg2offset(src_first); 1225 if (cbuf) { 1226 MacroAssembler _masm(cbuf); 1227 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1228 #ifndef PRODUCT 1229 } else { 1230 st->print("movl %s, [rsp + #%d]\t# spill", 1231 Matcher::regName[dst_first], 1232 offset); 1233 #endif 1234 } 1235 } 1236 return 0; 1237 } else if (dst_first_rc == rc_float) { 1238 // mem-> xmm 1239 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1240 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1241 // 64-bit 1242 int offset = ra_->reg2offset(src_first); 1243 if (cbuf) { 1244 MacroAssembler _masm(cbuf); 1245 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1246 #ifndef PRODUCT 1247 } else { 1248 st->print("%s %s, [rsp + #%d]\t# spill", 1249 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1250 Matcher::regName[dst_first], 1251 offset); 1252 #endif 1253 } 1254 } else { 1255 // 32-bit 1256 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1257 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1258 int offset = ra_->reg2offset(src_first); 1259 if (cbuf) { 1260 MacroAssembler _masm(cbuf); 1261 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1262 #ifndef PRODUCT 1263 } else { 1264 st->print("movss %s, [rsp + #%d]\t# spill", 1265 Matcher::regName[dst_first], 1266 offset); 1267 #endif 1268 } 1269 } 1270 return 0; 1271 } 1272 } else if (src_first_rc == rc_int) { 1273 // gpr -> 1274 if (dst_first_rc == rc_stack) { 1275 // gpr -> mem 1276 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1277 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1278 // 64-bit 1279 int offset = ra_->reg2offset(dst_first); 1280 if (cbuf) { 1281 MacroAssembler _masm(cbuf); 1282 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1283 #ifndef PRODUCT 1284 } else { 1285 st->print("movq [rsp + #%d], %s\t# spill", 1286 offset, 1287 Matcher::regName[src_first]); 1288 #endif 1289 } 1290 } else { 1291 // 32-bit 1292 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1293 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1294 int offset = ra_->reg2offset(dst_first); 1295 if (cbuf) { 1296 MacroAssembler _masm(cbuf); 1297 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1298 #ifndef PRODUCT 1299 } else { 1300 st->print("movl [rsp + #%d], %s\t# spill", 1301 offset, 1302 Matcher::regName[src_first]); 1303 #endif 1304 } 1305 } 1306 return 0; 1307 } else if (dst_first_rc == rc_int) { 1308 // gpr -> gpr 1309 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1310 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1311 // 64-bit 1312 if (cbuf) { 1313 MacroAssembler _masm(cbuf); 1314 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1315 as_Register(Matcher::_regEncode[src_first])); 1316 #ifndef PRODUCT 1317 } else { 1318 st->print("movq %s, %s\t# spill", 1319 Matcher::regName[dst_first], 1320 Matcher::regName[src_first]); 1321 #endif 1322 } 1323 return 0; 1324 } else { 1325 // 32-bit 1326 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1327 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1328 if (cbuf) { 1329 MacroAssembler _masm(cbuf); 1330 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1331 as_Register(Matcher::_regEncode[src_first])); 1332 #ifndef PRODUCT 1333 } else { 1334 st->print("movl %s, %s\t# spill", 1335 Matcher::regName[dst_first], 1336 Matcher::regName[src_first]); 1337 #endif 1338 } 1339 return 0; 1340 } 1341 } else if (dst_first_rc == rc_float) { 1342 // gpr -> xmm 1343 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1344 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1345 // 64-bit 1346 if (cbuf) { 1347 MacroAssembler _masm(cbuf); 1348 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1349 #ifndef PRODUCT 1350 } else { 1351 st->print("movdq %s, %s\t# spill", 1352 Matcher::regName[dst_first], 1353 Matcher::regName[src_first]); 1354 #endif 1355 } 1356 } else { 1357 // 32-bit 1358 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1359 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1360 if (cbuf) { 1361 MacroAssembler _masm(cbuf); 1362 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1363 #ifndef PRODUCT 1364 } else { 1365 st->print("movdl %s, %s\t# spill", 1366 Matcher::regName[dst_first], 1367 Matcher::regName[src_first]); 1368 #endif 1369 } 1370 } 1371 return 0; 1372 } 1373 } else if (src_first_rc == rc_float) { 1374 // xmm -> 1375 if (dst_first_rc == rc_stack) { 1376 // xmm -> mem 1377 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1378 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1379 // 64-bit 1380 int offset = ra_->reg2offset(dst_first); 1381 if (cbuf) { 1382 MacroAssembler _masm(cbuf); 1383 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1384 #ifndef PRODUCT 1385 } else { 1386 st->print("movsd [rsp + #%d], %s\t# spill", 1387 offset, 1388 Matcher::regName[src_first]); 1389 #endif 1390 } 1391 } else { 1392 // 32-bit 1393 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1394 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1395 int offset = ra_->reg2offset(dst_first); 1396 if (cbuf) { 1397 MacroAssembler _masm(cbuf); 1398 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1399 #ifndef PRODUCT 1400 } else { 1401 st->print("movss [rsp + #%d], %s\t# spill", 1402 offset, 1403 Matcher::regName[src_first]); 1404 #endif 1405 } 1406 } 1407 return 0; 1408 } else if (dst_first_rc == rc_int) { 1409 // xmm -> gpr 1410 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1411 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1412 // 64-bit 1413 if (cbuf) { 1414 MacroAssembler _masm(cbuf); 1415 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1416 #ifndef PRODUCT 1417 } else { 1418 st->print("movdq %s, %s\t# spill", 1419 Matcher::regName[dst_first], 1420 Matcher::regName[src_first]); 1421 #endif 1422 } 1423 } else { 1424 // 32-bit 1425 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1426 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1427 if (cbuf) { 1428 MacroAssembler _masm(cbuf); 1429 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1430 #ifndef PRODUCT 1431 } else { 1432 st->print("movdl %s, %s\t# spill", 1433 Matcher::regName[dst_first], 1434 Matcher::regName[src_first]); 1435 #endif 1436 } 1437 } 1438 return 0; 1439 } else if (dst_first_rc == rc_float) { 1440 // xmm -> xmm 1441 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1442 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1443 // 64-bit 1444 if (cbuf) { 1445 MacroAssembler _masm(cbuf); 1446 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1447 #ifndef PRODUCT 1448 } else { 1449 st->print("%s %s, %s\t# spill", 1450 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1451 Matcher::regName[dst_first], 1452 Matcher::regName[src_first]); 1453 #endif 1454 } 1455 } else { 1456 // 32-bit 1457 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1458 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1459 if (cbuf) { 1460 MacroAssembler _masm(cbuf); 1461 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1462 #ifndef PRODUCT 1463 } else { 1464 st->print("%s %s, %s\t# spill", 1465 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1466 Matcher::regName[dst_first], 1467 Matcher::regName[src_first]); 1468 #endif 1469 } 1470 } 1471 return 0; 1472 } 1473 } 1474 1475 assert(0," foo "); 1476 Unimplemented(); 1477 return 0; 1478 } 1479 1480 #ifndef PRODUCT 1481 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1482 implementation(NULL, ra_, false, st); 1483 } 1484 #endif 1485 1486 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1487 implementation(&cbuf, ra_, false, NULL); 1488 } 1489 1490 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1491 return MachNode::size(ra_); 1492 } 1493 1494 //============================================================================= 1495 #ifndef PRODUCT 1496 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1497 { 1498 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1499 int reg = ra_->get_reg_first(this); 1500 st->print("leaq %s, [rsp + #%d]\t# box lock", 1501 Matcher::regName[reg], offset); 1502 } 1503 #endif 1504 1505 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1506 { 1507 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1508 int reg = ra_->get_encode(this); 1509 if (offset >= 0x80) { 1510 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1511 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1512 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1513 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1514 emit_d32(cbuf, offset); 1515 } else { 1516 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1517 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1518 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1519 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1520 emit_d8(cbuf, offset); 1521 } 1522 } 1523 1524 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1525 { 1526 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1527 return (offset < 0x80) ? 5 : 8; // REX 1528 } 1529 1530 //============================================================================= 1531 #ifndef PRODUCT 1532 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1533 { 1534 if (UseCompressedClassPointers) { 1535 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1536 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1537 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1538 } else { 1539 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1540 "# Inline cache check"); 1541 } 1542 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1543 st->print_cr("\tnop\t# nops to align entry point"); 1544 } 1545 #endif 1546 1547 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1548 { 1549 MacroAssembler masm(&cbuf); 1550 uint insts_size = cbuf.insts_size(); 1551 if (UseCompressedClassPointers) { 1552 masm.load_klass(rscratch1, j_rarg0, rscratch2); 1553 masm.cmpptr(rax, rscratch1); 1554 } else { 1555 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1556 } 1557 1558 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1559 1560 /* WARNING these NOPs are critical so that verified entry point is properly 1561 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1562 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1563 if (OptoBreakpoint) { 1564 // Leave space for int3 1565 nops_cnt -= 1; 1566 } 1567 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1568 if (nops_cnt > 0) 1569 masm.nop(nops_cnt); 1570 } 1571 1572 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1573 { 1574 return MachNode::size(ra_); // too many variables; just compute it 1575 // the hard way 1576 } 1577 1578 1579 //============================================================================= 1580 1581 int Matcher::regnum_to_fpu_offset(int regnum) 1582 { 1583 return regnum - 32; // The FP registers are in the second chunk 1584 } 1585 1586 // This is UltraSparc specific, true just means we have fast l2f conversion 1587 const bool Matcher::convL2FSupported(void) { 1588 return true; 1589 } 1590 1591 // Is this branch offset short enough that a short branch can be used? 1592 // 1593 // NOTE: If the platform does not provide any short branch variants, then 1594 // this method should return false for offset 0. 1595 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1596 // The passed offset is relative to address of the branch. 1597 // On 86 a branch displacement is calculated relative to address 1598 // of a next instruction. 1599 offset -= br_size; 1600 1601 // the short version of jmpConUCF2 contains multiple branches, 1602 // making the reach slightly less 1603 if (rule == jmpConUCF2_rule) 1604 return (-126 <= offset && offset <= 125); 1605 return (-128 <= offset && offset <= 127); 1606 } 1607 1608 const bool Matcher::isSimpleConstant64(jlong value) { 1609 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1610 //return value == (int) value; // Cf. storeImmL and immL32. 1611 1612 // Probably always true, even if a temp register is required. 1613 return true; 1614 } 1615 1616 // The ecx parameter to rep stosq for the ClearArray node is in words. 1617 const bool Matcher::init_array_count_is_in_bytes = false; 1618 1619 // No additional cost for CMOVL. 1620 const int Matcher::long_cmove_cost() { return 0; } 1621 1622 // No CMOVF/CMOVD with SSE2 1623 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1624 1625 // Does the CPU require late expand (see block.cpp for description of late expand)? 1626 const bool Matcher::require_postalloc_expand = false; 1627 1628 // Do we need to mask the count passed to shift instructions or does 1629 // the cpu only look at the lower 5/6 bits anyway? 1630 const bool Matcher::need_masked_shift_count = false; 1631 1632 bool Matcher::narrow_oop_use_complex_address() { 1633 assert(UseCompressedOops, "only for compressed oops code"); 1634 return (LogMinObjAlignmentInBytes <= 3); 1635 } 1636 1637 bool Matcher::narrow_klass_use_complex_address() { 1638 assert(UseCompressedClassPointers, "only for compressed klass code"); 1639 return (LogKlassAlignmentInBytes <= 3); 1640 } 1641 1642 bool Matcher::const_oop_prefer_decode() { 1643 // Prefer ConN+DecodeN over ConP. 1644 return true; 1645 } 1646 1647 bool Matcher::const_klass_prefer_decode() { 1648 // Prefer ConP over ConNKlass+DecodeNKlass. 1649 return true; 1650 } 1651 1652 // Is it better to copy float constants, or load them directly from 1653 // memory? Intel can load a float constant from a direct address, 1654 // requiring no extra registers. Most RISCs will have to materialize 1655 // an address into a register first, so they would do better to copy 1656 // the constant from stack. 1657 const bool Matcher::rematerialize_float_constants = true; // XXX 1658 1659 // If CPU can load and store mis-aligned doubles directly then no 1660 // fixup is needed. Else we split the double into 2 integer pieces 1661 // and move it piece-by-piece. Only happens when passing doubles into 1662 // C code as the Java calling convention forces doubles to be aligned. 1663 const bool Matcher::misaligned_doubles_ok = true; 1664 1665 // No-op on amd64 1666 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1667 1668 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 1669 const bool Matcher::strict_fp_requires_explicit_rounding = false; 1670 1671 // Are floats conerted to double when stored to stack during deoptimization? 1672 // On x64 it is stored without convertion so we can use normal access. 1673 bool Matcher::float_in_double() { return false; } 1674 1675 // Do ints take an entire long register or just half? 1676 const bool Matcher::int_in_long = true; 1677 1678 // Return whether or not this register is ever used as an argument. 1679 // This function is used on startup to build the trampoline stubs in 1680 // generateOptoStub. Registers not mentioned will be killed by the VM 1681 // call in the trampoline, and arguments in those registers not be 1682 // available to the callee. 1683 bool Matcher::can_be_java_arg(int reg) 1684 { 1685 return 1686 reg == RDI_num || reg == RDI_H_num || 1687 reg == RSI_num || reg == RSI_H_num || 1688 reg == RDX_num || reg == RDX_H_num || 1689 reg == RCX_num || reg == RCX_H_num || 1690 reg == R8_num || reg == R8_H_num || 1691 reg == R9_num || reg == R9_H_num || 1692 reg == R12_num || reg == R12_H_num || 1693 reg == XMM0_num || reg == XMM0b_num || 1694 reg == XMM1_num || reg == XMM1b_num || 1695 reg == XMM2_num || reg == XMM2b_num || 1696 reg == XMM3_num || reg == XMM3b_num || 1697 reg == XMM4_num || reg == XMM4b_num || 1698 reg == XMM5_num || reg == XMM5b_num || 1699 reg == XMM6_num || reg == XMM6b_num || 1700 reg == XMM7_num || reg == XMM7b_num; 1701 } 1702 1703 bool Matcher::is_spillable_arg(int reg) 1704 { 1705 return can_be_java_arg(reg); 1706 } 1707 1708 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1709 // In 64 bit mode a code which use multiply when 1710 // devisor is constant is faster than hardware 1711 // DIV instruction (it uses MulHiL). 1712 return false; 1713 } 1714 1715 // Register for DIVI projection of divmodI 1716 RegMask Matcher::divI_proj_mask() { 1717 return INT_RAX_REG_mask(); 1718 } 1719 1720 // Register for MODI projection of divmodI 1721 RegMask Matcher::modI_proj_mask() { 1722 return INT_RDX_REG_mask(); 1723 } 1724 1725 // Register for DIVL projection of divmodL 1726 RegMask Matcher::divL_proj_mask() { 1727 return LONG_RAX_REG_mask(); 1728 } 1729 1730 // Register for MODL projection of divmodL 1731 RegMask Matcher::modL_proj_mask() { 1732 return LONG_RDX_REG_mask(); 1733 } 1734 1735 // Register for saving SP into on method handle invokes. Not used on x86_64. 1736 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1737 return NO_REG_mask(); 1738 } 1739 1740 %} 1741 1742 //----------ENCODING BLOCK----------------------------------------------------- 1743 // This block specifies the encoding classes used by the compiler to 1744 // output byte streams. Encoding classes are parameterized macros 1745 // used by Machine Instruction Nodes in order to generate the bit 1746 // encoding of the instruction. Operands specify their base encoding 1747 // interface with the interface keyword. There are currently 1748 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1749 // COND_INTER. REG_INTER causes an operand to generate a function 1750 // which returns its register number when queried. CONST_INTER causes 1751 // an operand to generate a function which returns the value of the 1752 // constant when queried. MEMORY_INTER causes an operand to generate 1753 // four functions which return the Base Register, the Index Register, 1754 // the Scale Value, and the Offset Value of the operand when queried. 1755 // COND_INTER causes an operand to generate six functions which return 1756 // the encoding code (ie - encoding bits for the instruction) 1757 // associated with each basic boolean condition for a conditional 1758 // instruction. 1759 // 1760 // Instructions specify two basic values for encoding. Again, a 1761 // function is available to check if the constant displacement is an 1762 // oop. They use the ins_encode keyword to specify their encoding 1763 // classes (which must be a sequence of enc_class names, and their 1764 // parameters, specified in the encoding block), and they use the 1765 // opcode keyword to specify, in order, their primary, secondary, and 1766 // tertiary opcode. Only the opcode sections which a particular 1767 // instruction needs for encoding need to be specified. 1768 encode %{ 1769 // Build emit functions for each basic byte or larger field in the 1770 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1771 // from C++ code in the enc_class source block. Emit functions will 1772 // live in the main source block for now. In future, we can 1773 // generalize this by adding a syntax that specifies the sizes of 1774 // fields in an order, so that the adlc can build the emit functions 1775 // automagically 1776 1777 // Emit primary opcode 1778 enc_class OpcP 1779 %{ 1780 emit_opcode(cbuf, $primary); 1781 %} 1782 1783 // Emit secondary opcode 1784 enc_class OpcS 1785 %{ 1786 emit_opcode(cbuf, $secondary); 1787 %} 1788 1789 // Emit tertiary opcode 1790 enc_class OpcT 1791 %{ 1792 emit_opcode(cbuf, $tertiary); 1793 %} 1794 1795 // Emit opcode directly 1796 enc_class Opcode(immI d8) 1797 %{ 1798 emit_opcode(cbuf, $d8$$constant); 1799 %} 1800 1801 // Emit size prefix 1802 enc_class SizePrefix 1803 %{ 1804 emit_opcode(cbuf, 0x66); 1805 %} 1806 1807 enc_class reg(rRegI reg) 1808 %{ 1809 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1810 %} 1811 1812 enc_class reg_reg(rRegI dst, rRegI src) 1813 %{ 1814 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1815 %} 1816 1817 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1818 %{ 1819 emit_opcode(cbuf, $opcode$$constant); 1820 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1821 %} 1822 1823 enc_class cdql_enc(no_rax_rdx_RegI div) 1824 %{ 1825 // Full implementation of Java idiv and irem; checks for 1826 // special case as described in JVM spec., p.243 & p.271. 1827 // 1828 // normal case special case 1829 // 1830 // input : rax: dividend min_int 1831 // reg: divisor -1 1832 // 1833 // output: rax: quotient (= rax idiv reg) min_int 1834 // rdx: remainder (= rax irem reg) 0 1835 // 1836 // Code sequnce: 1837 // 1838 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1839 // 5: 75 07/08 jne e <normal> 1840 // 7: 33 d2 xor %edx,%edx 1841 // [div >= 8 -> offset + 1] 1842 // [REX_B] 1843 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1844 // c: 74 03/04 je 11 <done> 1845 // 000000000000000e <normal>: 1846 // e: 99 cltd 1847 // [div >= 8 -> offset + 1] 1848 // [REX_B] 1849 // f: f7 f9 idiv $div 1850 // 0000000000000011 <done>: 1851 1852 // cmp $0x80000000,%eax 1853 emit_opcode(cbuf, 0x3d); 1854 emit_d8(cbuf, 0x00); 1855 emit_d8(cbuf, 0x00); 1856 emit_d8(cbuf, 0x00); 1857 emit_d8(cbuf, 0x80); 1858 1859 // jne e <normal> 1860 emit_opcode(cbuf, 0x75); 1861 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1862 1863 // xor %edx,%edx 1864 emit_opcode(cbuf, 0x33); 1865 emit_d8(cbuf, 0xD2); 1866 1867 // cmp $0xffffffffffffffff,%ecx 1868 if ($div$$reg >= 8) { 1869 emit_opcode(cbuf, Assembler::REX_B); 1870 } 1871 emit_opcode(cbuf, 0x83); 1872 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1873 emit_d8(cbuf, 0xFF); 1874 1875 // je 11 <done> 1876 emit_opcode(cbuf, 0x74); 1877 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1878 1879 // <normal> 1880 // cltd 1881 emit_opcode(cbuf, 0x99); 1882 1883 // idivl (note: must be emitted by the user of this rule) 1884 // <done> 1885 %} 1886 1887 enc_class cdqq_enc(no_rax_rdx_RegL div) 1888 %{ 1889 // Full implementation of Java ldiv and lrem; checks for 1890 // special case as described in JVM spec., p.243 & p.271. 1891 // 1892 // normal case special case 1893 // 1894 // input : rax: dividend min_long 1895 // reg: divisor -1 1896 // 1897 // output: rax: quotient (= rax idiv reg) min_long 1898 // rdx: remainder (= rax irem reg) 0 1899 // 1900 // Code sequnce: 1901 // 1902 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1903 // 7: 00 00 80 1904 // a: 48 39 d0 cmp %rdx,%rax 1905 // d: 75 08 jne 17 <normal> 1906 // f: 33 d2 xor %edx,%edx 1907 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1908 // 15: 74 05 je 1c <done> 1909 // 0000000000000017 <normal>: 1910 // 17: 48 99 cqto 1911 // 19: 48 f7 f9 idiv $div 1912 // 000000000000001c <done>: 1913 1914 // mov $0x8000000000000000,%rdx 1915 emit_opcode(cbuf, Assembler::REX_W); 1916 emit_opcode(cbuf, 0xBA); 1917 emit_d8(cbuf, 0x00); 1918 emit_d8(cbuf, 0x00); 1919 emit_d8(cbuf, 0x00); 1920 emit_d8(cbuf, 0x00); 1921 emit_d8(cbuf, 0x00); 1922 emit_d8(cbuf, 0x00); 1923 emit_d8(cbuf, 0x00); 1924 emit_d8(cbuf, 0x80); 1925 1926 // cmp %rdx,%rax 1927 emit_opcode(cbuf, Assembler::REX_W); 1928 emit_opcode(cbuf, 0x39); 1929 emit_d8(cbuf, 0xD0); 1930 1931 // jne 17 <normal> 1932 emit_opcode(cbuf, 0x75); 1933 emit_d8(cbuf, 0x08); 1934 1935 // xor %edx,%edx 1936 emit_opcode(cbuf, 0x33); 1937 emit_d8(cbuf, 0xD2); 1938 1939 // cmp $0xffffffffffffffff,$div 1940 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1941 emit_opcode(cbuf, 0x83); 1942 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1943 emit_d8(cbuf, 0xFF); 1944 1945 // je 1e <done> 1946 emit_opcode(cbuf, 0x74); 1947 emit_d8(cbuf, 0x05); 1948 1949 // <normal> 1950 // cqto 1951 emit_opcode(cbuf, Assembler::REX_W); 1952 emit_opcode(cbuf, 0x99); 1953 1954 // idivq (note: must be emitted by the user of this rule) 1955 // <done> 1956 %} 1957 1958 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1959 enc_class OpcSE(immI imm) 1960 %{ 1961 // Emit primary opcode and set sign-extend bit 1962 // Check for 8-bit immediate, and set sign extend bit in opcode 1963 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1964 emit_opcode(cbuf, $primary | 0x02); 1965 } else { 1966 // 32-bit immediate 1967 emit_opcode(cbuf, $primary); 1968 } 1969 %} 1970 1971 enc_class OpcSErm(rRegI dst, immI imm) 1972 %{ 1973 // OpcSEr/m 1974 int dstenc = $dst$$reg; 1975 if (dstenc >= 8) { 1976 emit_opcode(cbuf, Assembler::REX_B); 1977 dstenc -= 8; 1978 } 1979 // Emit primary opcode and set sign-extend bit 1980 // Check for 8-bit immediate, and set sign extend bit in opcode 1981 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1982 emit_opcode(cbuf, $primary | 0x02); 1983 } else { 1984 // 32-bit immediate 1985 emit_opcode(cbuf, $primary); 1986 } 1987 // Emit r/m byte with secondary opcode, after primary opcode. 1988 emit_rm(cbuf, 0x3, $secondary, dstenc); 1989 %} 1990 1991 enc_class OpcSErm_wide(rRegL dst, immI imm) 1992 %{ 1993 // OpcSEr/m 1994 int dstenc = $dst$$reg; 1995 if (dstenc < 8) { 1996 emit_opcode(cbuf, Assembler::REX_W); 1997 } else { 1998 emit_opcode(cbuf, Assembler::REX_WB); 1999 dstenc -= 8; 2000 } 2001 // Emit primary opcode and set sign-extend bit 2002 // Check for 8-bit immediate, and set sign extend bit in opcode 2003 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2004 emit_opcode(cbuf, $primary | 0x02); 2005 } else { 2006 // 32-bit immediate 2007 emit_opcode(cbuf, $primary); 2008 } 2009 // Emit r/m byte with secondary opcode, after primary opcode. 2010 emit_rm(cbuf, 0x3, $secondary, dstenc); 2011 %} 2012 2013 enc_class Con8or32(immI imm) 2014 %{ 2015 // Check for 8-bit immediate, and set sign extend bit in opcode 2016 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2017 $$$emit8$imm$$constant; 2018 } else { 2019 // 32-bit immediate 2020 $$$emit32$imm$$constant; 2021 } 2022 %} 2023 2024 enc_class opc2_reg(rRegI dst) 2025 %{ 2026 // BSWAP 2027 emit_cc(cbuf, $secondary, $dst$$reg); 2028 %} 2029 2030 enc_class opc3_reg(rRegI dst) 2031 %{ 2032 // BSWAP 2033 emit_cc(cbuf, $tertiary, $dst$$reg); 2034 %} 2035 2036 enc_class reg_opc(rRegI div) 2037 %{ 2038 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2039 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2040 %} 2041 2042 enc_class enc_cmov(cmpOp cop) 2043 %{ 2044 // CMOV 2045 $$$emit8$primary; 2046 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2047 %} 2048 2049 enc_class enc_PartialSubtypeCheck() 2050 %{ 2051 Register Rrdi = as_Register(RDI_enc); // result register 2052 Register Rrax = as_Register(RAX_enc); // super class 2053 Register Rrcx = as_Register(RCX_enc); // killed 2054 Register Rrsi = as_Register(RSI_enc); // sub class 2055 Label miss; 2056 const bool set_cond_codes = true; 2057 2058 MacroAssembler _masm(&cbuf); 2059 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2060 NULL, &miss, 2061 /*set_cond_codes:*/ true); 2062 if ($primary) { 2063 __ xorptr(Rrdi, Rrdi); 2064 } 2065 __ bind(miss); 2066 %} 2067 2068 enc_class clear_avx %{ 2069 debug_only(int off0 = cbuf.insts_size()); 2070 if (generate_vzeroupper(Compile::current())) { 2071 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2072 // Clear upper bits of YMM registers when current compiled code uses 2073 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2074 MacroAssembler _masm(&cbuf); 2075 __ vzeroupper(); 2076 } 2077 debug_only(int off1 = cbuf.insts_size()); 2078 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2079 %} 2080 2081 enc_class Java_To_Runtime(method meth) %{ 2082 // No relocation needed 2083 MacroAssembler _masm(&cbuf); 2084 __ mov64(r10, (int64_t) $meth$$method); 2085 __ call(r10); 2086 %} 2087 2088 enc_class Java_To_Interpreter(method meth) 2089 %{ 2090 // CALL Java_To_Interpreter 2091 // This is the instruction starting address for relocation info. 2092 cbuf.set_insts_mark(); 2093 $$$emit8$primary; 2094 // CALL directly to the runtime 2095 emit_d32_reloc(cbuf, 2096 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2097 runtime_call_Relocation::spec(), 2098 RELOC_DISP32); 2099 %} 2100 2101 enc_class Java_Static_Call(method meth) 2102 %{ 2103 // JAVA STATIC CALL 2104 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2105 // determine who we intended to call. 2106 cbuf.set_insts_mark(); 2107 $$$emit8$primary; 2108 2109 if (!_method) { 2110 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2111 runtime_call_Relocation::spec(), 2112 RELOC_DISP32); 2113 } else { 2114 int method_index = resolved_method_index(cbuf); 2115 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2116 : static_call_Relocation::spec(method_index); 2117 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2118 rspec, RELOC_DISP32); 2119 // Emit stubs for static call. 2120 address mark = cbuf.insts_mark(); 2121 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2122 if (stub == NULL) { 2123 ciEnv::current()->record_failure("CodeCache is full"); 2124 return; 2125 } 2126 #if INCLUDE_AOT 2127 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2128 #endif 2129 } 2130 %} 2131 2132 enc_class Java_Dynamic_Call(method meth) %{ 2133 MacroAssembler _masm(&cbuf); 2134 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2135 %} 2136 2137 enc_class Java_Compiled_Call(method meth) 2138 %{ 2139 // JAVA COMPILED CALL 2140 int disp = in_bytes(Method:: from_compiled_offset()); 2141 2142 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2143 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2144 2145 // callq *disp(%rax) 2146 cbuf.set_insts_mark(); 2147 $$$emit8$primary; 2148 if (disp < 0x80) { 2149 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2150 emit_d8(cbuf, disp); // Displacement 2151 } else { 2152 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2153 emit_d32(cbuf, disp); // Displacement 2154 } 2155 %} 2156 2157 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2158 %{ 2159 // SAL, SAR, SHR 2160 int dstenc = $dst$$reg; 2161 if (dstenc >= 8) { 2162 emit_opcode(cbuf, Assembler::REX_B); 2163 dstenc -= 8; 2164 } 2165 $$$emit8$primary; 2166 emit_rm(cbuf, 0x3, $secondary, dstenc); 2167 $$$emit8$shift$$constant; 2168 %} 2169 2170 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2171 %{ 2172 // SAL, SAR, SHR 2173 int dstenc = $dst$$reg; 2174 if (dstenc < 8) { 2175 emit_opcode(cbuf, Assembler::REX_W); 2176 } else { 2177 emit_opcode(cbuf, Assembler::REX_WB); 2178 dstenc -= 8; 2179 } 2180 $$$emit8$primary; 2181 emit_rm(cbuf, 0x3, $secondary, dstenc); 2182 $$$emit8$shift$$constant; 2183 %} 2184 2185 enc_class load_immI(rRegI dst, immI src) 2186 %{ 2187 int dstenc = $dst$$reg; 2188 if (dstenc >= 8) { 2189 emit_opcode(cbuf, Assembler::REX_B); 2190 dstenc -= 8; 2191 } 2192 emit_opcode(cbuf, 0xB8 | dstenc); 2193 $$$emit32$src$$constant; 2194 %} 2195 2196 enc_class load_immL(rRegL dst, immL src) 2197 %{ 2198 int dstenc = $dst$$reg; 2199 if (dstenc < 8) { 2200 emit_opcode(cbuf, Assembler::REX_W); 2201 } else { 2202 emit_opcode(cbuf, Assembler::REX_WB); 2203 dstenc -= 8; 2204 } 2205 emit_opcode(cbuf, 0xB8 | dstenc); 2206 emit_d64(cbuf, $src$$constant); 2207 %} 2208 2209 enc_class load_immUL32(rRegL dst, immUL32 src) 2210 %{ 2211 // same as load_immI, but this time we care about zeroes in the high word 2212 int dstenc = $dst$$reg; 2213 if (dstenc >= 8) { 2214 emit_opcode(cbuf, Assembler::REX_B); 2215 dstenc -= 8; 2216 } 2217 emit_opcode(cbuf, 0xB8 | dstenc); 2218 $$$emit32$src$$constant; 2219 %} 2220 2221 enc_class load_immL32(rRegL dst, immL32 src) 2222 %{ 2223 int dstenc = $dst$$reg; 2224 if (dstenc < 8) { 2225 emit_opcode(cbuf, Assembler::REX_W); 2226 } else { 2227 emit_opcode(cbuf, Assembler::REX_WB); 2228 dstenc -= 8; 2229 } 2230 emit_opcode(cbuf, 0xC7); 2231 emit_rm(cbuf, 0x03, 0x00, dstenc); 2232 $$$emit32$src$$constant; 2233 %} 2234 2235 enc_class load_immP31(rRegP dst, immP32 src) 2236 %{ 2237 // same as load_immI, but this time we care about zeroes in the high word 2238 int dstenc = $dst$$reg; 2239 if (dstenc >= 8) { 2240 emit_opcode(cbuf, Assembler::REX_B); 2241 dstenc -= 8; 2242 } 2243 emit_opcode(cbuf, 0xB8 | dstenc); 2244 $$$emit32$src$$constant; 2245 %} 2246 2247 enc_class load_immP(rRegP dst, immP src) 2248 %{ 2249 int dstenc = $dst$$reg; 2250 if (dstenc < 8) { 2251 emit_opcode(cbuf, Assembler::REX_W); 2252 } else { 2253 emit_opcode(cbuf, Assembler::REX_WB); 2254 dstenc -= 8; 2255 } 2256 emit_opcode(cbuf, 0xB8 | dstenc); 2257 // This next line should be generated from ADLC 2258 if ($src->constant_reloc() != relocInfo::none) { 2259 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2260 } else { 2261 emit_d64(cbuf, $src$$constant); 2262 } 2263 %} 2264 2265 enc_class Con32(immI src) 2266 %{ 2267 // Output immediate 2268 $$$emit32$src$$constant; 2269 %} 2270 2271 enc_class Con32F_as_bits(immF src) 2272 %{ 2273 // Output Float immediate bits 2274 jfloat jf = $src$$constant; 2275 jint jf_as_bits = jint_cast(jf); 2276 emit_d32(cbuf, jf_as_bits); 2277 %} 2278 2279 enc_class Con16(immI src) 2280 %{ 2281 // Output immediate 2282 $$$emit16$src$$constant; 2283 %} 2284 2285 // How is this different from Con32??? XXX 2286 enc_class Con_d32(immI src) 2287 %{ 2288 emit_d32(cbuf,$src$$constant); 2289 %} 2290 2291 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2292 // Output immediate memory reference 2293 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2294 emit_d32(cbuf, 0x00); 2295 %} 2296 2297 enc_class lock_prefix() 2298 %{ 2299 emit_opcode(cbuf, 0xF0); // lock 2300 %} 2301 2302 enc_class REX_mem(memory mem) 2303 %{ 2304 if ($mem$$base >= 8) { 2305 if ($mem$$index < 8) { 2306 emit_opcode(cbuf, Assembler::REX_B); 2307 } else { 2308 emit_opcode(cbuf, Assembler::REX_XB); 2309 } 2310 } else { 2311 if ($mem$$index >= 8) { 2312 emit_opcode(cbuf, Assembler::REX_X); 2313 } 2314 } 2315 %} 2316 2317 enc_class REX_mem_wide(memory mem) 2318 %{ 2319 if ($mem$$base >= 8) { 2320 if ($mem$$index < 8) { 2321 emit_opcode(cbuf, Assembler::REX_WB); 2322 } else { 2323 emit_opcode(cbuf, Assembler::REX_WXB); 2324 } 2325 } else { 2326 if ($mem$$index < 8) { 2327 emit_opcode(cbuf, Assembler::REX_W); 2328 } else { 2329 emit_opcode(cbuf, Assembler::REX_WX); 2330 } 2331 } 2332 %} 2333 2334 // for byte regs 2335 enc_class REX_breg(rRegI reg) 2336 %{ 2337 if ($reg$$reg >= 4) { 2338 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2339 } 2340 %} 2341 2342 // for byte regs 2343 enc_class REX_reg_breg(rRegI dst, rRegI src) 2344 %{ 2345 if ($dst$$reg < 8) { 2346 if ($src$$reg >= 4) { 2347 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2348 } 2349 } else { 2350 if ($src$$reg < 8) { 2351 emit_opcode(cbuf, Assembler::REX_R); 2352 } else { 2353 emit_opcode(cbuf, Assembler::REX_RB); 2354 } 2355 } 2356 %} 2357 2358 // for byte regs 2359 enc_class REX_breg_mem(rRegI reg, memory mem) 2360 %{ 2361 if ($reg$$reg < 8) { 2362 if ($mem$$base < 8) { 2363 if ($mem$$index >= 8) { 2364 emit_opcode(cbuf, Assembler::REX_X); 2365 } else if ($reg$$reg >= 4) { 2366 emit_opcode(cbuf, Assembler::REX); 2367 } 2368 } else { 2369 if ($mem$$index < 8) { 2370 emit_opcode(cbuf, Assembler::REX_B); 2371 } else { 2372 emit_opcode(cbuf, Assembler::REX_XB); 2373 } 2374 } 2375 } else { 2376 if ($mem$$base < 8) { 2377 if ($mem$$index < 8) { 2378 emit_opcode(cbuf, Assembler::REX_R); 2379 } else { 2380 emit_opcode(cbuf, Assembler::REX_RX); 2381 } 2382 } else { 2383 if ($mem$$index < 8) { 2384 emit_opcode(cbuf, Assembler::REX_RB); 2385 } else { 2386 emit_opcode(cbuf, Assembler::REX_RXB); 2387 } 2388 } 2389 } 2390 %} 2391 2392 enc_class REX_reg(rRegI reg) 2393 %{ 2394 if ($reg$$reg >= 8) { 2395 emit_opcode(cbuf, Assembler::REX_B); 2396 } 2397 %} 2398 2399 enc_class REX_reg_wide(rRegI reg) 2400 %{ 2401 if ($reg$$reg < 8) { 2402 emit_opcode(cbuf, Assembler::REX_W); 2403 } else { 2404 emit_opcode(cbuf, Assembler::REX_WB); 2405 } 2406 %} 2407 2408 enc_class REX_reg_reg(rRegI dst, rRegI src) 2409 %{ 2410 if ($dst$$reg < 8) { 2411 if ($src$$reg >= 8) { 2412 emit_opcode(cbuf, Assembler::REX_B); 2413 } 2414 } else { 2415 if ($src$$reg < 8) { 2416 emit_opcode(cbuf, Assembler::REX_R); 2417 } else { 2418 emit_opcode(cbuf, Assembler::REX_RB); 2419 } 2420 } 2421 %} 2422 2423 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2424 %{ 2425 if ($dst$$reg < 8) { 2426 if ($src$$reg < 8) { 2427 emit_opcode(cbuf, Assembler::REX_W); 2428 } else { 2429 emit_opcode(cbuf, Assembler::REX_WB); 2430 } 2431 } else { 2432 if ($src$$reg < 8) { 2433 emit_opcode(cbuf, Assembler::REX_WR); 2434 } else { 2435 emit_opcode(cbuf, Assembler::REX_WRB); 2436 } 2437 } 2438 %} 2439 2440 enc_class REX_reg_mem(rRegI reg, memory mem) 2441 %{ 2442 if ($reg$$reg < 8) { 2443 if ($mem$$base < 8) { 2444 if ($mem$$index >= 8) { 2445 emit_opcode(cbuf, Assembler::REX_X); 2446 } 2447 } else { 2448 if ($mem$$index < 8) { 2449 emit_opcode(cbuf, Assembler::REX_B); 2450 } else { 2451 emit_opcode(cbuf, Assembler::REX_XB); 2452 } 2453 } 2454 } else { 2455 if ($mem$$base < 8) { 2456 if ($mem$$index < 8) { 2457 emit_opcode(cbuf, Assembler::REX_R); 2458 } else { 2459 emit_opcode(cbuf, Assembler::REX_RX); 2460 } 2461 } else { 2462 if ($mem$$index < 8) { 2463 emit_opcode(cbuf, Assembler::REX_RB); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_RXB); 2466 } 2467 } 2468 } 2469 %} 2470 2471 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2472 %{ 2473 if ($reg$$reg < 8) { 2474 if ($mem$$base < 8) { 2475 if ($mem$$index < 8) { 2476 emit_opcode(cbuf, Assembler::REX_W); 2477 } else { 2478 emit_opcode(cbuf, Assembler::REX_WX); 2479 } 2480 } else { 2481 if ($mem$$index < 8) { 2482 emit_opcode(cbuf, Assembler::REX_WB); 2483 } else { 2484 emit_opcode(cbuf, Assembler::REX_WXB); 2485 } 2486 } 2487 } else { 2488 if ($mem$$base < 8) { 2489 if ($mem$$index < 8) { 2490 emit_opcode(cbuf, Assembler::REX_WR); 2491 } else { 2492 emit_opcode(cbuf, Assembler::REX_WRX); 2493 } 2494 } else { 2495 if ($mem$$index < 8) { 2496 emit_opcode(cbuf, Assembler::REX_WRB); 2497 } else { 2498 emit_opcode(cbuf, Assembler::REX_WRXB); 2499 } 2500 } 2501 } 2502 %} 2503 2504 enc_class reg_mem(rRegI ereg, memory mem) 2505 %{ 2506 // High registers handle in encode_RegMem 2507 int reg = $ereg$$reg; 2508 int base = $mem$$base; 2509 int index = $mem$$index; 2510 int scale = $mem$$scale; 2511 int disp = $mem$$disp; 2512 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2513 2514 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2515 %} 2516 2517 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2518 %{ 2519 int rm_byte_opcode = $rm_opcode$$constant; 2520 2521 // High registers handle in encode_RegMem 2522 int base = $mem$$base; 2523 int index = $mem$$index; 2524 int scale = $mem$$scale; 2525 int displace = $mem$$disp; 2526 2527 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2528 // working with static 2529 // globals 2530 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2531 disp_reloc); 2532 %} 2533 2534 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2535 %{ 2536 int reg_encoding = $dst$$reg; 2537 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2538 int index = 0x04; // 0x04 indicates no index 2539 int scale = 0x00; // 0x00 indicates no scale 2540 int displace = $src1$$constant; // 0x00 indicates no displacement 2541 relocInfo::relocType disp_reloc = relocInfo::none; 2542 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2543 disp_reloc); 2544 %} 2545 2546 enc_class neg_reg(rRegI dst) 2547 %{ 2548 int dstenc = $dst$$reg; 2549 if (dstenc >= 8) { 2550 emit_opcode(cbuf, Assembler::REX_B); 2551 dstenc -= 8; 2552 } 2553 // NEG $dst 2554 emit_opcode(cbuf, 0xF7); 2555 emit_rm(cbuf, 0x3, 0x03, dstenc); 2556 %} 2557 2558 enc_class neg_reg_wide(rRegI dst) 2559 %{ 2560 int dstenc = $dst$$reg; 2561 if (dstenc < 8) { 2562 emit_opcode(cbuf, Assembler::REX_W); 2563 } else { 2564 emit_opcode(cbuf, Assembler::REX_WB); 2565 dstenc -= 8; 2566 } 2567 // NEG $dst 2568 emit_opcode(cbuf, 0xF7); 2569 emit_rm(cbuf, 0x3, 0x03, dstenc); 2570 %} 2571 2572 enc_class setLT_reg(rRegI dst) 2573 %{ 2574 int dstenc = $dst$$reg; 2575 if (dstenc >= 8) { 2576 emit_opcode(cbuf, Assembler::REX_B); 2577 dstenc -= 8; 2578 } else if (dstenc >= 4) { 2579 emit_opcode(cbuf, Assembler::REX); 2580 } 2581 // SETLT $dst 2582 emit_opcode(cbuf, 0x0F); 2583 emit_opcode(cbuf, 0x9C); 2584 emit_rm(cbuf, 0x3, 0x0, dstenc); 2585 %} 2586 2587 enc_class setNZ_reg(rRegI dst) 2588 %{ 2589 int dstenc = $dst$$reg; 2590 if (dstenc >= 8) { 2591 emit_opcode(cbuf, Assembler::REX_B); 2592 dstenc -= 8; 2593 } else if (dstenc >= 4) { 2594 emit_opcode(cbuf, Assembler::REX); 2595 } 2596 // SETNZ $dst 2597 emit_opcode(cbuf, 0x0F); 2598 emit_opcode(cbuf, 0x95); 2599 emit_rm(cbuf, 0x3, 0x0, dstenc); 2600 %} 2601 2602 2603 // Compare the lonogs and set -1, 0, or 1 into dst 2604 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2605 %{ 2606 int src1enc = $src1$$reg; 2607 int src2enc = $src2$$reg; 2608 int dstenc = $dst$$reg; 2609 2610 // cmpq $src1, $src2 2611 if (src1enc < 8) { 2612 if (src2enc < 8) { 2613 emit_opcode(cbuf, Assembler::REX_W); 2614 } else { 2615 emit_opcode(cbuf, Assembler::REX_WB); 2616 } 2617 } else { 2618 if (src2enc < 8) { 2619 emit_opcode(cbuf, Assembler::REX_WR); 2620 } else { 2621 emit_opcode(cbuf, Assembler::REX_WRB); 2622 } 2623 } 2624 emit_opcode(cbuf, 0x3B); 2625 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2626 2627 // movl $dst, -1 2628 if (dstenc >= 8) { 2629 emit_opcode(cbuf, Assembler::REX_B); 2630 } 2631 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2632 emit_d32(cbuf, -1); 2633 2634 // jl,s done 2635 emit_opcode(cbuf, 0x7C); 2636 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2637 2638 // setne $dst 2639 if (dstenc >= 4) { 2640 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2641 } 2642 emit_opcode(cbuf, 0x0F); 2643 emit_opcode(cbuf, 0x95); 2644 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2645 2646 // movzbl $dst, $dst 2647 if (dstenc >= 4) { 2648 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2649 } 2650 emit_opcode(cbuf, 0x0F); 2651 emit_opcode(cbuf, 0xB6); 2652 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2653 %} 2654 2655 enc_class Push_ResultXD(regD dst) %{ 2656 MacroAssembler _masm(&cbuf); 2657 __ fstp_d(Address(rsp, 0)); 2658 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2659 __ addptr(rsp, 8); 2660 %} 2661 2662 enc_class Push_SrcXD(regD src) %{ 2663 MacroAssembler _masm(&cbuf); 2664 __ subptr(rsp, 8); 2665 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2666 __ fld_d(Address(rsp, 0)); 2667 %} 2668 2669 2670 enc_class enc_rethrow() 2671 %{ 2672 cbuf.set_insts_mark(); 2673 emit_opcode(cbuf, 0xE9); // jmp entry 2674 emit_d32_reloc(cbuf, 2675 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2676 runtime_call_Relocation::spec(), 2677 RELOC_DISP32); 2678 %} 2679 2680 %} 2681 2682 2683 2684 //----------FRAME-------------------------------------------------------------- 2685 // Definition of frame structure and management information. 2686 // 2687 // S T A C K L A Y O U T Allocators stack-slot number 2688 // | (to get allocators register number 2689 // G Owned by | | v add OptoReg::stack0()) 2690 // r CALLER | | 2691 // o | +--------+ pad to even-align allocators stack-slot 2692 // w V | pad0 | numbers; owned by CALLER 2693 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2694 // h ^ | in | 5 2695 // | | args | 4 Holes in incoming args owned by SELF 2696 // | | | | 3 2697 // | | +--------+ 2698 // V | | old out| Empty on Intel, window on Sparc 2699 // | old |preserve| Must be even aligned. 2700 // | SP-+--------+----> Matcher::_old_SP, even aligned 2701 // | | in | 3 area for Intel ret address 2702 // Owned by |preserve| Empty on Sparc. 2703 // SELF +--------+ 2704 // | | pad2 | 2 pad to align old SP 2705 // | +--------+ 1 2706 // | | locks | 0 2707 // | +--------+----> OptoReg::stack0(), even aligned 2708 // | | pad1 | 11 pad to align new SP 2709 // | +--------+ 2710 // | | | 10 2711 // | | spills | 9 spills 2712 // V | | 8 (pad0 slot for callee) 2713 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2714 // ^ | out | 7 2715 // | | args | 6 Holes in outgoing args owned by CALLEE 2716 // Owned by +--------+ 2717 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2718 // | new |preserve| Must be even-aligned. 2719 // | SP-+--------+----> Matcher::_new_SP, even aligned 2720 // | | | 2721 // 2722 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2723 // known from SELF's arguments and the Java calling convention. 2724 // Region 6-7 is determined per call site. 2725 // Note 2: If the calling convention leaves holes in the incoming argument 2726 // area, those holes are owned by SELF. Holes in the outgoing area 2727 // are owned by the CALLEE. Holes should not be nessecary in the 2728 // incoming area, as the Java calling convention is completely under 2729 // the control of the AD file. Doubles can be sorted and packed to 2730 // avoid holes. Holes in the outgoing arguments may be nessecary for 2731 // varargs C calling conventions. 2732 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2733 // even aligned with pad0 as needed. 2734 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2735 // region 6-11 is even aligned; it may be padded out more so that 2736 // the region from SP to FP meets the minimum stack alignment. 2737 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2738 // alignment. Region 11, pad1, may be dynamically extended so that 2739 // SP meets the minimum alignment. 2740 2741 frame 2742 %{ 2743 // What direction does stack grow in (assumed to be same for C & Java) 2744 stack_direction(TOWARDS_LOW); 2745 2746 // These three registers define part of the calling convention 2747 // between compiled code and the interpreter. 2748 inline_cache_reg(RAX); // Inline Cache Register 2749 interpreter_method_oop_reg(RBX); // Method Oop Register when 2750 // calling interpreter 2751 2752 // Optional: name the operand used by cisc-spilling to access 2753 // [stack_pointer + offset] 2754 cisc_spilling_operand_name(indOffset32); 2755 2756 // Number of stack slots consumed by locking an object 2757 sync_stack_slots(2); 2758 2759 // Compiled code's Frame Pointer 2760 frame_pointer(RSP); 2761 2762 // Interpreter stores its frame pointer in a register which is 2763 // stored to the stack by I2CAdaptors. 2764 // I2CAdaptors convert from interpreted java to compiled java. 2765 interpreter_frame_pointer(RBP); 2766 2767 // Stack alignment requirement 2768 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2769 2770 // Number of stack slots between incoming argument block and the start of 2771 // a new frame. The PROLOG must add this many slots to the stack. The 2772 // EPILOG must remove this many slots. amd64 needs two slots for 2773 // return address. 2774 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2775 2776 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2777 // for calls to C. Supports the var-args backing area for register parms. 2778 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2779 2780 // The after-PROLOG location of the return address. Location of 2781 // return address specifies a type (REG or STACK) and a number 2782 // representing the register number (i.e. - use a register name) or 2783 // stack slot. 2784 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2785 // Otherwise, it is above the locks and verification slot and alignment word 2786 return_addr(STACK - 2 + 2787 align_up((Compile::current()->in_preserve_stack_slots() + 2788 Compile::current()->fixed_slots()), 2789 stack_alignment_in_slots())); 2790 2791 // Body of function which returns an integer array locating 2792 // arguments either in registers or in stack slots. Passed an array 2793 // of ideal registers called "sig" and a "length" count. Stack-slot 2794 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2795 // arguments for a CALLEE. Incoming stack arguments are 2796 // automatically biased by the preserve_stack_slots field above. 2797 2798 calling_convention 2799 %{ 2800 // No difference between ingoing/outgoing just pass false 2801 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2802 %} 2803 2804 c_calling_convention 2805 %{ 2806 // This is obviously always outgoing 2807 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2808 %} 2809 2810 // Location of compiled Java return values. Same as C for now. 2811 return_value 2812 %{ 2813 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2814 "only return normal values"); 2815 2816 static const int lo[Op_RegL + 1] = { 2817 0, 2818 0, 2819 RAX_num, // Op_RegN 2820 RAX_num, // Op_RegI 2821 RAX_num, // Op_RegP 2822 XMM0_num, // Op_RegF 2823 XMM0_num, // Op_RegD 2824 RAX_num // Op_RegL 2825 }; 2826 static const int hi[Op_RegL + 1] = { 2827 0, 2828 0, 2829 OptoReg::Bad, // Op_RegN 2830 OptoReg::Bad, // Op_RegI 2831 RAX_H_num, // Op_RegP 2832 OptoReg::Bad, // Op_RegF 2833 XMM0b_num, // Op_RegD 2834 RAX_H_num // Op_RegL 2835 }; 2836 // Excluded flags and vector registers. 2837 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2838 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2839 %} 2840 %} 2841 2842 //----------ATTRIBUTES--------------------------------------------------------- 2843 //----------Operand Attributes------------------------------------------------- 2844 op_attrib op_cost(0); // Required cost attribute 2845 2846 //----------Instruction Attributes--------------------------------------------- 2847 ins_attrib ins_cost(100); // Required cost attribute 2848 ins_attrib ins_size(8); // Required size attribute (in bits) 2849 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2850 // a non-matching short branch variant 2851 // of some long branch? 2852 ins_attrib ins_alignment(1); // Required alignment attribute (must 2853 // be a power of 2) specifies the 2854 // alignment that some part of the 2855 // instruction (not necessarily the 2856 // start) requires. If > 1, a 2857 // compute_padding() function must be 2858 // provided for the instruction 2859 2860 //----------OPERANDS----------------------------------------------------------- 2861 // Operand definitions must precede instruction definitions for correct parsing 2862 // in the ADLC because operands constitute user defined types which are used in 2863 // instruction definitions. 2864 2865 //----------Simple Operands---------------------------------------------------- 2866 // Immediate Operands 2867 // Integer Immediate 2868 operand immI() 2869 %{ 2870 match(ConI); 2871 2872 op_cost(10); 2873 format %{ %} 2874 interface(CONST_INTER); 2875 %} 2876 2877 // Constant for test vs zero 2878 operand immI0() 2879 %{ 2880 predicate(n->get_int() == 0); 2881 match(ConI); 2882 2883 op_cost(0); 2884 format %{ %} 2885 interface(CONST_INTER); 2886 %} 2887 2888 // Constant for increment 2889 operand immI1() 2890 %{ 2891 predicate(n->get_int() == 1); 2892 match(ConI); 2893 2894 op_cost(0); 2895 format %{ %} 2896 interface(CONST_INTER); 2897 %} 2898 2899 // Constant for decrement 2900 operand immI_M1() 2901 %{ 2902 predicate(n->get_int() == -1); 2903 match(ConI); 2904 2905 op_cost(0); 2906 format %{ %} 2907 interface(CONST_INTER); 2908 %} 2909 2910 // Valid scale values for addressing modes 2911 operand immI2() 2912 %{ 2913 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2914 match(ConI); 2915 2916 format %{ %} 2917 interface(CONST_INTER); 2918 %} 2919 2920 operand immI8() 2921 %{ 2922 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2923 match(ConI); 2924 2925 op_cost(5); 2926 format %{ %} 2927 interface(CONST_INTER); 2928 %} 2929 2930 operand immU8() 2931 %{ 2932 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2933 match(ConI); 2934 2935 op_cost(5); 2936 format %{ %} 2937 interface(CONST_INTER); 2938 %} 2939 2940 operand immI16() 2941 %{ 2942 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2943 match(ConI); 2944 2945 op_cost(10); 2946 format %{ %} 2947 interface(CONST_INTER); 2948 %} 2949 2950 // Int Immediate non-negative 2951 operand immU31() 2952 %{ 2953 predicate(n->get_int() >= 0); 2954 match(ConI); 2955 2956 op_cost(0); 2957 format %{ %} 2958 interface(CONST_INTER); 2959 %} 2960 2961 // Constant for long shifts 2962 operand immI_32() 2963 %{ 2964 predicate( n->get_int() == 32 ); 2965 match(ConI); 2966 2967 op_cost(0); 2968 format %{ %} 2969 interface(CONST_INTER); 2970 %} 2971 2972 // Constant for long shifts 2973 operand immI_64() 2974 %{ 2975 predicate( n->get_int() == 64 ); 2976 match(ConI); 2977 2978 op_cost(0); 2979 format %{ %} 2980 interface(CONST_INTER); 2981 %} 2982 2983 // Pointer Immediate 2984 operand immP() 2985 %{ 2986 match(ConP); 2987 2988 op_cost(10); 2989 format %{ %} 2990 interface(CONST_INTER); 2991 %} 2992 2993 // NULL Pointer Immediate 2994 operand immP0() 2995 %{ 2996 predicate(n->get_ptr() == 0); 2997 match(ConP); 2998 2999 op_cost(5); 3000 format %{ %} 3001 interface(CONST_INTER); 3002 %} 3003 3004 // Pointer Immediate 3005 operand immN() %{ 3006 match(ConN); 3007 3008 op_cost(10); 3009 format %{ %} 3010 interface(CONST_INTER); 3011 %} 3012 3013 operand immNKlass() %{ 3014 match(ConNKlass); 3015 3016 op_cost(10); 3017 format %{ %} 3018 interface(CONST_INTER); 3019 %} 3020 3021 // NULL Pointer Immediate 3022 operand immN0() %{ 3023 predicate(n->get_narrowcon() == 0); 3024 match(ConN); 3025 3026 op_cost(5); 3027 format %{ %} 3028 interface(CONST_INTER); 3029 %} 3030 3031 operand immP31() 3032 %{ 3033 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3034 && (n->get_ptr() >> 31) == 0); 3035 match(ConP); 3036 3037 op_cost(5); 3038 format %{ %} 3039 interface(CONST_INTER); 3040 %} 3041 3042 3043 // Long Immediate 3044 operand immL() 3045 %{ 3046 match(ConL); 3047 3048 op_cost(20); 3049 format %{ %} 3050 interface(CONST_INTER); 3051 %} 3052 3053 // Long Immediate 8-bit 3054 operand immL8() 3055 %{ 3056 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3057 match(ConL); 3058 3059 op_cost(5); 3060 format %{ %} 3061 interface(CONST_INTER); 3062 %} 3063 3064 // Long Immediate 32-bit unsigned 3065 operand immUL32() 3066 %{ 3067 predicate(n->get_long() == (unsigned int) (n->get_long())); 3068 match(ConL); 3069 3070 op_cost(10); 3071 format %{ %} 3072 interface(CONST_INTER); 3073 %} 3074 3075 // Long Immediate 32-bit signed 3076 operand immL32() 3077 %{ 3078 predicate(n->get_long() == (int) (n->get_long())); 3079 match(ConL); 3080 3081 op_cost(15); 3082 format %{ %} 3083 interface(CONST_INTER); 3084 %} 3085 3086 operand immL_Pow2() 3087 %{ 3088 predicate(is_power_of_2((julong)n->get_long())); 3089 match(ConL); 3090 3091 op_cost(15); 3092 format %{ %} 3093 interface(CONST_INTER); 3094 %} 3095 3096 operand immL_NotPow2() 3097 %{ 3098 predicate(is_power_of_2((julong)~n->get_long())); 3099 match(ConL); 3100 3101 op_cost(15); 3102 format %{ %} 3103 interface(CONST_INTER); 3104 %} 3105 3106 // Long Immediate zero 3107 operand immL0() 3108 %{ 3109 predicate(n->get_long() == 0L); 3110 match(ConL); 3111 3112 op_cost(10); 3113 format %{ %} 3114 interface(CONST_INTER); 3115 %} 3116 3117 // Constant for increment 3118 operand immL1() 3119 %{ 3120 predicate(n->get_long() == 1); 3121 match(ConL); 3122 3123 format %{ %} 3124 interface(CONST_INTER); 3125 %} 3126 3127 // Constant for decrement 3128 operand immL_M1() 3129 %{ 3130 predicate(n->get_long() == -1); 3131 match(ConL); 3132 3133 format %{ %} 3134 interface(CONST_INTER); 3135 %} 3136 3137 // Long Immediate: the value 10 3138 operand immL10() 3139 %{ 3140 predicate(n->get_long() == 10); 3141 match(ConL); 3142 3143 format %{ %} 3144 interface(CONST_INTER); 3145 %} 3146 3147 // Long immediate from 0 to 127. 3148 // Used for a shorter form of long mul by 10. 3149 operand immL_127() 3150 %{ 3151 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3152 match(ConL); 3153 3154 op_cost(10); 3155 format %{ %} 3156 interface(CONST_INTER); 3157 %} 3158 3159 // Long Immediate: low 32-bit mask 3160 operand immL_32bits() 3161 %{ 3162 predicate(n->get_long() == 0xFFFFFFFFL); 3163 match(ConL); 3164 op_cost(20); 3165 3166 format %{ %} 3167 interface(CONST_INTER); 3168 %} 3169 3170 // Float Immediate zero 3171 operand immF0() 3172 %{ 3173 predicate(jint_cast(n->getf()) == 0); 3174 match(ConF); 3175 3176 op_cost(5); 3177 format %{ %} 3178 interface(CONST_INTER); 3179 %} 3180 3181 // Float Immediate 3182 operand immF() 3183 %{ 3184 match(ConF); 3185 3186 op_cost(15); 3187 format %{ %} 3188 interface(CONST_INTER); 3189 %} 3190 3191 // Double Immediate zero 3192 operand immD0() 3193 %{ 3194 predicate(jlong_cast(n->getd()) == 0); 3195 match(ConD); 3196 3197 op_cost(5); 3198 format %{ %} 3199 interface(CONST_INTER); 3200 %} 3201 3202 // Double Immediate 3203 operand immD() 3204 %{ 3205 match(ConD); 3206 3207 op_cost(15); 3208 format %{ %} 3209 interface(CONST_INTER); 3210 %} 3211 3212 // Immediates for special shifts (sign extend) 3213 3214 // Constants for increment 3215 operand immI_16() 3216 %{ 3217 predicate(n->get_int() == 16); 3218 match(ConI); 3219 3220 format %{ %} 3221 interface(CONST_INTER); 3222 %} 3223 3224 operand immI_24() 3225 %{ 3226 predicate(n->get_int() == 24); 3227 match(ConI); 3228 3229 format %{ %} 3230 interface(CONST_INTER); 3231 %} 3232 3233 // Constant for byte-wide masking 3234 operand immI_255() 3235 %{ 3236 predicate(n->get_int() == 255); 3237 match(ConI); 3238 3239 format %{ %} 3240 interface(CONST_INTER); 3241 %} 3242 3243 // Constant for short-wide masking 3244 operand immI_65535() 3245 %{ 3246 predicate(n->get_int() == 65535); 3247 match(ConI); 3248 3249 format %{ %} 3250 interface(CONST_INTER); 3251 %} 3252 3253 // Constant for byte-wide masking 3254 operand immL_255() 3255 %{ 3256 predicate(n->get_long() == 255); 3257 match(ConL); 3258 3259 format %{ %} 3260 interface(CONST_INTER); 3261 %} 3262 3263 // Constant for short-wide masking 3264 operand immL_65535() 3265 %{ 3266 predicate(n->get_long() == 65535); 3267 match(ConL); 3268 3269 format %{ %} 3270 interface(CONST_INTER); 3271 %} 3272 3273 // Register Operands 3274 // Integer Register 3275 operand rRegI() 3276 %{ 3277 constraint(ALLOC_IN_RC(int_reg)); 3278 match(RegI); 3279 3280 match(rax_RegI); 3281 match(rbx_RegI); 3282 match(rcx_RegI); 3283 match(rdx_RegI); 3284 match(rdi_RegI); 3285 3286 format %{ %} 3287 interface(REG_INTER); 3288 %} 3289 3290 // Special Registers 3291 operand rax_RegI() 3292 %{ 3293 constraint(ALLOC_IN_RC(int_rax_reg)); 3294 match(RegI); 3295 match(rRegI); 3296 3297 format %{ "RAX" %} 3298 interface(REG_INTER); 3299 %} 3300 3301 // Special Registers 3302 operand rbx_RegI() 3303 %{ 3304 constraint(ALLOC_IN_RC(int_rbx_reg)); 3305 match(RegI); 3306 match(rRegI); 3307 3308 format %{ "RBX" %} 3309 interface(REG_INTER); 3310 %} 3311 3312 operand rcx_RegI() 3313 %{ 3314 constraint(ALLOC_IN_RC(int_rcx_reg)); 3315 match(RegI); 3316 match(rRegI); 3317 3318 format %{ "RCX" %} 3319 interface(REG_INTER); 3320 %} 3321 3322 operand rdx_RegI() 3323 %{ 3324 constraint(ALLOC_IN_RC(int_rdx_reg)); 3325 match(RegI); 3326 match(rRegI); 3327 3328 format %{ "RDX" %} 3329 interface(REG_INTER); 3330 %} 3331 3332 operand rdi_RegI() 3333 %{ 3334 constraint(ALLOC_IN_RC(int_rdi_reg)); 3335 match(RegI); 3336 match(rRegI); 3337 3338 format %{ "RDI" %} 3339 interface(REG_INTER); 3340 %} 3341 3342 operand no_rax_rdx_RegI() 3343 %{ 3344 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3345 match(RegI); 3346 match(rbx_RegI); 3347 match(rcx_RegI); 3348 match(rdi_RegI); 3349 3350 format %{ %} 3351 interface(REG_INTER); 3352 %} 3353 3354 // Pointer Register 3355 operand any_RegP() 3356 %{ 3357 constraint(ALLOC_IN_RC(any_reg)); 3358 match(RegP); 3359 match(rax_RegP); 3360 match(rbx_RegP); 3361 match(rdi_RegP); 3362 match(rsi_RegP); 3363 match(rbp_RegP); 3364 match(r15_RegP); 3365 match(rRegP); 3366 3367 format %{ %} 3368 interface(REG_INTER); 3369 %} 3370 3371 operand rRegP() 3372 %{ 3373 constraint(ALLOC_IN_RC(ptr_reg)); 3374 match(RegP); 3375 match(rax_RegP); 3376 match(rbx_RegP); 3377 match(rdi_RegP); 3378 match(rsi_RegP); 3379 match(rbp_RegP); // See Q&A below about 3380 match(r15_RegP); // r15_RegP and rbp_RegP. 3381 3382 format %{ %} 3383 interface(REG_INTER); 3384 %} 3385 3386 operand rRegN() %{ 3387 constraint(ALLOC_IN_RC(int_reg)); 3388 match(RegN); 3389 3390 format %{ %} 3391 interface(REG_INTER); 3392 %} 3393 3394 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3395 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3396 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3397 // The output of an instruction is controlled by the allocator, which respects 3398 // register class masks, not match rules. Unless an instruction mentions 3399 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3400 // by the allocator as an input. 3401 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3402 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3403 // result, RBP is not included in the output of the instruction either. 3404 3405 operand no_rax_RegP() 3406 %{ 3407 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3408 match(RegP); 3409 match(rbx_RegP); 3410 match(rsi_RegP); 3411 match(rdi_RegP); 3412 3413 format %{ %} 3414 interface(REG_INTER); 3415 %} 3416 3417 // This operand is not allowed to use RBP even if 3418 // RBP is not used to hold the frame pointer. 3419 operand no_rbp_RegP() 3420 %{ 3421 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3422 match(RegP); 3423 match(rbx_RegP); 3424 match(rsi_RegP); 3425 match(rdi_RegP); 3426 3427 format %{ %} 3428 interface(REG_INTER); 3429 %} 3430 3431 operand no_rax_rbx_RegP() 3432 %{ 3433 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3434 match(RegP); 3435 match(rsi_RegP); 3436 match(rdi_RegP); 3437 3438 format %{ %} 3439 interface(REG_INTER); 3440 %} 3441 3442 // Special Registers 3443 // Return a pointer value 3444 operand rax_RegP() 3445 %{ 3446 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3447 match(RegP); 3448 match(rRegP); 3449 3450 format %{ %} 3451 interface(REG_INTER); 3452 %} 3453 3454 // Special Registers 3455 // Return a compressed pointer value 3456 operand rax_RegN() 3457 %{ 3458 constraint(ALLOC_IN_RC(int_rax_reg)); 3459 match(RegN); 3460 match(rRegN); 3461 3462 format %{ %} 3463 interface(REG_INTER); 3464 %} 3465 3466 // Used in AtomicAdd 3467 operand rbx_RegP() 3468 %{ 3469 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3470 match(RegP); 3471 match(rRegP); 3472 3473 format %{ %} 3474 interface(REG_INTER); 3475 %} 3476 3477 operand rsi_RegP() 3478 %{ 3479 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3480 match(RegP); 3481 match(rRegP); 3482 3483 format %{ %} 3484 interface(REG_INTER); 3485 %} 3486 3487 operand rbp_RegP() 3488 %{ 3489 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3490 match(RegP); 3491 match(rRegP); 3492 3493 format %{ %} 3494 interface(REG_INTER); 3495 %} 3496 3497 // Used in rep stosq 3498 operand rdi_RegP() 3499 %{ 3500 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3501 match(RegP); 3502 match(rRegP); 3503 3504 format %{ %} 3505 interface(REG_INTER); 3506 %} 3507 3508 operand r15_RegP() 3509 %{ 3510 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3511 match(RegP); 3512 match(rRegP); 3513 3514 format %{ %} 3515 interface(REG_INTER); 3516 %} 3517 3518 operand rRegL() 3519 %{ 3520 constraint(ALLOC_IN_RC(long_reg)); 3521 match(RegL); 3522 match(rax_RegL); 3523 match(rdx_RegL); 3524 3525 format %{ %} 3526 interface(REG_INTER); 3527 %} 3528 3529 // Special Registers 3530 operand no_rax_rdx_RegL() 3531 %{ 3532 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3533 match(RegL); 3534 match(rRegL); 3535 3536 format %{ %} 3537 interface(REG_INTER); 3538 %} 3539 3540 operand no_rax_RegL() 3541 %{ 3542 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3543 match(RegL); 3544 match(rRegL); 3545 match(rdx_RegL); 3546 3547 format %{ %} 3548 interface(REG_INTER); 3549 %} 3550 3551 operand rax_RegL() 3552 %{ 3553 constraint(ALLOC_IN_RC(long_rax_reg)); 3554 match(RegL); 3555 match(rRegL); 3556 3557 format %{ "RAX" %} 3558 interface(REG_INTER); 3559 %} 3560 3561 operand rcx_RegL() 3562 %{ 3563 constraint(ALLOC_IN_RC(long_rcx_reg)); 3564 match(RegL); 3565 match(rRegL); 3566 3567 format %{ %} 3568 interface(REG_INTER); 3569 %} 3570 3571 operand rdx_RegL() 3572 %{ 3573 constraint(ALLOC_IN_RC(long_rdx_reg)); 3574 match(RegL); 3575 match(rRegL); 3576 3577 format %{ %} 3578 interface(REG_INTER); 3579 %} 3580 3581 // Flags register, used as output of compare instructions 3582 operand rFlagsReg() 3583 %{ 3584 constraint(ALLOC_IN_RC(int_flags)); 3585 match(RegFlags); 3586 3587 format %{ "RFLAGS" %} 3588 interface(REG_INTER); 3589 %} 3590 3591 // Flags register, used as output of FLOATING POINT compare instructions 3592 operand rFlagsRegU() 3593 %{ 3594 constraint(ALLOC_IN_RC(int_flags)); 3595 match(RegFlags); 3596 3597 format %{ "RFLAGS_U" %} 3598 interface(REG_INTER); 3599 %} 3600 3601 operand rFlagsRegUCF() %{ 3602 constraint(ALLOC_IN_RC(int_flags)); 3603 match(RegFlags); 3604 predicate(false); 3605 3606 format %{ "RFLAGS_U_CF" %} 3607 interface(REG_INTER); 3608 %} 3609 3610 // Float register operands 3611 operand regF() %{ 3612 constraint(ALLOC_IN_RC(float_reg)); 3613 match(RegF); 3614 3615 format %{ %} 3616 interface(REG_INTER); 3617 %} 3618 3619 // Float register operands 3620 operand legRegF() %{ 3621 constraint(ALLOC_IN_RC(float_reg_legacy)); 3622 match(RegF); 3623 3624 format %{ %} 3625 interface(REG_INTER); 3626 %} 3627 3628 // Float register operands 3629 operand vlRegF() %{ 3630 constraint(ALLOC_IN_RC(float_reg_vl)); 3631 match(RegF); 3632 3633 format %{ %} 3634 interface(REG_INTER); 3635 %} 3636 3637 // Double register operands 3638 operand regD() %{ 3639 constraint(ALLOC_IN_RC(double_reg)); 3640 match(RegD); 3641 3642 format %{ %} 3643 interface(REG_INTER); 3644 %} 3645 3646 // Double register operands 3647 operand legRegD() %{ 3648 constraint(ALLOC_IN_RC(double_reg_legacy)); 3649 match(RegD); 3650 3651 format %{ %} 3652 interface(REG_INTER); 3653 %} 3654 3655 // Double register operands 3656 operand vlRegD() %{ 3657 constraint(ALLOC_IN_RC(double_reg_vl)); 3658 match(RegD); 3659 3660 format %{ %} 3661 interface(REG_INTER); 3662 %} 3663 3664 //----------Memory Operands---------------------------------------------------- 3665 // Direct Memory Operand 3666 // operand direct(immP addr) 3667 // %{ 3668 // match(addr); 3669 3670 // format %{ "[$addr]" %} 3671 // interface(MEMORY_INTER) %{ 3672 // base(0xFFFFFFFF); 3673 // index(0x4); 3674 // scale(0x0); 3675 // disp($addr); 3676 // %} 3677 // %} 3678 3679 // Indirect Memory Operand 3680 operand indirect(any_RegP reg) 3681 %{ 3682 constraint(ALLOC_IN_RC(ptr_reg)); 3683 match(reg); 3684 3685 format %{ "[$reg]" %} 3686 interface(MEMORY_INTER) %{ 3687 base($reg); 3688 index(0x4); 3689 scale(0x0); 3690 disp(0x0); 3691 %} 3692 %} 3693 3694 // Indirect Memory Plus Short Offset Operand 3695 operand indOffset8(any_RegP reg, immL8 off) 3696 %{ 3697 constraint(ALLOC_IN_RC(ptr_reg)); 3698 match(AddP reg off); 3699 3700 format %{ "[$reg + $off (8-bit)]" %} 3701 interface(MEMORY_INTER) %{ 3702 base($reg); 3703 index(0x4); 3704 scale(0x0); 3705 disp($off); 3706 %} 3707 %} 3708 3709 // Indirect Memory Plus Long Offset Operand 3710 operand indOffset32(any_RegP reg, immL32 off) 3711 %{ 3712 constraint(ALLOC_IN_RC(ptr_reg)); 3713 match(AddP reg off); 3714 3715 format %{ "[$reg + $off (32-bit)]" %} 3716 interface(MEMORY_INTER) %{ 3717 base($reg); 3718 index(0x4); 3719 scale(0x0); 3720 disp($off); 3721 %} 3722 %} 3723 3724 // Indirect Memory Plus Index Register Plus Offset Operand 3725 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3726 %{ 3727 constraint(ALLOC_IN_RC(ptr_reg)); 3728 match(AddP (AddP reg lreg) off); 3729 3730 op_cost(10); 3731 format %{"[$reg + $off + $lreg]" %} 3732 interface(MEMORY_INTER) %{ 3733 base($reg); 3734 index($lreg); 3735 scale(0x0); 3736 disp($off); 3737 %} 3738 %} 3739 3740 // Indirect Memory Plus Index Register Plus Offset Operand 3741 operand indIndex(any_RegP reg, rRegL lreg) 3742 %{ 3743 constraint(ALLOC_IN_RC(ptr_reg)); 3744 match(AddP reg lreg); 3745 3746 op_cost(10); 3747 format %{"[$reg + $lreg]" %} 3748 interface(MEMORY_INTER) %{ 3749 base($reg); 3750 index($lreg); 3751 scale(0x0); 3752 disp(0x0); 3753 %} 3754 %} 3755 3756 // Indirect Memory Times Scale Plus Index Register 3757 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3758 %{ 3759 constraint(ALLOC_IN_RC(ptr_reg)); 3760 match(AddP reg (LShiftL lreg scale)); 3761 3762 op_cost(10); 3763 format %{"[$reg + $lreg << $scale]" %} 3764 interface(MEMORY_INTER) %{ 3765 base($reg); 3766 index($lreg); 3767 scale($scale); 3768 disp(0x0); 3769 %} 3770 %} 3771 3772 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3773 %{ 3774 constraint(ALLOC_IN_RC(ptr_reg)); 3775 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3776 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3777 3778 op_cost(10); 3779 format %{"[$reg + pos $idx << $scale]" %} 3780 interface(MEMORY_INTER) %{ 3781 base($reg); 3782 index($idx); 3783 scale($scale); 3784 disp(0x0); 3785 %} 3786 %} 3787 3788 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3789 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3790 %{ 3791 constraint(ALLOC_IN_RC(ptr_reg)); 3792 match(AddP (AddP reg (LShiftL lreg scale)) off); 3793 3794 op_cost(10); 3795 format %{"[$reg + $off + $lreg << $scale]" %} 3796 interface(MEMORY_INTER) %{ 3797 base($reg); 3798 index($lreg); 3799 scale($scale); 3800 disp($off); 3801 %} 3802 %} 3803 3804 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3805 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3806 %{ 3807 constraint(ALLOC_IN_RC(ptr_reg)); 3808 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3809 match(AddP (AddP reg (ConvI2L idx)) off); 3810 3811 op_cost(10); 3812 format %{"[$reg + $off + $idx]" %} 3813 interface(MEMORY_INTER) %{ 3814 base($reg); 3815 index($idx); 3816 scale(0x0); 3817 disp($off); 3818 %} 3819 %} 3820 3821 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3822 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3823 %{ 3824 constraint(ALLOC_IN_RC(ptr_reg)); 3825 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3826 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3827 3828 op_cost(10); 3829 format %{"[$reg + $off + $idx << $scale]" %} 3830 interface(MEMORY_INTER) %{ 3831 base($reg); 3832 index($idx); 3833 scale($scale); 3834 disp($off); 3835 %} 3836 %} 3837 3838 // Indirect Narrow Oop Plus Offset Operand 3839 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3840 // we can't free r12 even with CompressedOops::base() == NULL. 3841 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3842 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3843 constraint(ALLOC_IN_RC(ptr_reg)); 3844 match(AddP (DecodeN reg) off); 3845 3846 op_cost(10); 3847 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3848 interface(MEMORY_INTER) %{ 3849 base(0xc); // R12 3850 index($reg); 3851 scale(0x3); 3852 disp($off); 3853 %} 3854 %} 3855 3856 // Indirect Memory Operand 3857 operand indirectNarrow(rRegN reg) 3858 %{ 3859 predicate(CompressedOops::shift() == 0); 3860 constraint(ALLOC_IN_RC(ptr_reg)); 3861 match(DecodeN reg); 3862 3863 format %{ "[$reg]" %} 3864 interface(MEMORY_INTER) %{ 3865 base($reg); 3866 index(0x4); 3867 scale(0x0); 3868 disp(0x0); 3869 %} 3870 %} 3871 3872 // Indirect Memory Plus Short Offset Operand 3873 operand indOffset8Narrow(rRegN reg, immL8 off) 3874 %{ 3875 predicate(CompressedOops::shift() == 0); 3876 constraint(ALLOC_IN_RC(ptr_reg)); 3877 match(AddP (DecodeN reg) off); 3878 3879 format %{ "[$reg + $off (8-bit)]" %} 3880 interface(MEMORY_INTER) %{ 3881 base($reg); 3882 index(0x4); 3883 scale(0x0); 3884 disp($off); 3885 %} 3886 %} 3887 3888 // Indirect Memory Plus Long Offset Operand 3889 operand indOffset32Narrow(rRegN reg, immL32 off) 3890 %{ 3891 predicate(CompressedOops::shift() == 0); 3892 constraint(ALLOC_IN_RC(ptr_reg)); 3893 match(AddP (DecodeN reg) off); 3894 3895 format %{ "[$reg + $off (32-bit)]" %} 3896 interface(MEMORY_INTER) %{ 3897 base($reg); 3898 index(0x4); 3899 scale(0x0); 3900 disp($off); 3901 %} 3902 %} 3903 3904 // Indirect Memory Plus Index Register Plus Offset Operand 3905 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3906 %{ 3907 predicate(CompressedOops::shift() == 0); 3908 constraint(ALLOC_IN_RC(ptr_reg)); 3909 match(AddP (AddP (DecodeN reg) lreg) off); 3910 3911 op_cost(10); 3912 format %{"[$reg + $off + $lreg]" %} 3913 interface(MEMORY_INTER) %{ 3914 base($reg); 3915 index($lreg); 3916 scale(0x0); 3917 disp($off); 3918 %} 3919 %} 3920 3921 // Indirect Memory Plus Index Register Plus Offset Operand 3922 operand indIndexNarrow(rRegN reg, rRegL lreg) 3923 %{ 3924 predicate(CompressedOops::shift() == 0); 3925 constraint(ALLOC_IN_RC(ptr_reg)); 3926 match(AddP (DecodeN reg) lreg); 3927 3928 op_cost(10); 3929 format %{"[$reg + $lreg]" %} 3930 interface(MEMORY_INTER) %{ 3931 base($reg); 3932 index($lreg); 3933 scale(0x0); 3934 disp(0x0); 3935 %} 3936 %} 3937 3938 // Indirect Memory Times Scale Plus Index Register 3939 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3940 %{ 3941 predicate(CompressedOops::shift() == 0); 3942 constraint(ALLOC_IN_RC(ptr_reg)); 3943 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3944 3945 op_cost(10); 3946 format %{"[$reg + $lreg << $scale]" %} 3947 interface(MEMORY_INTER) %{ 3948 base($reg); 3949 index($lreg); 3950 scale($scale); 3951 disp(0x0); 3952 %} 3953 %} 3954 3955 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3956 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3957 %{ 3958 predicate(CompressedOops::shift() == 0); 3959 constraint(ALLOC_IN_RC(ptr_reg)); 3960 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3961 3962 op_cost(10); 3963 format %{"[$reg + $off + $lreg << $scale]" %} 3964 interface(MEMORY_INTER) %{ 3965 base($reg); 3966 index($lreg); 3967 scale($scale); 3968 disp($off); 3969 %} 3970 %} 3971 3972 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3973 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3974 %{ 3975 constraint(ALLOC_IN_RC(ptr_reg)); 3976 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3977 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3978 3979 op_cost(10); 3980 format %{"[$reg + $off + $idx]" %} 3981 interface(MEMORY_INTER) %{ 3982 base($reg); 3983 index($idx); 3984 scale(0x0); 3985 disp($off); 3986 %} 3987 %} 3988 3989 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3990 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3991 %{ 3992 constraint(ALLOC_IN_RC(ptr_reg)); 3993 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3994 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3995 3996 op_cost(10); 3997 format %{"[$reg + $off + $idx << $scale]" %} 3998 interface(MEMORY_INTER) %{ 3999 base($reg); 4000 index($idx); 4001 scale($scale); 4002 disp($off); 4003 %} 4004 %} 4005 4006 //----------Special Memory Operands-------------------------------------------- 4007 // Stack Slot Operand - This operand is used for loading and storing temporary 4008 // values on the stack where a match requires a value to 4009 // flow through memory. 4010 operand stackSlotP(sRegP reg) 4011 %{ 4012 constraint(ALLOC_IN_RC(stack_slots)); 4013 // No match rule because this operand is only generated in matching 4014 4015 format %{ "[$reg]" %} 4016 interface(MEMORY_INTER) %{ 4017 base(0x4); // RSP 4018 index(0x4); // No Index 4019 scale(0x0); // No Scale 4020 disp($reg); // Stack Offset 4021 %} 4022 %} 4023 4024 operand stackSlotI(sRegI reg) 4025 %{ 4026 constraint(ALLOC_IN_RC(stack_slots)); 4027 // No match rule because this operand is only generated in matching 4028 4029 format %{ "[$reg]" %} 4030 interface(MEMORY_INTER) %{ 4031 base(0x4); // RSP 4032 index(0x4); // No Index 4033 scale(0x0); // No Scale 4034 disp($reg); // Stack Offset 4035 %} 4036 %} 4037 4038 operand stackSlotF(sRegF reg) 4039 %{ 4040 constraint(ALLOC_IN_RC(stack_slots)); 4041 // No match rule because this operand is only generated in matching 4042 4043 format %{ "[$reg]" %} 4044 interface(MEMORY_INTER) %{ 4045 base(0x4); // RSP 4046 index(0x4); // No Index 4047 scale(0x0); // No Scale 4048 disp($reg); // Stack Offset 4049 %} 4050 %} 4051 4052 operand stackSlotD(sRegD reg) 4053 %{ 4054 constraint(ALLOC_IN_RC(stack_slots)); 4055 // No match rule because this operand is only generated in matching 4056 4057 format %{ "[$reg]" %} 4058 interface(MEMORY_INTER) %{ 4059 base(0x4); // RSP 4060 index(0x4); // No Index 4061 scale(0x0); // No Scale 4062 disp($reg); // Stack Offset 4063 %} 4064 %} 4065 operand stackSlotL(sRegL reg) 4066 %{ 4067 constraint(ALLOC_IN_RC(stack_slots)); 4068 // No match rule because this operand is only generated in matching 4069 4070 format %{ "[$reg]" %} 4071 interface(MEMORY_INTER) %{ 4072 base(0x4); // RSP 4073 index(0x4); // No Index 4074 scale(0x0); // No Scale 4075 disp($reg); // Stack Offset 4076 %} 4077 %} 4078 4079 //----------Conditional Branch Operands---------------------------------------- 4080 // Comparison Op - This is the operation of the comparison, and is limited to 4081 // the following set of codes: 4082 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4083 // 4084 // Other attributes of the comparison, such as unsignedness, are specified 4085 // by the comparison instruction that sets a condition code flags register. 4086 // That result is represented by a flags operand whose subtype is appropriate 4087 // to the unsignedness (etc.) of the comparison. 4088 // 4089 // Later, the instruction which matches both the Comparison Op (a Bool) and 4090 // the flags (produced by the Cmp) specifies the coding of the comparison op 4091 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4092 4093 // Comparision Code 4094 operand cmpOp() 4095 %{ 4096 match(Bool); 4097 4098 format %{ "" %} 4099 interface(COND_INTER) %{ 4100 equal(0x4, "e"); 4101 not_equal(0x5, "ne"); 4102 less(0xC, "l"); 4103 greater_equal(0xD, "ge"); 4104 less_equal(0xE, "le"); 4105 greater(0xF, "g"); 4106 overflow(0x0, "o"); 4107 no_overflow(0x1, "no"); 4108 %} 4109 %} 4110 4111 // Comparison Code, unsigned compare. Used by FP also, with 4112 // C2 (unordered) turned into GT or LT already. The other bits 4113 // C0 and C3 are turned into Carry & Zero flags. 4114 operand cmpOpU() 4115 %{ 4116 match(Bool); 4117 4118 format %{ "" %} 4119 interface(COND_INTER) %{ 4120 equal(0x4, "e"); 4121 not_equal(0x5, "ne"); 4122 less(0x2, "b"); 4123 greater_equal(0x3, "nb"); 4124 less_equal(0x6, "be"); 4125 greater(0x7, "nbe"); 4126 overflow(0x0, "o"); 4127 no_overflow(0x1, "no"); 4128 %} 4129 %} 4130 4131 4132 // Floating comparisons that don't require any fixup for the unordered case 4133 operand cmpOpUCF() %{ 4134 match(Bool); 4135 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4136 n->as_Bool()->_test._test == BoolTest::ge || 4137 n->as_Bool()->_test._test == BoolTest::le || 4138 n->as_Bool()->_test._test == BoolTest::gt); 4139 format %{ "" %} 4140 interface(COND_INTER) %{ 4141 equal(0x4, "e"); 4142 not_equal(0x5, "ne"); 4143 less(0x2, "b"); 4144 greater_equal(0x3, "nb"); 4145 less_equal(0x6, "be"); 4146 greater(0x7, "nbe"); 4147 overflow(0x0, "o"); 4148 no_overflow(0x1, "no"); 4149 %} 4150 %} 4151 4152 4153 // Floating comparisons that can be fixed up with extra conditional jumps 4154 operand cmpOpUCF2() %{ 4155 match(Bool); 4156 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4157 n->as_Bool()->_test._test == BoolTest::eq); 4158 format %{ "" %} 4159 interface(COND_INTER) %{ 4160 equal(0x4, "e"); 4161 not_equal(0x5, "ne"); 4162 less(0x2, "b"); 4163 greater_equal(0x3, "nb"); 4164 less_equal(0x6, "be"); 4165 greater(0x7, "nbe"); 4166 overflow(0x0, "o"); 4167 no_overflow(0x1, "no"); 4168 %} 4169 %} 4170 4171 //----------OPERAND CLASSES---------------------------------------------------- 4172 // Operand Classes are groups of operands that are used as to simplify 4173 // instruction definitions by not requiring the AD writer to specify separate 4174 // instructions for every form of operand when the instruction accepts 4175 // multiple operand types with the same basic encoding and format. The classic 4176 // case of this is memory operands. 4177 4178 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4179 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4180 indCompressedOopOffset, 4181 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4182 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4183 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4184 4185 //----------PIPELINE----------------------------------------------------------- 4186 // Rules which define the behavior of the target architectures pipeline. 4187 pipeline %{ 4188 4189 //----------ATTRIBUTES--------------------------------------------------------- 4190 attributes %{ 4191 variable_size_instructions; // Fixed size instructions 4192 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4193 instruction_unit_size = 1; // An instruction is 1 bytes long 4194 instruction_fetch_unit_size = 16; // The processor fetches one line 4195 instruction_fetch_units = 1; // of 16 bytes 4196 4197 // List of nop instructions 4198 nops( MachNop ); 4199 %} 4200 4201 //----------RESOURCES---------------------------------------------------------- 4202 // Resources are the functional units available to the machine 4203 4204 // Generic P2/P3 pipeline 4205 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4206 // 3 instructions decoded per cycle. 4207 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4208 // 3 ALU op, only ALU0 handles mul instructions. 4209 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4210 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4211 BR, FPU, 4212 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4213 4214 //----------PIPELINE DESCRIPTION----------------------------------------------- 4215 // Pipeline Description specifies the stages in the machine's pipeline 4216 4217 // Generic P2/P3 pipeline 4218 pipe_desc(S0, S1, S2, S3, S4, S5); 4219 4220 //----------PIPELINE CLASSES--------------------------------------------------- 4221 // Pipeline Classes describe the stages in which input and output are 4222 // referenced by the hardware pipeline. 4223 4224 // Naming convention: ialu or fpu 4225 // Then: _reg 4226 // Then: _reg if there is a 2nd register 4227 // Then: _long if it's a pair of instructions implementing a long 4228 // Then: _fat if it requires the big decoder 4229 // Or: _mem if it requires the big decoder and a memory unit. 4230 4231 // Integer ALU reg operation 4232 pipe_class ialu_reg(rRegI dst) 4233 %{ 4234 single_instruction; 4235 dst : S4(write); 4236 dst : S3(read); 4237 DECODE : S0; // any decoder 4238 ALU : S3; // any alu 4239 %} 4240 4241 // Long ALU reg operation 4242 pipe_class ialu_reg_long(rRegL dst) 4243 %{ 4244 instruction_count(2); 4245 dst : S4(write); 4246 dst : S3(read); 4247 DECODE : S0(2); // any 2 decoders 4248 ALU : S3(2); // both alus 4249 %} 4250 4251 // Integer ALU reg operation using big decoder 4252 pipe_class ialu_reg_fat(rRegI dst) 4253 %{ 4254 single_instruction; 4255 dst : S4(write); 4256 dst : S3(read); 4257 D0 : S0; // big decoder only 4258 ALU : S3; // any alu 4259 %} 4260 4261 // Long ALU reg operation using big decoder 4262 pipe_class ialu_reg_long_fat(rRegL dst) 4263 %{ 4264 instruction_count(2); 4265 dst : S4(write); 4266 dst : S3(read); 4267 D0 : S0(2); // big decoder only; twice 4268 ALU : S3(2); // any 2 alus 4269 %} 4270 4271 // Integer ALU reg-reg operation 4272 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4273 %{ 4274 single_instruction; 4275 dst : S4(write); 4276 src : S3(read); 4277 DECODE : S0; // any decoder 4278 ALU : S3; // any alu 4279 %} 4280 4281 // Long ALU reg-reg operation 4282 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4283 %{ 4284 instruction_count(2); 4285 dst : S4(write); 4286 src : S3(read); 4287 DECODE : S0(2); // any 2 decoders 4288 ALU : S3(2); // both alus 4289 %} 4290 4291 // Integer ALU reg-reg operation 4292 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4293 %{ 4294 single_instruction; 4295 dst : S4(write); 4296 src : S3(read); 4297 D0 : S0; // big decoder only 4298 ALU : S3; // any alu 4299 %} 4300 4301 // Long ALU reg-reg operation 4302 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4303 %{ 4304 instruction_count(2); 4305 dst : S4(write); 4306 src : S3(read); 4307 D0 : S0(2); // big decoder only; twice 4308 ALU : S3(2); // both alus 4309 %} 4310 4311 // Integer ALU reg-mem operation 4312 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4313 %{ 4314 single_instruction; 4315 dst : S5(write); 4316 mem : S3(read); 4317 D0 : S0; // big decoder only 4318 ALU : S4; // any alu 4319 MEM : S3; // any mem 4320 %} 4321 4322 // Integer mem operation (prefetch) 4323 pipe_class ialu_mem(memory mem) 4324 %{ 4325 single_instruction; 4326 mem : S3(read); 4327 D0 : S0; // big decoder only 4328 MEM : S3; // any mem 4329 %} 4330 4331 // Integer Store to Memory 4332 pipe_class ialu_mem_reg(memory mem, rRegI src) 4333 %{ 4334 single_instruction; 4335 mem : S3(read); 4336 src : S5(read); 4337 D0 : S0; // big decoder only 4338 ALU : S4; // any alu 4339 MEM : S3; 4340 %} 4341 4342 // // Long Store to Memory 4343 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4344 // %{ 4345 // instruction_count(2); 4346 // mem : S3(read); 4347 // src : S5(read); 4348 // D0 : S0(2); // big decoder only; twice 4349 // ALU : S4(2); // any 2 alus 4350 // MEM : S3(2); // Both mems 4351 // %} 4352 4353 // Integer Store to Memory 4354 pipe_class ialu_mem_imm(memory mem) 4355 %{ 4356 single_instruction; 4357 mem : S3(read); 4358 D0 : S0; // big decoder only 4359 ALU : S4; // any alu 4360 MEM : S3; 4361 %} 4362 4363 // Integer ALU0 reg-reg operation 4364 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4365 %{ 4366 single_instruction; 4367 dst : S4(write); 4368 src : S3(read); 4369 D0 : S0; // Big decoder only 4370 ALU0 : S3; // only alu0 4371 %} 4372 4373 // Integer ALU0 reg-mem operation 4374 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4375 %{ 4376 single_instruction; 4377 dst : S5(write); 4378 mem : S3(read); 4379 D0 : S0; // big decoder only 4380 ALU0 : S4; // ALU0 only 4381 MEM : S3; // any mem 4382 %} 4383 4384 // Integer ALU reg-reg operation 4385 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4386 %{ 4387 single_instruction; 4388 cr : S4(write); 4389 src1 : S3(read); 4390 src2 : S3(read); 4391 DECODE : S0; // any decoder 4392 ALU : S3; // any alu 4393 %} 4394 4395 // Integer ALU reg-imm operation 4396 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4397 %{ 4398 single_instruction; 4399 cr : S4(write); 4400 src1 : S3(read); 4401 DECODE : S0; // any decoder 4402 ALU : S3; // any alu 4403 %} 4404 4405 // Integer ALU reg-mem operation 4406 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4407 %{ 4408 single_instruction; 4409 cr : S4(write); 4410 src1 : S3(read); 4411 src2 : S3(read); 4412 D0 : S0; // big decoder only 4413 ALU : S4; // any alu 4414 MEM : S3; 4415 %} 4416 4417 // Conditional move reg-reg 4418 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4419 %{ 4420 instruction_count(4); 4421 y : S4(read); 4422 q : S3(read); 4423 p : S3(read); 4424 DECODE : S0(4); // any decoder 4425 %} 4426 4427 // Conditional move reg-reg 4428 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4429 %{ 4430 single_instruction; 4431 dst : S4(write); 4432 src : S3(read); 4433 cr : S3(read); 4434 DECODE : S0; // any decoder 4435 %} 4436 4437 // Conditional move reg-mem 4438 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4439 %{ 4440 single_instruction; 4441 dst : S4(write); 4442 src : S3(read); 4443 cr : S3(read); 4444 DECODE : S0; // any decoder 4445 MEM : S3; 4446 %} 4447 4448 // Conditional move reg-reg long 4449 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4450 %{ 4451 single_instruction; 4452 dst : S4(write); 4453 src : S3(read); 4454 cr : S3(read); 4455 DECODE : S0(2); // any 2 decoders 4456 %} 4457 4458 // XXX 4459 // // Conditional move double reg-reg 4460 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4461 // %{ 4462 // single_instruction; 4463 // dst : S4(write); 4464 // src : S3(read); 4465 // cr : S3(read); 4466 // DECODE : S0; // any decoder 4467 // %} 4468 4469 // Float reg-reg operation 4470 pipe_class fpu_reg(regD dst) 4471 %{ 4472 instruction_count(2); 4473 dst : S3(read); 4474 DECODE : S0(2); // any 2 decoders 4475 FPU : S3; 4476 %} 4477 4478 // Float reg-reg operation 4479 pipe_class fpu_reg_reg(regD dst, regD src) 4480 %{ 4481 instruction_count(2); 4482 dst : S4(write); 4483 src : S3(read); 4484 DECODE : S0(2); // any 2 decoders 4485 FPU : S3; 4486 %} 4487 4488 // Float reg-reg operation 4489 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4490 %{ 4491 instruction_count(3); 4492 dst : S4(write); 4493 src1 : S3(read); 4494 src2 : S3(read); 4495 DECODE : S0(3); // any 3 decoders 4496 FPU : S3(2); 4497 %} 4498 4499 // Float reg-reg operation 4500 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4501 %{ 4502 instruction_count(4); 4503 dst : S4(write); 4504 src1 : S3(read); 4505 src2 : S3(read); 4506 src3 : S3(read); 4507 DECODE : S0(4); // any 3 decoders 4508 FPU : S3(2); 4509 %} 4510 4511 // Float reg-reg operation 4512 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4513 %{ 4514 instruction_count(4); 4515 dst : S4(write); 4516 src1 : S3(read); 4517 src2 : S3(read); 4518 src3 : S3(read); 4519 DECODE : S1(3); // any 3 decoders 4520 D0 : S0; // Big decoder only 4521 FPU : S3(2); 4522 MEM : S3; 4523 %} 4524 4525 // Float reg-mem operation 4526 pipe_class fpu_reg_mem(regD dst, memory mem) 4527 %{ 4528 instruction_count(2); 4529 dst : S5(write); 4530 mem : S3(read); 4531 D0 : S0; // big decoder only 4532 DECODE : S1; // any decoder for FPU POP 4533 FPU : S4; 4534 MEM : S3; // any mem 4535 %} 4536 4537 // Float reg-mem operation 4538 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4539 %{ 4540 instruction_count(3); 4541 dst : S5(write); 4542 src1 : S3(read); 4543 mem : S3(read); 4544 D0 : S0; // big decoder only 4545 DECODE : S1(2); // any decoder for FPU POP 4546 FPU : S4; 4547 MEM : S3; // any mem 4548 %} 4549 4550 // Float mem-reg operation 4551 pipe_class fpu_mem_reg(memory mem, regD src) 4552 %{ 4553 instruction_count(2); 4554 src : S5(read); 4555 mem : S3(read); 4556 DECODE : S0; // any decoder for FPU PUSH 4557 D0 : S1; // big decoder only 4558 FPU : S4; 4559 MEM : S3; // any mem 4560 %} 4561 4562 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4563 %{ 4564 instruction_count(3); 4565 src1 : S3(read); 4566 src2 : S3(read); 4567 mem : S3(read); 4568 DECODE : S0(2); // any decoder for FPU PUSH 4569 D0 : S1; // big decoder only 4570 FPU : S4; 4571 MEM : S3; // any mem 4572 %} 4573 4574 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4575 %{ 4576 instruction_count(3); 4577 src1 : S3(read); 4578 src2 : S3(read); 4579 mem : S4(read); 4580 DECODE : S0; // any decoder for FPU PUSH 4581 D0 : S0(2); // big decoder only 4582 FPU : S4; 4583 MEM : S3(2); // any mem 4584 %} 4585 4586 pipe_class fpu_mem_mem(memory dst, memory src1) 4587 %{ 4588 instruction_count(2); 4589 src1 : S3(read); 4590 dst : S4(read); 4591 D0 : S0(2); // big decoder only 4592 MEM : S3(2); // any mem 4593 %} 4594 4595 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4596 %{ 4597 instruction_count(3); 4598 src1 : S3(read); 4599 src2 : S3(read); 4600 dst : S4(read); 4601 D0 : S0(3); // big decoder only 4602 FPU : S4; 4603 MEM : S3(3); // any mem 4604 %} 4605 4606 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4607 %{ 4608 instruction_count(3); 4609 src1 : S4(read); 4610 mem : S4(read); 4611 DECODE : S0; // any decoder for FPU PUSH 4612 D0 : S0(2); // big decoder only 4613 FPU : S4; 4614 MEM : S3(2); // any mem 4615 %} 4616 4617 // Float load constant 4618 pipe_class fpu_reg_con(regD dst) 4619 %{ 4620 instruction_count(2); 4621 dst : S5(write); 4622 D0 : S0; // big decoder only for the load 4623 DECODE : S1; // any decoder for FPU POP 4624 FPU : S4; 4625 MEM : S3; // any mem 4626 %} 4627 4628 // Float load constant 4629 pipe_class fpu_reg_reg_con(regD dst, regD src) 4630 %{ 4631 instruction_count(3); 4632 dst : S5(write); 4633 src : S3(read); 4634 D0 : S0; // big decoder only for the load 4635 DECODE : S1(2); // any decoder for FPU POP 4636 FPU : S4; 4637 MEM : S3; // any mem 4638 %} 4639 4640 // UnConditional branch 4641 pipe_class pipe_jmp(label labl) 4642 %{ 4643 single_instruction; 4644 BR : S3; 4645 %} 4646 4647 // Conditional branch 4648 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4649 %{ 4650 single_instruction; 4651 cr : S1(read); 4652 BR : S3; 4653 %} 4654 4655 // Allocation idiom 4656 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4657 %{ 4658 instruction_count(1); force_serialization; 4659 fixed_latency(6); 4660 heap_ptr : S3(read); 4661 DECODE : S0(3); 4662 D0 : S2; 4663 MEM : S3; 4664 ALU : S3(2); 4665 dst : S5(write); 4666 BR : S5; 4667 %} 4668 4669 // Generic big/slow expanded idiom 4670 pipe_class pipe_slow() 4671 %{ 4672 instruction_count(10); multiple_bundles; force_serialization; 4673 fixed_latency(100); 4674 D0 : S0(2); 4675 MEM : S3(2); 4676 %} 4677 4678 // The real do-nothing guy 4679 pipe_class empty() 4680 %{ 4681 instruction_count(0); 4682 %} 4683 4684 // Define the class for the Nop node 4685 define 4686 %{ 4687 MachNop = empty; 4688 %} 4689 4690 %} 4691 4692 //----------INSTRUCTIONS------------------------------------------------------- 4693 // 4694 // match -- States which machine-independent subtree may be replaced 4695 // by this instruction. 4696 // ins_cost -- The estimated cost of this instruction is used by instruction 4697 // selection to identify a minimum cost tree of machine 4698 // instructions that matches a tree of machine-independent 4699 // instructions. 4700 // format -- A string providing the disassembly for this instruction. 4701 // The value of an instruction's operand may be inserted 4702 // by referring to it with a '$' prefix. 4703 // opcode -- Three instruction opcodes may be provided. These are referred 4704 // to within an encode class as $primary, $secondary, and $tertiary 4705 // rrspectively. The primary opcode is commonly used to 4706 // indicate the type of machine instruction, while secondary 4707 // and tertiary are often used for prefix options or addressing 4708 // modes. 4709 // ins_encode -- A list of encode classes with parameters. The encode class 4710 // name must have been defined in an 'enc_class' specification 4711 // in the encode section of the architecture description. 4712 4713 4714 //----------Load/Store/Move Instructions--------------------------------------- 4715 //----------Load Instructions-------------------------------------------------- 4716 4717 // Load Byte (8 bit signed) 4718 instruct loadB(rRegI dst, memory mem) 4719 %{ 4720 match(Set dst (LoadB mem)); 4721 4722 ins_cost(125); 4723 format %{ "movsbl $dst, $mem\t# byte" %} 4724 4725 ins_encode %{ 4726 __ movsbl($dst$$Register, $mem$$Address); 4727 %} 4728 4729 ins_pipe(ialu_reg_mem); 4730 %} 4731 4732 // Load Byte (8 bit signed) into Long Register 4733 instruct loadB2L(rRegL dst, memory mem) 4734 %{ 4735 match(Set dst (ConvI2L (LoadB mem))); 4736 4737 ins_cost(125); 4738 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4739 4740 ins_encode %{ 4741 __ movsbq($dst$$Register, $mem$$Address); 4742 %} 4743 4744 ins_pipe(ialu_reg_mem); 4745 %} 4746 4747 // Load Unsigned Byte (8 bit UNsigned) 4748 instruct loadUB(rRegI dst, memory mem) 4749 %{ 4750 match(Set dst (LoadUB mem)); 4751 4752 ins_cost(125); 4753 format %{ "movzbl $dst, $mem\t# ubyte" %} 4754 4755 ins_encode %{ 4756 __ movzbl($dst$$Register, $mem$$Address); 4757 %} 4758 4759 ins_pipe(ialu_reg_mem); 4760 %} 4761 4762 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4763 instruct loadUB2L(rRegL dst, memory mem) 4764 %{ 4765 match(Set dst (ConvI2L (LoadUB mem))); 4766 4767 ins_cost(125); 4768 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4769 4770 ins_encode %{ 4771 __ movzbq($dst$$Register, $mem$$Address); 4772 %} 4773 4774 ins_pipe(ialu_reg_mem); 4775 %} 4776 4777 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4778 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4779 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4780 effect(KILL cr); 4781 4782 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4783 "andl $dst, right_n_bits($mask, 8)" %} 4784 ins_encode %{ 4785 Register Rdst = $dst$$Register; 4786 __ movzbq(Rdst, $mem$$Address); 4787 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4788 %} 4789 ins_pipe(ialu_reg_mem); 4790 %} 4791 4792 // Load Short (16 bit signed) 4793 instruct loadS(rRegI dst, memory mem) 4794 %{ 4795 match(Set dst (LoadS mem)); 4796 4797 ins_cost(125); 4798 format %{ "movswl $dst, $mem\t# short" %} 4799 4800 ins_encode %{ 4801 __ movswl($dst$$Register, $mem$$Address); 4802 %} 4803 4804 ins_pipe(ialu_reg_mem); 4805 %} 4806 4807 // Load Short (16 bit signed) to Byte (8 bit signed) 4808 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4809 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4810 4811 ins_cost(125); 4812 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4813 ins_encode %{ 4814 __ movsbl($dst$$Register, $mem$$Address); 4815 %} 4816 ins_pipe(ialu_reg_mem); 4817 %} 4818 4819 // Load Short (16 bit signed) into Long Register 4820 instruct loadS2L(rRegL dst, memory mem) 4821 %{ 4822 match(Set dst (ConvI2L (LoadS mem))); 4823 4824 ins_cost(125); 4825 format %{ "movswq $dst, $mem\t# short -> long" %} 4826 4827 ins_encode %{ 4828 __ movswq($dst$$Register, $mem$$Address); 4829 %} 4830 4831 ins_pipe(ialu_reg_mem); 4832 %} 4833 4834 // Load Unsigned Short/Char (16 bit UNsigned) 4835 instruct loadUS(rRegI dst, memory mem) 4836 %{ 4837 match(Set dst (LoadUS mem)); 4838 4839 ins_cost(125); 4840 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4841 4842 ins_encode %{ 4843 __ movzwl($dst$$Register, $mem$$Address); 4844 %} 4845 4846 ins_pipe(ialu_reg_mem); 4847 %} 4848 4849 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4850 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4851 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4852 4853 ins_cost(125); 4854 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4855 ins_encode %{ 4856 __ movsbl($dst$$Register, $mem$$Address); 4857 %} 4858 ins_pipe(ialu_reg_mem); 4859 %} 4860 4861 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4862 instruct loadUS2L(rRegL dst, memory mem) 4863 %{ 4864 match(Set dst (ConvI2L (LoadUS mem))); 4865 4866 ins_cost(125); 4867 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4868 4869 ins_encode %{ 4870 __ movzwq($dst$$Register, $mem$$Address); 4871 %} 4872 4873 ins_pipe(ialu_reg_mem); 4874 %} 4875 4876 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4877 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4878 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4879 4880 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4881 ins_encode %{ 4882 __ movzbq($dst$$Register, $mem$$Address); 4883 %} 4884 ins_pipe(ialu_reg_mem); 4885 %} 4886 4887 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4888 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4889 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4890 effect(KILL cr); 4891 4892 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4893 "andl $dst, right_n_bits($mask, 16)" %} 4894 ins_encode %{ 4895 Register Rdst = $dst$$Register; 4896 __ movzwq(Rdst, $mem$$Address); 4897 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4898 %} 4899 ins_pipe(ialu_reg_mem); 4900 %} 4901 4902 // Load Integer 4903 instruct loadI(rRegI dst, memory mem) 4904 %{ 4905 match(Set dst (LoadI mem)); 4906 4907 ins_cost(125); 4908 format %{ "movl $dst, $mem\t# int" %} 4909 4910 ins_encode %{ 4911 __ movl($dst$$Register, $mem$$Address); 4912 %} 4913 4914 ins_pipe(ialu_reg_mem); 4915 %} 4916 4917 // Load Integer (32 bit signed) to Byte (8 bit signed) 4918 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4919 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4920 4921 ins_cost(125); 4922 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4923 ins_encode %{ 4924 __ movsbl($dst$$Register, $mem$$Address); 4925 %} 4926 ins_pipe(ialu_reg_mem); 4927 %} 4928 4929 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4930 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4931 match(Set dst (AndI (LoadI mem) mask)); 4932 4933 ins_cost(125); 4934 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4935 ins_encode %{ 4936 __ movzbl($dst$$Register, $mem$$Address); 4937 %} 4938 ins_pipe(ialu_reg_mem); 4939 %} 4940 4941 // Load Integer (32 bit signed) to Short (16 bit signed) 4942 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4943 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4944 4945 ins_cost(125); 4946 format %{ "movswl $dst, $mem\t# int -> short" %} 4947 ins_encode %{ 4948 __ movswl($dst$$Register, $mem$$Address); 4949 %} 4950 ins_pipe(ialu_reg_mem); 4951 %} 4952 4953 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4954 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4955 match(Set dst (AndI (LoadI mem) mask)); 4956 4957 ins_cost(125); 4958 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4959 ins_encode %{ 4960 __ movzwl($dst$$Register, $mem$$Address); 4961 %} 4962 ins_pipe(ialu_reg_mem); 4963 %} 4964 4965 // Load Integer into Long Register 4966 instruct loadI2L(rRegL dst, memory mem) 4967 %{ 4968 match(Set dst (ConvI2L (LoadI mem))); 4969 4970 ins_cost(125); 4971 format %{ "movslq $dst, $mem\t# int -> long" %} 4972 4973 ins_encode %{ 4974 __ movslq($dst$$Register, $mem$$Address); 4975 %} 4976 4977 ins_pipe(ialu_reg_mem); 4978 %} 4979 4980 // Load Integer with mask 0xFF into Long Register 4981 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4982 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4983 4984 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4985 ins_encode %{ 4986 __ movzbq($dst$$Register, $mem$$Address); 4987 %} 4988 ins_pipe(ialu_reg_mem); 4989 %} 4990 4991 // Load Integer with mask 0xFFFF into Long Register 4992 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4993 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4994 4995 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4996 ins_encode %{ 4997 __ movzwq($dst$$Register, $mem$$Address); 4998 %} 4999 ins_pipe(ialu_reg_mem); 5000 %} 5001 5002 // Load Integer with a 31-bit mask into Long Register 5003 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5004 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5005 effect(KILL cr); 5006 5007 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5008 "andl $dst, $mask" %} 5009 ins_encode %{ 5010 Register Rdst = $dst$$Register; 5011 __ movl(Rdst, $mem$$Address); 5012 __ andl(Rdst, $mask$$constant); 5013 %} 5014 ins_pipe(ialu_reg_mem); 5015 %} 5016 5017 // Load Unsigned Integer into Long Register 5018 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5019 %{ 5020 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5021 5022 ins_cost(125); 5023 format %{ "movl $dst, $mem\t# uint -> long" %} 5024 5025 ins_encode %{ 5026 __ movl($dst$$Register, $mem$$Address); 5027 %} 5028 5029 ins_pipe(ialu_reg_mem); 5030 %} 5031 5032 // Load Long 5033 instruct loadL(rRegL dst, memory mem) 5034 %{ 5035 match(Set dst (LoadL mem)); 5036 5037 ins_cost(125); 5038 format %{ "movq $dst, $mem\t# long" %} 5039 5040 ins_encode %{ 5041 __ movq($dst$$Register, $mem$$Address); 5042 %} 5043 5044 ins_pipe(ialu_reg_mem); // XXX 5045 %} 5046 5047 // Load Range 5048 instruct loadRange(rRegI dst, memory mem) 5049 %{ 5050 match(Set dst (LoadRange mem)); 5051 5052 ins_cost(125); // XXX 5053 format %{ "movl $dst, $mem\t# range" %} 5054 opcode(0x8B); 5055 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5056 ins_pipe(ialu_reg_mem); 5057 %} 5058 5059 // Load Pointer 5060 instruct loadP(rRegP dst, memory mem) 5061 %{ 5062 match(Set dst (LoadP mem)); 5063 predicate(n->as_Load()->barrier_data() == 0); 5064 5065 ins_cost(125); // XXX 5066 format %{ "movq $dst, $mem\t# ptr" %} 5067 opcode(0x8B); 5068 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5069 ins_pipe(ialu_reg_mem); // XXX 5070 %} 5071 5072 // Load Compressed Pointer 5073 instruct loadN(rRegN dst, memory mem) 5074 %{ 5075 match(Set dst (LoadN mem)); 5076 5077 ins_cost(125); // XXX 5078 format %{ "movl $dst, $mem\t# compressed ptr" %} 5079 ins_encode %{ 5080 __ movl($dst$$Register, $mem$$Address); 5081 %} 5082 ins_pipe(ialu_reg_mem); // XXX 5083 %} 5084 5085 5086 // Load Klass Pointer 5087 instruct loadKlass(rRegP dst, memory mem) 5088 %{ 5089 match(Set dst (LoadKlass mem)); 5090 5091 ins_cost(125); // XXX 5092 format %{ "movq $dst, $mem\t# class" %} 5093 opcode(0x8B); 5094 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5095 ins_pipe(ialu_reg_mem); // XXX 5096 %} 5097 5098 // Load narrow Klass Pointer 5099 instruct loadNKlass(rRegN dst, memory mem) 5100 %{ 5101 match(Set dst (LoadNKlass mem)); 5102 5103 ins_cost(125); // XXX 5104 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5105 ins_encode %{ 5106 __ movl($dst$$Register, $mem$$Address); 5107 %} 5108 ins_pipe(ialu_reg_mem); // XXX 5109 %} 5110 5111 // Load Float 5112 instruct loadF(regF dst, memory mem) 5113 %{ 5114 match(Set dst (LoadF mem)); 5115 5116 ins_cost(145); // XXX 5117 format %{ "movss $dst, $mem\t# float" %} 5118 ins_encode %{ 5119 __ movflt($dst$$XMMRegister, $mem$$Address); 5120 %} 5121 ins_pipe(pipe_slow); // XXX 5122 %} 5123 5124 // Load Float 5125 instruct MoveF2VL(vlRegF dst, regF src) %{ 5126 match(Set dst src); 5127 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5128 ins_encode %{ 5129 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5130 %} 5131 ins_pipe( fpu_reg_reg ); 5132 %} 5133 5134 // Load Float 5135 instruct MoveF2LEG(legRegF dst, regF src) %{ 5136 match(Set dst src); 5137 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5138 ins_encode %{ 5139 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5140 %} 5141 ins_pipe( fpu_reg_reg ); 5142 %} 5143 5144 // Load Float 5145 instruct MoveVL2F(regF dst, vlRegF src) %{ 5146 match(Set dst src); 5147 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5148 ins_encode %{ 5149 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5150 %} 5151 ins_pipe( fpu_reg_reg ); 5152 %} 5153 5154 // Load Float 5155 instruct MoveLEG2F(regF dst, legRegF src) %{ 5156 match(Set dst src); 5157 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5158 ins_encode %{ 5159 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5160 %} 5161 ins_pipe( fpu_reg_reg ); 5162 %} 5163 5164 // Load Double 5165 instruct loadD_partial(regD dst, memory mem) 5166 %{ 5167 predicate(!UseXmmLoadAndClearUpper); 5168 match(Set dst (LoadD mem)); 5169 5170 ins_cost(145); // XXX 5171 format %{ "movlpd $dst, $mem\t# double" %} 5172 ins_encode %{ 5173 __ movdbl($dst$$XMMRegister, $mem$$Address); 5174 %} 5175 ins_pipe(pipe_slow); // XXX 5176 %} 5177 5178 instruct loadD(regD dst, memory mem) 5179 %{ 5180 predicate(UseXmmLoadAndClearUpper); 5181 match(Set dst (LoadD mem)); 5182 5183 ins_cost(145); // XXX 5184 format %{ "movsd $dst, $mem\t# double" %} 5185 ins_encode %{ 5186 __ movdbl($dst$$XMMRegister, $mem$$Address); 5187 %} 5188 ins_pipe(pipe_slow); // XXX 5189 %} 5190 5191 // Load Double 5192 instruct MoveD2VL(vlRegD dst, regD src) %{ 5193 match(Set dst src); 5194 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5195 ins_encode %{ 5196 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5197 %} 5198 ins_pipe( fpu_reg_reg ); 5199 %} 5200 5201 // Load Double 5202 instruct MoveD2LEG(legRegD dst, regD src) %{ 5203 match(Set dst src); 5204 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5205 ins_encode %{ 5206 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5207 %} 5208 ins_pipe( fpu_reg_reg ); 5209 %} 5210 5211 // Load Double 5212 instruct MoveVL2D(regD dst, vlRegD src) %{ 5213 match(Set dst src); 5214 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5215 ins_encode %{ 5216 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5217 %} 5218 ins_pipe( fpu_reg_reg ); 5219 %} 5220 5221 // Load Double 5222 instruct MoveLEG2D(regD dst, legRegD src) %{ 5223 match(Set dst src); 5224 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5225 ins_encode %{ 5226 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5227 %} 5228 ins_pipe( fpu_reg_reg ); 5229 %} 5230 5231 // Following pseudo code describes the algorithm for max[FD]: 5232 // Min algorithm is on similar lines 5233 // btmp = (b < +0.0) ? a : b 5234 // atmp = (b < +0.0) ? b : a 5235 // Tmp = Max_Float(atmp , btmp) 5236 // Res = (atmp == NaN) ? atmp : Tmp 5237 5238 // max = java.lang.Math.max(float a, float b) 5239 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5240 predicate(UseAVX > 0 && !n->is_reduction()); 5241 match(Set dst (MaxF a b)); 5242 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5243 format %{ 5244 "blendvps $btmp,$b,$a,$b \n\t" 5245 "blendvps $atmp,$a,$b,$b \n\t" 5246 "vmaxss $tmp,$atmp,$btmp \n\t" 5247 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5248 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5249 %} 5250 ins_encode %{ 5251 int vector_len = Assembler::AVX_128bit; 5252 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5253 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5254 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5255 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5256 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5257 %} 5258 ins_pipe( pipe_slow ); 5259 %} 5260 5261 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 5262 predicate(UseAVX > 0 && n->is_reduction()); 5263 match(Set dst (MaxF a b)); 5264 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5265 5266 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 5267 ins_encode %{ 5268 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5269 false /*min*/, true /*single*/); 5270 %} 5271 ins_pipe( pipe_slow ); 5272 %} 5273 5274 // max = java.lang.Math.max(double a, double b) 5275 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5276 predicate(UseAVX > 0 && !n->is_reduction()); 5277 match(Set dst (MaxD a b)); 5278 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 5279 format %{ 5280 "blendvpd $btmp,$b,$a,$b \n\t" 5281 "blendvpd $atmp,$a,$b,$b \n\t" 5282 "vmaxsd $tmp,$atmp,$btmp \n\t" 5283 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5284 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5285 %} 5286 ins_encode %{ 5287 int vector_len = Assembler::AVX_128bit; 5288 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5289 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5290 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5291 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5292 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5293 %} 5294 ins_pipe( pipe_slow ); 5295 %} 5296 5297 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 5298 predicate(UseAVX > 0 && n->is_reduction()); 5299 match(Set dst (MaxD a b)); 5300 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5301 5302 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 5303 ins_encode %{ 5304 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5305 false /*min*/, false /*single*/); 5306 %} 5307 ins_pipe( pipe_slow ); 5308 %} 5309 5310 // min = java.lang.Math.min(float a, float b) 5311 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5312 predicate(UseAVX > 0 && !n->is_reduction()); 5313 match(Set dst (MinF a b)); 5314 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5315 format %{ 5316 "blendvps $atmp,$a,$b,$a \n\t" 5317 "blendvps $btmp,$b,$a,$a \n\t" 5318 "vminss $tmp,$atmp,$btmp \n\t" 5319 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5320 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5321 %} 5322 ins_encode %{ 5323 int vector_len = Assembler::AVX_128bit; 5324 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5325 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5326 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5327 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5328 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5329 %} 5330 ins_pipe( pipe_slow ); 5331 %} 5332 5333 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 5334 predicate(UseAVX > 0 && n->is_reduction()); 5335 match(Set dst (MinF a b)); 5336 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5337 5338 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 5339 ins_encode %{ 5340 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5341 true /*min*/, true /*single*/); 5342 %} 5343 ins_pipe( pipe_slow ); 5344 %} 5345 5346 // min = java.lang.Math.min(double a, double b) 5347 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5348 predicate(UseAVX > 0 && !n->is_reduction()); 5349 match(Set dst (MinD a b)); 5350 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5351 format %{ 5352 "blendvpd $atmp,$a,$b,$a \n\t" 5353 "blendvpd $btmp,$b,$a,$a \n\t" 5354 "vminsd $tmp,$atmp,$btmp \n\t" 5355 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5356 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5357 %} 5358 ins_encode %{ 5359 int vector_len = Assembler::AVX_128bit; 5360 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5361 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5362 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5363 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5364 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5365 %} 5366 ins_pipe( pipe_slow ); 5367 %} 5368 5369 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 5370 predicate(UseAVX > 0 && n->is_reduction()); 5371 match(Set dst (MinD a b)); 5372 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5373 5374 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 5375 ins_encode %{ 5376 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5377 true /*min*/, false /*single*/); 5378 %} 5379 ins_pipe( pipe_slow ); 5380 %} 5381 5382 // Load Effective Address 5383 instruct leaP8(rRegP dst, indOffset8 mem) 5384 %{ 5385 match(Set dst mem); 5386 5387 ins_cost(110); // XXX 5388 format %{ "leaq $dst, $mem\t# ptr 8" %} 5389 opcode(0x8D); 5390 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5391 ins_pipe(ialu_reg_reg_fat); 5392 %} 5393 5394 instruct leaP32(rRegP dst, indOffset32 mem) 5395 %{ 5396 match(Set dst mem); 5397 5398 ins_cost(110); 5399 format %{ "leaq $dst, $mem\t# ptr 32" %} 5400 opcode(0x8D); 5401 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5402 ins_pipe(ialu_reg_reg_fat); 5403 %} 5404 5405 // instruct leaPIdx(rRegP dst, indIndex mem) 5406 // %{ 5407 // match(Set dst mem); 5408 5409 // ins_cost(110); 5410 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5411 // opcode(0x8D); 5412 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5413 // ins_pipe(ialu_reg_reg_fat); 5414 // %} 5415 5416 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5417 %{ 5418 match(Set dst mem); 5419 5420 ins_cost(110); 5421 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5422 opcode(0x8D); 5423 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5424 ins_pipe(ialu_reg_reg_fat); 5425 %} 5426 5427 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5428 %{ 5429 match(Set dst mem); 5430 5431 ins_cost(110); 5432 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5433 opcode(0x8D); 5434 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5435 ins_pipe(ialu_reg_reg_fat); 5436 %} 5437 5438 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5439 %{ 5440 match(Set dst mem); 5441 5442 ins_cost(110); 5443 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5444 opcode(0x8D); 5445 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5446 ins_pipe(ialu_reg_reg_fat); 5447 %} 5448 5449 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5450 %{ 5451 match(Set dst mem); 5452 5453 ins_cost(110); 5454 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5455 opcode(0x8D); 5456 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5457 ins_pipe(ialu_reg_reg_fat); 5458 %} 5459 5460 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5461 %{ 5462 match(Set dst mem); 5463 5464 ins_cost(110); 5465 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5466 opcode(0x8D); 5467 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5468 ins_pipe(ialu_reg_reg_fat); 5469 %} 5470 5471 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5472 %{ 5473 match(Set dst mem); 5474 5475 ins_cost(110); 5476 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5477 opcode(0x8D); 5478 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5479 ins_pipe(ialu_reg_reg_fat); 5480 %} 5481 5482 // Load Effective Address which uses Narrow (32-bits) oop 5483 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5484 %{ 5485 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 5486 match(Set dst mem); 5487 5488 ins_cost(110); 5489 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5490 opcode(0x8D); 5491 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5492 ins_pipe(ialu_reg_reg_fat); 5493 %} 5494 5495 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5496 %{ 5497 predicate(CompressedOops::shift() == 0); 5498 match(Set dst mem); 5499 5500 ins_cost(110); // XXX 5501 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5502 opcode(0x8D); 5503 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5504 ins_pipe(ialu_reg_reg_fat); 5505 %} 5506 5507 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5508 %{ 5509 predicate(CompressedOops::shift() == 0); 5510 match(Set dst mem); 5511 5512 ins_cost(110); 5513 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5514 opcode(0x8D); 5515 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5516 ins_pipe(ialu_reg_reg_fat); 5517 %} 5518 5519 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5520 %{ 5521 predicate(CompressedOops::shift() == 0); 5522 match(Set dst mem); 5523 5524 ins_cost(110); 5525 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5526 opcode(0x8D); 5527 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5528 ins_pipe(ialu_reg_reg_fat); 5529 %} 5530 5531 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5532 %{ 5533 predicate(CompressedOops::shift() == 0); 5534 match(Set dst mem); 5535 5536 ins_cost(110); 5537 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5538 opcode(0x8D); 5539 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5540 ins_pipe(ialu_reg_reg_fat); 5541 %} 5542 5543 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5544 %{ 5545 predicate(CompressedOops::shift() == 0); 5546 match(Set dst mem); 5547 5548 ins_cost(110); 5549 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5550 opcode(0x8D); 5551 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5552 ins_pipe(ialu_reg_reg_fat); 5553 %} 5554 5555 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5556 %{ 5557 predicate(CompressedOops::shift() == 0); 5558 match(Set dst mem); 5559 5560 ins_cost(110); 5561 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5562 opcode(0x8D); 5563 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5564 ins_pipe(ialu_reg_reg_fat); 5565 %} 5566 5567 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5568 %{ 5569 predicate(CompressedOops::shift() == 0); 5570 match(Set dst mem); 5571 5572 ins_cost(110); 5573 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5574 opcode(0x8D); 5575 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5576 ins_pipe(ialu_reg_reg_fat); 5577 %} 5578 5579 instruct loadConI(rRegI dst, immI src) 5580 %{ 5581 match(Set dst src); 5582 5583 format %{ "movl $dst, $src\t# int" %} 5584 ins_encode(load_immI(dst, src)); 5585 ins_pipe(ialu_reg_fat); // XXX 5586 %} 5587 5588 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5589 %{ 5590 match(Set dst src); 5591 effect(KILL cr); 5592 5593 ins_cost(50); 5594 format %{ "xorl $dst, $dst\t# int" %} 5595 opcode(0x33); /* + rd */ 5596 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5597 ins_pipe(ialu_reg); 5598 %} 5599 5600 instruct loadConL(rRegL dst, immL src) 5601 %{ 5602 match(Set dst src); 5603 5604 ins_cost(150); 5605 format %{ "movq $dst, $src\t# long" %} 5606 ins_encode(load_immL(dst, src)); 5607 ins_pipe(ialu_reg); 5608 %} 5609 5610 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5611 %{ 5612 match(Set dst src); 5613 effect(KILL cr); 5614 5615 ins_cost(50); 5616 format %{ "xorl $dst, $dst\t# long" %} 5617 opcode(0x33); /* + rd */ 5618 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5619 ins_pipe(ialu_reg); // XXX 5620 %} 5621 5622 instruct loadConUL32(rRegL dst, immUL32 src) 5623 %{ 5624 match(Set dst src); 5625 5626 ins_cost(60); 5627 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5628 ins_encode(load_immUL32(dst, src)); 5629 ins_pipe(ialu_reg); 5630 %} 5631 5632 instruct loadConL32(rRegL dst, immL32 src) 5633 %{ 5634 match(Set dst src); 5635 5636 ins_cost(70); 5637 format %{ "movq $dst, $src\t# long (32-bit)" %} 5638 ins_encode(load_immL32(dst, src)); 5639 ins_pipe(ialu_reg); 5640 %} 5641 5642 instruct loadConP(rRegP dst, immP con) %{ 5643 match(Set dst con); 5644 5645 format %{ "movq $dst, $con\t# ptr" %} 5646 ins_encode(load_immP(dst, con)); 5647 ins_pipe(ialu_reg_fat); // XXX 5648 %} 5649 5650 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5651 %{ 5652 match(Set dst src); 5653 effect(KILL cr); 5654 5655 ins_cost(50); 5656 format %{ "xorl $dst, $dst\t# ptr" %} 5657 opcode(0x33); /* + rd */ 5658 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5659 ins_pipe(ialu_reg); 5660 %} 5661 5662 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5663 %{ 5664 match(Set dst src); 5665 effect(KILL cr); 5666 5667 ins_cost(60); 5668 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5669 ins_encode(load_immP31(dst, src)); 5670 ins_pipe(ialu_reg); 5671 %} 5672 5673 instruct loadConF(regF dst, immF con) %{ 5674 match(Set dst con); 5675 ins_cost(125); 5676 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5677 ins_encode %{ 5678 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5679 %} 5680 ins_pipe(pipe_slow); 5681 %} 5682 5683 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5684 match(Set dst src); 5685 effect(KILL cr); 5686 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5687 ins_encode %{ 5688 __ xorq($dst$$Register, $dst$$Register); 5689 %} 5690 ins_pipe(ialu_reg); 5691 %} 5692 5693 instruct loadConN(rRegN dst, immN src) %{ 5694 match(Set dst src); 5695 5696 ins_cost(125); 5697 format %{ "movl $dst, $src\t# compressed ptr" %} 5698 ins_encode %{ 5699 address con = (address)$src$$constant; 5700 if (con == NULL) { 5701 ShouldNotReachHere(); 5702 } else { 5703 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5704 } 5705 %} 5706 ins_pipe(ialu_reg_fat); // XXX 5707 %} 5708 5709 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5710 match(Set dst src); 5711 5712 ins_cost(125); 5713 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5714 ins_encode %{ 5715 address con = (address)$src$$constant; 5716 if (con == NULL) { 5717 ShouldNotReachHere(); 5718 } else { 5719 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5720 } 5721 %} 5722 ins_pipe(ialu_reg_fat); // XXX 5723 %} 5724 5725 instruct loadConF0(regF dst, immF0 src) 5726 %{ 5727 match(Set dst src); 5728 ins_cost(100); 5729 5730 format %{ "xorps $dst, $dst\t# float 0.0" %} 5731 ins_encode %{ 5732 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5733 %} 5734 ins_pipe(pipe_slow); 5735 %} 5736 5737 // Use the same format since predicate() can not be used here. 5738 instruct loadConD(regD dst, immD con) %{ 5739 match(Set dst con); 5740 ins_cost(125); 5741 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5742 ins_encode %{ 5743 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5744 %} 5745 ins_pipe(pipe_slow); 5746 %} 5747 5748 instruct loadConD0(regD dst, immD0 src) 5749 %{ 5750 match(Set dst src); 5751 ins_cost(100); 5752 5753 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5754 ins_encode %{ 5755 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5756 %} 5757 ins_pipe(pipe_slow); 5758 %} 5759 5760 instruct loadSSI(rRegI dst, stackSlotI src) 5761 %{ 5762 match(Set dst src); 5763 5764 ins_cost(125); 5765 format %{ "movl $dst, $src\t# int stk" %} 5766 opcode(0x8B); 5767 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5768 ins_pipe(ialu_reg_mem); 5769 %} 5770 5771 instruct loadSSL(rRegL dst, stackSlotL src) 5772 %{ 5773 match(Set dst src); 5774 5775 ins_cost(125); 5776 format %{ "movq $dst, $src\t# long stk" %} 5777 opcode(0x8B); 5778 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5779 ins_pipe(ialu_reg_mem); 5780 %} 5781 5782 instruct loadSSP(rRegP dst, stackSlotP src) 5783 %{ 5784 match(Set dst src); 5785 5786 ins_cost(125); 5787 format %{ "movq $dst, $src\t# ptr stk" %} 5788 opcode(0x8B); 5789 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5790 ins_pipe(ialu_reg_mem); 5791 %} 5792 5793 instruct loadSSF(regF dst, stackSlotF src) 5794 %{ 5795 match(Set dst src); 5796 5797 ins_cost(125); 5798 format %{ "movss $dst, $src\t# float stk" %} 5799 ins_encode %{ 5800 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5801 %} 5802 ins_pipe(pipe_slow); // XXX 5803 %} 5804 5805 // Use the same format since predicate() can not be used here. 5806 instruct loadSSD(regD dst, stackSlotD src) 5807 %{ 5808 match(Set dst src); 5809 5810 ins_cost(125); 5811 format %{ "movsd $dst, $src\t# double stk" %} 5812 ins_encode %{ 5813 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5814 %} 5815 ins_pipe(pipe_slow); // XXX 5816 %} 5817 5818 // Prefetch instructions for allocation. 5819 // Must be safe to execute with invalid address (cannot fault). 5820 5821 instruct prefetchAlloc( memory mem ) %{ 5822 predicate(AllocatePrefetchInstr==3); 5823 match(PrefetchAllocation mem); 5824 ins_cost(125); 5825 5826 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5827 ins_encode %{ 5828 __ prefetchw($mem$$Address); 5829 %} 5830 ins_pipe(ialu_mem); 5831 %} 5832 5833 instruct prefetchAllocNTA( memory mem ) %{ 5834 predicate(AllocatePrefetchInstr==0); 5835 match(PrefetchAllocation mem); 5836 ins_cost(125); 5837 5838 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5839 ins_encode %{ 5840 __ prefetchnta($mem$$Address); 5841 %} 5842 ins_pipe(ialu_mem); 5843 %} 5844 5845 instruct prefetchAllocT0( memory mem ) %{ 5846 predicate(AllocatePrefetchInstr==1); 5847 match(PrefetchAllocation mem); 5848 ins_cost(125); 5849 5850 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5851 ins_encode %{ 5852 __ prefetcht0($mem$$Address); 5853 %} 5854 ins_pipe(ialu_mem); 5855 %} 5856 5857 instruct prefetchAllocT2( memory mem ) %{ 5858 predicate(AllocatePrefetchInstr==2); 5859 match(PrefetchAllocation mem); 5860 ins_cost(125); 5861 5862 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5863 ins_encode %{ 5864 __ prefetcht2($mem$$Address); 5865 %} 5866 ins_pipe(ialu_mem); 5867 %} 5868 5869 //----------Store Instructions------------------------------------------------- 5870 5871 // Store Byte 5872 instruct storeB(memory mem, rRegI src) 5873 %{ 5874 match(Set mem (StoreB mem src)); 5875 5876 ins_cost(125); // XXX 5877 format %{ "movb $mem, $src\t# byte" %} 5878 opcode(0x88); 5879 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5880 ins_pipe(ialu_mem_reg); 5881 %} 5882 5883 // Store Char/Short 5884 instruct storeC(memory mem, rRegI src) 5885 %{ 5886 match(Set mem (StoreC mem src)); 5887 5888 ins_cost(125); // XXX 5889 format %{ "movw $mem, $src\t# char/short" %} 5890 opcode(0x89); 5891 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5892 ins_pipe(ialu_mem_reg); 5893 %} 5894 5895 // Store Integer 5896 instruct storeI(memory mem, rRegI src) 5897 %{ 5898 match(Set mem (StoreI mem src)); 5899 5900 ins_cost(125); // XXX 5901 format %{ "movl $mem, $src\t# int" %} 5902 opcode(0x89); 5903 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5904 ins_pipe(ialu_mem_reg); 5905 %} 5906 5907 // Store Long 5908 instruct storeL(memory mem, rRegL src) 5909 %{ 5910 match(Set mem (StoreL mem src)); 5911 5912 ins_cost(125); // XXX 5913 format %{ "movq $mem, $src\t# long" %} 5914 opcode(0x89); 5915 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5916 ins_pipe(ialu_mem_reg); // XXX 5917 %} 5918 5919 // Store Pointer 5920 instruct storeP(memory mem, any_RegP src) 5921 %{ 5922 match(Set mem (StoreP mem src)); 5923 5924 ins_cost(125); // XXX 5925 format %{ "movq $mem, $src\t# ptr" %} 5926 opcode(0x89); 5927 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5928 ins_pipe(ialu_mem_reg); 5929 %} 5930 5931 instruct storeImmP0(memory mem, immP0 zero) 5932 %{ 5933 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 5934 match(Set mem (StoreP mem zero)); 5935 5936 ins_cost(125); // XXX 5937 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5938 ins_encode %{ 5939 __ movq($mem$$Address, r12); 5940 %} 5941 ins_pipe(ialu_mem_reg); 5942 %} 5943 5944 // Store NULL Pointer, mark word, or other simple pointer constant. 5945 instruct storeImmP(memory mem, immP31 src) 5946 %{ 5947 match(Set mem (StoreP mem src)); 5948 5949 ins_cost(150); // XXX 5950 format %{ "movq $mem, $src\t# ptr" %} 5951 opcode(0xC7); /* C7 /0 */ 5952 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5953 ins_pipe(ialu_mem_imm); 5954 %} 5955 5956 // Store Compressed Pointer 5957 instruct storeN(memory mem, rRegN src) 5958 %{ 5959 match(Set mem (StoreN mem src)); 5960 5961 ins_cost(125); // XXX 5962 format %{ "movl $mem, $src\t# compressed ptr" %} 5963 ins_encode %{ 5964 __ movl($mem$$Address, $src$$Register); 5965 %} 5966 ins_pipe(ialu_mem_reg); 5967 %} 5968 5969 instruct storeNKlass(memory mem, rRegN src) 5970 %{ 5971 match(Set mem (StoreNKlass mem src)); 5972 5973 ins_cost(125); // XXX 5974 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5975 ins_encode %{ 5976 __ movl($mem$$Address, $src$$Register); 5977 %} 5978 ins_pipe(ialu_mem_reg); 5979 %} 5980 5981 instruct storeImmN0(memory mem, immN0 zero) 5982 %{ 5983 predicate(CompressedOops::base() == NULL); 5984 match(Set mem (StoreN mem zero)); 5985 5986 ins_cost(125); // XXX 5987 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5988 ins_encode %{ 5989 __ movl($mem$$Address, r12); 5990 %} 5991 ins_pipe(ialu_mem_reg); 5992 %} 5993 5994 instruct storeImmN(memory mem, immN src) 5995 %{ 5996 match(Set mem (StoreN mem src)); 5997 5998 ins_cost(150); // XXX 5999 format %{ "movl $mem, $src\t# compressed ptr" %} 6000 ins_encode %{ 6001 address con = (address)$src$$constant; 6002 if (con == NULL) { 6003 __ movl($mem$$Address, (int32_t)0); 6004 } else { 6005 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6006 } 6007 %} 6008 ins_pipe(ialu_mem_imm); 6009 %} 6010 6011 instruct storeImmNKlass(memory mem, immNKlass src) 6012 %{ 6013 match(Set mem (StoreNKlass mem src)); 6014 6015 ins_cost(150); // XXX 6016 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6017 ins_encode %{ 6018 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6019 %} 6020 ins_pipe(ialu_mem_imm); 6021 %} 6022 6023 // Store Integer Immediate 6024 instruct storeImmI0(memory mem, immI0 zero) 6025 %{ 6026 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6027 match(Set mem (StoreI mem zero)); 6028 6029 ins_cost(125); // XXX 6030 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6031 ins_encode %{ 6032 __ movl($mem$$Address, r12); 6033 %} 6034 ins_pipe(ialu_mem_reg); 6035 %} 6036 6037 instruct storeImmI(memory mem, immI src) 6038 %{ 6039 match(Set mem (StoreI mem src)); 6040 6041 ins_cost(150); 6042 format %{ "movl $mem, $src\t# int" %} 6043 opcode(0xC7); /* C7 /0 */ 6044 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6045 ins_pipe(ialu_mem_imm); 6046 %} 6047 6048 // Store Long Immediate 6049 instruct storeImmL0(memory mem, immL0 zero) 6050 %{ 6051 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6052 match(Set mem (StoreL mem zero)); 6053 6054 ins_cost(125); // XXX 6055 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6056 ins_encode %{ 6057 __ movq($mem$$Address, r12); 6058 %} 6059 ins_pipe(ialu_mem_reg); 6060 %} 6061 6062 instruct storeImmL(memory mem, immL32 src) 6063 %{ 6064 match(Set mem (StoreL mem src)); 6065 6066 ins_cost(150); 6067 format %{ "movq $mem, $src\t# long" %} 6068 opcode(0xC7); /* C7 /0 */ 6069 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6070 ins_pipe(ialu_mem_imm); 6071 %} 6072 6073 // Store Short/Char Immediate 6074 instruct storeImmC0(memory mem, immI0 zero) 6075 %{ 6076 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6077 match(Set mem (StoreC mem zero)); 6078 6079 ins_cost(125); // XXX 6080 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6081 ins_encode %{ 6082 __ movw($mem$$Address, r12); 6083 %} 6084 ins_pipe(ialu_mem_reg); 6085 %} 6086 6087 instruct storeImmI16(memory mem, immI16 src) 6088 %{ 6089 predicate(UseStoreImmI16); 6090 match(Set mem (StoreC mem src)); 6091 6092 ins_cost(150); 6093 format %{ "movw $mem, $src\t# short/char" %} 6094 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6095 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6096 ins_pipe(ialu_mem_imm); 6097 %} 6098 6099 // Store Byte Immediate 6100 instruct storeImmB0(memory mem, immI0 zero) 6101 %{ 6102 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6103 match(Set mem (StoreB mem zero)); 6104 6105 ins_cost(125); // XXX 6106 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6107 ins_encode %{ 6108 __ movb($mem$$Address, r12); 6109 %} 6110 ins_pipe(ialu_mem_reg); 6111 %} 6112 6113 instruct storeImmB(memory mem, immI8 src) 6114 %{ 6115 match(Set mem (StoreB mem src)); 6116 6117 ins_cost(150); // XXX 6118 format %{ "movb $mem, $src\t# byte" %} 6119 opcode(0xC6); /* C6 /0 */ 6120 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6121 ins_pipe(ialu_mem_imm); 6122 %} 6123 6124 // Store CMS card-mark Immediate 6125 instruct storeImmCM0_reg(memory mem, immI0 zero) 6126 %{ 6127 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6128 match(Set mem (StoreCM mem zero)); 6129 6130 ins_cost(125); // XXX 6131 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6132 ins_encode %{ 6133 __ movb($mem$$Address, r12); 6134 %} 6135 ins_pipe(ialu_mem_reg); 6136 %} 6137 6138 instruct storeImmCM0(memory mem, immI0 src) 6139 %{ 6140 match(Set mem (StoreCM mem src)); 6141 6142 ins_cost(150); // XXX 6143 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6144 opcode(0xC6); /* C6 /0 */ 6145 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6146 ins_pipe(ialu_mem_imm); 6147 %} 6148 6149 // Store Float 6150 instruct storeF(memory mem, regF src) 6151 %{ 6152 match(Set mem (StoreF mem src)); 6153 6154 ins_cost(95); // XXX 6155 format %{ "movss $mem, $src\t# float" %} 6156 ins_encode %{ 6157 __ movflt($mem$$Address, $src$$XMMRegister); 6158 %} 6159 ins_pipe(pipe_slow); // XXX 6160 %} 6161 6162 // Store immediate Float value (it is faster than store from XMM register) 6163 instruct storeF0(memory mem, immF0 zero) 6164 %{ 6165 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6166 match(Set mem (StoreF mem zero)); 6167 6168 ins_cost(25); // XXX 6169 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6170 ins_encode %{ 6171 __ movl($mem$$Address, r12); 6172 %} 6173 ins_pipe(ialu_mem_reg); 6174 %} 6175 6176 instruct storeF_imm(memory mem, immF src) 6177 %{ 6178 match(Set mem (StoreF mem src)); 6179 6180 ins_cost(50); 6181 format %{ "movl $mem, $src\t# float" %} 6182 opcode(0xC7); /* C7 /0 */ 6183 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6184 ins_pipe(ialu_mem_imm); 6185 %} 6186 6187 // Store Double 6188 instruct storeD(memory mem, regD src) 6189 %{ 6190 match(Set mem (StoreD mem src)); 6191 6192 ins_cost(95); // XXX 6193 format %{ "movsd $mem, $src\t# double" %} 6194 ins_encode %{ 6195 __ movdbl($mem$$Address, $src$$XMMRegister); 6196 %} 6197 ins_pipe(pipe_slow); // XXX 6198 %} 6199 6200 // Store immediate double 0.0 (it is faster than store from XMM register) 6201 instruct storeD0_imm(memory mem, immD0 src) 6202 %{ 6203 predicate(!UseCompressedOops || (CompressedOops::base() != NULL)); 6204 match(Set mem (StoreD mem src)); 6205 6206 ins_cost(50); 6207 format %{ "movq $mem, $src\t# double 0." %} 6208 opcode(0xC7); /* C7 /0 */ 6209 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6210 ins_pipe(ialu_mem_imm); 6211 %} 6212 6213 instruct storeD0(memory mem, immD0 zero) 6214 %{ 6215 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6216 match(Set mem (StoreD mem zero)); 6217 6218 ins_cost(25); // XXX 6219 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6220 ins_encode %{ 6221 __ movq($mem$$Address, r12); 6222 %} 6223 ins_pipe(ialu_mem_reg); 6224 %} 6225 6226 instruct storeSSI(stackSlotI dst, rRegI src) 6227 %{ 6228 match(Set dst src); 6229 6230 ins_cost(100); 6231 format %{ "movl $dst, $src\t# int stk" %} 6232 opcode(0x89); 6233 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6234 ins_pipe( ialu_mem_reg ); 6235 %} 6236 6237 instruct storeSSL(stackSlotL dst, rRegL src) 6238 %{ 6239 match(Set dst src); 6240 6241 ins_cost(100); 6242 format %{ "movq $dst, $src\t# long stk" %} 6243 opcode(0x89); 6244 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6245 ins_pipe(ialu_mem_reg); 6246 %} 6247 6248 instruct storeSSP(stackSlotP dst, rRegP src) 6249 %{ 6250 match(Set dst src); 6251 6252 ins_cost(100); 6253 format %{ "movq $dst, $src\t# ptr stk" %} 6254 opcode(0x89); 6255 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6256 ins_pipe(ialu_mem_reg); 6257 %} 6258 6259 instruct storeSSF(stackSlotF dst, regF src) 6260 %{ 6261 match(Set dst src); 6262 6263 ins_cost(95); // XXX 6264 format %{ "movss $dst, $src\t# float stk" %} 6265 ins_encode %{ 6266 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6267 %} 6268 ins_pipe(pipe_slow); // XXX 6269 %} 6270 6271 instruct storeSSD(stackSlotD dst, regD src) 6272 %{ 6273 match(Set dst src); 6274 6275 ins_cost(95); // XXX 6276 format %{ "movsd $dst, $src\t# double stk" %} 6277 ins_encode %{ 6278 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6279 %} 6280 ins_pipe(pipe_slow); // XXX 6281 %} 6282 6283 instruct cacheWB(indirect addr) 6284 %{ 6285 predicate(VM_Version::supports_data_cache_line_flush()); 6286 match(CacheWB addr); 6287 6288 ins_cost(100); 6289 format %{"cache wb $addr" %} 6290 ins_encode %{ 6291 assert($addr->index_position() < 0, "should be"); 6292 assert($addr$$disp == 0, "should be"); 6293 __ cache_wb(Address($addr$$base$$Register, 0)); 6294 %} 6295 ins_pipe(pipe_slow); // XXX 6296 %} 6297 6298 instruct cacheWBPreSync() 6299 %{ 6300 predicate(VM_Version::supports_data_cache_line_flush()); 6301 match(CacheWBPreSync); 6302 6303 ins_cost(100); 6304 format %{"cache wb presync" %} 6305 ins_encode %{ 6306 __ cache_wbsync(true); 6307 %} 6308 ins_pipe(pipe_slow); // XXX 6309 %} 6310 6311 instruct cacheWBPostSync() 6312 %{ 6313 predicate(VM_Version::supports_data_cache_line_flush()); 6314 match(CacheWBPostSync); 6315 6316 ins_cost(100); 6317 format %{"cache wb postsync" %} 6318 ins_encode %{ 6319 __ cache_wbsync(false); 6320 %} 6321 ins_pipe(pipe_slow); // XXX 6322 %} 6323 6324 //----------BSWAP Instructions------------------------------------------------- 6325 instruct bytes_reverse_int(rRegI dst) %{ 6326 match(Set dst (ReverseBytesI dst)); 6327 6328 format %{ "bswapl $dst" %} 6329 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6330 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6331 ins_pipe( ialu_reg ); 6332 %} 6333 6334 instruct bytes_reverse_long(rRegL dst) %{ 6335 match(Set dst (ReverseBytesL dst)); 6336 6337 format %{ "bswapq $dst" %} 6338 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6339 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6340 ins_pipe( ialu_reg); 6341 %} 6342 6343 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6344 match(Set dst (ReverseBytesUS dst)); 6345 effect(KILL cr); 6346 6347 format %{ "bswapl $dst\n\t" 6348 "shrl $dst,16\n\t" %} 6349 ins_encode %{ 6350 __ bswapl($dst$$Register); 6351 __ shrl($dst$$Register, 16); 6352 %} 6353 ins_pipe( ialu_reg ); 6354 %} 6355 6356 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6357 match(Set dst (ReverseBytesS dst)); 6358 effect(KILL cr); 6359 6360 format %{ "bswapl $dst\n\t" 6361 "sar $dst,16\n\t" %} 6362 ins_encode %{ 6363 __ bswapl($dst$$Register); 6364 __ sarl($dst$$Register, 16); 6365 %} 6366 ins_pipe( ialu_reg ); 6367 %} 6368 6369 //---------- Zeros Count Instructions ------------------------------------------ 6370 6371 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6372 predicate(UseCountLeadingZerosInstruction); 6373 match(Set dst (CountLeadingZerosI src)); 6374 effect(KILL cr); 6375 6376 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6377 ins_encode %{ 6378 __ lzcntl($dst$$Register, $src$$Register); 6379 %} 6380 ins_pipe(ialu_reg); 6381 %} 6382 6383 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6384 predicate(!UseCountLeadingZerosInstruction); 6385 match(Set dst (CountLeadingZerosI src)); 6386 effect(KILL cr); 6387 6388 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6389 "jnz skip\n\t" 6390 "movl $dst, -1\n" 6391 "skip:\n\t" 6392 "negl $dst\n\t" 6393 "addl $dst, 31" %} 6394 ins_encode %{ 6395 Register Rdst = $dst$$Register; 6396 Register Rsrc = $src$$Register; 6397 Label skip; 6398 __ bsrl(Rdst, Rsrc); 6399 __ jccb(Assembler::notZero, skip); 6400 __ movl(Rdst, -1); 6401 __ bind(skip); 6402 __ negl(Rdst); 6403 __ addl(Rdst, BitsPerInt - 1); 6404 %} 6405 ins_pipe(ialu_reg); 6406 %} 6407 6408 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6409 predicate(UseCountLeadingZerosInstruction); 6410 match(Set dst (CountLeadingZerosL src)); 6411 effect(KILL cr); 6412 6413 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6414 ins_encode %{ 6415 __ lzcntq($dst$$Register, $src$$Register); 6416 %} 6417 ins_pipe(ialu_reg); 6418 %} 6419 6420 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6421 predicate(!UseCountLeadingZerosInstruction); 6422 match(Set dst (CountLeadingZerosL src)); 6423 effect(KILL cr); 6424 6425 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6426 "jnz skip\n\t" 6427 "movl $dst, -1\n" 6428 "skip:\n\t" 6429 "negl $dst\n\t" 6430 "addl $dst, 63" %} 6431 ins_encode %{ 6432 Register Rdst = $dst$$Register; 6433 Register Rsrc = $src$$Register; 6434 Label skip; 6435 __ bsrq(Rdst, Rsrc); 6436 __ jccb(Assembler::notZero, skip); 6437 __ movl(Rdst, -1); 6438 __ bind(skip); 6439 __ negl(Rdst); 6440 __ addl(Rdst, BitsPerLong - 1); 6441 %} 6442 ins_pipe(ialu_reg); 6443 %} 6444 6445 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6446 predicate(UseCountTrailingZerosInstruction); 6447 match(Set dst (CountTrailingZerosI src)); 6448 effect(KILL cr); 6449 6450 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6451 ins_encode %{ 6452 __ tzcntl($dst$$Register, $src$$Register); 6453 %} 6454 ins_pipe(ialu_reg); 6455 %} 6456 6457 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6458 predicate(!UseCountTrailingZerosInstruction); 6459 match(Set dst (CountTrailingZerosI src)); 6460 effect(KILL cr); 6461 6462 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6463 "jnz done\n\t" 6464 "movl $dst, 32\n" 6465 "done:" %} 6466 ins_encode %{ 6467 Register Rdst = $dst$$Register; 6468 Label done; 6469 __ bsfl(Rdst, $src$$Register); 6470 __ jccb(Assembler::notZero, done); 6471 __ movl(Rdst, BitsPerInt); 6472 __ bind(done); 6473 %} 6474 ins_pipe(ialu_reg); 6475 %} 6476 6477 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6478 predicate(UseCountTrailingZerosInstruction); 6479 match(Set dst (CountTrailingZerosL src)); 6480 effect(KILL cr); 6481 6482 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6483 ins_encode %{ 6484 __ tzcntq($dst$$Register, $src$$Register); 6485 %} 6486 ins_pipe(ialu_reg); 6487 %} 6488 6489 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6490 predicate(!UseCountTrailingZerosInstruction); 6491 match(Set dst (CountTrailingZerosL src)); 6492 effect(KILL cr); 6493 6494 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6495 "jnz done\n\t" 6496 "movl $dst, 64\n" 6497 "done:" %} 6498 ins_encode %{ 6499 Register Rdst = $dst$$Register; 6500 Label done; 6501 __ bsfq(Rdst, $src$$Register); 6502 __ jccb(Assembler::notZero, done); 6503 __ movl(Rdst, BitsPerLong); 6504 __ bind(done); 6505 %} 6506 ins_pipe(ialu_reg); 6507 %} 6508 6509 6510 //---------- Population Count Instructions ------------------------------------- 6511 6512 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6513 predicate(UsePopCountInstruction); 6514 match(Set dst (PopCountI src)); 6515 effect(KILL cr); 6516 6517 format %{ "popcnt $dst, $src" %} 6518 ins_encode %{ 6519 __ popcntl($dst$$Register, $src$$Register); 6520 %} 6521 ins_pipe(ialu_reg); 6522 %} 6523 6524 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6525 predicate(UsePopCountInstruction); 6526 match(Set dst (PopCountI (LoadI mem))); 6527 effect(KILL cr); 6528 6529 format %{ "popcnt $dst, $mem" %} 6530 ins_encode %{ 6531 __ popcntl($dst$$Register, $mem$$Address); 6532 %} 6533 ins_pipe(ialu_reg); 6534 %} 6535 6536 // Note: Long.bitCount(long) returns an int. 6537 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6538 predicate(UsePopCountInstruction); 6539 match(Set dst (PopCountL src)); 6540 effect(KILL cr); 6541 6542 format %{ "popcnt $dst, $src" %} 6543 ins_encode %{ 6544 __ popcntq($dst$$Register, $src$$Register); 6545 %} 6546 ins_pipe(ialu_reg); 6547 %} 6548 6549 // Note: Long.bitCount(long) returns an int. 6550 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6551 predicate(UsePopCountInstruction); 6552 match(Set dst (PopCountL (LoadL mem))); 6553 effect(KILL cr); 6554 6555 format %{ "popcnt $dst, $mem" %} 6556 ins_encode %{ 6557 __ popcntq($dst$$Register, $mem$$Address); 6558 %} 6559 ins_pipe(ialu_reg); 6560 %} 6561 6562 6563 //----------MemBar Instructions----------------------------------------------- 6564 // Memory barrier flavors 6565 6566 instruct membar_acquire() 6567 %{ 6568 match(MemBarAcquire); 6569 match(LoadFence); 6570 ins_cost(0); 6571 6572 size(0); 6573 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6574 ins_encode(); 6575 ins_pipe(empty); 6576 %} 6577 6578 instruct membar_acquire_lock() 6579 %{ 6580 match(MemBarAcquireLock); 6581 ins_cost(0); 6582 6583 size(0); 6584 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6585 ins_encode(); 6586 ins_pipe(empty); 6587 %} 6588 6589 instruct membar_release() 6590 %{ 6591 match(MemBarRelease); 6592 match(StoreFence); 6593 ins_cost(0); 6594 6595 size(0); 6596 format %{ "MEMBAR-release ! (empty encoding)" %} 6597 ins_encode(); 6598 ins_pipe(empty); 6599 %} 6600 6601 instruct membar_release_lock() 6602 %{ 6603 match(MemBarReleaseLock); 6604 ins_cost(0); 6605 6606 size(0); 6607 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6608 ins_encode(); 6609 ins_pipe(empty); 6610 %} 6611 6612 instruct membar_volatile(rFlagsReg cr) %{ 6613 match(MemBarVolatile); 6614 effect(KILL cr); 6615 ins_cost(400); 6616 6617 format %{ 6618 $$template 6619 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6620 %} 6621 ins_encode %{ 6622 __ membar(Assembler::StoreLoad); 6623 %} 6624 ins_pipe(pipe_slow); 6625 %} 6626 6627 instruct unnecessary_membar_volatile() 6628 %{ 6629 match(MemBarVolatile); 6630 predicate(Matcher::post_store_load_barrier(n)); 6631 ins_cost(0); 6632 6633 size(0); 6634 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6635 ins_encode(); 6636 ins_pipe(empty); 6637 %} 6638 6639 instruct membar_storestore() %{ 6640 match(MemBarStoreStore); 6641 ins_cost(0); 6642 6643 size(0); 6644 format %{ "MEMBAR-storestore (empty encoding)" %} 6645 ins_encode( ); 6646 ins_pipe(empty); 6647 %} 6648 6649 //----------Move Instructions-------------------------------------------------- 6650 6651 instruct castX2P(rRegP dst, rRegL src) 6652 %{ 6653 match(Set dst (CastX2P src)); 6654 6655 format %{ "movq $dst, $src\t# long->ptr" %} 6656 ins_encode %{ 6657 if ($dst$$reg != $src$$reg) { 6658 __ movptr($dst$$Register, $src$$Register); 6659 } 6660 %} 6661 ins_pipe(ialu_reg_reg); // XXX 6662 %} 6663 6664 instruct castP2X(rRegL dst, rRegP src) 6665 %{ 6666 match(Set dst (CastP2X src)); 6667 6668 format %{ "movq $dst, $src\t# ptr -> long" %} 6669 ins_encode %{ 6670 if ($dst$$reg != $src$$reg) { 6671 __ movptr($dst$$Register, $src$$Register); 6672 } 6673 %} 6674 ins_pipe(ialu_reg_reg); // XXX 6675 %} 6676 6677 // Convert oop into int for vectors alignment masking 6678 instruct convP2I(rRegI dst, rRegP src) 6679 %{ 6680 match(Set dst (ConvL2I (CastP2X src))); 6681 6682 format %{ "movl $dst, $src\t# ptr -> int" %} 6683 ins_encode %{ 6684 __ movl($dst$$Register, $src$$Register); 6685 %} 6686 ins_pipe(ialu_reg_reg); // XXX 6687 %} 6688 6689 // Convert compressed oop into int for vectors alignment masking 6690 // in case of 32bit oops (heap < 4Gb). 6691 instruct convN2I(rRegI dst, rRegN src) 6692 %{ 6693 predicate(CompressedOops::shift() == 0); 6694 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6695 6696 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6697 ins_encode %{ 6698 __ movl($dst$$Register, $src$$Register); 6699 %} 6700 ins_pipe(ialu_reg_reg); // XXX 6701 %} 6702 6703 // Convert oop pointer into compressed form 6704 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6705 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6706 match(Set dst (EncodeP src)); 6707 effect(KILL cr); 6708 format %{ "encode_heap_oop $dst,$src" %} 6709 ins_encode %{ 6710 Register s = $src$$Register; 6711 Register d = $dst$$Register; 6712 if (s != d) { 6713 __ movq(d, s); 6714 } 6715 __ encode_heap_oop(d); 6716 %} 6717 ins_pipe(ialu_reg_long); 6718 %} 6719 6720 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6721 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6722 match(Set dst (EncodeP src)); 6723 effect(KILL cr); 6724 format %{ "encode_heap_oop_not_null $dst,$src" %} 6725 ins_encode %{ 6726 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6727 %} 6728 ins_pipe(ialu_reg_long); 6729 %} 6730 6731 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6732 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6733 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6734 match(Set dst (DecodeN src)); 6735 effect(KILL cr); 6736 format %{ "decode_heap_oop $dst,$src" %} 6737 ins_encode %{ 6738 Register s = $src$$Register; 6739 Register d = $dst$$Register; 6740 if (s != d) { 6741 __ movq(d, s); 6742 } 6743 __ decode_heap_oop(d); 6744 %} 6745 ins_pipe(ialu_reg_long); 6746 %} 6747 6748 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6749 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6750 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6751 match(Set dst (DecodeN src)); 6752 effect(KILL cr); 6753 format %{ "decode_heap_oop_not_null $dst,$src" %} 6754 ins_encode %{ 6755 Register s = $src$$Register; 6756 Register d = $dst$$Register; 6757 if (s != d) { 6758 __ decode_heap_oop_not_null(d, s); 6759 } else { 6760 __ decode_heap_oop_not_null(d); 6761 } 6762 %} 6763 ins_pipe(ialu_reg_long); 6764 %} 6765 6766 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6767 match(Set dst (EncodePKlass src)); 6768 effect(TEMP dst, KILL cr); 6769 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6770 ins_encode %{ 6771 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6772 %} 6773 ins_pipe(ialu_reg_long); 6774 %} 6775 6776 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6777 match(Set dst (DecodeNKlass src)); 6778 effect(TEMP dst, KILL cr); 6779 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6780 ins_encode %{ 6781 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6782 %} 6783 ins_pipe(ialu_reg_long); 6784 %} 6785 6786 //----------Conditional Move--------------------------------------------------- 6787 // Jump 6788 // dummy instruction for generating temp registers 6789 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6790 match(Jump (LShiftL switch_val shift)); 6791 ins_cost(350); 6792 predicate(false); 6793 effect(TEMP dest); 6794 6795 format %{ "leaq $dest, [$constantaddress]\n\t" 6796 "jmp [$dest + $switch_val << $shift]\n\t" %} 6797 ins_encode %{ 6798 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6799 // to do that and the compiler is using that register as one it can allocate. 6800 // So we build it all by hand. 6801 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6802 // ArrayAddress dispatch(table, index); 6803 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6804 __ lea($dest$$Register, $constantaddress); 6805 __ jmp(dispatch); 6806 %} 6807 ins_pipe(pipe_jmp); 6808 %} 6809 6810 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6811 match(Jump (AddL (LShiftL switch_val shift) offset)); 6812 ins_cost(350); 6813 effect(TEMP dest); 6814 6815 format %{ "leaq $dest, [$constantaddress]\n\t" 6816 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6817 ins_encode %{ 6818 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6819 // to do that and the compiler is using that register as one it can allocate. 6820 // So we build it all by hand. 6821 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6822 // ArrayAddress dispatch(table, index); 6823 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6824 __ lea($dest$$Register, $constantaddress); 6825 __ jmp(dispatch); 6826 %} 6827 ins_pipe(pipe_jmp); 6828 %} 6829 6830 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6831 match(Jump switch_val); 6832 ins_cost(350); 6833 effect(TEMP dest); 6834 6835 format %{ "leaq $dest, [$constantaddress]\n\t" 6836 "jmp [$dest + $switch_val]\n\t" %} 6837 ins_encode %{ 6838 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6839 // to do that and the compiler is using that register as one it can allocate. 6840 // So we build it all by hand. 6841 // Address index(noreg, switch_reg, Address::times_1); 6842 // ArrayAddress dispatch(table, index); 6843 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6844 __ lea($dest$$Register, $constantaddress); 6845 __ jmp(dispatch); 6846 %} 6847 ins_pipe(pipe_jmp); 6848 %} 6849 6850 // Conditional move 6851 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6852 %{ 6853 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6854 6855 ins_cost(200); // XXX 6856 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6857 opcode(0x0F, 0x40); 6858 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6859 ins_pipe(pipe_cmov_reg); 6860 %} 6861 6862 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6863 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6864 6865 ins_cost(200); // XXX 6866 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6867 opcode(0x0F, 0x40); 6868 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6869 ins_pipe(pipe_cmov_reg); 6870 %} 6871 6872 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6873 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6874 ins_cost(200); 6875 expand %{ 6876 cmovI_regU(cop, cr, dst, src); 6877 %} 6878 %} 6879 6880 // Conditional move 6881 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6882 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6883 6884 ins_cost(250); // XXX 6885 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6886 opcode(0x0F, 0x40); 6887 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6888 ins_pipe(pipe_cmov_mem); 6889 %} 6890 6891 // Conditional move 6892 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6893 %{ 6894 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6895 6896 ins_cost(250); // XXX 6897 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6898 opcode(0x0F, 0x40); 6899 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6900 ins_pipe(pipe_cmov_mem); 6901 %} 6902 6903 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6904 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6905 ins_cost(250); 6906 expand %{ 6907 cmovI_memU(cop, cr, dst, src); 6908 %} 6909 %} 6910 6911 // Conditional move 6912 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6913 %{ 6914 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6915 6916 ins_cost(200); // XXX 6917 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6918 opcode(0x0F, 0x40); 6919 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6920 ins_pipe(pipe_cmov_reg); 6921 %} 6922 6923 // Conditional move 6924 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6925 %{ 6926 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6927 6928 ins_cost(200); // XXX 6929 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6930 opcode(0x0F, 0x40); 6931 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6932 ins_pipe(pipe_cmov_reg); 6933 %} 6934 6935 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6936 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6937 ins_cost(200); 6938 expand %{ 6939 cmovN_regU(cop, cr, dst, src); 6940 %} 6941 %} 6942 6943 // Conditional move 6944 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6945 %{ 6946 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6947 6948 ins_cost(200); // XXX 6949 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6950 opcode(0x0F, 0x40); 6951 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6952 ins_pipe(pipe_cmov_reg); // XXX 6953 %} 6954 6955 // Conditional move 6956 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6957 %{ 6958 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6959 6960 ins_cost(200); // XXX 6961 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6962 opcode(0x0F, 0x40); 6963 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6964 ins_pipe(pipe_cmov_reg); // XXX 6965 %} 6966 6967 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6968 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6969 ins_cost(200); 6970 expand %{ 6971 cmovP_regU(cop, cr, dst, src); 6972 %} 6973 %} 6974 6975 // DISABLED: Requires the ADLC to emit a bottom_type call that 6976 // correctly meets the two pointer arguments; one is an incoming 6977 // register but the other is a memory operand. ALSO appears to 6978 // be buggy with implicit null checks. 6979 // 6980 //// Conditional move 6981 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6982 //%{ 6983 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6984 // ins_cost(250); 6985 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6986 // opcode(0x0F,0x40); 6987 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6988 // ins_pipe( pipe_cmov_mem ); 6989 //%} 6990 // 6991 //// Conditional move 6992 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6993 //%{ 6994 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6995 // ins_cost(250); 6996 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6997 // opcode(0x0F,0x40); 6998 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6999 // ins_pipe( pipe_cmov_mem ); 7000 //%} 7001 7002 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7003 %{ 7004 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7005 7006 ins_cost(200); // XXX 7007 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7008 opcode(0x0F, 0x40); 7009 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7010 ins_pipe(pipe_cmov_reg); // XXX 7011 %} 7012 7013 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7014 %{ 7015 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7016 7017 ins_cost(200); // XXX 7018 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7019 opcode(0x0F, 0x40); 7020 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7021 ins_pipe(pipe_cmov_mem); // XXX 7022 %} 7023 7024 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7025 %{ 7026 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7027 7028 ins_cost(200); // XXX 7029 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7030 opcode(0x0F, 0x40); 7031 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7032 ins_pipe(pipe_cmov_reg); // XXX 7033 %} 7034 7035 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7036 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7037 ins_cost(200); 7038 expand %{ 7039 cmovL_regU(cop, cr, dst, src); 7040 %} 7041 %} 7042 7043 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7044 %{ 7045 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7046 7047 ins_cost(200); // XXX 7048 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7049 opcode(0x0F, 0x40); 7050 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7051 ins_pipe(pipe_cmov_mem); // XXX 7052 %} 7053 7054 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7055 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7056 ins_cost(200); 7057 expand %{ 7058 cmovL_memU(cop, cr, dst, src); 7059 %} 7060 %} 7061 7062 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7063 %{ 7064 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7065 7066 ins_cost(200); // XXX 7067 format %{ "jn$cop skip\t# signed cmove float\n\t" 7068 "movss $dst, $src\n" 7069 "skip:" %} 7070 ins_encode %{ 7071 Label Lskip; 7072 // Invert sense of branch from sense of CMOV 7073 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7074 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7075 __ bind(Lskip); 7076 %} 7077 ins_pipe(pipe_slow); 7078 %} 7079 7080 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7081 // %{ 7082 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7083 7084 // ins_cost(200); // XXX 7085 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7086 // "movss $dst, $src\n" 7087 // "skip:" %} 7088 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7089 // ins_pipe(pipe_slow); 7090 // %} 7091 7092 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7093 %{ 7094 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7095 7096 ins_cost(200); // XXX 7097 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7098 "movss $dst, $src\n" 7099 "skip:" %} 7100 ins_encode %{ 7101 Label Lskip; 7102 // Invert sense of branch from sense of CMOV 7103 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7104 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7105 __ bind(Lskip); 7106 %} 7107 ins_pipe(pipe_slow); 7108 %} 7109 7110 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7111 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7112 ins_cost(200); 7113 expand %{ 7114 cmovF_regU(cop, cr, dst, src); 7115 %} 7116 %} 7117 7118 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7119 %{ 7120 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7121 7122 ins_cost(200); // XXX 7123 format %{ "jn$cop skip\t# signed cmove double\n\t" 7124 "movsd $dst, $src\n" 7125 "skip:" %} 7126 ins_encode %{ 7127 Label Lskip; 7128 // Invert sense of branch from sense of CMOV 7129 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7130 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7131 __ bind(Lskip); 7132 %} 7133 ins_pipe(pipe_slow); 7134 %} 7135 7136 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7137 %{ 7138 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7139 7140 ins_cost(200); // XXX 7141 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7142 "movsd $dst, $src\n" 7143 "skip:" %} 7144 ins_encode %{ 7145 Label Lskip; 7146 // Invert sense of branch from sense of CMOV 7147 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7148 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7149 __ bind(Lskip); 7150 %} 7151 ins_pipe(pipe_slow); 7152 %} 7153 7154 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7155 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7156 ins_cost(200); 7157 expand %{ 7158 cmovD_regU(cop, cr, dst, src); 7159 %} 7160 %} 7161 7162 //----------Arithmetic Instructions-------------------------------------------- 7163 //----------Addition Instructions---------------------------------------------- 7164 7165 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7166 %{ 7167 match(Set dst (AddI dst src)); 7168 effect(KILL cr); 7169 7170 format %{ "addl $dst, $src\t# int" %} 7171 opcode(0x03); 7172 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7173 ins_pipe(ialu_reg_reg); 7174 %} 7175 7176 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7177 %{ 7178 match(Set dst (AddI dst src)); 7179 effect(KILL cr); 7180 7181 format %{ "addl $dst, $src\t# int" %} 7182 opcode(0x81, 0x00); /* /0 id */ 7183 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7184 ins_pipe( ialu_reg ); 7185 %} 7186 7187 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7188 %{ 7189 match(Set dst (AddI dst (LoadI src))); 7190 effect(KILL cr); 7191 7192 ins_cost(125); // XXX 7193 format %{ "addl $dst, $src\t# int" %} 7194 opcode(0x03); 7195 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7196 ins_pipe(ialu_reg_mem); 7197 %} 7198 7199 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7200 %{ 7201 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7202 effect(KILL cr); 7203 7204 ins_cost(150); // XXX 7205 format %{ "addl $dst, $src\t# int" %} 7206 opcode(0x01); /* Opcode 01 /r */ 7207 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7208 ins_pipe(ialu_mem_reg); 7209 %} 7210 7211 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7212 %{ 7213 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7214 effect(KILL cr); 7215 7216 ins_cost(125); // XXX 7217 format %{ "addl $dst, $src\t# int" %} 7218 opcode(0x81); /* Opcode 81 /0 id */ 7219 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7220 ins_pipe(ialu_mem_imm); 7221 %} 7222 7223 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7224 %{ 7225 predicate(UseIncDec); 7226 match(Set dst (AddI dst src)); 7227 effect(KILL cr); 7228 7229 format %{ "incl $dst\t# int" %} 7230 opcode(0xFF, 0x00); // FF /0 7231 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7232 ins_pipe(ialu_reg); 7233 %} 7234 7235 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7236 %{ 7237 predicate(UseIncDec); 7238 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7239 effect(KILL cr); 7240 7241 ins_cost(125); // XXX 7242 format %{ "incl $dst\t# int" %} 7243 opcode(0xFF); /* Opcode FF /0 */ 7244 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7245 ins_pipe(ialu_mem_imm); 7246 %} 7247 7248 // XXX why does that use AddI 7249 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7250 %{ 7251 predicate(UseIncDec); 7252 match(Set dst (AddI dst src)); 7253 effect(KILL cr); 7254 7255 format %{ "decl $dst\t# int" %} 7256 opcode(0xFF, 0x01); // FF /1 7257 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7258 ins_pipe(ialu_reg); 7259 %} 7260 7261 // XXX why does that use AddI 7262 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7263 %{ 7264 predicate(UseIncDec); 7265 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7266 effect(KILL cr); 7267 7268 ins_cost(125); // XXX 7269 format %{ "decl $dst\t# int" %} 7270 opcode(0xFF); /* Opcode FF /1 */ 7271 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7272 ins_pipe(ialu_mem_imm); 7273 %} 7274 7275 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7276 %{ 7277 match(Set dst (AddI src0 src1)); 7278 7279 ins_cost(110); 7280 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7281 opcode(0x8D); /* 0x8D /r */ 7282 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7283 ins_pipe(ialu_reg_reg); 7284 %} 7285 7286 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7287 %{ 7288 match(Set dst (AddL dst src)); 7289 effect(KILL cr); 7290 7291 format %{ "addq $dst, $src\t# long" %} 7292 opcode(0x03); 7293 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7294 ins_pipe(ialu_reg_reg); 7295 %} 7296 7297 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7298 %{ 7299 match(Set dst (AddL dst src)); 7300 effect(KILL cr); 7301 7302 format %{ "addq $dst, $src\t# long" %} 7303 opcode(0x81, 0x00); /* /0 id */ 7304 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7305 ins_pipe( ialu_reg ); 7306 %} 7307 7308 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7309 %{ 7310 match(Set dst (AddL dst (LoadL src))); 7311 effect(KILL cr); 7312 7313 ins_cost(125); // XXX 7314 format %{ "addq $dst, $src\t# long" %} 7315 opcode(0x03); 7316 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7317 ins_pipe(ialu_reg_mem); 7318 %} 7319 7320 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7321 %{ 7322 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7323 effect(KILL cr); 7324 7325 ins_cost(150); // XXX 7326 format %{ "addq $dst, $src\t# long" %} 7327 opcode(0x01); /* Opcode 01 /r */ 7328 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7329 ins_pipe(ialu_mem_reg); 7330 %} 7331 7332 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7333 %{ 7334 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7335 effect(KILL cr); 7336 7337 ins_cost(125); // XXX 7338 format %{ "addq $dst, $src\t# long" %} 7339 opcode(0x81); /* Opcode 81 /0 id */ 7340 ins_encode(REX_mem_wide(dst), 7341 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7342 ins_pipe(ialu_mem_imm); 7343 %} 7344 7345 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7346 %{ 7347 predicate(UseIncDec); 7348 match(Set dst (AddL dst src)); 7349 effect(KILL cr); 7350 7351 format %{ "incq $dst\t# long" %} 7352 opcode(0xFF, 0x00); // FF /0 7353 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7354 ins_pipe(ialu_reg); 7355 %} 7356 7357 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7358 %{ 7359 predicate(UseIncDec); 7360 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7361 effect(KILL cr); 7362 7363 ins_cost(125); // XXX 7364 format %{ "incq $dst\t# long" %} 7365 opcode(0xFF); /* Opcode FF /0 */ 7366 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7367 ins_pipe(ialu_mem_imm); 7368 %} 7369 7370 // XXX why does that use AddL 7371 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7372 %{ 7373 predicate(UseIncDec); 7374 match(Set dst (AddL dst src)); 7375 effect(KILL cr); 7376 7377 format %{ "decq $dst\t# long" %} 7378 opcode(0xFF, 0x01); // FF /1 7379 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7380 ins_pipe(ialu_reg); 7381 %} 7382 7383 // XXX why does that use AddL 7384 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7385 %{ 7386 predicate(UseIncDec); 7387 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7388 effect(KILL cr); 7389 7390 ins_cost(125); // XXX 7391 format %{ "decq $dst\t# long" %} 7392 opcode(0xFF); /* Opcode FF /1 */ 7393 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7394 ins_pipe(ialu_mem_imm); 7395 %} 7396 7397 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7398 %{ 7399 match(Set dst (AddL src0 src1)); 7400 7401 ins_cost(110); 7402 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7403 opcode(0x8D); /* 0x8D /r */ 7404 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7405 ins_pipe(ialu_reg_reg); 7406 %} 7407 7408 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7409 %{ 7410 match(Set dst (AddP dst src)); 7411 effect(KILL cr); 7412 7413 format %{ "addq $dst, $src\t# ptr" %} 7414 opcode(0x03); 7415 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7416 ins_pipe(ialu_reg_reg); 7417 %} 7418 7419 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7420 %{ 7421 match(Set dst (AddP dst src)); 7422 effect(KILL cr); 7423 7424 format %{ "addq $dst, $src\t# ptr" %} 7425 opcode(0x81, 0x00); /* /0 id */ 7426 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7427 ins_pipe( ialu_reg ); 7428 %} 7429 7430 // XXX addP mem ops ???? 7431 7432 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7433 %{ 7434 match(Set dst (AddP src0 src1)); 7435 7436 ins_cost(110); 7437 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7438 opcode(0x8D); /* 0x8D /r */ 7439 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7440 ins_pipe(ialu_reg_reg); 7441 %} 7442 7443 instruct checkCastPP(rRegP dst) 7444 %{ 7445 match(Set dst (CheckCastPP dst)); 7446 7447 size(0); 7448 format %{ "# checkcastPP of $dst" %} 7449 ins_encode(/* empty encoding */); 7450 ins_pipe(empty); 7451 %} 7452 7453 instruct castPP(rRegP dst) 7454 %{ 7455 match(Set dst (CastPP dst)); 7456 7457 size(0); 7458 format %{ "# castPP of $dst" %} 7459 ins_encode(/* empty encoding */); 7460 ins_pipe(empty); 7461 %} 7462 7463 instruct castII(rRegI dst) 7464 %{ 7465 match(Set dst (CastII dst)); 7466 7467 size(0); 7468 format %{ "# castII of $dst" %} 7469 ins_encode(/* empty encoding */); 7470 ins_cost(0); 7471 ins_pipe(empty); 7472 %} 7473 7474 // LoadP-locked same as a regular LoadP when used with compare-swap 7475 instruct loadPLocked(rRegP dst, memory mem) 7476 %{ 7477 match(Set dst (LoadPLocked mem)); 7478 7479 ins_cost(125); // XXX 7480 format %{ "movq $dst, $mem\t# ptr locked" %} 7481 opcode(0x8B); 7482 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7483 ins_pipe(ialu_reg_mem); // XXX 7484 %} 7485 7486 // Conditional-store of the updated heap-top. 7487 // Used during allocation of the shared heap. 7488 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7489 7490 instruct storePConditional(memory heap_top_ptr, 7491 rax_RegP oldval, rRegP newval, 7492 rFlagsReg cr) 7493 %{ 7494 predicate(n->as_LoadStore()->barrier_data() == 0); 7495 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7496 7497 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7498 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7499 opcode(0x0F, 0xB1); 7500 ins_encode(lock_prefix, 7501 REX_reg_mem_wide(newval, heap_top_ptr), 7502 OpcP, OpcS, 7503 reg_mem(newval, heap_top_ptr)); 7504 ins_pipe(pipe_cmpxchg); 7505 %} 7506 7507 // Conditional-store of an int value. 7508 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7509 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7510 %{ 7511 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7512 effect(KILL oldval); 7513 7514 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7515 opcode(0x0F, 0xB1); 7516 ins_encode(lock_prefix, 7517 REX_reg_mem(newval, mem), 7518 OpcP, OpcS, 7519 reg_mem(newval, mem)); 7520 ins_pipe(pipe_cmpxchg); 7521 %} 7522 7523 // Conditional-store of a long value. 7524 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7525 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7526 %{ 7527 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7528 effect(KILL oldval); 7529 7530 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7531 opcode(0x0F, 0xB1); 7532 ins_encode(lock_prefix, 7533 REX_reg_mem_wide(newval, mem), 7534 OpcP, OpcS, 7535 reg_mem(newval, mem)); 7536 ins_pipe(pipe_cmpxchg); 7537 %} 7538 7539 7540 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7541 instruct compareAndSwapP(rRegI res, 7542 memory mem_ptr, 7543 rax_RegP oldval, rRegP newval, 7544 rFlagsReg cr) 7545 %{ 7546 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0); 7547 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7548 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7549 effect(KILL cr, KILL oldval); 7550 7551 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7552 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7553 "sete $res\n\t" 7554 "movzbl $res, $res" %} 7555 opcode(0x0F, 0xB1); 7556 ins_encode(lock_prefix, 7557 REX_reg_mem_wide(newval, mem_ptr), 7558 OpcP, OpcS, 7559 reg_mem(newval, mem_ptr), 7560 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7561 REX_reg_breg(res, res), // movzbl 7562 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7563 ins_pipe( pipe_cmpxchg ); 7564 %} 7565 7566 instruct compareAndSwapL(rRegI res, 7567 memory mem_ptr, 7568 rax_RegL oldval, rRegL newval, 7569 rFlagsReg cr) 7570 %{ 7571 predicate(VM_Version::supports_cx8()); 7572 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7573 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7574 effect(KILL cr, KILL oldval); 7575 7576 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7577 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7578 "sete $res\n\t" 7579 "movzbl $res, $res" %} 7580 opcode(0x0F, 0xB1); 7581 ins_encode(lock_prefix, 7582 REX_reg_mem_wide(newval, mem_ptr), 7583 OpcP, OpcS, 7584 reg_mem(newval, mem_ptr), 7585 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7586 REX_reg_breg(res, res), // movzbl 7587 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7588 ins_pipe( pipe_cmpxchg ); 7589 %} 7590 7591 instruct compareAndSwapI(rRegI res, 7592 memory mem_ptr, 7593 rax_RegI oldval, rRegI newval, 7594 rFlagsReg cr) 7595 %{ 7596 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7597 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7598 effect(KILL cr, KILL oldval); 7599 7600 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7601 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7602 "sete $res\n\t" 7603 "movzbl $res, $res" %} 7604 opcode(0x0F, 0xB1); 7605 ins_encode(lock_prefix, 7606 REX_reg_mem(newval, mem_ptr), 7607 OpcP, OpcS, 7608 reg_mem(newval, mem_ptr), 7609 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7610 REX_reg_breg(res, res), // movzbl 7611 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7612 ins_pipe( pipe_cmpxchg ); 7613 %} 7614 7615 instruct compareAndSwapB(rRegI res, 7616 memory mem_ptr, 7617 rax_RegI oldval, rRegI newval, 7618 rFlagsReg cr) 7619 %{ 7620 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7621 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7622 effect(KILL cr, KILL oldval); 7623 7624 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7625 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7626 "sete $res\n\t" 7627 "movzbl $res, $res" %} 7628 opcode(0x0F, 0xB0); 7629 ins_encode(lock_prefix, 7630 REX_breg_mem(newval, mem_ptr), 7631 OpcP, OpcS, 7632 reg_mem(newval, mem_ptr), 7633 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7634 REX_reg_breg(res, res), // movzbl 7635 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7636 ins_pipe( pipe_cmpxchg ); 7637 %} 7638 7639 instruct compareAndSwapS(rRegI res, 7640 memory mem_ptr, 7641 rax_RegI oldval, rRegI newval, 7642 rFlagsReg cr) 7643 %{ 7644 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7645 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7646 effect(KILL cr, KILL oldval); 7647 7648 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7649 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7650 "sete $res\n\t" 7651 "movzbl $res, $res" %} 7652 opcode(0x0F, 0xB1); 7653 ins_encode(lock_prefix, 7654 SizePrefix, 7655 REX_reg_mem(newval, mem_ptr), 7656 OpcP, OpcS, 7657 reg_mem(newval, mem_ptr), 7658 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7659 REX_reg_breg(res, res), // movzbl 7660 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7661 ins_pipe( pipe_cmpxchg ); 7662 %} 7663 7664 instruct compareAndSwapN(rRegI res, 7665 memory mem_ptr, 7666 rax_RegN oldval, rRegN newval, 7667 rFlagsReg cr) %{ 7668 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7669 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7670 effect(KILL cr, KILL oldval); 7671 7672 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7673 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7674 "sete $res\n\t" 7675 "movzbl $res, $res" %} 7676 opcode(0x0F, 0xB1); 7677 ins_encode(lock_prefix, 7678 REX_reg_mem(newval, mem_ptr), 7679 OpcP, OpcS, 7680 reg_mem(newval, mem_ptr), 7681 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7682 REX_reg_breg(res, res), // movzbl 7683 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7684 ins_pipe( pipe_cmpxchg ); 7685 %} 7686 7687 instruct compareAndExchangeB( 7688 memory mem_ptr, 7689 rax_RegI oldval, rRegI newval, 7690 rFlagsReg cr) 7691 %{ 7692 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7693 effect(KILL cr); 7694 7695 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7696 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7697 opcode(0x0F, 0xB0); 7698 ins_encode(lock_prefix, 7699 REX_breg_mem(newval, mem_ptr), 7700 OpcP, OpcS, 7701 reg_mem(newval, mem_ptr) // lock cmpxchg 7702 ); 7703 ins_pipe( pipe_cmpxchg ); 7704 %} 7705 7706 instruct compareAndExchangeS( 7707 memory mem_ptr, 7708 rax_RegI oldval, rRegI newval, 7709 rFlagsReg cr) 7710 %{ 7711 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7712 effect(KILL cr); 7713 7714 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7715 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7716 opcode(0x0F, 0xB1); 7717 ins_encode(lock_prefix, 7718 SizePrefix, 7719 REX_reg_mem(newval, mem_ptr), 7720 OpcP, OpcS, 7721 reg_mem(newval, mem_ptr) // lock cmpxchg 7722 ); 7723 ins_pipe( pipe_cmpxchg ); 7724 %} 7725 7726 instruct compareAndExchangeI( 7727 memory mem_ptr, 7728 rax_RegI oldval, rRegI newval, 7729 rFlagsReg cr) 7730 %{ 7731 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7732 effect(KILL cr); 7733 7734 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7735 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7736 opcode(0x0F, 0xB1); 7737 ins_encode(lock_prefix, 7738 REX_reg_mem(newval, mem_ptr), 7739 OpcP, OpcS, 7740 reg_mem(newval, mem_ptr) // lock cmpxchg 7741 ); 7742 ins_pipe( pipe_cmpxchg ); 7743 %} 7744 7745 instruct compareAndExchangeL( 7746 memory mem_ptr, 7747 rax_RegL oldval, rRegL newval, 7748 rFlagsReg cr) 7749 %{ 7750 predicate(VM_Version::supports_cx8()); 7751 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7752 effect(KILL cr); 7753 7754 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7755 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7756 opcode(0x0F, 0xB1); 7757 ins_encode(lock_prefix, 7758 REX_reg_mem_wide(newval, mem_ptr), 7759 OpcP, OpcS, 7760 reg_mem(newval, mem_ptr) // lock cmpxchg 7761 ); 7762 ins_pipe( pipe_cmpxchg ); 7763 %} 7764 7765 instruct compareAndExchangeN( 7766 memory mem_ptr, 7767 rax_RegN oldval, rRegN newval, 7768 rFlagsReg cr) %{ 7769 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7770 effect(KILL cr); 7771 7772 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7773 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7774 opcode(0x0F, 0xB1); 7775 ins_encode(lock_prefix, 7776 REX_reg_mem(newval, mem_ptr), 7777 OpcP, OpcS, 7778 reg_mem(newval, mem_ptr) // lock cmpxchg 7779 ); 7780 ins_pipe( pipe_cmpxchg ); 7781 %} 7782 7783 instruct compareAndExchangeP( 7784 memory mem_ptr, 7785 rax_RegP oldval, rRegP newval, 7786 rFlagsReg cr) 7787 %{ 7788 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0); 7789 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7790 effect(KILL cr); 7791 7792 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7793 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7794 opcode(0x0F, 0xB1); 7795 ins_encode(lock_prefix, 7796 REX_reg_mem_wide(newval, mem_ptr), 7797 OpcP, OpcS, 7798 reg_mem(newval, mem_ptr) // lock cmpxchg 7799 ); 7800 ins_pipe( pipe_cmpxchg ); 7801 %} 7802 7803 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7804 predicate(n->as_LoadStore()->result_not_used()); 7805 match(Set dummy (GetAndAddB mem add)); 7806 effect(KILL cr); 7807 format %{ "ADDB [$mem],$add" %} 7808 ins_encode %{ 7809 __ lock(); 7810 __ addb($mem$$Address, $add$$constant); 7811 %} 7812 ins_pipe( pipe_cmpxchg ); 7813 %} 7814 7815 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7816 match(Set newval (GetAndAddB mem newval)); 7817 effect(KILL cr); 7818 format %{ "XADDB [$mem],$newval" %} 7819 ins_encode %{ 7820 __ lock(); 7821 __ xaddb($mem$$Address, $newval$$Register); 7822 %} 7823 ins_pipe( pipe_cmpxchg ); 7824 %} 7825 7826 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7827 predicate(n->as_LoadStore()->result_not_used()); 7828 match(Set dummy (GetAndAddS mem add)); 7829 effect(KILL cr); 7830 format %{ "ADDW [$mem],$add" %} 7831 ins_encode %{ 7832 __ lock(); 7833 __ addw($mem$$Address, $add$$constant); 7834 %} 7835 ins_pipe( pipe_cmpxchg ); 7836 %} 7837 7838 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7839 match(Set newval (GetAndAddS mem newval)); 7840 effect(KILL cr); 7841 format %{ "XADDW [$mem],$newval" %} 7842 ins_encode %{ 7843 __ lock(); 7844 __ xaddw($mem$$Address, $newval$$Register); 7845 %} 7846 ins_pipe( pipe_cmpxchg ); 7847 %} 7848 7849 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7850 predicate(n->as_LoadStore()->result_not_used()); 7851 match(Set dummy (GetAndAddI mem add)); 7852 effect(KILL cr); 7853 format %{ "ADDL [$mem],$add" %} 7854 ins_encode %{ 7855 __ lock(); 7856 __ addl($mem$$Address, $add$$constant); 7857 %} 7858 ins_pipe( pipe_cmpxchg ); 7859 %} 7860 7861 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7862 match(Set newval (GetAndAddI mem newval)); 7863 effect(KILL cr); 7864 format %{ "XADDL [$mem],$newval" %} 7865 ins_encode %{ 7866 __ lock(); 7867 __ xaddl($mem$$Address, $newval$$Register); 7868 %} 7869 ins_pipe( pipe_cmpxchg ); 7870 %} 7871 7872 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7873 predicate(n->as_LoadStore()->result_not_used()); 7874 match(Set dummy (GetAndAddL mem add)); 7875 effect(KILL cr); 7876 format %{ "ADDQ [$mem],$add" %} 7877 ins_encode %{ 7878 __ lock(); 7879 __ addq($mem$$Address, $add$$constant); 7880 %} 7881 ins_pipe( pipe_cmpxchg ); 7882 %} 7883 7884 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7885 match(Set newval (GetAndAddL mem newval)); 7886 effect(KILL cr); 7887 format %{ "XADDQ [$mem],$newval" %} 7888 ins_encode %{ 7889 __ lock(); 7890 __ xaddq($mem$$Address, $newval$$Register); 7891 %} 7892 ins_pipe( pipe_cmpxchg ); 7893 %} 7894 7895 instruct xchgB( memory mem, rRegI newval) %{ 7896 match(Set newval (GetAndSetB mem newval)); 7897 format %{ "XCHGB $newval,[$mem]" %} 7898 ins_encode %{ 7899 __ xchgb($newval$$Register, $mem$$Address); 7900 %} 7901 ins_pipe( pipe_cmpxchg ); 7902 %} 7903 7904 instruct xchgS( memory mem, rRegI newval) %{ 7905 match(Set newval (GetAndSetS mem newval)); 7906 format %{ "XCHGW $newval,[$mem]" %} 7907 ins_encode %{ 7908 __ xchgw($newval$$Register, $mem$$Address); 7909 %} 7910 ins_pipe( pipe_cmpxchg ); 7911 %} 7912 7913 instruct xchgI( memory mem, rRegI newval) %{ 7914 match(Set newval (GetAndSetI mem newval)); 7915 format %{ "XCHGL $newval,[$mem]" %} 7916 ins_encode %{ 7917 __ xchgl($newval$$Register, $mem$$Address); 7918 %} 7919 ins_pipe( pipe_cmpxchg ); 7920 %} 7921 7922 instruct xchgL( memory mem, rRegL newval) %{ 7923 match(Set newval (GetAndSetL mem newval)); 7924 format %{ "XCHGL $newval,[$mem]" %} 7925 ins_encode %{ 7926 __ xchgq($newval$$Register, $mem$$Address); 7927 %} 7928 ins_pipe( pipe_cmpxchg ); 7929 %} 7930 7931 instruct xchgP( memory mem, rRegP newval) %{ 7932 match(Set newval (GetAndSetP mem newval)); 7933 predicate(n->as_LoadStore()->barrier_data() == 0); 7934 format %{ "XCHGQ $newval,[$mem]" %} 7935 ins_encode %{ 7936 __ xchgq($newval$$Register, $mem$$Address); 7937 %} 7938 ins_pipe( pipe_cmpxchg ); 7939 %} 7940 7941 instruct xchgN( memory mem, rRegN newval) %{ 7942 match(Set newval (GetAndSetN mem newval)); 7943 format %{ "XCHGL $newval,$mem]" %} 7944 ins_encode %{ 7945 __ xchgl($newval$$Register, $mem$$Address); 7946 %} 7947 ins_pipe( pipe_cmpxchg ); 7948 %} 7949 7950 //----------Abs Instructions------------------------------------------- 7951 7952 // Integer Absolute Instructions 7953 instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr) 7954 %{ 7955 match(Set dst (AbsI src)); 7956 effect(TEMP dst, TEMP tmp, KILL cr); 7957 format %{ "movl $tmp, $src\n\t" 7958 "sarl $tmp, 31\n\t" 7959 "movl $dst, $src\n\t" 7960 "xorl $dst, $tmp\n\t" 7961 "subl $dst, $tmp\n" 7962 %} 7963 ins_encode %{ 7964 __ movl($tmp$$Register, $src$$Register); 7965 __ sarl($tmp$$Register, 31); 7966 __ movl($dst$$Register, $src$$Register); 7967 __ xorl($dst$$Register, $tmp$$Register); 7968 __ subl($dst$$Register, $tmp$$Register); 7969 %} 7970 7971 ins_pipe(ialu_reg_reg); 7972 %} 7973 7974 // Long Absolute Instructions 7975 instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr) 7976 %{ 7977 match(Set dst (AbsL src)); 7978 effect(TEMP dst, TEMP tmp, KILL cr); 7979 format %{ "movq $tmp, $src\n\t" 7980 "sarq $tmp, 63\n\t" 7981 "movq $dst, $src\n\t" 7982 "xorq $dst, $tmp\n\t" 7983 "subq $dst, $tmp\n" 7984 %} 7985 ins_encode %{ 7986 __ movq($tmp$$Register, $src$$Register); 7987 __ sarq($tmp$$Register, 63); 7988 __ movq($dst$$Register, $src$$Register); 7989 __ xorq($dst$$Register, $tmp$$Register); 7990 __ subq($dst$$Register, $tmp$$Register); 7991 %} 7992 7993 ins_pipe(ialu_reg_reg); 7994 %} 7995 7996 //----------Subtraction Instructions------------------------------------------- 7997 7998 // Integer Subtraction Instructions 7999 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8000 %{ 8001 match(Set dst (SubI dst src)); 8002 effect(KILL cr); 8003 8004 format %{ "subl $dst, $src\t# int" %} 8005 opcode(0x2B); 8006 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8007 ins_pipe(ialu_reg_reg); 8008 %} 8009 8010 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8011 %{ 8012 match(Set dst (SubI dst src)); 8013 effect(KILL cr); 8014 8015 format %{ "subl $dst, $src\t# int" %} 8016 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8017 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8018 ins_pipe(ialu_reg); 8019 %} 8020 8021 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8022 %{ 8023 match(Set dst (SubI dst (LoadI src))); 8024 effect(KILL cr); 8025 8026 ins_cost(125); 8027 format %{ "subl $dst, $src\t# int" %} 8028 opcode(0x2B); 8029 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8030 ins_pipe(ialu_reg_mem); 8031 %} 8032 8033 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8034 %{ 8035 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8036 effect(KILL cr); 8037 8038 ins_cost(150); 8039 format %{ "subl $dst, $src\t# int" %} 8040 opcode(0x29); /* Opcode 29 /r */ 8041 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8042 ins_pipe(ialu_mem_reg); 8043 %} 8044 8045 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8046 %{ 8047 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8048 effect(KILL cr); 8049 8050 ins_cost(125); // XXX 8051 format %{ "subl $dst, $src\t# int" %} 8052 opcode(0x81); /* Opcode 81 /5 id */ 8053 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8054 ins_pipe(ialu_mem_imm); 8055 %} 8056 8057 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8058 %{ 8059 match(Set dst (SubL dst src)); 8060 effect(KILL cr); 8061 8062 format %{ "subq $dst, $src\t# long" %} 8063 opcode(0x2B); 8064 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8065 ins_pipe(ialu_reg_reg); 8066 %} 8067 8068 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8069 %{ 8070 match(Set dst (SubL dst src)); 8071 effect(KILL cr); 8072 8073 format %{ "subq $dst, $src\t# long" %} 8074 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8075 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8076 ins_pipe(ialu_reg); 8077 %} 8078 8079 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8080 %{ 8081 match(Set dst (SubL dst (LoadL src))); 8082 effect(KILL cr); 8083 8084 ins_cost(125); 8085 format %{ "subq $dst, $src\t# long" %} 8086 opcode(0x2B); 8087 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8088 ins_pipe(ialu_reg_mem); 8089 %} 8090 8091 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8092 %{ 8093 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8094 effect(KILL cr); 8095 8096 ins_cost(150); 8097 format %{ "subq $dst, $src\t# long" %} 8098 opcode(0x29); /* Opcode 29 /r */ 8099 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8100 ins_pipe(ialu_mem_reg); 8101 %} 8102 8103 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8104 %{ 8105 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8106 effect(KILL cr); 8107 8108 ins_cost(125); // XXX 8109 format %{ "subq $dst, $src\t# long" %} 8110 opcode(0x81); /* Opcode 81 /5 id */ 8111 ins_encode(REX_mem_wide(dst), 8112 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8113 ins_pipe(ialu_mem_imm); 8114 %} 8115 8116 // Subtract from a pointer 8117 // XXX hmpf??? 8118 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8119 %{ 8120 match(Set dst (AddP dst (SubI zero src))); 8121 effect(KILL cr); 8122 8123 format %{ "subq $dst, $src\t# ptr - int" %} 8124 opcode(0x2B); 8125 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8126 ins_pipe(ialu_reg_reg); 8127 %} 8128 8129 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8130 %{ 8131 match(Set dst (SubI zero dst)); 8132 effect(KILL cr); 8133 8134 format %{ "negl $dst\t# int" %} 8135 opcode(0xF7, 0x03); // Opcode F7 /3 8136 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8137 ins_pipe(ialu_reg); 8138 %} 8139 8140 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8141 %{ 8142 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8143 effect(KILL cr); 8144 8145 format %{ "negl $dst\t# int" %} 8146 opcode(0xF7, 0x03); // Opcode F7 /3 8147 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8148 ins_pipe(ialu_reg); 8149 %} 8150 8151 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8152 %{ 8153 match(Set dst (SubL zero dst)); 8154 effect(KILL cr); 8155 8156 format %{ "negq $dst\t# long" %} 8157 opcode(0xF7, 0x03); // Opcode F7 /3 8158 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8159 ins_pipe(ialu_reg); 8160 %} 8161 8162 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8163 %{ 8164 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8165 effect(KILL cr); 8166 8167 format %{ "negq $dst\t# long" %} 8168 opcode(0xF7, 0x03); // Opcode F7 /3 8169 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8170 ins_pipe(ialu_reg); 8171 %} 8172 8173 //----------Multiplication/Division Instructions------------------------------- 8174 // Integer Multiplication Instructions 8175 // Multiply Register 8176 8177 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8178 %{ 8179 match(Set dst (MulI dst src)); 8180 effect(KILL cr); 8181 8182 ins_cost(300); 8183 format %{ "imull $dst, $src\t# int" %} 8184 opcode(0x0F, 0xAF); 8185 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8186 ins_pipe(ialu_reg_reg_alu0); 8187 %} 8188 8189 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8190 %{ 8191 match(Set dst (MulI src imm)); 8192 effect(KILL cr); 8193 8194 ins_cost(300); 8195 format %{ "imull $dst, $src, $imm\t# int" %} 8196 opcode(0x69); /* 69 /r id */ 8197 ins_encode(REX_reg_reg(dst, src), 8198 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8199 ins_pipe(ialu_reg_reg_alu0); 8200 %} 8201 8202 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8203 %{ 8204 match(Set dst (MulI dst (LoadI src))); 8205 effect(KILL cr); 8206 8207 ins_cost(350); 8208 format %{ "imull $dst, $src\t# int" %} 8209 opcode(0x0F, 0xAF); 8210 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8211 ins_pipe(ialu_reg_mem_alu0); 8212 %} 8213 8214 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8215 %{ 8216 match(Set dst (MulI (LoadI src) imm)); 8217 effect(KILL cr); 8218 8219 ins_cost(300); 8220 format %{ "imull $dst, $src, $imm\t# int" %} 8221 opcode(0x69); /* 69 /r id */ 8222 ins_encode(REX_reg_mem(dst, src), 8223 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8224 ins_pipe(ialu_reg_mem_alu0); 8225 %} 8226 8227 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8228 %{ 8229 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8230 effect(KILL cr, KILL src2); 8231 8232 expand %{ mulI_rReg(dst, src1, cr); 8233 mulI_rReg(src2, src3, cr); 8234 addI_rReg(dst, src2, cr); %} 8235 %} 8236 8237 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8238 %{ 8239 match(Set dst (MulL dst src)); 8240 effect(KILL cr); 8241 8242 ins_cost(300); 8243 format %{ "imulq $dst, $src\t# long" %} 8244 opcode(0x0F, 0xAF); 8245 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8246 ins_pipe(ialu_reg_reg_alu0); 8247 %} 8248 8249 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8250 %{ 8251 match(Set dst (MulL src imm)); 8252 effect(KILL cr); 8253 8254 ins_cost(300); 8255 format %{ "imulq $dst, $src, $imm\t# long" %} 8256 opcode(0x69); /* 69 /r id */ 8257 ins_encode(REX_reg_reg_wide(dst, src), 8258 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8259 ins_pipe(ialu_reg_reg_alu0); 8260 %} 8261 8262 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8263 %{ 8264 match(Set dst (MulL dst (LoadL src))); 8265 effect(KILL cr); 8266 8267 ins_cost(350); 8268 format %{ "imulq $dst, $src\t# long" %} 8269 opcode(0x0F, 0xAF); 8270 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8271 ins_pipe(ialu_reg_mem_alu0); 8272 %} 8273 8274 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8275 %{ 8276 match(Set dst (MulL (LoadL src) imm)); 8277 effect(KILL cr); 8278 8279 ins_cost(300); 8280 format %{ "imulq $dst, $src, $imm\t# long" %} 8281 opcode(0x69); /* 69 /r id */ 8282 ins_encode(REX_reg_mem_wide(dst, src), 8283 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8284 ins_pipe(ialu_reg_mem_alu0); 8285 %} 8286 8287 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8288 %{ 8289 match(Set dst (MulHiL src rax)); 8290 effect(USE_KILL rax, KILL cr); 8291 8292 ins_cost(300); 8293 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8294 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8295 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8296 ins_pipe(ialu_reg_reg_alu0); 8297 %} 8298 8299 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8300 rFlagsReg cr) 8301 %{ 8302 match(Set rax (DivI rax div)); 8303 effect(KILL rdx, KILL cr); 8304 8305 ins_cost(30*100+10*100); // XXX 8306 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8307 "jne,s normal\n\t" 8308 "xorl rdx, rdx\n\t" 8309 "cmpl $div, -1\n\t" 8310 "je,s done\n" 8311 "normal: cdql\n\t" 8312 "idivl $div\n" 8313 "done:" %} 8314 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8315 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8316 ins_pipe(ialu_reg_reg_alu0); 8317 %} 8318 8319 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8320 rFlagsReg cr) 8321 %{ 8322 match(Set rax (DivL rax div)); 8323 effect(KILL rdx, KILL cr); 8324 8325 ins_cost(30*100+10*100); // XXX 8326 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8327 "cmpq rax, rdx\n\t" 8328 "jne,s normal\n\t" 8329 "xorl rdx, rdx\n\t" 8330 "cmpq $div, -1\n\t" 8331 "je,s done\n" 8332 "normal: cdqq\n\t" 8333 "idivq $div\n" 8334 "done:" %} 8335 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8336 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8337 ins_pipe(ialu_reg_reg_alu0); 8338 %} 8339 8340 // Integer DIVMOD with Register, both quotient and mod results 8341 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8342 rFlagsReg cr) 8343 %{ 8344 match(DivModI rax div); 8345 effect(KILL cr); 8346 8347 ins_cost(30*100+10*100); // XXX 8348 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8349 "jne,s normal\n\t" 8350 "xorl rdx, rdx\n\t" 8351 "cmpl $div, -1\n\t" 8352 "je,s done\n" 8353 "normal: cdql\n\t" 8354 "idivl $div\n" 8355 "done:" %} 8356 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8357 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8358 ins_pipe(pipe_slow); 8359 %} 8360 8361 // Long DIVMOD with Register, both quotient and mod results 8362 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8363 rFlagsReg cr) 8364 %{ 8365 match(DivModL rax div); 8366 effect(KILL cr); 8367 8368 ins_cost(30*100+10*100); // XXX 8369 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8370 "cmpq rax, rdx\n\t" 8371 "jne,s normal\n\t" 8372 "xorl rdx, rdx\n\t" 8373 "cmpq $div, -1\n\t" 8374 "je,s done\n" 8375 "normal: cdqq\n\t" 8376 "idivq $div\n" 8377 "done:" %} 8378 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8379 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8380 ins_pipe(pipe_slow); 8381 %} 8382 8383 //----------- DivL-By-Constant-Expansions-------------------------------------- 8384 // DivI cases are handled by the compiler 8385 8386 // Magic constant, reciprocal of 10 8387 instruct loadConL_0x6666666666666667(rRegL dst) 8388 %{ 8389 effect(DEF dst); 8390 8391 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8392 ins_encode(load_immL(dst, 0x6666666666666667)); 8393 ins_pipe(ialu_reg); 8394 %} 8395 8396 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8397 %{ 8398 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8399 8400 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8401 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8402 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8403 ins_pipe(ialu_reg_reg_alu0); 8404 %} 8405 8406 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8407 %{ 8408 effect(USE_DEF dst, KILL cr); 8409 8410 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8411 opcode(0xC1, 0x7); /* C1 /7 ib */ 8412 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8413 ins_pipe(ialu_reg); 8414 %} 8415 8416 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8417 %{ 8418 effect(USE_DEF dst, KILL cr); 8419 8420 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8421 opcode(0xC1, 0x7); /* C1 /7 ib */ 8422 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8423 ins_pipe(ialu_reg); 8424 %} 8425 8426 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8427 %{ 8428 match(Set dst (DivL src div)); 8429 8430 ins_cost((5+8)*100); 8431 expand %{ 8432 rax_RegL rax; // Killed temp 8433 rFlagsReg cr; // Killed 8434 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8435 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8436 sarL_rReg_63(src, cr); // sarq src, 63 8437 sarL_rReg_2(dst, cr); // sarq rdx, 2 8438 subL_rReg(dst, src, cr); // subl rdx, src 8439 %} 8440 %} 8441 8442 //----------------------------------------------------------------------------- 8443 8444 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8445 rFlagsReg cr) 8446 %{ 8447 match(Set rdx (ModI rax div)); 8448 effect(KILL rax, KILL cr); 8449 8450 ins_cost(300); // XXX 8451 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8452 "jne,s normal\n\t" 8453 "xorl rdx, rdx\n\t" 8454 "cmpl $div, -1\n\t" 8455 "je,s done\n" 8456 "normal: cdql\n\t" 8457 "idivl $div\n" 8458 "done:" %} 8459 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8460 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8461 ins_pipe(ialu_reg_reg_alu0); 8462 %} 8463 8464 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8465 rFlagsReg cr) 8466 %{ 8467 match(Set rdx (ModL rax div)); 8468 effect(KILL rax, KILL cr); 8469 8470 ins_cost(300); // XXX 8471 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8472 "cmpq rax, rdx\n\t" 8473 "jne,s normal\n\t" 8474 "xorl rdx, rdx\n\t" 8475 "cmpq $div, -1\n\t" 8476 "je,s done\n" 8477 "normal: cdqq\n\t" 8478 "idivq $div\n" 8479 "done:" %} 8480 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8481 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8482 ins_pipe(ialu_reg_reg_alu0); 8483 %} 8484 8485 // Integer Shift Instructions 8486 // Shift Left by one 8487 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8488 %{ 8489 match(Set dst (LShiftI dst shift)); 8490 effect(KILL cr); 8491 8492 format %{ "sall $dst, $shift" %} 8493 opcode(0xD1, 0x4); /* D1 /4 */ 8494 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8495 ins_pipe(ialu_reg); 8496 %} 8497 8498 // Shift Left by one 8499 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8500 %{ 8501 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8502 effect(KILL cr); 8503 8504 format %{ "sall $dst, $shift\t" %} 8505 opcode(0xD1, 0x4); /* D1 /4 */ 8506 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8507 ins_pipe(ialu_mem_imm); 8508 %} 8509 8510 // Shift Left by 8-bit immediate 8511 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8512 %{ 8513 match(Set dst (LShiftI dst shift)); 8514 effect(KILL cr); 8515 8516 format %{ "sall $dst, $shift" %} 8517 opcode(0xC1, 0x4); /* C1 /4 ib */ 8518 ins_encode(reg_opc_imm(dst, shift)); 8519 ins_pipe(ialu_reg); 8520 %} 8521 8522 // Shift Left by 8-bit immediate 8523 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8524 %{ 8525 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8526 effect(KILL cr); 8527 8528 format %{ "sall $dst, $shift" %} 8529 opcode(0xC1, 0x4); /* C1 /4 ib */ 8530 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8531 ins_pipe(ialu_mem_imm); 8532 %} 8533 8534 // Shift Left by variable 8535 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8536 %{ 8537 match(Set dst (LShiftI dst shift)); 8538 effect(KILL cr); 8539 8540 format %{ "sall $dst, $shift" %} 8541 opcode(0xD3, 0x4); /* D3 /4 */ 8542 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8543 ins_pipe(ialu_reg_reg); 8544 %} 8545 8546 // Shift Left by variable 8547 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8548 %{ 8549 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8550 effect(KILL cr); 8551 8552 format %{ "sall $dst, $shift" %} 8553 opcode(0xD3, 0x4); /* D3 /4 */ 8554 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8555 ins_pipe(ialu_mem_reg); 8556 %} 8557 8558 // Arithmetic shift right by one 8559 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8560 %{ 8561 match(Set dst (RShiftI dst shift)); 8562 effect(KILL cr); 8563 8564 format %{ "sarl $dst, $shift" %} 8565 opcode(0xD1, 0x7); /* D1 /7 */ 8566 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8567 ins_pipe(ialu_reg); 8568 %} 8569 8570 // Arithmetic shift right by one 8571 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8572 %{ 8573 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8574 effect(KILL cr); 8575 8576 format %{ "sarl $dst, $shift" %} 8577 opcode(0xD1, 0x7); /* D1 /7 */ 8578 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8579 ins_pipe(ialu_mem_imm); 8580 %} 8581 8582 // Arithmetic Shift Right by 8-bit immediate 8583 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8584 %{ 8585 match(Set dst (RShiftI dst shift)); 8586 effect(KILL cr); 8587 8588 format %{ "sarl $dst, $shift" %} 8589 opcode(0xC1, 0x7); /* C1 /7 ib */ 8590 ins_encode(reg_opc_imm(dst, shift)); 8591 ins_pipe(ialu_mem_imm); 8592 %} 8593 8594 // Arithmetic Shift Right by 8-bit immediate 8595 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8596 %{ 8597 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8598 effect(KILL cr); 8599 8600 format %{ "sarl $dst, $shift" %} 8601 opcode(0xC1, 0x7); /* C1 /7 ib */ 8602 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8603 ins_pipe(ialu_mem_imm); 8604 %} 8605 8606 // Arithmetic Shift Right by variable 8607 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8608 %{ 8609 match(Set dst (RShiftI dst shift)); 8610 effect(KILL cr); 8611 8612 format %{ "sarl $dst, $shift" %} 8613 opcode(0xD3, 0x7); /* D3 /7 */ 8614 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8615 ins_pipe(ialu_reg_reg); 8616 %} 8617 8618 // Arithmetic Shift Right by variable 8619 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8620 %{ 8621 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8622 effect(KILL cr); 8623 8624 format %{ "sarl $dst, $shift" %} 8625 opcode(0xD3, 0x7); /* D3 /7 */ 8626 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8627 ins_pipe(ialu_mem_reg); 8628 %} 8629 8630 // Logical shift right by one 8631 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8632 %{ 8633 match(Set dst (URShiftI dst shift)); 8634 effect(KILL cr); 8635 8636 format %{ "shrl $dst, $shift" %} 8637 opcode(0xD1, 0x5); /* D1 /5 */ 8638 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8639 ins_pipe(ialu_reg); 8640 %} 8641 8642 // Logical shift right by one 8643 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8644 %{ 8645 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8646 effect(KILL cr); 8647 8648 format %{ "shrl $dst, $shift" %} 8649 opcode(0xD1, 0x5); /* D1 /5 */ 8650 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8651 ins_pipe(ialu_mem_imm); 8652 %} 8653 8654 // Logical Shift Right by 8-bit immediate 8655 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8656 %{ 8657 match(Set dst (URShiftI dst shift)); 8658 effect(KILL cr); 8659 8660 format %{ "shrl $dst, $shift" %} 8661 opcode(0xC1, 0x5); /* C1 /5 ib */ 8662 ins_encode(reg_opc_imm(dst, shift)); 8663 ins_pipe(ialu_reg); 8664 %} 8665 8666 // Logical Shift Right by 8-bit immediate 8667 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8668 %{ 8669 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8670 effect(KILL cr); 8671 8672 format %{ "shrl $dst, $shift" %} 8673 opcode(0xC1, 0x5); /* C1 /5 ib */ 8674 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8675 ins_pipe(ialu_mem_imm); 8676 %} 8677 8678 // Logical Shift Right by variable 8679 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8680 %{ 8681 match(Set dst (URShiftI dst shift)); 8682 effect(KILL cr); 8683 8684 format %{ "shrl $dst, $shift" %} 8685 opcode(0xD3, 0x5); /* D3 /5 */ 8686 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8687 ins_pipe(ialu_reg_reg); 8688 %} 8689 8690 // Logical Shift Right by variable 8691 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8692 %{ 8693 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8694 effect(KILL cr); 8695 8696 format %{ "shrl $dst, $shift" %} 8697 opcode(0xD3, 0x5); /* D3 /5 */ 8698 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8699 ins_pipe(ialu_mem_reg); 8700 %} 8701 8702 // Long Shift Instructions 8703 // Shift Left by one 8704 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8705 %{ 8706 match(Set dst (LShiftL dst shift)); 8707 effect(KILL cr); 8708 8709 format %{ "salq $dst, $shift" %} 8710 opcode(0xD1, 0x4); /* D1 /4 */ 8711 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8712 ins_pipe(ialu_reg); 8713 %} 8714 8715 // Shift Left by one 8716 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8717 %{ 8718 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8719 effect(KILL cr); 8720 8721 format %{ "salq $dst, $shift" %} 8722 opcode(0xD1, 0x4); /* D1 /4 */ 8723 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8724 ins_pipe(ialu_mem_imm); 8725 %} 8726 8727 // Shift Left by 8-bit immediate 8728 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8729 %{ 8730 match(Set dst (LShiftL dst shift)); 8731 effect(KILL cr); 8732 8733 format %{ "salq $dst, $shift" %} 8734 opcode(0xC1, 0x4); /* C1 /4 ib */ 8735 ins_encode(reg_opc_imm_wide(dst, shift)); 8736 ins_pipe(ialu_reg); 8737 %} 8738 8739 // Shift Left by 8-bit immediate 8740 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8741 %{ 8742 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8743 effect(KILL cr); 8744 8745 format %{ "salq $dst, $shift" %} 8746 opcode(0xC1, 0x4); /* C1 /4 ib */ 8747 ins_encode(REX_mem_wide(dst), OpcP, 8748 RM_opc_mem(secondary, dst), Con8or32(shift)); 8749 ins_pipe(ialu_mem_imm); 8750 %} 8751 8752 // Shift Left by variable 8753 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8754 %{ 8755 match(Set dst (LShiftL dst shift)); 8756 effect(KILL cr); 8757 8758 format %{ "salq $dst, $shift" %} 8759 opcode(0xD3, 0x4); /* D3 /4 */ 8760 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8761 ins_pipe(ialu_reg_reg); 8762 %} 8763 8764 // Shift Left by variable 8765 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8766 %{ 8767 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8768 effect(KILL cr); 8769 8770 format %{ "salq $dst, $shift" %} 8771 opcode(0xD3, 0x4); /* D3 /4 */ 8772 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8773 ins_pipe(ialu_mem_reg); 8774 %} 8775 8776 // Arithmetic shift right by one 8777 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8778 %{ 8779 match(Set dst (RShiftL dst shift)); 8780 effect(KILL cr); 8781 8782 format %{ "sarq $dst, $shift" %} 8783 opcode(0xD1, 0x7); /* D1 /7 */ 8784 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8785 ins_pipe(ialu_reg); 8786 %} 8787 8788 // Arithmetic shift right by one 8789 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8790 %{ 8791 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8792 effect(KILL cr); 8793 8794 format %{ "sarq $dst, $shift" %} 8795 opcode(0xD1, 0x7); /* D1 /7 */ 8796 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8797 ins_pipe(ialu_mem_imm); 8798 %} 8799 8800 // Arithmetic Shift Right by 8-bit immediate 8801 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8802 %{ 8803 match(Set dst (RShiftL dst shift)); 8804 effect(KILL cr); 8805 8806 format %{ "sarq $dst, $shift" %} 8807 opcode(0xC1, 0x7); /* C1 /7 ib */ 8808 ins_encode(reg_opc_imm_wide(dst, shift)); 8809 ins_pipe(ialu_mem_imm); 8810 %} 8811 8812 // Arithmetic Shift Right by 8-bit immediate 8813 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8814 %{ 8815 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8816 effect(KILL cr); 8817 8818 format %{ "sarq $dst, $shift" %} 8819 opcode(0xC1, 0x7); /* C1 /7 ib */ 8820 ins_encode(REX_mem_wide(dst), OpcP, 8821 RM_opc_mem(secondary, dst), Con8or32(shift)); 8822 ins_pipe(ialu_mem_imm); 8823 %} 8824 8825 // Arithmetic Shift Right by variable 8826 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8827 %{ 8828 match(Set dst (RShiftL dst shift)); 8829 effect(KILL cr); 8830 8831 format %{ "sarq $dst, $shift" %} 8832 opcode(0xD3, 0x7); /* D3 /7 */ 8833 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8834 ins_pipe(ialu_reg_reg); 8835 %} 8836 8837 // Arithmetic Shift Right by variable 8838 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8839 %{ 8840 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8841 effect(KILL cr); 8842 8843 format %{ "sarq $dst, $shift" %} 8844 opcode(0xD3, 0x7); /* D3 /7 */ 8845 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8846 ins_pipe(ialu_mem_reg); 8847 %} 8848 8849 // Logical shift right by one 8850 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8851 %{ 8852 match(Set dst (URShiftL dst shift)); 8853 effect(KILL cr); 8854 8855 format %{ "shrq $dst, $shift" %} 8856 opcode(0xD1, 0x5); /* D1 /5 */ 8857 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8858 ins_pipe(ialu_reg); 8859 %} 8860 8861 // Logical shift right by one 8862 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8863 %{ 8864 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8865 effect(KILL cr); 8866 8867 format %{ "shrq $dst, $shift" %} 8868 opcode(0xD1, 0x5); /* D1 /5 */ 8869 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8870 ins_pipe(ialu_mem_imm); 8871 %} 8872 8873 // Logical Shift Right by 8-bit immediate 8874 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8875 %{ 8876 match(Set dst (URShiftL dst shift)); 8877 effect(KILL cr); 8878 8879 format %{ "shrq $dst, $shift" %} 8880 opcode(0xC1, 0x5); /* C1 /5 ib */ 8881 ins_encode(reg_opc_imm_wide(dst, shift)); 8882 ins_pipe(ialu_reg); 8883 %} 8884 8885 8886 // Logical Shift Right by 8-bit immediate 8887 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8888 %{ 8889 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8890 effect(KILL cr); 8891 8892 format %{ "shrq $dst, $shift" %} 8893 opcode(0xC1, 0x5); /* C1 /5 ib */ 8894 ins_encode(REX_mem_wide(dst), OpcP, 8895 RM_opc_mem(secondary, dst), Con8or32(shift)); 8896 ins_pipe(ialu_mem_imm); 8897 %} 8898 8899 // Logical Shift Right by variable 8900 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8901 %{ 8902 match(Set dst (URShiftL dst shift)); 8903 effect(KILL cr); 8904 8905 format %{ "shrq $dst, $shift" %} 8906 opcode(0xD3, 0x5); /* D3 /5 */ 8907 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8908 ins_pipe(ialu_reg_reg); 8909 %} 8910 8911 // Logical Shift Right by variable 8912 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8913 %{ 8914 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8915 effect(KILL cr); 8916 8917 format %{ "shrq $dst, $shift" %} 8918 opcode(0xD3, 0x5); /* D3 /5 */ 8919 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8920 ins_pipe(ialu_mem_reg); 8921 %} 8922 8923 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8924 // This idiom is used by the compiler for the i2b bytecode. 8925 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8926 %{ 8927 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8928 8929 format %{ "movsbl $dst, $src\t# i2b" %} 8930 opcode(0x0F, 0xBE); 8931 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8932 ins_pipe(ialu_reg_reg); 8933 %} 8934 8935 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8936 // This idiom is used by the compiler the i2s bytecode. 8937 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8938 %{ 8939 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8940 8941 format %{ "movswl $dst, $src\t# i2s" %} 8942 opcode(0x0F, 0xBF); 8943 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8944 ins_pipe(ialu_reg_reg); 8945 %} 8946 8947 // ROL/ROR instructions 8948 8949 // Rotate left by constant. 8950 instruct rolI_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8951 %{ 8952 predicate(n->bottom_type()->basic_type() == T_INT); 8953 match(Set dst (RotateLeft dst shift)); 8954 effect(KILL cr); 8955 format %{ "roll $dst, $shift" %} 8956 ins_encode %{ 8957 __ roll($dst$$Register, $shift$$constant); 8958 %} 8959 ins_pipe(ialu_reg); 8960 %} 8961 8962 // Rotate Left by variable 8963 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8964 %{ 8965 predicate(n->bottom_type()->basic_type() == T_INT); 8966 match(Set dst (RotateLeft dst shift)); 8967 effect(KILL cr); 8968 format %{ "roll $dst, $shift" %} 8969 ins_encode %{ 8970 __ roll($dst$$Register); 8971 %} 8972 ins_pipe(ialu_reg_reg); 8973 %} 8974 8975 // Rotate Right by constant. 8976 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8977 %{ 8978 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8979 match(Set dst (RotateRight dst shift)); 8980 effect(KILL cr); 8981 format %{ "rorl $dst, $shift" %} 8982 ins_encode %{ 8983 __ rorl($dst$$Register, $shift$$constant); 8984 %} 8985 ins_pipe(ialu_reg); 8986 %} 8987 8988 // Rotate Right by constant. 8989 instruct rorI_immI8(rRegI dst, immI8 shift) 8990 %{ 8991 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8992 match(Set dst (RotateRight dst shift)); 8993 format %{ "rorxd $dst, $shift" %} 8994 ins_encode %{ 8995 __ rorxd($dst$$Register, $dst$$Register, $shift$$constant); 8996 %} 8997 ins_pipe(ialu_reg_reg); 8998 %} 8999 9000 // Rotate Right by variable 9001 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9002 %{ 9003 predicate(n->bottom_type()->basic_type() == T_INT); 9004 match(Set dst (RotateRight dst shift)); 9005 effect(KILL cr); 9006 format %{ "rorl $dst, $shift" %} 9007 ins_encode %{ 9008 __ rorl($dst$$Register); 9009 %} 9010 ins_pipe(ialu_reg_reg); 9011 %} 9012 9013 9014 // Rotate Left by constant. 9015 instruct rolL_immI8(rRegL dst, immI8 shift, rFlagsReg cr) 9016 %{ 9017 predicate(n->bottom_type()->basic_type() == T_LONG); 9018 match(Set dst (RotateLeft dst shift)); 9019 effect(KILL cr); 9020 format %{ "rolq $dst, $shift" %} 9021 ins_encode %{ 9022 __ rolq($dst$$Register, $shift$$constant); 9023 %} 9024 ins_pipe(ialu_reg); 9025 %} 9026 9027 // Rotate Left by variable 9028 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9029 %{ 9030 predicate(n->bottom_type()->basic_type() == T_LONG); 9031 match(Set dst (RotateLeft dst shift)); 9032 effect(KILL cr); 9033 format %{ "rolq $dst, $shift" %} 9034 ins_encode %{ 9035 __ rolq($dst$$Register); 9036 %} 9037 ins_pipe(ialu_reg_reg); 9038 %} 9039 9040 9041 // Rotate Right by constant. 9042 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9043 %{ 9044 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9045 match(Set dst (RotateRight dst shift)); 9046 effect(KILL cr); 9047 format %{ "rorq $dst, $shift" %} 9048 ins_encode %{ 9049 __ rorq($dst$$Register, $shift$$constant); 9050 %} 9051 ins_pipe(ialu_reg); 9052 %} 9053 9054 9055 // Rotate Right by constant 9056 instruct rorL_immI8(rRegL dst, immI8 shift) 9057 %{ 9058 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9059 match(Set dst (RotateRight dst shift)); 9060 format %{ "rorxq $dst, $shift" %} 9061 ins_encode %{ 9062 __ rorxq($dst$$Register, $dst$$Register, $shift$$constant); 9063 %} 9064 ins_pipe(ialu_reg_reg); 9065 %} 9066 9067 // Rotate Right by variable 9068 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9069 %{ 9070 predicate(n->bottom_type()->basic_type() == T_LONG); 9071 match(Set dst (RotateRight dst shift)); 9072 effect(KILL cr); 9073 format %{ "rorq $dst, $shift" %} 9074 ins_encode %{ 9075 __ rorq($dst$$Register); 9076 %} 9077 ins_pipe(ialu_reg_reg); 9078 %} 9079 9080 9081 // Logical Instructions 9082 9083 // Integer Logical Instructions 9084 9085 // And Instructions 9086 // And Register with Register 9087 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9088 %{ 9089 match(Set dst (AndI dst src)); 9090 effect(KILL cr); 9091 9092 format %{ "andl $dst, $src\t# int" %} 9093 opcode(0x23); 9094 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9095 ins_pipe(ialu_reg_reg); 9096 %} 9097 9098 // And Register with Immediate 255 9099 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9100 %{ 9101 match(Set dst (AndI dst src)); 9102 9103 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9104 opcode(0x0F, 0xB6); 9105 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9106 ins_pipe(ialu_reg); 9107 %} 9108 9109 // And Register with Immediate 255 and promote to long 9110 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9111 %{ 9112 match(Set dst (ConvI2L (AndI src mask))); 9113 9114 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9115 opcode(0x0F, 0xB6); 9116 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9117 ins_pipe(ialu_reg); 9118 %} 9119 9120 // And Register with Immediate 65535 9121 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9122 %{ 9123 match(Set dst (AndI dst src)); 9124 9125 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9126 opcode(0x0F, 0xB7); 9127 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9128 ins_pipe(ialu_reg); 9129 %} 9130 9131 // And Register with Immediate 65535 and promote to long 9132 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9133 %{ 9134 match(Set dst (ConvI2L (AndI src mask))); 9135 9136 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9137 opcode(0x0F, 0xB7); 9138 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9139 ins_pipe(ialu_reg); 9140 %} 9141 9142 // And Register with Immediate 9143 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9144 %{ 9145 match(Set dst (AndI dst src)); 9146 effect(KILL cr); 9147 9148 format %{ "andl $dst, $src\t# int" %} 9149 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9150 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9151 ins_pipe(ialu_reg); 9152 %} 9153 9154 // And Register with Memory 9155 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9156 %{ 9157 match(Set dst (AndI dst (LoadI src))); 9158 effect(KILL cr); 9159 9160 ins_cost(125); 9161 format %{ "andl $dst, $src\t# int" %} 9162 opcode(0x23); 9163 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9164 ins_pipe(ialu_reg_mem); 9165 %} 9166 9167 // And Memory with Register 9168 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9169 %{ 9170 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9171 effect(KILL cr); 9172 9173 ins_cost(150); 9174 format %{ "andb $dst, $src\t# byte" %} 9175 opcode(0x20); 9176 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9177 ins_pipe(ialu_mem_reg); 9178 %} 9179 9180 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9181 %{ 9182 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9183 effect(KILL cr); 9184 9185 ins_cost(150); 9186 format %{ "andl $dst, $src\t# int" %} 9187 opcode(0x21); /* Opcode 21 /r */ 9188 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9189 ins_pipe(ialu_mem_reg); 9190 %} 9191 9192 // And Memory with Immediate 9193 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9194 %{ 9195 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9196 effect(KILL cr); 9197 9198 ins_cost(125); 9199 format %{ "andl $dst, $src\t# int" %} 9200 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9201 ins_encode(REX_mem(dst), OpcSE(src), 9202 RM_opc_mem(secondary, dst), Con8or32(src)); 9203 ins_pipe(ialu_mem_imm); 9204 %} 9205 9206 // BMI1 instructions 9207 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9208 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9209 predicate(UseBMI1Instructions); 9210 effect(KILL cr); 9211 9212 ins_cost(125); 9213 format %{ "andnl $dst, $src1, $src2" %} 9214 9215 ins_encode %{ 9216 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9217 %} 9218 ins_pipe(ialu_reg_mem); 9219 %} 9220 9221 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9222 match(Set dst (AndI (XorI src1 minus_1) src2)); 9223 predicate(UseBMI1Instructions); 9224 effect(KILL cr); 9225 9226 format %{ "andnl $dst, $src1, $src2" %} 9227 9228 ins_encode %{ 9229 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9230 %} 9231 ins_pipe(ialu_reg); 9232 %} 9233 9234 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9235 match(Set dst (AndI (SubI imm_zero src) src)); 9236 predicate(UseBMI1Instructions); 9237 effect(KILL cr); 9238 9239 format %{ "blsil $dst, $src" %} 9240 9241 ins_encode %{ 9242 __ blsil($dst$$Register, $src$$Register); 9243 %} 9244 ins_pipe(ialu_reg); 9245 %} 9246 9247 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9248 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9249 predicate(UseBMI1Instructions); 9250 effect(KILL cr); 9251 9252 ins_cost(125); 9253 format %{ "blsil $dst, $src" %} 9254 9255 ins_encode %{ 9256 __ blsil($dst$$Register, $src$$Address); 9257 %} 9258 ins_pipe(ialu_reg_mem); 9259 %} 9260 9261 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9262 %{ 9263 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9264 predicate(UseBMI1Instructions); 9265 effect(KILL cr); 9266 9267 ins_cost(125); 9268 format %{ "blsmskl $dst, $src" %} 9269 9270 ins_encode %{ 9271 __ blsmskl($dst$$Register, $src$$Address); 9272 %} 9273 ins_pipe(ialu_reg_mem); 9274 %} 9275 9276 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9277 %{ 9278 match(Set dst (XorI (AddI src minus_1) src)); 9279 predicate(UseBMI1Instructions); 9280 effect(KILL cr); 9281 9282 format %{ "blsmskl $dst, $src" %} 9283 9284 ins_encode %{ 9285 __ blsmskl($dst$$Register, $src$$Register); 9286 %} 9287 9288 ins_pipe(ialu_reg); 9289 %} 9290 9291 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9292 %{ 9293 match(Set dst (AndI (AddI src minus_1) src) ); 9294 predicate(UseBMI1Instructions); 9295 effect(KILL cr); 9296 9297 format %{ "blsrl $dst, $src" %} 9298 9299 ins_encode %{ 9300 __ blsrl($dst$$Register, $src$$Register); 9301 %} 9302 9303 ins_pipe(ialu_reg_mem); 9304 %} 9305 9306 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9307 %{ 9308 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9309 predicate(UseBMI1Instructions); 9310 effect(KILL cr); 9311 9312 ins_cost(125); 9313 format %{ "blsrl $dst, $src" %} 9314 9315 ins_encode %{ 9316 __ blsrl($dst$$Register, $src$$Address); 9317 %} 9318 9319 ins_pipe(ialu_reg); 9320 %} 9321 9322 // Or Instructions 9323 // Or Register with Register 9324 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9325 %{ 9326 match(Set dst (OrI dst src)); 9327 effect(KILL cr); 9328 9329 format %{ "orl $dst, $src\t# int" %} 9330 opcode(0x0B); 9331 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9332 ins_pipe(ialu_reg_reg); 9333 %} 9334 9335 // Or Register with Immediate 9336 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9337 %{ 9338 match(Set dst (OrI dst src)); 9339 effect(KILL cr); 9340 9341 format %{ "orl $dst, $src\t# int" %} 9342 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9343 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9344 ins_pipe(ialu_reg); 9345 %} 9346 9347 // Or Register with Memory 9348 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9349 %{ 9350 match(Set dst (OrI dst (LoadI src))); 9351 effect(KILL cr); 9352 9353 ins_cost(125); 9354 format %{ "orl $dst, $src\t# int" %} 9355 opcode(0x0B); 9356 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9357 ins_pipe(ialu_reg_mem); 9358 %} 9359 9360 // Or Memory with Register 9361 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9362 %{ 9363 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9364 effect(KILL cr); 9365 9366 ins_cost(150); 9367 format %{ "orb $dst, $src\t# byte" %} 9368 opcode(0x08); 9369 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9370 ins_pipe(ialu_mem_reg); 9371 %} 9372 9373 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9374 %{ 9375 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9376 effect(KILL cr); 9377 9378 ins_cost(150); 9379 format %{ "orl $dst, $src\t# int" %} 9380 opcode(0x09); /* Opcode 09 /r */ 9381 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9382 ins_pipe(ialu_mem_reg); 9383 %} 9384 9385 // Or Memory with Immediate 9386 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9387 %{ 9388 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9389 effect(KILL cr); 9390 9391 ins_cost(125); 9392 format %{ "orl $dst, $src\t# int" %} 9393 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9394 ins_encode(REX_mem(dst), OpcSE(src), 9395 RM_opc_mem(secondary, dst), Con8or32(src)); 9396 ins_pipe(ialu_mem_imm); 9397 %} 9398 9399 // Xor Instructions 9400 // Xor Register with Register 9401 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9402 %{ 9403 match(Set dst (XorI dst src)); 9404 effect(KILL cr); 9405 9406 format %{ "xorl $dst, $src\t# int" %} 9407 opcode(0x33); 9408 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9409 ins_pipe(ialu_reg_reg); 9410 %} 9411 9412 // Xor Register with Immediate -1 9413 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9414 match(Set dst (XorI dst imm)); 9415 9416 format %{ "not $dst" %} 9417 ins_encode %{ 9418 __ notl($dst$$Register); 9419 %} 9420 ins_pipe(ialu_reg); 9421 %} 9422 9423 // Xor Register with Immediate 9424 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9425 %{ 9426 match(Set dst (XorI dst src)); 9427 effect(KILL cr); 9428 9429 format %{ "xorl $dst, $src\t# int" %} 9430 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9431 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9432 ins_pipe(ialu_reg); 9433 %} 9434 9435 // Xor Register with Memory 9436 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9437 %{ 9438 match(Set dst (XorI dst (LoadI src))); 9439 effect(KILL cr); 9440 9441 ins_cost(125); 9442 format %{ "xorl $dst, $src\t# int" %} 9443 opcode(0x33); 9444 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9445 ins_pipe(ialu_reg_mem); 9446 %} 9447 9448 // Xor Memory with Register 9449 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9450 %{ 9451 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9452 effect(KILL cr); 9453 9454 ins_cost(150); 9455 format %{ "xorb $dst, $src\t# byte" %} 9456 opcode(0x30); 9457 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9458 ins_pipe(ialu_mem_reg); 9459 %} 9460 9461 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9462 %{ 9463 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9464 effect(KILL cr); 9465 9466 ins_cost(150); 9467 format %{ "xorl $dst, $src\t# int" %} 9468 opcode(0x31); /* Opcode 31 /r */ 9469 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9470 ins_pipe(ialu_mem_reg); 9471 %} 9472 9473 // Xor Memory with Immediate 9474 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9475 %{ 9476 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9477 effect(KILL cr); 9478 9479 ins_cost(125); 9480 format %{ "xorl $dst, $src\t# int" %} 9481 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9482 ins_encode(REX_mem(dst), OpcSE(src), 9483 RM_opc_mem(secondary, dst), Con8or32(src)); 9484 ins_pipe(ialu_mem_imm); 9485 %} 9486 9487 9488 // Long Logical Instructions 9489 9490 // And Instructions 9491 // And Register with Register 9492 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9493 %{ 9494 match(Set dst (AndL dst src)); 9495 effect(KILL cr); 9496 9497 format %{ "andq $dst, $src\t# long" %} 9498 opcode(0x23); 9499 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9500 ins_pipe(ialu_reg_reg); 9501 %} 9502 9503 // And Register with Immediate 255 9504 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9505 %{ 9506 match(Set dst (AndL dst src)); 9507 9508 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9509 opcode(0x0F, 0xB6); 9510 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9511 ins_pipe(ialu_reg); 9512 %} 9513 9514 // And Register with Immediate 65535 9515 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9516 %{ 9517 match(Set dst (AndL dst src)); 9518 9519 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9520 opcode(0x0F, 0xB7); 9521 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9522 ins_pipe(ialu_reg); 9523 %} 9524 9525 // And Register with Immediate 9526 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9527 %{ 9528 match(Set dst (AndL dst src)); 9529 effect(KILL cr); 9530 9531 format %{ "andq $dst, $src\t# long" %} 9532 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9533 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9534 ins_pipe(ialu_reg); 9535 %} 9536 9537 // And Register with Memory 9538 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9539 %{ 9540 match(Set dst (AndL dst (LoadL src))); 9541 effect(KILL cr); 9542 9543 ins_cost(125); 9544 format %{ "andq $dst, $src\t# long" %} 9545 opcode(0x23); 9546 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9547 ins_pipe(ialu_reg_mem); 9548 %} 9549 9550 // And Memory with Register 9551 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9552 %{ 9553 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9554 effect(KILL cr); 9555 9556 ins_cost(150); 9557 format %{ "andq $dst, $src\t# long" %} 9558 opcode(0x21); /* Opcode 21 /r */ 9559 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9560 ins_pipe(ialu_mem_reg); 9561 %} 9562 9563 // And Memory with Immediate 9564 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9565 %{ 9566 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9567 effect(KILL cr); 9568 9569 ins_cost(125); 9570 format %{ "andq $dst, $src\t# long" %} 9571 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9572 ins_encode(REX_mem_wide(dst), OpcSE(src), 9573 RM_opc_mem(secondary, dst), Con8or32(src)); 9574 ins_pipe(ialu_mem_imm); 9575 %} 9576 9577 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9578 %{ 9579 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9580 // because AND/OR works well enough for 8/32-bit values. 9581 predicate(log2_long(~n->in(3)->in(2)->get_long()) > 30); 9582 9583 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9584 effect(KILL cr); 9585 9586 ins_cost(125); 9587 format %{ "btrq $dst, log2(not($con))\t# long" %} 9588 ins_encode %{ 9589 __ btrq($dst$$Address, log2_long(~$con$$constant)); 9590 %} 9591 ins_pipe(ialu_mem_imm); 9592 %} 9593 9594 // BMI1 instructions 9595 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9596 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9597 predicate(UseBMI1Instructions); 9598 effect(KILL cr); 9599 9600 ins_cost(125); 9601 format %{ "andnq $dst, $src1, $src2" %} 9602 9603 ins_encode %{ 9604 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9605 %} 9606 ins_pipe(ialu_reg_mem); 9607 %} 9608 9609 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9610 match(Set dst (AndL (XorL src1 minus_1) src2)); 9611 predicate(UseBMI1Instructions); 9612 effect(KILL cr); 9613 9614 format %{ "andnq $dst, $src1, $src2" %} 9615 9616 ins_encode %{ 9617 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9618 %} 9619 ins_pipe(ialu_reg_mem); 9620 %} 9621 9622 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9623 match(Set dst (AndL (SubL imm_zero src) src)); 9624 predicate(UseBMI1Instructions); 9625 effect(KILL cr); 9626 9627 format %{ "blsiq $dst, $src" %} 9628 9629 ins_encode %{ 9630 __ blsiq($dst$$Register, $src$$Register); 9631 %} 9632 ins_pipe(ialu_reg); 9633 %} 9634 9635 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9636 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9637 predicate(UseBMI1Instructions); 9638 effect(KILL cr); 9639 9640 ins_cost(125); 9641 format %{ "blsiq $dst, $src" %} 9642 9643 ins_encode %{ 9644 __ blsiq($dst$$Register, $src$$Address); 9645 %} 9646 ins_pipe(ialu_reg_mem); 9647 %} 9648 9649 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9650 %{ 9651 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9652 predicate(UseBMI1Instructions); 9653 effect(KILL cr); 9654 9655 ins_cost(125); 9656 format %{ "blsmskq $dst, $src" %} 9657 9658 ins_encode %{ 9659 __ blsmskq($dst$$Register, $src$$Address); 9660 %} 9661 ins_pipe(ialu_reg_mem); 9662 %} 9663 9664 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9665 %{ 9666 match(Set dst (XorL (AddL src minus_1) src)); 9667 predicate(UseBMI1Instructions); 9668 effect(KILL cr); 9669 9670 format %{ "blsmskq $dst, $src" %} 9671 9672 ins_encode %{ 9673 __ blsmskq($dst$$Register, $src$$Register); 9674 %} 9675 9676 ins_pipe(ialu_reg); 9677 %} 9678 9679 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9680 %{ 9681 match(Set dst (AndL (AddL src minus_1) src) ); 9682 predicate(UseBMI1Instructions); 9683 effect(KILL cr); 9684 9685 format %{ "blsrq $dst, $src" %} 9686 9687 ins_encode %{ 9688 __ blsrq($dst$$Register, $src$$Register); 9689 %} 9690 9691 ins_pipe(ialu_reg); 9692 %} 9693 9694 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9695 %{ 9696 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9697 predicate(UseBMI1Instructions); 9698 effect(KILL cr); 9699 9700 ins_cost(125); 9701 format %{ "blsrq $dst, $src" %} 9702 9703 ins_encode %{ 9704 __ blsrq($dst$$Register, $src$$Address); 9705 %} 9706 9707 ins_pipe(ialu_reg); 9708 %} 9709 9710 // Or Instructions 9711 // Or Register with Register 9712 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9713 %{ 9714 match(Set dst (OrL dst src)); 9715 effect(KILL cr); 9716 9717 format %{ "orq $dst, $src\t# long" %} 9718 opcode(0x0B); 9719 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9720 ins_pipe(ialu_reg_reg); 9721 %} 9722 9723 // Use any_RegP to match R15 (TLS register) without spilling. 9724 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9725 match(Set dst (OrL dst (CastP2X src))); 9726 effect(KILL cr); 9727 9728 format %{ "orq $dst, $src\t# long" %} 9729 opcode(0x0B); 9730 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9731 ins_pipe(ialu_reg_reg); 9732 %} 9733 9734 9735 // Or Register with Immediate 9736 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9737 %{ 9738 match(Set dst (OrL dst src)); 9739 effect(KILL cr); 9740 9741 format %{ "orq $dst, $src\t# long" %} 9742 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9743 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9744 ins_pipe(ialu_reg); 9745 %} 9746 9747 // Or Register with Memory 9748 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9749 %{ 9750 match(Set dst (OrL dst (LoadL src))); 9751 effect(KILL cr); 9752 9753 ins_cost(125); 9754 format %{ "orq $dst, $src\t# long" %} 9755 opcode(0x0B); 9756 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9757 ins_pipe(ialu_reg_mem); 9758 %} 9759 9760 // Or Memory with Register 9761 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9762 %{ 9763 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9764 effect(KILL cr); 9765 9766 ins_cost(150); 9767 format %{ "orq $dst, $src\t# long" %} 9768 opcode(0x09); /* Opcode 09 /r */ 9769 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9770 ins_pipe(ialu_mem_reg); 9771 %} 9772 9773 // Or Memory with Immediate 9774 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9775 %{ 9776 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9777 effect(KILL cr); 9778 9779 ins_cost(125); 9780 format %{ "orq $dst, $src\t# long" %} 9781 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9782 ins_encode(REX_mem_wide(dst), OpcSE(src), 9783 RM_opc_mem(secondary, dst), Con8or32(src)); 9784 ins_pipe(ialu_mem_imm); 9785 %} 9786 9787 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9788 %{ 9789 // con should be a pure 64-bit power of 2 immediate 9790 // because AND/OR works well enough for 8/32-bit values. 9791 predicate(log2_long(n->in(3)->in(2)->get_long()) > 31); 9792 9793 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9794 effect(KILL cr); 9795 9796 ins_cost(125); 9797 format %{ "btsq $dst, log2($con)\t# long" %} 9798 ins_encode %{ 9799 __ btsq($dst$$Address, log2_long((julong)$con$$constant)); 9800 %} 9801 ins_pipe(ialu_mem_imm); 9802 %} 9803 9804 // Xor Instructions 9805 // Xor Register with Register 9806 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9807 %{ 9808 match(Set dst (XorL dst src)); 9809 effect(KILL cr); 9810 9811 format %{ "xorq $dst, $src\t# long" %} 9812 opcode(0x33); 9813 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9814 ins_pipe(ialu_reg_reg); 9815 %} 9816 9817 // Xor Register with Immediate -1 9818 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9819 match(Set dst (XorL dst imm)); 9820 9821 format %{ "notq $dst" %} 9822 ins_encode %{ 9823 __ notq($dst$$Register); 9824 %} 9825 ins_pipe(ialu_reg); 9826 %} 9827 9828 // Xor Register with Immediate 9829 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9830 %{ 9831 match(Set dst (XorL dst src)); 9832 effect(KILL cr); 9833 9834 format %{ "xorq $dst, $src\t# long" %} 9835 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9836 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9837 ins_pipe(ialu_reg); 9838 %} 9839 9840 // Xor Register with Memory 9841 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9842 %{ 9843 match(Set dst (XorL dst (LoadL src))); 9844 effect(KILL cr); 9845 9846 ins_cost(125); 9847 format %{ "xorq $dst, $src\t# long" %} 9848 opcode(0x33); 9849 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9850 ins_pipe(ialu_reg_mem); 9851 %} 9852 9853 // Xor Memory with Register 9854 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9855 %{ 9856 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9857 effect(KILL cr); 9858 9859 ins_cost(150); 9860 format %{ "xorq $dst, $src\t# long" %} 9861 opcode(0x31); /* Opcode 31 /r */ 9862 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9863 ins_pipe(ialu_mem_reg); 9864 %} 9865 9866 // Xor Memory with Immediate 9867 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9868 %{ 9869 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9870 effect(KILL cr); 9871 9872 ins_cost(125); 9873 format %{ "xorq $dst, $src\t# long" %} 9874 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9875 ins_encode(REX_mem_wide(dst), OpcSE(src), 9876 RM_opc_mem(secondary, dst), Con8or32(src)); 9877 ins_pipe(ialu_mem_imm); 9878 %} 9879 9880 // Convert Int to Boolean 9881 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9882 %{ 9883 match(Set dst (Conv2B src)); 9884 effect(KILL cr); 9885 9886 format %{ "testl $src, $src\t# ci2b\n\t" 9887 "setnz $dst\n\t" 9888 "movzbl $dst, $dst" %} 9889 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9890 setNZ_reg(dst), 9891 REX_reg_breg(dst, dst), // movzbl 9892 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9893 ins_pipe(pipe_slow); // XXX 9894 %} 9895 9896 // Convert Pointer to Boolean 9897 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9898 %{ 9899 match(Set dst (Conv2B src)); 9900 effect(KILL cr); 9901 9902 format %{ "testq $src, $src\t# cp2b\n\t" 9903 "setnz $dst\n\t" 9904 "movzbl $dst, $dst" %} 9905 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9906 setNZ_reg(dst), 9907 REX_reg_breg(dst, dst), // movzbl 9908 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9909 ins_pipe(pipe_slow); // XXX 9910 %} 9911 9912 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9913 %{ 9914 match(Set dst (CmpLTMask p q)); 9915 effect(KILL cr); 9916 9917 ins_cost(400); 9918 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9919 "setlt $dst\n\t" 9920 "movzbl $dst, $dst\n\t" 9921 "negl $dst" %} 9922 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9923 setLT_reg(dst), 9924 REX_reg_breg(dst, dst), // movzbl 9925 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9926 neg_reg(dst)); 9927 ins_pipe(pipe_slow); 9928 %} 9929 9930 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9931 %{ 9932 match(Set dst (CmpLTMask dst zero)); 9933 effect(KILL cr); 9934 9935 ins_cost(100); 9936 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9937 ins_encode %{ 9938 __ sarl($dst$$Register, 31); 9939 %} 9940 ins_pipe(ialu_reg); 9941 %} 9942 9943 /* Better to save a register than avoid a branch */ 9944 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9945 %{ 9946 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9947 effect(KILL cr); 9948 ins_cost(300); 9949 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9950 "jge done\n\t" 9951 "addl $p,$y\n" 9952 "done: " %} 9953 ins_encode %{ 9954 Register Rp = $p$$Register; 9955 Register Rq = $q$$Register; 9956 Register Ry = $y$$Register; 9957 Label done; 9958 __ subl(Rp, Rq); 9959 __ jccb(Assembler::greaterEqual, done); 9960 __ addl(Rp, Ry); 9961 __ bind(done); 9962 %} 9963 ins_pipe(pipe_cmplt); 9964 %} 9965 9966 /* Better to save a register than avoid a branch */ 9967 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9968 %{ 9969 match(Set y (AndI (CmpLTMask p q) y)); 9970 effect(KILL cr); 9971 9972 ins_cost(300); 9973 9974 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9975 "jlt done\n\t" 9976 "xorl $y, $y\n" 9977 "done: " %} 9978 ins_encode %{ 9979 Register Rp = $p$$Register; 9980 Register Rq = $q$$Register; 9981 Register Ry = $y$$Register; 9982 Label done; 9983 __ cmpl(Rp, Rq); 9984 __ jccb(Assembler::less, done); 9985 __ xorl(Ry, Ry); 9986 __ bind(done); 9987 %} 9988 ins_pipe(pipe_cmplt); 9989 %} 9990 9991 9992 //---------- FP Instructions------------------------------------------------ 9993 9994 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9995 %{ 9996 match(Set cr (CmpF src1 src2)); 9997 9998 ins_cost(145); 9999 format %{ "ucomiss $src1, $src2\n\t" 10000 "jnp,s exit\n\t" 10001 "pushfq\t# saw NaN, set CF\n\t" 10002 "andq [rsp], #0xffffff2b\n\t" 10003 "popfq\n" 10004 "exit:" %} 10005 ins_encode %{ 10006 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10007 emit_cmpfp_fixup(_masm); 10008 %} 10009 ins_pipe(pipe_slow); 10010 %} 10011 10012 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10013 match(Set cr (CmpF src1 src2)); 10014 10015 ins_cost(100); 10016 format %{ "ucomiss $src1, $src2" %} 10017 ins_encode %{ 10018 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10019 %} 10020 ins_pipe(pipe_slow); 10021 %} 10022 10023 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10024 %{ 10025 match(Set cr (CmpF src1 (LoadF src2))); 10026 10027 ins_cost(145); 10028 format %{ "ucomiss $src1, $src2\n\t" 10029 "jnp,s exit\n\t" 10030 "pushfq\t# saw NaN, set CF\n\t" 10031 "andq [rsp], #0xffffff2b\n\t" 10032 "popfq\n" 10033 "exit:" %} 10034 ins_encode %{ 10035 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10036 emit_cmpfp_fixup(_masm); 10037 %} 10038 ins_pipe(pipe_slow); 10039 %} 10040 10041 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10042 match(Set cr (CmpF src1 (LoadF src2))); 10043 10044 ins_cost(100); 10045 format %{ "ucomiss $src1, $src2" %} 10046 ins_encode %{ 10047 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10048 %} 10049 ins_pipe(pipe_slow); 10050 %} 10051 10052 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10053 match(Set cr (CmpF src con)); 10054 10055 ins_cost(145); 10056 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10057 "jnp,s exit\n\t" 10058 "pushfq\t# saw NaN, set CF\n\t" 10059 "andq [rsp], #0xffffff2b\n\t" 10060 "popfq\n" 10061 "exit:" %} 10062 ins_encode %{ 10063 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10064 emit_cmpfp_fixup(_masm); 10065 %} 10066 ins_pipe(pipe_slow); 10067 %} 10068 10069 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10070 match(Set cr (CmpF src con)); 10071 ins_cost(100); 10072 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10073 ins_encode %{ 10074 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10075 %} 10076 ins_pipe(pipe_slow); 10077 %} 10078 10079 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10080 %{ 10081 match(Set cr (CmpD src1 src2)); 10082 10083 ins_cost(145); 10084 format %{ "ucomisd $src1, $src2\n\t" 10085 "jnp,s exit\n\t" 10086 "pushfq\t# saw NaN, set CF\n\t" 10087 "andq [rsp], #0xffffff2b\n\t" 10088 "popfq\n" 10089 "exit:" %} 10090 ins_encode %{ 10091 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10092 emit_cmpfp_fixup(_masm); 10093 %} 10094 ins_pipe(pipe_slow); 10095 %} 10096 10097 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10098 match(Set cr (CmpD src1 src2)); 10099 10100 ins_cost(100); 10101 format %{ "ucomisd $src1, $src2 test" %} 10102 ins_encode %{ 10103 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10104 %} 10105 ins_pipe(pipe_slow); 10106 %} 10107 10108 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10109 %{ 10110 match(Set cr (CmpD src1 (LoadD src2))); 10111 10112 ins_cost(145); 10113 format %{ "ucomisd $src1, $src2\n\t" 10114 "jnp,s exit\n\t" 10115 "pushfq\t# saw NaN, set CF\n\t" 10116 "andq [rsp], #0xffffff2b\n\t" 10117 "popfq\n" 10118 "exit:" %} 10119 ins_encode %{ 10120 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10121 emit_cmpfp_fixup(_masm); 10122 %} 10123 ins_pipe(pipe_slow); 10124 %} 10125 10126 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10127 match(Set cr (CmpD src1 (LoadD src2))); 10128 10129 ins_cost(100); 10130 format %{ "ucomisd $src1, $src2" %} 10131 ins_encode %{ 10132 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10133 %} 10134 ins_pipe(pipe_slow); 10135 %} 10136 10137 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10138 match(Set cr (CmpD src con)); 10139 10140 ins_cost(145); 10141 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10142 "jnp,s exit\n\t" 10143 "pushfq\t# saw NaN, set CF\n\t" 10144 "andq [rsp], #0xffffff2b\n\t" 10145 "popfq\n" 10146 "exit:" %} 10147 ins_encode %{ 10148 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10149 emit_cmpfp_fixup(_masm); 10150 %} 10151 ins_pipe(pipe_slow); 10152 %} 10153 10154 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10155 match(Set cr (CmpD src con)); 10156 ins_cost(100); 10157 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10158 ins_encode %{ 10159 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10160 %} 10161 ins_pipe(pipe_slow); 10162 %} 10163 10164 // Compare into -1,0,1 10165 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10166 %{ 10167 match(Set dst (CmpF3 src1 src2)); 10168 effect(KILL cr); 10169 10170 ins_cost(275); 10171 format %{ "ucomiss $src1, $src2\n\t" 10172 "movl $dst, #-1\n\t" 10173 "jp,s done\n\t" 10174 "jb,s done\n\t" 10175 "setne $dst\n\t" 10176 "movzbl $dst, $dst\n" 10177 "done:" %} 10178 ins_encode %{ 10179 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10180 emit_cmpfp3(_masm, $dst$$Register); 10181 %} 10182 ins_pipe(pipe_slow); 10183 %} 10184 10185 // Compare into -1,0,1 10186 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10187 %{ 10188 match(Set dst (CmpF3 src1 (LoadF src2))); 10189 effect(KILL cr); 10190 10191 ins_cost(275); 10192 format %{ "ucomiss $src1, $src2\n\t" 10193 "movl $dst, #-1\n\t" 10194 "jp,s done\n\t" 10195 "jb,s done\n\t" 10196 "setne $dst\n\t" 10197 "movzbl $dst, $dst\n" 10198 "done:" %} 10199 ins_encode %{ 10200 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10201 emit_cmpfp3(_masm, $dst$$Register); 10202 %} 10203 ins_pipe(pipe_slow); 10204 %} 10205 10206 // Compare into -1,0,1 10207 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10208 match(Set dst (CmpF3 src con)); 10209 effect(KILL cr); 10210 10211 ins_cost(275); 10212 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10213 "movl $dst, #-1\n\t" 10214 "jp,s done\n\t" 10215 "jb,s done\n\t" 10216 "setne $dst\n\t" 10217 "movzbl $dst, $dst\n" 10218 "done:" %} 10219 ins_encode %{ 10220 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10221 emit_cmpfp3(_masm, $dst$$Register); 10222 %} 10223 ins_pipe(pipe_slow); 10224 %} 10225 10226 // Compare into -1,0,1 10227 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10228 %{ 10229 match(Set dst (CmpD3 src1 src2)); 10230 effect(KILL cr); 10231 10232 ins_cost(275); 10233 format %{ "ucomisd $src1, $src2\n\t" 10234 "movl $dst, #-1\n\t" 10235 "jp,s done\n\t" 10236 "jb,s done\n\t" 10237 "setne $dst\n\t" 10238 "movzbl $dst, $dst\n" 10239 "done:" %} 10240 ins_encode %{ 10241 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10242 emit_cmpfp3(_masm, $dst$$Register); 10243 %} 10244 ins_pipe(pipe_slow); 10245 %} 10246 10247 // Compare into -1,0,1 10248 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10249 %{ 10250 match(Set dst (CmpD3 src1 (LoadD src2))); 10251 effect(KILL cr); 10252 10253 ins_cost(275); 10254 format %{ "ucomisd $src1, $src2\n\t" 10255 "movl $dst, #-1\n\t" 10256 "jp,s done\n\t" 10257 "jb,s done\n\t" 10258 "setne $dst\n\t" 10259 "movzbl $dst, $dst\n" 10260 "done:" %} 10261 ins_encode %{ 10262 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10263 emit_cmpfp3(_masm, $dst$$Register); 10264 %} 10265 ins_pipe(pipe_slow); 10266 %} 10267 10268 // Compare into -1,0,1 10269 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10270 match(Set dst (CmpD3 src con)); 10271 effect(KILL cr); 10272 10273 ins_cost(275); 10274 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10275 "movl $dst, #-1\n\t" 10276 "jp,s done\n\t" 10277 "jb,s done\n\t" 10278 "setne $dst\n\t" 10279 "movzbl $dst, $dst\n" 10280 "done:" %} 10281 ins_encode %{ 10282 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10283 emit_cmpfp3(_masm, $dst$$Register); 10284 %} 10285 ins_pipe(pipe_slow); 10286 %} 10287 10288 //----------Arithmetic Conversion Instructions--------------------------------- 10289 10290 instruct convF2D_reg_reg(regD dst, regF src) 10291 %{ 10292 match(Set dst (ConvF2D src)); 10293 10294 format %{ "cvtss2sd $dst, $src" %} 10295 ins_encode %{ 10296 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10297 %} 10298 ins_pipe(pipe_slow); // XXX 10299 %} 10300 10301 instruct convF2D_reg_mem(regD dst, memory src) 10302 %{ 10303 match(Set dst (ConvF2D (LoadF src))); 10304 10305 format %{ "cvtss2sd $dst, $src" %} 10306 ins_encode %{ 10307 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10308 %} 10309 ins_pipe(pipe_slow); // XXX 10310 %} 10311 10312 instruct convD2F_reg_reg(regF dst, regD src) 10313 %{ 10314 match(Set dst (ConvD2F src)); 10315 10316 format %{ "cvtsd2ss $dst, $src" %} 10317 ins_encode %{ 10318 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10319 %} 10320 ins_pipe(pipe_slow); // XXX 10321 %} 10322 10323 instruct convD2F_reg_mem(regF dst, memory src) 10324 %{ 10325 match(Set dst (ConvD2F (LoadD src))); 10326 10327 format %{ "cvtsd2ss $dst, $src" %} 10328 ins_encode %{ 10329 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10330 %} 10331 ins_pipe(pipe_slow); // XXX 10332 %} 10333 10334 // XXX do mem variants 10335 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10336 %{ 10337 match(Set dst (ConvF2I src)); 10338 effect(KILL cr); 10339 format %{ "convert_f2i $dst,$src" %} 10340 ins_encode %{ 10341 __ convert_f2i($dst$$Register, $src$$XMMRegister); 10342 %} 10343 ins_pipe(pipe_slow); 10344 %} 10345 10346 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10347 %{ 10348 match(Set dst (ConvF2L src)); 10349 effect(KILL cr); 10350 format %{ "convert_f2l $dst,$src"%} 10351 ins_encode %{ 10352 __ convert_f2l($dst$$Register, $src$$XMMRegister); 10353 %} 10354 ins_pipe(pipe_slow); 10355 %} 10356 10357 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10358 %{ 10359 match(Set dst (ConvD2I src)); 10360 effect(KILL cr); 10361 format %{ "convert_d2i $dst,$src"%} 10362 ins_encode %{ 10363 __ convert_d2i($dst$$Register, $src$$XMMRegister); 10364 %} 10365 ins_pipe(pipe_slow); 10366 %} 10367 10368 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10369 %{ 10370 match(Set dst (ConvD2L src)); 10371 effect(KILL cr); 10372 format %{ "convert_d2l $dst,$src"%} 10373 ins_encode %{ 10374 __ convert_d2l($dst$$Register, $src$$XMMRegister); 10375 %} 10376 ins_pipe(pipe_slow); 10377 %} 10378 10379 instruct convI2F_reg_reg(regF dst, rRegI src) 10380 %{ 10381 predicate(!UseXmmI2F); 10382 match(Set dst (ConvI2F src)); 10383 10384 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10385 ins_encode %{ 10386 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10387 %} 10388 ins_pipe(pipe_slow); // XXX 10389 %} 10390 10391 instruct convI2F_reg_mem(regF dst, memory src) 10392 %{ 10393 match(Set dst (ConvI2F (LoadI src))); 10394 10395 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10396 ins_encode %{ 10397 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10398 %} 10399 ins_pipe(pipe_slow); // XXX 10400 %} 10401 10402 instruct convI2D_reg_reg(regD dst, rRegI src) 10403 %{ 10404 predicate(!UseXmmI2D); 10405 match(Set dst (ConvI2D src)); 10406 10407 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10408 ins_encode %{ 10409 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10410 %} 10411 ins_pipe(pipe_slow); // XXX 10412 %} 10413 10414 instruct convI2D_reg_mem(regD dst, memory src) 10415 %{ 10416 match(Set dst (ConvI2D (LoadI src))); 10417 10418 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10419 ins_encode %{ 10420 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10421 %} 10422 ins_pipe(pipe_slow); // XXX 10423 %} 10424 10425 instruct convXI2F_reg(regF dst, rRegI src) 10426 %{ 10427 predicate(UseXmmI2F); 10428 match(Set dst (ConvI2F src)); 10429 10430 format %{ "movdl $dst, $src\n\t" 10431 "cvtdq2psl $dst, $dst\t# i2f" %} 10432 ins_encode %{ 10433 __ movdl($dst$$XMMRegister, $src$$Register); 10434 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10435 %} 10436 ins_pipe(pipe_slow); // XXX 10437 %} 10438 10439 instruct convXI2D_reg(regD dst, rRegI src) 10440 %{ 10441 predicate(UseXmmI2D); 10442 match(Set dst (ConvI2D src)); 10443 10444 format %{ "movdl $dst, $src\n\t" 10445 "cvtdq2pdl $dst, $dst\t# i2d" %} 10446 ins_encode %{ 10447 __ movdl($dst$$XMMRegister, $src$$Register); 10448 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10449 %} 10450 ins_pipe(pipe_slow); // XXX 10451 %} 10452 10453 instruct convL2F_reg_reg(regF dst, rRegL src) 10454 %{ 10455 match(Set dst (ConvL2F src)); 10456 10457 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10458 ins_encode %{ 10459 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10460 %} 10461 ins_pipe(pipe_slow); // XXX 10462 %} 10463 10464 instruct convL2F_reg_mem(regF dst, memory src) 10465 %{ 10466 match(Set dst (ConvL2F (LoadL src))); 10467 10468 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10469 ins_encode %{ 10470 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10471 %} 10472 ins_pipe(pipe_slow); // XXX 10473 %} 10474 10475 instruct convL2D_reg_reg(regD dst, rRegL src) 10476 %{ 10477 match(Set dst (ConvL2D src)); 10478 10479 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10480 ins_encode %{ 10481 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10482 %} 10483 ins_pipe(pipe_slow); // XXX 10484 %} 10485 10486 instruct convL2D_reg_mem(regD dst, memory src) 10487 %{ 10488 match(Set dst (ConvL2D (LoadL src))); 10489 10490 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10491 ins_encode %{ 10492 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10493 %} 10494 ins_pipe(pipe_slow); // XXX 10495 %} 10496 10497 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10498 %{ 10499 match(Set dst (ConvI2L src)); 10500 10501 ins_cost(125); 10502 format %{ "movslq $dst, $src\t# i2l" %} 10503 ins_encode %{ 10504 __ movslq($dst$$Register, $src$$Register); 10505 %} 10506 ins_pipe(ialu_reg_reg); 10507 %} 10508 10509 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10510 // %{ 10511 // match(Set dst (ConvI2L src)); 10512 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10513 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10514 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10515 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10516 // ((const TypeNode*) n)->type()->is_long()->_lo == 10517 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10518 10519 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10520 // ins_encode(enc_copy(dst, src)); 10521 // // opcode(0x63); // needs REX.W 10522 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10523 // ins_pipe(ialu_reg_reg); 10524 // %} 10525 10526 // Zero-extend convert int to long 10527 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10528 %{ 10529 match(Set dst (AndL (ConvI2L src) mask)); 10530 10531 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10532 ins_encode %{ 10533 if ($dst$$reg != $src$$reg) { 10534 __ movl($dst$$Register, $src$$Register); 10535 } 10536 %} 10537 ins_pipe(ialu_reg_reg); 10538 %} 10539 10540 // Zero-extend convert int to long 10541 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10542 %{ 10543 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10544 10545 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10546 ins_encode %{ 10547 __ movl($dst$$Register, $src$$Address); 10548 %} 10549 ins_pipe(ialu_reg_mem); 10550 %} 10551 10552 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10553 %{ 10554 match(Set dst (AndL src mask)); 10555 10556 format %{ "movl $dst, $src\t# zero-extend long" %} 10557 ins_encode %{ 10558 __ movl($dst$$Register, $src$$Register); 10559 %} 10560 ins_pipe(ialu_reg_reg); 10561 %} 10562 10563 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10564 %{ 10565 match(Set dst (ConvL2I src)); 10566 10567 format %{ "movl $dst, $src\t# l2i" %} 10568 ins_encode %{ 10569 __ movl($dst$$Register, $src$$Register); 10570 %} 10571 ins_pipe(ialu_reg_reg); 10572 %} 10573 10574 10575 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10576 match(Set dst (MoveF2I src)); 10577 effect(DEF dst, USE src); 10578 10579 ins_cost(125); 10580 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10581 ins_encode %{ 10582 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10583 %} 10584 ins_pipe(ialu_reg_mem); 10585 %} 10586 10587 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10588 match(Set dst (MoveI2F src)); 10589 effect(DEF dst, USE src); 10590 10591 ins_cost(125); 10592 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10593 ins_encode %{ 10594 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10595 %} 10596 ins_pipe(pipe_slow); 10597 %} 10598 10599 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10600 match(Set dst (MoveD2L src)); 10601 effect(DEF dst, USE src); 10602 10603 ins_cost(125); 10604 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10605 ins_encode %{ 10606 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10607 %} 10608 ins_pipe(ialu_reg_mem); 10609 %} 10610 10611 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10612 predicate(!UseXmmLoadAndClearUpper); 10613 match(Set dst (MoveL2D src)); 10614 effect(DEF dst, USE src); 10615 10616 ins_cost(125); 10617 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10618 ins_encode %{ 10619 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10620 %} 10621 ins_pipe(pipe_slow); 10622 %} 10623 10624 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10625 predicate(UseXmmLoadAndClearUpper); 10626 match(Set dst (MoveL2D src)); 10627 effect(DEF dst, USE src); 10628 10629 ins_cost(125); 10630 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10631 ins_encode %{ 10632 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10633 %} 10634 ins_pipe(pipe_slow); 10635 %} 10636 10637 10638 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10639 match(Set dst (MoveF2I src)); 10640 effect(DEF dst, USE src); 10641 10642 ins_cost(95); // XXX 10643 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10644 ins_encode %{ 10645 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10646 %} 10647 ins_pipe(pipe_slow); 10648 %} 10649 10650 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10651 match(Set dst (MoveI2F src)); 10652 effect(DEF dst, USE src); 10653 10654 ins_cost(100); 10655 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10656 ins_encode %{ 10657 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10658 %} 10659 ins_pipe( ialu_mem_reg ); 10660 %} 10661 10662 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10663 match(Set dst (MoveD2L src)); 10664 effect(DEF dst, USE src); 10665 10666 ins_cost(95); // XXX 10667 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10668 ins_encode %{ 10669 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10670 %} 10671 ins_pipe(pipe_slow); 10672 %} 10673 10674 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10675 match(Set dst (MoveL2D src)); 10676 effect(DEF dst, USE src); 10677 10678 ins_cost(100); 10679 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10680 ins_encode %{ 10681 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10682 %} 10683 ins_pipe(ialu_mem_reg); 10684 %} 10685 10686 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10687 match(Set dst (MoveF2I src)); 10688 effect(DEF dst, USE src); 10689 ins_cost(85); 10690 format %{ "movd $dst,$src\t# MoveF2I" %} 10691 ins_encode %{ 10692 __ movdl($dst$$Register, $src$$XMMRegister); 10693 %} 10694 ins_pipe( pipe_slow ); 10695 %} 10696 10697 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10698 match(Set dst (MoveD2L src)); 10699 effect(DEF dst, USE src); 10700 ins_cost(85); 10701 format %{ "movd $dst,$src\t# MoveD2L" %} 10702 ins_encode %{ 10703 __ movdq($dst$$Register, $src$$XMMRegister); 10704 %} 10705 ins_pipe( pipe_slow ); 10706 %} 10707 10708 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10709 match(Set dst (MoveI2F src)); 10710 effect(DEF dst, USE src); 10711 ins_cost(100); 10712 format %{ "movd $dst,$src\t# MoveI2F" %} 10713 ins_encode %{ 10714 __ movdl($dst$$XMMRegister, $src$$Register); 10715 %} 10716 ins_pipe( pipe_slow ); 10717 %} 10718 10719 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10720 match(Set dst (MoveL2D src)); 10721 effect(DEF dst, USE src); 10722 ins_cost(100); 10723 format %{ "movd $dst,$src\t# MoveL2D" %} 10724 ins_encode %{ 10725 __ movdq($dst$$XMMRegister, $src$$Register); 10726 %} 10727 ins_pipe( pipe_slow ); 10728 %} 10729 10730 10731 // ======================================================================= 10732 // fast clearing of an array 10733 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10734 Universe dummy, rFlagsReg cr) 10735 %{ 10736 predicate(!((ClearArrayNode*)n)->is_large()); 10737 match(Set dummy (ClearArray cnt base)); 10738 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10739 10740 format %{ $$template 10741 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10742 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10743 $$emit$$"jg LARGE\n\t" 10744 $$emit$$"dec rcx\n\t" 10745 $$emit$$"js DONE\t# Zero length\n\t" 10746 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10747 $$emit$$"dec rcx\n\t" 10748 $$emit$$"jge LOOP\n\t" 10749 $$emit$$"jmp DONE\n\t" 10750 $$emit$$"# LARGE:\n\t" 10751 if (UseFastStosb) { 10752 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10753 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10754 } else if (UseXMMForObjInit) { 10755 $$emit$$"mov rdi,rax\n\t" 10756 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10757 $$emit$$"jmpq L_zero_64_bytes\n\t" 10758 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10759 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10760 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10761 $$emit$$"add 0x40,rax\n\t" 10762 $$emit$$"# L_zero_64_bytes:\n\t" 10763 $$emit$$"sub 0x8,rcx\n\t" 10764 $$emit$$"jge L_loop\n\t" 10765 $$emit$$"add 0x4,rcx\n\t" 10766 $$emit$$"jl L_tail\n\t" 10767 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10768 $$emit$$"add 0x20,rax\n\t" 10769 $$emit$$"sub 0x4,rcx\n\t" 10770 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10771 $$emit$$"add 0x4,rcx\n\t" 10772 $$emit$$"jle L_end\n\t" 10773 $$emit$$"dec rcx\n\t" 10774 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10775 $$emit$$"vmovq xmm0,(rax)\n\t" 10776 $$emit$$"add 0x8,rax\n\t" 10777 $$emit$$"dec rcx\n\t" 10778 $$emit$$"jge L_sloop\n\t" 10779 $$emit$$"# L_end:\n\t" 10780 } else { 10781 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10782 } 10783 $$emit$$"# DONE" 10784 %} 10785 ins_encode %{ 10786 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10787 $tmp$$XMMRegister, false); 10788 %} 10789 ins_pipe(pipe_slow); 10790 %} 10791 10792 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10793 Universe dummy, rFlagsReg cr) 10794 %{ 10795 predicate(((ClearArrayNode*)n)->is_large()); 10796 match(Set dummy (ClearArray cnt base)); 10797 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10798 10799 format %{ $$template 10800 if (UseFastStosb) { 10801 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10802 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10803 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10804 } else if (UseXMMForObjInit) { 10805 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10806 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10807 $$emit$$"jmpq L_zero_64_bytes\n\t" 10808 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10809 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10810 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10811 $$emit$$"add 0x40,rax\n\t" 10812 $$emit$$"# L_zero_64_bytes:\n\t" 10813 $$emit$$"sub 0x8,rcx\n\t" 10814 $$emit$$"jge L_loop\n\t" 10815 $$emit$$"add 0x4,rcx\n\t" 10816 $$emit$$"jl L_tail\n\t" 10817 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10818 $$emit$$"add 0x20,rax\n\t" 10819 $$emit$$"sub 0x4,rcx\n\t" 10820 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10821 $$emit$$"add 0x4,rcx\n\t" 10822 $$emit$$"jle L_end\n\t" 10823 $$emit$$"dec rcx\n\t" 10824 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10825 $$emit$$"vmovq xmm0,(rax)\n\t" 10826 $$emit$$"add 0x8,rax\n\t" 10827 $$emit$$"dec rcx\n\t" 10828 $$emit$$"jge L_sloop\n\t" 10829 $$emit$$"# L_end:\n\t" 10830 } else { 10831 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10832 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10833 } 10834 %} 10835 ins_encode %{ 10836 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10837 $tmp$$XMMRegister, true); 10838 %} 10839 ins_pipe(pipe_slow); 10840 %} 10841 10842 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10843 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10844 %{ 10845 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10846 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10847 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10848 10849 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10850 ins_encode %{ 10851 __ string_compare($str1$$Register, $str2$$Register, 10852 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10853 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10854 %} 10855 ins_pipe( pipe_slow ); 10856 %} 10857 10858 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10859 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10860 %{ 10861 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10862 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10863 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10864 10865 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10866 ins_encode %{ 10867 __ string_compare($str1$$Register, $str2$$Register, 10868 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10869 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10870 %} 10871 ins_pipe( pipe_slow ); 10872 %} 10873 10874 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10875 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10876 %{ 10877 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10878 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10879 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10880 10881 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10882 ins_encode %{ 10883 __ string_compare($str1$$Register, $str2$$Register, 10884 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10885 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10886 %} 10887 ins_pipe( pipe_slow ); 10888 %} 10889 10890 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10891 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10892 %{ 10893 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10894 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10895 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10896 10897 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10898 ins_encode %{ 10899 __ string_compare($str2$$Register, $str1$$Register, 10900 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10901 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 10902 %} 10903 ins_pipe( pipe_slow ); 10904 %} 10905 10906 // fast search of substring with known size. 10907 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10908 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10909 %{ 10910 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10911 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10912 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10913 10914 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10915 ins_encode %{ 10916 int icnt2 = (int)$int_cnt2$$constant; 10917 if (icnt2 >= 16) { 10918 // IndexOf for constant substrings with size >= 16 elements 10919 // which don't need to be loaded through stack. 10920 __ string_indexofC8($str1$$Register, $str2$$Register, 10921 $cnt1$$Register, $cnt2$$Register, 10922 icnt2, $result$$Register, 10923 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10924 } else { 10925 // Small strings are loaded through stack if they cross page boundary. 10926 __ string_indexof($str1$$Register, $str2$$Register, 10927 $cnt1$$Register, $cnt2$$Register, 10928 icnt2, $result$$Register, 10929 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10930 } 10931 %} 10932 ins_pipe( pipe_slow ); 10933 %} 10934 10935 // fast search of substring with known size. 10936 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10937 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10938 %{ 10939 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10940 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10941 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10942 10943 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10944 ins_encode %{ 10945 int icnt2 = (int)$int_cnt2$$constant; 10946 if (icnt2 >= 8) { 10947 // IndexOf for constant substrings with size >= 8 elements 10948 // which don't need to be loaded through stack. 10949 __ string_indexofC8($str1$$Register, $str2$$Register, 10950 $cnt1$$Register, $cnt2$$Register, 10951 icnt2, $result$$Register, 10952 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10953 } else { 10954 // Small strings are loaded through stack if they cross page boundary. 10955 __ string_indexof($str1$$Register, $str2$$Register, 10956 $cnt1$$Register, $cnt2$$Register, 10957 icnt2, $result$$Register, 10958 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10959 } 10960 %} 10961 ins_pipe( pipe_slow ); 10962 %} 10963 10964 // fast search of substring with known size. 10965 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10966 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10967 %{ 10968 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10969 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10970 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10971 10972 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10973 ins_encode %{ 10974 int icnt2 = (int)$int_cnt2$$constant; 10975 if (icnt2 >= 8) { 10976 // IndexOf for constant substrings with size >= 8 elements 10977 // which don't need to be loaded through stack. 10978 __ string_indexofC8($str1$$Register, $str2$$Register, 10979 $cnt1$$Register, $cnt2$$Register, 10980 icnt2, $result$$Register, 10981 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10982 } else { 10983 // Small strings are loaded through stack if they cross page boundary. 10984 __ string_indexof($str1$$Register, $str2$$Register, 10985 $cnt1$$Register, $cnt2$$Register, 10986 icnt2, $result$$Register, 10987 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10988 } 10989 %} 10990 ins_pipe( pipe_slow ); 10991 %} 10992 10993 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10994 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10995 %{ 10996 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10997 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10998 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10999 11000 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11001 ins_encode %{ 11002 __ string_indexof($str1$$Register, $str2$$Register, 11003 $cnt1$$Register, $cnt2$$Register, 11004 (-1), $result$$Register, 11005 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11006 %} 11007 ins_pipe( pipe_slow ); 11008 %} 11009 11010 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11011 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11012 %{ 11013 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11014 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11015 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11016 11017 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11018 ins_encode %{ 11019 __ string_indexof($str1$$Register, $str2$$Register, 11020 $cnt1$$Register, $cnt2$$Register, 11021 (-1), $result$$Register, 11022 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11023 %} 11024 ins_pipe( pipe_slow ); 11025 %} 11026 11027 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11028 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11029 %{ 11030 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11031 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11032 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11033 11034 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11035 ins_encode %{ 11036 __ string_indexof($str1$$Register, $str2$$Register, 11037 $cnt1$$Register, $cnt2$$Register, 11038 (-1), $result$$Register, 11039 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11040 %} 11041 ins_pipe( pipe_slow ); 11042 %} 11043 11044 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11045 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11046 %{ 11047 predicate(UseSSE42Intrinsics); 11048 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11049 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11050 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11051 ins_encode %{ 11052 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11053 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11054 %} 11055 ins_pipe( pipe_slow ); 11056 %} 11057 11058 // fast string equals 11059 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11060 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11061 %{ 11062 match(Set result (StrEquals (Binary str1 str2) cnt)); 11063 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11064 11065 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11066 ins_encode %{ 11067 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11068 $cnt$$Register, $result$$Register, $tmp3$$Register, 11069 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11070 %} 11071 ins_pipe( pipe_slow ); 11072 %} 11073 11074 // fast array equals 11075 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11076 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11077 %{ 11078 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11079 match(Set result (AryEq ary1 ary2)); 11080 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11081 11082 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11083 ins_encode %{ 11084 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11085 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11086 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11087 %} 11088 ins_pipe( pipe_slow ); 11089 %} 11090 11091 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11092 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11093 %{ 11094 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11095 match(Set result (AryEq ary1 ary2)); 11096 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11097 11098 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11099 ins_encode %{ 11100 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11101 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11102 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11103 %} 11104 ins_pipe( pipe_slow ); 11105 %} 11106 11107 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11108 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11109 %{ 11110 match(Set result (HasNegatives ary1 len)); 11111 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11112 11113 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11114 ins_encode %{ 11115 __ has_negatives($ary1$$Register, $len$$Register, 11116 $result$$Register, $tmp3$$Register, 11117 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11118 %} 11119 ins_pipe( pipe_slow ); 11120 %} 11121 11122 // fast char[] to byte[] compression 11123 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11124 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11125 match(Set result (StrCompressedCopy src (Binary dst len))); 11126 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11127 11128 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11129 ins_encode %{ 11130 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11131 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11132 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11133 %} 11134 ins_pipe( pipe_slow ); 11135 %} 11136 11137 // fast byte[] to char[] inflation 11138 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11139 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11140 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11141 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11142 11143 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11144 ins_encode %{ 11145 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11146 $tmp1$$XMMRegister, $tmp2$$Register); 11147 %} 11148 ins_pipe( pipe_slow ); 11149 %} 11150 11151 // encode char[] to byte[] in ISO_8859_1 11152 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11153 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11154 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11155 match(Set result (EncodeISOArray src (Binary dst len))); 11156 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11157 11158 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11159 ins_encode %{ 11160 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11161 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11162 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11163 %} 11164 ins_pipe( pipe_slow ); 11165 %} 11166 11167 //----------Overflow Math Instructions----------------------------------------- 11168 11169 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11170 %{ 11171 match(Set cr (OverflowAddI op1 op2)); 11172 effect(DEF cr, USE_KILL op1, USE op2); 11173 11174 format %{ "addl $op1, $op2\t# overflow check int" %} 11175 11176 ins_encode %{ 11177 __ addl($op1$$Register, $op2$$Register); 11178 %} 11179 ins_pipe(ialu_reg_reg); 11180 %} 11181 11182 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11183 %{ 11184 match(Set cr (OverflowAddI op1 op2)); 11185 effect(DEF cr, USE_KILL op1, USE op2); 11186 11187 format %{ "addl $op1, $op2\t# overflow check int" %} 11188 11189 ins_encode %{ 11190 __ addl($op1$$Register, $op2$$constant); 11191 %} 11192 ins_pipe(ialu_reg_reg); 11193 %} 11194 11195 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11196 %{ 11197 match(Set cr (OverflowAddL op1 op2)); 11198 effect(DEF cr, USE_KILL op1, USE op2); 11199 11200 format %{ "addq $op1, $op2\t# overflow check long" %} 11201 ins_encode %{ 11202 __ addq($op1$$Register, $op2$$Register); 11203 %} 11204 ins_pipe(ialu_reg_reg); 11205 %} 11206 11207 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11208 %{ 11209 match(Set cr (OverflowAddL op1 op2)); 11210 effect(DEF cr, USE_KILL op1, USE op2); 11211 11212 format %{ "addq $op1, $op2\t# overflow check long" %} 11213 ins_encode %{ 11214 __ addq($op1$$Register, $op2$$constant); 11215 %} 11216 ins_pipe(ialu_reg_reg); 11217 %} 11218 11219 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11220 %{ 11221 match(Set cr (OverflowSubI op1 op2)); 11222 11223 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11224 ins_encode %{ 11225 __ cmpl($op1$$Register, $op2$$Register); 11226 %} 11227 ins_pipe(ialu_reg_reg); 11228 %} 11229 11230 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11231 %{ 11232 match(Set cr (OverflowSubI op1 op2)); 11233 11234 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11235 ins_encode %{ 11236 __ cmpl($op1$$Register, $op2$$constant); 11237 %} 11238 ins_pipe(ialu_reg_reg); 11239 %} 11240 11241 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11242 %{ 11243 match(Set cr (OverflowSubL op1 op2)); 11244 11245 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11246 ins_encode %{ 11247 __ cmpq($op1$$Register, $op2$$Register); 11248 %} 11249 ins_pipe(ialu_reg_reg); 11250 %} 11251 11252 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11253 %{ 11254 match(Set cr (OverflowSubL op1 op2)); 11255 11256 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11257 ins_encode %{ 11258 __ cmpq($op1$$Register, $op2$$constant); 11259 %} 11260 ins_pipe(ialu_reg_reg); 11261 %} 11262 11263 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11264 %{ 11265 match(Set cr (OverflowSubI zero op2)); 11266 effect(DEF cr, USE_KILL op2); 11267 11268 format %{ "negl $op2\t# overflow check int" %} 11269 ins_encode %{ 11270 __ negl($op2$$Register); 11271 %} 11272 ins_pipe(ialu_reg_reg); 11273 %} 11274 11275 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11276 %{ 11277 match(Set cr (OverflowSubL zero op2)); 11278 effect(DEF cr, USE_KILL op2); 11279 11280 format %{ "negq $op2\t# overflow check long" %} 11281 ins_encode %{ 11282 __ negq($op2$$Register); 11283 %} 11284 ins_pipe(ialu_reg_reg); 11285 %} 11286 11287 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11288 %{ 11289 match(Set cr (OverflowMulI op1 op2)); 11290 effect(DEF cr, USE_KILL op1, USE op2); 11291 11292 format %{ "imull $op1, $op2\t# overflow check int" %} 11293 ins_encode %{ 11294 __ imull($op1$$Register, $op2$$Register); 11295 %} 11296 ins_pipe(ialu_reg_reg_alu0); 11297 %} 11298 11299 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11300 %{ 11301 match(Set cr (OverflowMulI op1 op2)); 11302 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11303 11304 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11305 ins_encode %{ 11306 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11307 %} 11308 ins_pipe(ialu_reg_reg_alu0); 11309 %} 11310 11311 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11312 %{ 11313 match(Set cr (OverflowMulL op1 op2)); 11314 effect(DEF cr, USE_KILL op1, USE op2); 11315 11316 format %{ "imulq $op1, $op2\t# overflow check long" %} 11317 ins_encode %{ 11318 __ imulq($op1$$Register, $op2$$Register); 11319 %} 11320 ins_pipe(ialu_reg_reg_alu0); 11321 %} 11322 11323 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11324 %{ 11325 match(Set cr (OverflowMulL op1 op2)); 11326 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11327 11328 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11329 ins_encode %{ 11330 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11331 %} 11332 ins_pipe(ialu_reg_reg_alu0); 11333 %} 11334 11335 11336 //----------Control Flow Instructions------------------------------------------ 11337 // Signed compare Instructions 11338 11339 // XXX more variants!! 11340 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11341 %{ 11342 match(Set cr (CmpI op1 op2)); 11343 effect(DEF cr, USE op1, USE op2); 11344 11345 format %{ "cmpl $op1, $op2" %} 11346 opcode(0x3B); /* Opcode 3B /r */ 11347 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11348 ins_pipe(ialu_cr_reg_reg); 11349 %} 11350 11351 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11352 %{ 11353 match(Set cr (CmpI op1 op2)); 11354 11355 format %{ "cmpl $op1, $op2" %} 11356 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11357 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11358 ins_pipe(ialu_cr_reg_imm); 11359 %} 11360 11361 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11362 %{ 11363 match(Set cr (CmpI op1 (LoadI op2))); 11364 11365 ins_cost(500); // XXX 11366 format %{ "cmpl $op1, $op2" %} 11367 opcode(0x3B); /* Opcode 3B /r */ 11368 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11369 ins_pipe(ialu_cr_reg_mem); 11370 %} 11371 11372 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11373 %{ 11374 match(Set cr (CmpI src zero)); 11375 11376 format %{ "testl $src, $src" %} 11377 opcode(0x85); 11378 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11379 ins_pipe(ialu_cr_reg_imm); 11380 %} 11381 11382 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11383 %{ 11384 match(Set cr (CmpI (AndI src con) zero)); 11385 11386 format %{ "testl $src, $con" %} 11387 opcode(0xF7, 0x00); 11388 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11389 ins_pipe(ialu_cr_reg_imm); 11390 %} 11391 11392 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11393 %{ 11394 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11395 11396 format %{ "testl $src, $mem" %} 11397 opcode(0x85); 11398 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11399 ins_pipe(ialu_cr_reg_mem); 11400 %} 11401 11402 // Unsigned compare Instructions; really, same as signed except they 11403 // produce an rFlagsRegU instead of rFlagsReg. 11404 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11405 %{ 11406 match(Set cr (CmpU op1 op2)); 11407 11408 format %{ "cmpl $op1, $op2\t# unsigned" %} 11409 opcode(0x3B); /* Opcode 3B /r */ 11410 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11411 ins_pipe(ialu_cr_reg_reg); 11412 %} 11413 11414 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11415 %{ 11416 match(Set cr (CmpU op1 op2)); 11417 11418 format %{ "cmpl $op1, $op2\t# unsigned" %} 11419 opcode(0x81,0x07); /* Opcode 81 /7 */ 11420 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11421 ins_pipe(ialu_cr_reg_imm); 11422 %} 11423 11424 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11425 %{ 11426 match(Set cr (CmpU op1 (LoadI op2))); 11427 11428 ins_cost(500); // XXX 11429 format %{ "cmpl $op1, $op2\t# unsigned" %} 11430 opcode(0x3B); /* Opcode 3B /r */ 11431 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11432 ins_pipe(ialu_cr_reg_mem); 11433 %} 11434 11435 // // // Cisc-spilled version of cmpU_rReg 11436 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11437 // //%{ 11438 // // match(Set cr (CmpU (LoadI op1) op2)); 11439 // // 11440 // // format %{ "CMPu $op1,$op2" %} 11441 // // ins_cost(500); 11442 // // opcode(0x39); /* Opcode 39 /r */ 11443 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11444 // //%} 11445 11446 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11447 %{ 11448 match(Set cr (CmpU src zero)); 11449 11450 format %{ "testl $src, $src\t# unsigned" %} 11451 opcode(0x85); 11452 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11453 ins_pipe(ialu_cr_reg_imm); 11454 %} 11455 11456 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11457 %{ 11458 match(Set cr (CmpP op1 op2)); 11459 11460 format %{ "cmpq $op1, $op2\t# ptr" %} 11461 opcode(0x3B); /* Opcode 3B /r */ 11462 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11463 ins_pipe(ialu_cr_reg_reg); 11464 %} 11465 11466 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11467 %{ 11468 match(Set cr (CmpP op1 (LoadP op2))); 11469 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11470 11471 ins_cost(500); // XXX 11472 format %{ "cmpq $op1, $op2\t# ptr" %} 11473 opcode(0x3B); /* Opcode 3B /r */ 11474 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11475 ins_pipe(ialu_cr_reg_mem); 11476 %} 11477 11478 // // // Cisc-spilled version of cmpP_rReg 11479 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11480 // //%{ 11481 // // match(Set cr (CmpP (LoadP op1) op2)); 11482 // // 11483 // // format %{ "CMPu $op1,$op2" %} 11484 // // ins_cost(500); 11485 // // opcode(0x39); /* Opcode 39 /r */ 11486 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11487 // //%} 11488 11489 // XXX this is generalized by compP_rReg_mem??? 11490 // Compare raw pointer (used in out-of-heap check). 11491 // Only works because non-oop pointers must be raw pointers 11492 // and raw pointers have no anti-dependencies. 11493 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11494 %{ 11495 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11496 n->in(2)->as_Load()->barrier_data() == 0); 11497 match(Set cr (CmpP op1 (LoadP op2))); 11498 11499 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11500 opcode(0x3B); /* Opcode 3B /r */ 11501 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11502 ins_pipe(ialu_cr_reg_mem); 11503 %} 11504 11505 // This will generate a signed flags result. This should be OK since 11506 // any compare to a zero should be eq/neq. 11507 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11508 %{ 11509 match(Set cr (CmpP src zero)); 11510 11511 format %{ "testq $src, $src\t# ptr" %} 11512 opcode(0x85); 11513 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11514 ins_pipe(ialu_cr_reg_imm); 11515 %} 11516 11517 // This will generate a signed flags result. This should be OK since 11518 // any compare to a zero should be eq/neq. 11519 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11520 %{ 11521 predicate((!UseCompressedOops || (CompressedOops::base() != NULL)) && 11522 n->in(1)->as_Load()->barrier_data() == 0); 11523 match(Set cr (CmpP (LoadP op) zero)); 11524 11525 ins_cost(500); // XXX 11526 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11527 opcode(0xF7); /* Opcode F7 /0 */ 11528 ins_encode(REX_mem_wide(op), 11529 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11530 ins_pipe(ialu_cr_reg_imm); 11531 %} 11532 11533 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11534 %{ 11535 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && 11536 n->in(1)->as_Load()->barrier_data() == 0); 11537 match(Set cr (CmpP (LoadP mem) zero)); 11538 11539 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11540 ins_encode %{ 11541 __ cmpq(r12, $mem$$Address); 11542 %} 11543 ins_pipe(ialu_cr_reg_mem); 11544 %} 11545 11546 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11547 %{ 11548 match(Set cr (CmpN op1 op2)); 11549 11550 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11551 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11552 ins_pipe(ialu_cr_reg_reg); 11553 %} 11554 11555 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11556 %{ 11557 match(Set cr (CmpN src (LoadN mem))); 11558 11559 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11560 ins_encode %{ 11561 __ cmpl($src$$Register, $mem$$Address); 11562 %} 11563 ins_pipe(ialu_cr_reg_mem); 11564 %} 11565 11566 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11567 match(Set cr (CmpN op1 op2)); 11568 11569 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11570 ins_encode %{ 11571 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11572 %} 11573 ins_pipe(ialu_cr_reg_imm); 11574 %} 11575 11576 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11577 %{ 11578 match(Set cr (CmpN src (LoadN mem))); 11579 11580 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11581 ins_encode %{ 11582 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11583 %} 11584 ins_pipe(ialu_cr_reg_mem); 11585 %} 11586 11587 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11588 match(Set cr (CmpN op1 op2)); 11589 11590 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11591 ins_encode %{ 11592 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11593 %} 11594 ins_pipe(ialu_cr_reg_imm); 11595 %} 11596 11597 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11598 %{ 11599 match(Set cr (CmpN src (LoadNKlass mem))); 11600 11601 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11602 ins_encode %{ 11603 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11604 %} 11605 ins_pipe(ialu_cr_reg_mem); 11606 %} 11607 11608 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11609 match(Set cr (CmpN src zero)); 11610 11611 format %{ "testl $src, $src\t# compressed ptr" %} 11612 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11613 ins_pipe(ialu_cr_reg_imm); 11614 %} 11615 11616 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11617 %{ 11618 predicate(CompressedOops::base() != NULL); 11619 match(Set cr (CmpN (LoadN mem) zero)); 11620 11621 ins_cost(500); // XXX 11622 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11623 ins_encode %{ 11624 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11625 %} 11626 ins_pipe(ialu_cr_reg_mem); 11627 %} 11628 11629 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11630 %{ 11631 predicate(CompressedOops::base() == NULL); 11632 match(Set cr (CmpN (LoadN mem) zero)); 11633 11634 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11635 ins_encode %{ 11636 __ cmpl(r12, $mem$$Address); 11637 %} 11638 ins_pipe(ialu_cr_reg_mem); 11639 %} 11640 11641 // Yanked all unsigned pointer compare operations. 11642 // Pointer compares are done with CmpP which is already unsigned. 11643 11644 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11645 %{ 11646 match(Set cr (CmpL op1 op2)); 11647 11648 format %{ "cmpq $op1, $op2" %} 11649 opcode(0x3B); /* Opcode 3B /r */ 11650 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11651 ins_pipe(ialu_cr_reg_reg); 11652 %} 11653 11654 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11655 %{ 11656 match(Set cr (CmpL op1 op2)); 11657 11658 format %{ "cmpq $op1, $op2" %} 11659 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11660 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11661 ins_pipe(ialu_cr_reg_imm); 11662 %} 11663 11664 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11665 %{ 11666 match(Set cr (CmpL op1 (LoadL op2))); 11667 11668 format %{ "cmpq $op1, $op2" %} 11669 opcode(0x3B); /* Opcode 3B /r */ 11670 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11671 ins_pipe(ialu_cr_reg_mem); 11672 %} 11673 11674 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11675 %{ 11676 match(Set cr (CmpL src zero)); 11677 11678 format %{ "testq $src, $src" %} 11679 opcode(0x85); 11680 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11681 ins_pipe(ialu_cr_reg_imm); 11682 %} 11683 11684 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11685 %{ 11686 match(Set cr (CmpL (AndL src con) zero)); 11687 11688 format %{ "testq $src, $con\t# long" %} 11689 opcode(0xF7, 0x00); 11690 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11691 ins_pipe(ialu_cr_reg_imm); 11692 %} 11693 11694 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11695 %{ 11696 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11697 11698 format %{ "testq $src, $mem" %} 11699 opcode(0x85); 11700 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11701 ins_pipe(ialu_cr_reg_mem); 11702 %} 11703 11704 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11705 %{ 11706 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11707 11708 format %{ "testq $src, $mem" %} 11709 opcode(0x85); 11710 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11711 ins_pipe(ialu_cr_reg_mem); 11712 %} 11713 11714 // Manifest a CmpL result in an integer register. Very painful. 11715 // This is the test to avoid. 11716 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11717 %{ 11718 match(Set dst (CmpL3 src1 src2)); 11719 effect(KILL flags); 11720 11721 ins_cost(275); // XXX 11722 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11723 "movl $dst, -1\n\t" 11724 "jl,s done\n\t" 11725 "setne $dst\n\t" 11726 "movzbl $dst, $dst\n\t" 11727 "done:" %} 11728 ins_encode(cmpl3_flag(src1, src2, dst)); 11729 ins_pipe(pipe_slow); 11730 %} 11731 11732 // Unsigned long compare Instructions; really, same as signed long except they 11733 // produce an rFlagsRegU instead of rFlagsReg. 11734 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11735 %{ 11736 match(Set cr (CmpUL op1 op2)); 11737 11738 format %{ "cmpq $op1, $op2\t# unsigned" %} 11739 opcode(0x3B); /* Opcode 3B /r */ 11740 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11741 ins_pipe(ialu_cr_reg_reg); 11742 %} 11743 11744 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11745 %{ 11746 match(Set cr (CmpUL op1 op2)); 11747 11748 format %{ "cmpq $op1, $op2\t# unsigned" %} 11749 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11750 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11751 ins_pipe(ialu_cr_reg_imm); 11752 %} 11753 11754 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11755 %{ 11756 match(Set cr (CmpUL op1 (LoadL op2))); 11757 11758 format %{ "cmpq $op1, $op2\t# unsigned" %} 11759 opcode(0x3B); /* Opcode 3B /r */ 11760 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11761 ins_pipe(ialu_cr_reg_mem); 11762 %} 11763 11764 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11765 %{ 11766 match(Set cr (CmpUL src zero)); 11767 11768 format %{ "testq $src, $src\t# unsigned" %} 11769 opcode(0x85); 11770 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11771 ins_pipe(ialu_cr_reg_imm); 11772 %} 11773 11774 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11775 %{ 11776 match(Set cr (CmpI (LoadB mem) imm)); 11777 11778 ins_cost(125); 11779 format %{ "cmpb $mem, $imm" %} 11780 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11781 ins_pipe(ialu_cr_reg_mem); 11782 %} 11783 11784 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 11785 %{ 11786 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11787 11788 ins_cost(125); 11789 format %{ "testb $mem, $imm\t# ubyte" %} 11790 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11791 ins_pipe(ialu_cr_reg_mem); 11792 %} 11793 11794 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11795 %{ 11796 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11797 11798 ins_cost(125); 11799 format %{ "testb $mem, $imm\t# byte" %} 11800 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11801 ins_pipe(ialu_cr_reg_mem); 11802 %} 11803 11804 //----------Max and Min-------------------------------------------------------- 11805 // Min Instructions 11806 11807 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11808 %{ 11809 effect(USE_DEF dst, USE src, USE cr); 11810 11811 format %{ "cmovlgt $dst, $src\t# min" %} 11812 opcode(0x0F, 0x4F); 11813 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11814 ins_pipe(pipe_cmov_reg); 11815 %} 11816 11817 11818 instruct minI_rReg(rRegI dst, rRegI src) 11819 %{ 11820 match(Set dst (MinI dst src)); 11821 11822 ins_cost(200); 11823 expand %{ 11824 rFlagsReg cr; 11825 compI_rReg(cr, dst, src); 11826 cmovI_reg_g(dst, src, cr); 11827 %} 11828 %} 11829 11830 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11831 %{ 11832 effect(USE_DEF dst, USE src, USE cr); 11833 11834 format %{ "cmovllt $dst, $src\t# max" %} 11835 opcode(0x0F, 0x4C); 11836 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11837 ins_pipe(pipe_cmov_reg); 11838 %} 11839 11840 11841 instruct maxI_rReg(rRegI dst, rRegI src) 11842 %{ 11843 match(Set dst (MaxI dst src)); 11844 11845 ins_cost(200); 11846 expand %{ 11847 rFlagsReg cr; 11848 compI_rReg(cr, dst, src); 11849 cmovI_reg_l(dst, src, cr); 11850 %} 11851 %} 11852 11853 // ============================================================================ 11854 // Branch Instructions 11855 11856 // Jump Direct - Label defines a relative address from JMP+1 11857 instruct jmpDir(label labl) 11858 %{ 11859 match(Goto); 11860 effect(USE labl); 11861 11862 ins_cost(300); 11863 format %{ "jmp $labl" %} 11864 size(5); 11865 ins_encode %{ 11866 Label* L = $labl$$label; 11867 __ jmp(*L, false); // Always long jump 11868 %} 11869 ins_pipe(pipe_jmp); 11870 %} 11871 11872 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11873 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11874 %{ 11875 match(If cop cr); 11876 effect(USE labl); 11877 11878 ins_cost(300); 11879 format %{ "j$cop $labl" %} 11880 size(6); 11881 ins_encode %{ 11882 Label* L = $labl$$label; 11883 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11884 %} 11885 ins_pipe(pipe_jcc); 11886 %} 11887 11888 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11889 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11890 %{ 11891 predicate(!n->has_vector_mask_set()); 11892 match(CountedLoopEnd cop cr); 11893 effect(USE labl); 11894 11895 ins_cost(300); 11896 format %{ "j$cop $labl\t# loop end" %} 11897 size(6); 11898 ins_encode %{ 11899 Label* L = $labl$$label; 11900 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11901 %} 11902 ins_pipe(pipe_jcc); 11903 %} 11904 11905 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11906 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11907 predicate(!n->has_vector_mask_set()); 11908 match(CountedLoopEnd cop cmp); 11909 effect(USE labl); 11910 11911 ins_cost(300); 11912 format %{ "j$cop,u $labl\t# loop end" %} 11913 size(6); 11914 ins_encode %{ 11915 Label* L = $labl$$label; 11916 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11917 %} 11918 ins_pipe(pipe_jcc); 11919 %} 11920 11921 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11922 predicate(!n->has_vector_mask_set()); 11923 match(CountedLoopEnd cop cmp); 11924 effect(USE labl); 11925 11926 ins_cost(200); 11927 format %{ "j$cop,u $labl\t# loop end" %} 11928 size(6); 11929 ins_encode %{ 11930 Label* L = $labl$$label; 11931 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11932 %} 11933 ins_pipe(pipe_jcc); 11934 %} 11935 11936 // mask version 11937 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11938 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 11939 %{ 11940 predicate(n->has_vector_mask_set()); 11941 match(CountedLoopEnd cop cr); 11942 effect(USE labl); 11943 11944 ins_cost(400); 11945 format %{ "j$cop $labl\t# loop end\n\t" 11946 "restorevectmask \t# vector mask restore for loops" %} 11947 size(10); 11948 ins_encode %{ 11949 Label* L = $labl$$label; 11950 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11951 __ restorevectmask(); 11952 %} 11953 ins_pipe(pipe_jcc); 11954 %} 11955 11956 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11957 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11958 predicate(n->has_vector_mask_set()); 11959 match(CountedLoopEnd cop cmp); 11960 effect(USE labl); 11961 11962 ins_cost(400); 11963 format %{ "j$cop,u $labl\t# loop end\n\t" 11964 "restorevectmask \t# vector mask restore for loops" %} 11965 size(10); 11966 ins_encode %{ 11967 Label* L = $labl$$label; 11968 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11969 __ restorevectmask(); 11970 %} 11971 ins_pipe(pipe_jcc); 11972 %} 11973 11974 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11975 predicate(n->has_vector_mask_set()); 11976 match(CountedLoopEnd cop cmp); 11977 effect(USE labl); 11978 11979 ins_cost(300); 11980 format %{ "j$cop,u $labl\t# loop end\n\t" 11981 "restorevectmask \t# vector mask restore for loops" %} 11982 size(10); 11983 ins_encode %{ 11984 Label* L = $labl$$label; 11985 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11986 __ restorevectmask(); 11987 %} 11988 ins_pipe(pipe_jcc); 11989 %} 11990 11991 // Jump Direct Conditional - using unsigned comparison 11992 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11993 match(If cop cmp); 11994 effect(USE labl); 11995 11996 ins_cost(300); 11997 format %{ "j$cop,u $labl" %} 11998 size(6); 11999 ins_encode %{ 12000 Label* L = $labl$$label; 12001 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12002 %} 12003 ins_pipe(pipe_jcc); 12004 %} 12005 12006 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12007 match(If cop cmp); 12008 effect(USE labl); 12009 12010 ins_cost(200); 12011 format %{ "j$cop,u $labl" %} 12012 size(6); 12013 ins_encode %{ 12014 Label* L = $labl$$label; 12015 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12016 %} 12017 ins_pipe(pipe_jcc); 12018 %} 12019 12020 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12021 match(If cop cmp); 12022 effect(USE labl); 12023 12024 ins_cost(200); 12025 format %{ $$template 12026 if ($cop$$cmpcode == Assembler::notEqual) { 12027 $$emit$$"jp,u $labl\n\t" 12028 $$emit$$"j$cop,u $labl" 12029 } else { 12030 $$emit$$"jp,u done\n\t" 12031 $$emit$$"j$cop,u $labl\n\t" 12032 $$emit$$"done:" 12033 } 12034 %} 12035 ins_encode %{ 12036 Label* l = $labl$$label; 12037 if ($cop$$cmpcode == Assembler::notEqual) { 12038 __ jcc(Assembler::parity, *l, false); 12039 __ jcc(Assembler::notEqual, *l, false); 12040 } else if ($cop$$cmpcode == Assembler::equal) { 12041 Label done; 12042 __ jccb(Assembler::parity, done); 12043 __ jcc(Assembler::equal, *l, false); 12044 __ bind(done); 12045 } else { 12046 ShouldNotReachHere(); 12047 } 12048 %} 12049 ins_pipe(pipe_jcc); 12050 %} 12051 12052 // ============================================================================ 12053 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12054 // superklass array for an instance of the superklass. Set a hidden 12055 // internal cache on a hit (cache is checked with exposed code in 12056 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12057 // encoding ALSO sets flags. 12058 12059 instruct partialSubtypeCheck(rdi_RegP result, 12060 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12061 rFlagsReg cr) 12062 %{ 12063 match(Set result (PartialSubtypeCheck sub super)); 12064 effect(KILL rcx, KILL cr); 12065 12066 ins_cost(1100); // slightly larger than the next version 12067 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12068 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12069 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12070 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12071 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12072 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12073 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12074 "miss:\t" %} 12075 12076 opcode(0x1); // Force a XOR of RDI 12077 ins_encode(enc_PartialSubtypeCheck()); 12078 ins_pipe(pipe_slow); 12079 %} 12080 12081 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12082 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12083 immP0 zero, 12084 rdi_RegP result) 12085 %{ 12086 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12087 effect(KILL rcx, KILL result); 12088 12089 ins_cost(1000); 12090 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12091 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12092 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12093 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12094 "jne,s miss\t\t# Missed: flags nz\n\t" 12095 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12096 "miss:\t" %} 12097 12098 opcode(0x0); // No need to XOR RDI 12099 ins_encode(enc_PartialSubtypeCheck()); 12100 ins_pipe(pipe_slow); 12101 %} 12102 12103 // ============================================================================ 12104 // Branch Instructions -- short offset versions 12105 // 12106 // These instructions are used to replace jumps of a long offset (the default 12107 // match) with jumps of a shorter offset. These instructions are all tagged 12108 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12109 // match rules in general matching. Instead, the ADLC generates a conversion 12110 // method in the MachNode which can be used to do in-place replacement of the 12111 // long variant with the shorter variant. The compiler will determine if a 12112 // branch can be taken by the is_short_branch_offset() predicate in the machine 12113 // specific code section of the file. 12114 12115 // Jump Direct - Label defines a relative address from JMP+1 12116 instruct jmpDir_short(label labl) %{ 12117 match(Goto); 12118 effect(USE labl); 12119 12120 ins_cost(300); 12121 format %{ "jmp,s $labl" %} 12122 size(2); 12123 ins_encode %{ 12124 Label* L = $labl$$label; 12125 __ jmpb(*L); 12126 %} 12127 ins_pipe(pipe_jmp); 12128 ins_short_branch(1); 12129 %} 12130 12131 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12132 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12133 match(If cop cr); 12134 effect(USE labl); 12135 12136 ins_cost(300); 12137 format %{ "j$cop,s $labl" %} 12138 size(2); 12139 ins_encode %{ 12140 Label* L = $labl$$label; 12141 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12142 %} 12143 ins_pipe(pipe_jcc); 12144 ins_short_branch(1); 12145 %} 12146 12147 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12148 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12149 match(CountedLoopEnd cop cr); 12150 effect(USE labl); 12151 12152 ins_cost(300); 12153 format %{ "j$cop,s $labl\t# loop end" %} 12154 size(2); 12155 ins_encode %{ 12156 Label* L = $labl$$label; 12157 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12158 %} 12159 ins_pipe(pipe_jcc); 12160 ins_short_branch(1); 12161 %} 12162 12163 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12164 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12165 match(CountedLoopEnd cop cmp); 12166 effect(USE labl); 12167 12168 ins_cost(300); 12169 format %{ "j$cop,us $labl\t# loop end" %} 12170 size(2); 12171 ins_encode %{ 12172 Label* L = $labl$$label; 12173 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12174 %} 12175 ins_pipe(pipe_jcc); 12176 ins_short_branch(1); 12177 %} 12178 12179 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12180 match(CountedLoopEnd cop cmp); 12181 effect(USE labl); 12182 12183 ins_cost(300); 12184 format %{ "j$cop,us $labl\t# loop end" %} 12185 size(2); 12186 ins_encode %{ 12187 Label* L = $labl$$label; 12188 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12189 %} 12190 ins_pipe(pipe_jcc); 12191 ins_short_branch(1); 12192 %} 12193 12194 // Jump Direct Conditional - using unsigned comparison 12195 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12196 match(If cop cmp); 12197 effect(USE labl); 12198 12199 ins_cost(300); 12200 format %{ "j$cop,us $labl" %} 12201 size(2); 12202 ins_encode %{ 12203 Label* L = $labl$$label; 12204 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12205 %} 12206 ins_pipe(pipe_jcc); 12207 ins_short_branch(1); 12208 %} 12209 12210 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12211 match(If cop cmp); 12212 effect(USE labl); 12213 12214 ins_cost(300); 12215 format %{ "j$cop,us $labl" %} 12216 size(2); 12217 ins_encode %{ 12218 Label* L = $labl$$label; 12219 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12220 %} 12221 ins_pipe(pipe_jcc); 12222 ins_short_branch(1); 12223 %} 12224 12225 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12226 match(If cop cmp); 12227 effect(USE labl); 12228 12229 ins_cost(300); 12230 format %{ $$template 12231 if ($cop$$cmpcode == Assembler::notEqual) { 12232 $$emit$$"jp,u,s $labl\n\t" 12233 $$emit$$"j$cop,u,s $labl" 12234 } else { 12235 $$emit$$"jp,u,s done\n\t" 12236 $$emit$$"j$cop,u,s $labl\n\t" 12237 $$emit$$"done:" 12238 } 12239 %} 12240 size(4); 12241 ins_encode %{ 12242 Label* l = $labl$$label; 12243 if ($cop$$cmpcode == Assembler::notEqual) { 12244 __ jccb(Assembler::parity, *l); 12245 __ jccb(Assembler::notEqual, *l); 12246 } else if ($cop$$cmpcode == Assembler::equal) { 12247 Label done; 12248 __ jccb(Assembler::parity, done); 12249 __ jccb(Assembler::equal, *l); 12250 __ bind(done); 12251 } else { 12252 ShouldNotReachHere(); 12253 } 12254 %} 12255 ins_pipe(pipe_jcc); 12256 ins_short_branch(1); 12257 %} 12258 12259 // ============================================================================ 12260 // inlined locking and unlocking 12261 12262 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12263 predicate(Compile::current()->use_rtm()); 12264 match(Set cr (FastLock object box)); 12265 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12266 ins_cost(300); 12267 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12268 ins_encode %{ 12269 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12270 $scr$$Register, $cx1$$Register, $cx2$$Register, 12271 _counters, _rtm_counters, _stack_rtm_counters, 12272 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12273 true, ra_->C->profile_rtm()); 12274 %} 12275 ins_pipe(pipe_slow); 12276 %} 12277 12278 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr, rRegP cx1) %{ 12279 predicate(!Compile::current()->use_rtm()); 12280 match(Set cr (FastLock object box)); 12281 effect(TEMP tmp, TEMP scr, TEMP cx1, USE_KILL box); 12282 ins_cost(300); 12283 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12284 ins_encode %{ 12285 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12286 $scr$$Register, $cx1$$Register, noreg, _counters, NULL, NULL, NULL, false, false); 12287 %} 12288 ins_pipe(pipe_slow); 12289 %} 12290 12291 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12292 match(Set cr (FastUnlock object box)); 12293 effect(TEMP tmp, USE_KILL box); 12294 ins_cost(300); 12295 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12296 ins_encode %{ 12297 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12298 %} 12299 ins_pipe(pipe_slow); 12300 %} 12301 12302 12303 // ============================================================================ 12304 // Safepoint Instructions 12305 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12306 %{ 12307 match(SafePoint poll); 12308 effect(KILL cr, USE poll); 12309 12310 format %{ "testl rax, [$poll]\t" 12311 "# Safepoint: poll for GC" %} 12312 ins_cost(125); 12313 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12314 ins_encode %{ 12315 __ relocate(relocInfo::poll_type); 12316 address pre_pc = __ pc(); 12317 __ testl(rax, Address($poll$$Register, 0)); 12318 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12319 %} 12320 ins_pipe(ialu_reg_mem); 12321 %} 12322 12323 // ============================================================================ 12324 // Procedure Call/Return Instructions 12325 // Call Java Static Instruction 12326 // Note: If this code changes, the corresponding ret_addr_offset() and 12327 // compute_padding() functions will have to be adjusted. 12328 instruct CallStaticJavaDirect(method meth) %{ 12329 match(CallStaticJava); 12330 effect(USE meth); 12331 12332 ins_cost(300); 12333 format %{ "call,static " %} 12334 opcode(0xE8); /* E8 cd */ 12335 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12336 ins_pipe(pipe_slow); 12337 ins_alignment(4); 12338 %} 12339 12340 // Call Java Dynamic Instruction 12341 // Note: If this code changes, the corresponding ret_addr_offset() and 12342 // compute_padding() functions will have to be adjusted. 12343 instruct CallDynamicJavaDirect(method meth) 12344 %{ 12345 match(CallDynamicJava); 12346 effect(USE meth); 12347 12348 ins_cost(300); 12349 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12350 "call,dynamic " %} 12351 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12352 ins_pipe(pipe_slow); 12353 ins_alignment(4); 12354 %} 12355 12356 // Call Runtime Instruction 12357 instruct CallRuntimeDirect(method meth) 12358 %{ 12359 match(CallRuntime); 12360 effect(USE meth); 12361 12362 ins_cost(300); 12363 format %{ "call,runtime " %} 12364 ins_encode(clear_avx, Java_To_Runtime(meth)); 12365 ins_pipe(pipe_slow); 12366 %} 12367 12368 // Call runtime without safepoint 12369 instruct CallLeafDirect(method meth) 12370 %{ 12371 match(CallLeaf); 12372 effect(USE meth); 12373 12374 ins_cost(300); 12375 format %{ "call_leaf,runtime " %} 12376 ins_encode(clear_avx, Java_To_Runtime(meth)); 12377 ins_pipe(pipe_slow); 12378 %} 12379 12380 // Call runtime without safepoint 12381 instruct CallLeafNoFPDirect(method meth) 12382 %{ 12383 match(CallLeafNoFP); 12384 effect(USE meth); 12385 12386 ins_cost(300); 12387 format %{ "call_leaf_nofp,runtime " %} 12388 ins_encode(clear_avx, Java_To_Runtime(meth)); 12389 ins_pipe(pipe_slow); 12390 %} 12391 12392 // Return Instruction 12393 // Remove the return address & jump to it. 12394 // Notice: We always emit a nop after a ret to make sure there is room 12395 // for safepoint patching 12396 instruct Ret() 12397 %{ 12398 match(Return); 12399 12400 format %{ "ret" %} 12401 opcode(0xC3); 12402 ins_encode(OpcP); 12403 ins_pipe(pipe_jmp); 12404 %} 12405 12406 // Tail Call; Jump from runtime stub to Java code. 12407 // Also known as an 'interprocedural jump'. 12408 // Target of jump will eventually return to caller. 12409 // TailJump below removes the return address. 12410 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12411 %{ 12412 match(TailCall jump_target method_ptr); 12413 12414 ins_cost(300); 12415 format %{ "jmp $jump_target\t# rbx holds method" %} 12416 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12417 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12418 ins_pipe(pipe_jmp); 12419 %} 12420 12421 // Tail Jump; remove the return address; jump to target. 12422 // TailCall above leaves the return address around. 12423 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12424 %{ 12425 match(TailJump jump_target ex_oop); 12426 12427 ins_cost(300); 12428 format %{ "popq rdx\t# pop return address\n\t" 12429 "jmp $jump_target" %} 12430 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12431 ins_encode(Opcode(0x5a), // popq rdx 12432 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12433 ins_pipe(pipe_jmp); 12434 %} 12435 12436 // Create exception oop: created by stack-crawling runtime code. 12437 // Created exception is now available to this handler, and is setup 12438 // just prior to jumping to this handler. No code emitted. 12439 instruct CreateException(rax_RegP ex_oop) 12440 %{ 12441 match(Set ex_oop (CreateEx)); 12442 12443 size(0); 12444 // use the following format syntax 12445 format %{ "# exception oop is in rax; no code emitted" %} 12446 ins_encode(); 12447 ins_pipe(empty); 12448 %} 12449 12450 // Rethrow exception: 12451 // The exception oop will come in the first argument position. 12452 // Then JUMP (not call) to the rethrow stub code. 12453 instruct RethrowException() 12454 %{ 12455 match(Rethrow); 12456 12457 // use the following format syntax 12458 format %{ "jmp rethrow_stub" %} 12459 ins_encode(enc_rethrow); 12460 ins_pipe(pipe_jmp); 12461 %} 12462 12463 // ============================================================================ 12464 // This name is KNOWN by the ADLC and cannot be changed. 12465 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12466 // for this guy. 12467 instruct tlsLoadP(r15_RegP dst) %{ 12468 match(Set dst (ThreadLocal)); 12469 effect(DEF dst); 12470 12471 size(0); 12472 format %{ "# TLS is in R15" %} 12473 ins_encode( /*empty encoding*/ ); 12474 ins_pipe(ialu_reg_reg); 12475 %} 12476 12477 12478 //----------PEEPHOLE RULES----------------------------------------------------- 12479 // These must follow all instruction definitions as they use the names 12480 // defined in the instructions definitions. 12481 // 12482 // peepmatch ( root_instr_name [preceding_instruction]* ); 12483 // 12484 // peepconstraint %{ 12485 // (instruction_number.operand_name relational_op instruction_number.operand_name 12486 // [, ...] ); 12487 // // instruction numbers are zero-based using left to right order in peepmatch 12488 // 12489 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12490 // // provide an instruction_number.operand_name for each operand that appears 12491 // // in the replacement instruction's match rule 12492 // 12493 // ---------VM FLAGS--------------------------------------------------------- 12494 // 12495 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12496 // 12497 // Each peephole rule is given an identifying number starting with zero and 12498 // increasing by one in the order seen by the parser. An individual peephole 12499 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12500 // on the command-line. 12501 // 12502 // ---------CURRENT LIMITATIONS---------------------------------------------- 12503 // 12504 // Only match adjacent instructions in same basic block 12505 // Only equality constraints 12506 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12507 // Only one replacement instruction 12508 // 12509 // ---------EXAMPLE---------------------------------------------------------- 12510 // 12511 // // pertinent parts of existing instructions in architecture description 12512 // instruct movI(rRegI dst, rRegI src) 12513 // %{ 12514 // match(Set dst (CopyI src)); 12515 // %} 12516 // 12517 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12518 // %{ 12519 // match(Set dst (AddI dst src)); 12520 // effect(KILL cr); 12521 // %} 12522 // 12523 // // Change (inc mov) to lea 12524 // peephole %{ 12525 // // increment preceeded by register-register move 12526 // peepmatch ( incI_rReg movI ); 12527 // // require that the destination register of the increment 12528 // // match the destination register of the move 12529 // peepconstraint ( 0.dst == 1.dst ); 12530 // // construct a replacement instruction that sets 12531 // // the destination to ( move's source register + one ) 12532 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12533 // %} 12534 // 12535 12536 // Implementation no longer uses movX instructions since 12537 // machine-independent system no longer uses CopyX nodes. 12538 // 12539 // peephole 12540 // %{ 12541 // peepmatch (incI_rReg movI); 12542 // peepconstraint (0.dst == 1.dst); 12543 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12544 // %} 12545 12546 // peephole 12547 // %{ 12548 // peepmatch (decI_rReg movI); 12549 // peepconstraint (0.dst == 1.dst); 12550 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12551 // %} 12552 12553 // peephole 12554 // %{ 12555 // peepmatch (addI_rReg_imm movI); 12556 // peepconstraint (0.dst == 1.dst); 12557 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12558 // %} 12559 12560 // peephole 12561 // %{ 12562 // peepmatch (incL_rReg movL); 12563 // peepconstraint (0.dst == 1.dst); 12564 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12565 // %} 12566 12567 // peephole 12568 // %{ 12569 // peepmatch (decL_rReg movL); 12570 // peepconstraint (0.dst == 1.dst); 12571 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12572 // %} 12573 12574 // peephole 12575 // %{ 12576 // peepmatch (addL_rReg_imm movL); 12577 // peepconstraint (0.dst == 1.dst); 12578 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12579 // %} 12580 12581 // peephole 12582 // %{ 12583 // peepmatch (addP_rReg_imm movP); 12584 // peepconstraint (0.dst == 1.dst); 12585 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12586 // %} 12587 12588 // // Change load of spilled value to only a spill 12589 // instruct storeI(memory mem, rRegI src) 12590 // %{ 12591 // match(Set mem (StoreI mem src)); 12592 // %} 12593 // 12594 // instruct loadI(rRegI dst, memory mem) 12595 // %{ 12596 // match(Set dst (LoadI mem)); 12597 // %} 12598 // 12599 12600 peephole 12601 %{ 12602 peepmatch (loadI storeI); 12603 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12604 peepreplace (storeI(1.mem 1.mem 1.src)); 12605 %} 12606 12607 peephole 12608 %{ 12609 peepmatch (loadL storeL); 12610 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12611 peepreplace (storeL(1.mem 1.mem 1.src)); 12612 %} 12613 12614 //----------SMARTSPILL RULES--------------------------------------------------- 12615 // These must follow all instruction definitions as they use the names 12616 // defined in the instructions definitions.