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