1 // 2 // Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer/long registers 173 reg_class all_reg(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all int registers 191 reg_class all_int_reg(RAX 192 RDX, 193 RBP, 194 RDI, 195 RSI, 196 RCX, 197 RBX, 198 R8, 199 R9, 200 R10, 201 R11, 202 R12, 203 R13, 204 R14); 205 206 // Class for all pointer registers 207 reg_class any_reg %{ 208 return _ANY_REG_mask; 209 %} 210 211 // Class for all pointer registers (excluding RSP) 212 reg_class ptr_reg %{ 213 return _PTR_REG_mask; 214 %} 215 216 // Class for all pointer registers (excluding RSP and RBP) 217 reg_class ptr_reg_no_rbp %{ 218 return _PTR_REG_NO_RBP_mask; 219 %} 220 221 // Class for all pointer registers (excluding RAX and RSP) 222 reg_class ptr_no_rax_reg %{ 223 return _PTR_NO_RAX_REG_mask; 224 %} 225 226 // Class for all pointer registers (excluding RAX, RBX, and RSP) 227 reg_class ptr_no_rax_rbx_reg %{ 228 return _PTR_NO_RAX_RBX_REG_mask; 229 %} 230 231 // Class for all long registers (excluding RSP) 232 reg_class long_reg %{ 233 return _LONG_REG_mask; 234 %} 235 236 // Class for all long registers (excluding RAX, RDX and RSP) 237 reg_class long_no_rax_rdx_reg %{ 238 return _LONG_NO_RAX_RDX_REG_mask; 239 %} 240 241 // Class for all long registers (excluding RCX and RSP) 242 reg_class long_no_rcx_reg %{ 243 return _LONG_NO_RCX_REG_mask; 244 %} 245 246 // Class for all int registers (excluding RSP) 247 reg_class int_reg %{ 248 return _INT_REG_mask; 249 %} 250 251 // Class for all int registers (excluding RAX, RDX, and RSP) 252 reg_class int_no_rax_rdx_reg %{ 253 return _INT_NO_RAX_RDX_REG_mask; 254 %} 255 256 // Class for all int registers (excluding RCX and RSP) 257 reg_class int_no_rcx_reg %{ 258 return _INT_NO_RCX_REG_mask; 259 %} 260 261 // Singleton class for RAX pointer register 262 reg_class ptr_rax_reg(RAX, RAX_H); 263 264 // Singleton class for RBX pointer register 265 reg_class ptr_rbx_reg(RBX, RBX_H); 266 267 // Singleton class for RSI pointer register 268 reg_class ptr_rsi_reg(RSI, RSI_H); 269 270 // Singleton class for RBP pointer register 271 reg_class ptr_rbp_reg(RBP, RBP_H); 272 273 // Singleton class for RDI pointer register 274 reg_class ptr_rdi_reg(RDI, RDI_H); 275 276 // Singleton class for stack pointer 277 reg_class ptr_rsp_reg(RSP, RSP_H); 278 279 // Singleton class for TLS pointer 280 reg_class ptr_r15_reg(R15, R15_H); 281 282 // Singleton class for RAX long register 283 reg_class long_rax_reg(RAX, RAX_H); 284 285 // Singleton class for RCX long register 286 reg_class long_rcx_reg(RCX, RCX_H); 287 288 // Singleton class for RDX long register 289 reg_class long_rdx_reg(RDX, RDX_H); 290 291 // Singleton class for RAX int register 292 reg_class int_rax_reg(RAX); 293 294 // Singleton class for RBX int register 295 reg_class int_rbx_reg(RBX); 296 297 // Singleton class for RCX int register 298 reg_class int_rcx_reg(RCX); 299 300 // Singleton class for RCX int register 301 reg_class int_rdx_reg(RDX); 302 303 // Singleton class for RCX int register 304 reg_class int_rdi_reg(RDI); 305 306 // Singleton class for instruction pointer 307 // reg_class ip_reg(RIP); 308 309 %} 310 311 //----------SOURCE BLOCK------------------------------------------------------- 312 // This is a block of C++ code which provides values, functions, and 313 // definitions necessary in the rest of the architecture description 314 source_hpp %{ 315 316 extern RegMask _ANY_REG_mask; 317 extern RegMask _PTR_REG_mask; 318 extern RegMask _PTR_REG_NO_RBP_mask; 319 extern RegMask _PTR_NO_RAX_REG_mask; 320 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 321 extern RegMask _LONG_REG_mask; 322 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 323 extern RegMask _LONG_NO_RCX_REG_mask; 324 extern RegMask _INT_REG_mask; 325 extern RegMask _INT_NO_RAX_RDX_REG_mask; 326 extern RegMask _INT_NO_RCX_REG_mask; 327 328 extern RegMask _STACK_OR_PTR_REG_mask; 329 extern RegMask _STACK_OR_LONG_REG_mask; 330 extern RegMask _STACK_OR_INT_REG_mask; 331 332 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 333 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 334 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 335 336 %} 337 338 source %{ 339 #define RELOC_IMM64 Assembler::imm_operand 340 #define RELOC_DISP32 Assembler::disp32_operand 341 342 #define __ _masm. 343 344 RegMask _ANY_REG_mask; 345 RegMask _PTR_REG_mask; 346 RegMask _PTR_REG_NO_RBP_mask; 347 RegMask _PTR_NO_RAX_REG_mask; 348 RegMask _PTR_NO_RAX_RBX_REG_mask; 349 RegMask _LONG_REG_mask; 350 RegMask _LONG_NO_RAX_RDX_REG_mask; 351 RegMask _LONG_NO_RCX_REG_mask; 352 RegMask _INT_REG_mask; 353 RegMask _INT_NO_RAX_RDX_REG_mask; 354 RegMask _INT_NO_RCX_REG_mask; 355 RegMask _STACK_OR_PTR_REG_mask; 356 RegMask _STACK_OR_LONG_REG_mask; 357 RegMask _STACK_OR_INT_REG_mask; 358 359 static bool need_r12_heapbase() { 360 return UseCompressedOops; 361 } 362 363 void reg_mask_init() { 364 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 365 // We derive a number of subsets from it. 366 _ANY_REG_mask = _ALL_REG_mask; 367 368 if (PreserveFramePointer) { 369 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 370 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 371 } 372 if (need_r12_heapbase()) { 373 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 374 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 375 } 376 377 _PTR_REG_mask = _ANY_REG_mask; 378 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 379 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 380 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 381 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 382 383 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 384 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 385 386 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 387 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 388 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 389 390 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 391 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 392 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 393 394 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 395 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 396 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 397 398 _LONG_REG_mask = _PTR_REG_mask; 399 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 400 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 401 402 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 403 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 404 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 405 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 406 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 407 408 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 409 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 410 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 411 412 _INT_REG_mask = _ALL_INT_REG_mask; 413 if (PreserveFramePointer) { 414 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 415 } 416 if (need_r12_heapbase()) { 417 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 418 } 419 420 _STACK_OR_INT_REG_mask = _INT_REG_mask; 421 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 422 423 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 424 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 425 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 426 427 _INT_NO_RCX_REG_mask = _INT_REG_mask; 428 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 429 } 430 431 static bool generate_vzeroupper(Compile* C) { 432 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 433 } 434 435 static int clear_avx_size() { 436 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 437 } 438 439 // !!!!! Special hack to get all types of calls to specify the byte offset 440 // from the start of the call to the point where the return address 441 // will point. 442 int MachCallStaticJavaNode::ret_addr_offset() 443 { 444 int offset = 5; // 5 bytes from start of call to where return address points 445 offset += clear_avx_size(); 446 return offset; 447 } 448 449 int MachCallDynamicJavaNode::ret_addr_offset() 450 { 451 int offset = 15; // 15 bytes from start of call to where return address points 452 offset += clear_avx_size(); 453 return offset; 454 } 455 456 int MachCallRuntimeNode::ret_addr_offset() { 457 int offset = 13; // movq r10,#addr; callq (r10) 458 offset += clear_avx_size(); 459 return offset; 460 } 461 462 // 463 // Compute padding required for nodes which need alignment 464 // 465 466 // The address of the call instruction needs to be 4-byte aligned to 467 // ensure that it does not span a cache line so that it can be patched. 468 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 469 { 470 current_offset += clear_avx_size(); // skip vzeroupper 471 current_offset += 1; // skip call opcode byte 472 return align_up(current_offset, alignment_required()) - current_offset; 473 } 474 475 // The address of the call instruction needs to be 4-byte aligned to 476 // ensure that it does not span a cache line so that it can be patched. 477 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 478 { 479 current_offset += clear_avx_size(); // skip vzeroupper 480 current_offset += 11; // skip movq instruction + call opcode byte 481 return align_up(current_offset, alignment_required()) - current_offset; 482 } 483 484 // EMIT_RM() 485 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 486 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 487 cbuf.insts()->emit_int8(c); 488 } 489 490 // EMIT_CC() 491 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 492 unsigned char c = (unsigned char) (f1 | f2); 493 cbuf.insts()->emit_int8(c); 494 } 495 496 // EMIT_OPCODE() 497 void emit_opcode(CodeBuffer &cbuf, int code) { 498 cbuf.insts()->emit_int8((unsigned char) code); 499 } 500 501 // EMIT_OPCODE() w/ relocation information 502 void emit_opcode(CodeBuffer &cbuf, 503 int code, relocInfo::relocType reloc, int offset, int format) 504 { 505 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 506 emit_opcode(cbuf, code); 507 } 508 509 // EMIT_D8() 510 void emit_d8(CodeBuffer &cbuf, int d8) { 511 cbuf.insts()->emit_int8((unsigned char) d8); 512 } 513 514 // EMIT_D16() 515 void emit_d16(CodeBuffer &cbuf, int d16) { 516 cbuf.insts()->emit_int16(d16); 517 } 518 519 // EMIT_D32() 520 void emit_d32(CodeBuffer &cbuf, int d32) { 521 cbuf.insts()->emit_int32(d32); 522 } 523 524 // EMIT_D64() 525 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 526 cbuf.insts()->emit_int64(d64); 527 } 528 529 // emit 32 bit value and construct relocation entry from relocInfo::relocType 530 void emit_d32_reloc(CodeBuffer& cbuf, 531 int d32, 532 relocInfo::relocType reloc, 533 int format) 534 { 535 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 536 cbuf.relocate(cbuf.insts_mark(), reloc, format); 537 cbuf.insts()->emit_int32(d32); 538 } 539 540 // emit 32 bit value and construct relocation entry from RelocationHolder 541 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 542 #ifdef ASSERT 543 if (rspec.reloc()->type() == relocInfo::oop_type && 544 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 545 assert(Universe::heap()->is_in((address)(intptr_t)d32), "should be real oop"); 546 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)), "cannot embed broken oops in code"); 547 } 548 #endif 549 cbuf.relocate(cbuf.insts_mark(), rspec, format); 550 cbuf.insts()->emit_int32(d32); 551 } 552 553 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 554 address next_ip = cbuf.insts_end() + 4; 555 emit_d32_reloc(cbuf, (int) (addr - next_ip), 556 external_word_Relocation::spec(addr), 557 RELOC_DISP32); 558 } 559 560 561 // emit 64 bit value and construct relocation entry from relocInfo::relocType 562 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 563 cbuf.relocate(cbuf.insts_mark(), reloc, format); 564 cbuf.insts()->emit_int64(d64); 565 } 566 567 // emit 64 bit value and construct relocation entry from RelocationHolder 568 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 569 #ifdef ASSERT 570 if (rspec.reloc()->type() == relocInfo::oop_type && 571 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 572 assert(Universe::heap()->is_in((address)d64), "should be real oop"); 573 assert(oopDesc::is_oop(cast_to_oop(d64)), "cannot embed broken oops in code"); 574 } 575 #endif 576 cbuf.relocate(cbuf.insts_mark(), rspec, format); 577 cbuf.insts()->emit_int64(d64); 578 } 579 580 // Access stack slot for load or store 581 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 582 { 583 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 584 if (-0x80 <= disp && disp < 0x80) { 585 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 586 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 587 emit_d8(cbuf, disp); // Displacement // R/M byte 588 } else { 589 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 590 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 591 emit_d32(cbuf, disp); // Displacement // R/M byte 592 } 593 } 594 595 // rRegI ereg, memory mem) %{ // emit_reg_mem 596 void encode_RegMem(CodeBuffer &cbuf, 597 int reg, 598 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 599 { 600 assert(disp_reloc == relocInfo::none, "cannot have disp"); 601 int regenc = reg & 7; 602 int baseenc = base & 7; 603 int indexenc = index & 7; 604 605 // There is no index & no scale, use form without SIB byte 606 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 607 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 608 if (disp == 0 && base != RBP_enc && base != R13_enc) { 609 emit_rm(cbuf, 0x0, regenc, baseenc); // * 610 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 611 // If 8-bit displacement, mode 0x1 612 emit_rm(cbuf, 0x1, regenc, baseenc); // * 613 emit_d8(cbuf, disp); 614 } else { 615 // If 32-bit displacement 616 if (base == -1) { // Special flag for absolute address 617 emit_rm(cbuf, 0x0, regenc, 0x5); // * 618 if (disp_reloc != relocInfo::none) { 619 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 620 } else { 621 emit_d32(cbuf, disp); 622 } 623 } else { 624 // Normal base + offset 625 emit_rm(cbuf, 0x2, regenc, baseenc); // * 626 if (disp_reloc != relocInfo::none) { 627 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 628 } else { 629 emit_d32(cbuf, disp); 630 } 631 } 632 } 633 } else { 634 // Else, encode with the SIB byte 635 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 636 if (disp == 0 && base != RBP_enc && base != R13_enc) { 637 // If no displacement 638 emit_rm(cbuf, 0x0, regenc, 0x4); // * 639 emit_rm(cbuf, scale, indexenc, baseenc); 640 } else { 641 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 642 // If 8-bit displacement, mode 0x1 643 emit_rm(cbuf, 0x1, regenc, 0x4); // * 644 emit_rm(cbuf, scale, indexenc, baseenc); 645 emit_d8(cbuf, disp); 646 } else { 647 // If 32-bit displacement 648 if (base == 0x04 ) { 649 emit_rm(cbuf, 0x2, regenc, 0x4); 650 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 651 } else { 652 emit_rm(cbuf, 0x2, regenc, 0x4); 653 emit_rm(cbuf, scale, indexenc, baseenc); // * 654 } 655 if (disp_reloc != relocInfo::none) { 656 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 657 } else { 658 emit_d32(cbuf, disp); 659 } 660 } 661 } 662 } 663 } 664 665 // This could be in MacroAssembler but it's fairly C2 specific 666 void emit_cmpfp_fixup(MacroAssembler& _masm) { 667 Label exit; 668 __ jccb(Assembler::noParity, exit); 669 __ pushf(); 670 // 671 // comiss/ucomiss instructions set ZF,PF,CF flags and 672 // zero OF,AF,SF for NaN values. 673 // Fixup flags by zeroing ZF,PF so that compare of NaN 674 // values returns 'less than' result (CF is set). 675 // Leave the rest of flags unchanged. 676 // 677 // 7 6 5 4 3 2 1 0 678 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 679 // 0 0 1 0 1 0 1 1 (0x2B) 680 // 681 __ andq(Address(rsp, 0), 0xffffff2b); 682 __ popf(); 683 __ bind(exit); 684 } 685 686 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 687 Label done; 688 __ movl(dst, -1); 689 __ jcc(Assembler::parity, done); 690 __ jcc(Assembler::below, done); 691 __ setb(Assembler::notEqual, dst); 692 __ movzbl(dst, dst); 693 __ bind(done); 694 } 695 696 // Math.min() # Math.max() 697 // -------------------------- 698 // ucomis[s/d] # 699 // ja -> b # a 700 // jp -> NaN # NaN 701 // jb -> a # b 702 // je # 703 // |-jz -> a | b # a & b 704 // | -> a # 705 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst, 706 XMMRegister a, XMMRegister b, 707 XMMRegister xmmt, Register rt, 708 bool min, bool single) { 709 710 Label nan, zero, below, above, done; 711 712 if (single) 713 __ ucomiss(a, b); 714 else 715 __ ucomisd(a, b); 716 717 if (dst->encoding() != (min ? b : a)->encoding()) 718 __ jccb(Assembler::above, above); // CF=0 & ZF=0 719 else 720 __ jccb(Assembler::above, done); 721 722 __ jccb(Assembler::parity, nan); // PF=1 723 __ jccb(Assembler::below, below); // CF=1 724 725 // equal 726 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 727 if (single) { 728 __ ucomiss(a, xmmt); 729 __ jccb(Assembler::equal, zero); 730 731 __ movflt(dst, a); 732 __ jmp(done); 733 } 734 else { 735 __ ucomisd(a, xmmt); 736 __ jccb(Assembler::equal, zero); 737 738 __ movdbl(dst, a); 739 __ jmp(done); 740 } 741 742 __ bind(zero); 743 if (min) 744 __ vpor(dst, a, b, Assembler::AVX_128bit); 745 else 746 __ vpand(dst, a, b, Assembler::AVX_128bit); 747 748 __ jmp(done); 749 750 __ bind(above); 751 if (single) 752 __ movflt(dst, min ? b : a); 753 else 754 __ movdbl(dst, min ? b : a); 755 756 __ jmp(done); 757 758 __ bind(nan); 759 if (single) { 760 __ movl(rt, 0x7fc00000); // Float.NaN 761 __ movdl(dst, rt); 762 } 763 else { 764 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 765 __ movdq(dst, rt); 766 } 767 __ jmp(done); 768 769 __ bind(below); 770 if (single) 771 __ movflt(dst, min ? a : b); 772 else 773 __ movdbl(dst, min ? a : b); 774 775 __ bind(done); 776 } 777 778 //============================================================================= 779 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 780 781 int ConstantTable::calculate_table_base_offset() const { 782 return 0; // absolute addressing, no offset 783 } 784 785 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 786 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 787 ShouldNotReachHere(); 788 } 789 790 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 791 // Empty encoding 792 } 793 794 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 795 return 0; 796 } 797 798 #ifndef PRODUCT 799 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 800 st->print("# MachConstantBaseNode (empty encoding)"); 801 } 802 #endif 803 804 805 //============================================================================= 806 #ifndef PRODUCT 807 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 808 Compile* C = ra_->C; 809 810 int framesize = C->output()->frame_size_in_bytes(); 811 int bangsize = C->output()->bang_size_in_bytes(); 812 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 813 // Remove wordSize for return addr which is already pushed. 814 framesize -= wordSize; 815 816 if (C->output()->need_stack_bang(bangsize)) { 817 framesize -= wordSize; 818 st->print("# stack bang (%d bytes)", bangsize); 819 st->print("\n\t"); 820 st->print("pushq rbp\t# Save rbp"); 821 if (PreserveFramePointer) { 822 st->print("\n\t"); 823 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 824 } 825 if (framesize) { 826 st->print("\n\t"); 827 st->print("subq rsp, #%d\t# Create frame",framesize); 828 } 829 } else { 830 st->print("subq rsp, #%d\t# Create frame",framesize); 831 st->print("\n\t"); 832 framesize -= wordSize; 833 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 834 if (PreserveFramePointer) { 835 st->print("\n\t"); 836 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 837 if (framesize > 0) { 838 st->print("\n\t"); 839 st->print("addq rbp, #%d", framesize); 840 } 841 } 842 } 843 844 if (VerifyStackAtCalls) { 845 st->print("\n\t"); 846 framesize -= wordSize; 847 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 848 #ifdef ASSERT 849 st->print("\n\t"); 850 st->print("# stack alignment check"); 851 #endif 852 } 853 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 854 st->print("\n\t"); 855 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t"); 856 st->print("\n\t"); 857 st->print("je fast_entry\t"); 858 st->print("\n\t"); 859 st->print("call #nmethod_entry_barrier_stub\t"); 860 st->print("\n\tfast_entry:"); 861 } 862 st->cr(); 863 } 864 #endif 865 866 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 867 Compile* C = ra_->C; 868 MacroAssembler _masm(&cbuf); 869 870 int framesize = C->output()->frame_size_in_bytes(); 871 int bangsize = C->output()->bang_size_in_bytes(); 872 873 if (C->clinit_barrier_on_entry()) { 874 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 875 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 876 877 Label L_skip_barrier; 878 Register klass = rscratch1; 879 880 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 881 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 882 883 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 884 885 __ bind(L_skip_barrier); 886 } 887 888 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != NULL); 889 890 C->output()->set_frame_complete(cbuf.insts_size()); 891 892 if (C->has_mach_constant_base_node()) { 893 // NOTE: We set the table base offset here because users might be 894 // emitted before MachConstantBaseNode. 895 ConstantTable& constant_table = C->output()->constant_table(); 896 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 897 } 898 } 899 900 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 901 { 902 return MachNode::size(ra_); // too many variables; just compute it 903 // the hard way 904 } 905 906 int MachPrologNode::reloc() const 907 { 908 return 0; // a large enough number 909 } 910 911 //============================================================================= 912 #ifndef PRODUCT 913 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 914 { 915 Compile* C = ra_->C; 916 if (generate_vzeroupper(C)) { 917 st->print("vzeroupper"); 918 st->cr(); st->print("\t"); 919 } 920 921 int framesize = C->output()->frame_size_in_bytes(); 922 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 923 // Remove word for return adr already pushed 924 // and RBP 925 framesize -= 2*wordSize; 926 927 if (framesize) { 928 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 929 st->print("\t"); 930 } 931 932 st->print_cr("popq rbp"); 933 if (do_polling() && C->is_method_compilation()) { 934 st->print("\t"); 935 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 936 "testl rax, [rscratch1]\t" 937 "# Safepoint: poll for GC"); 938 } 939 } 940 #endif 941 942 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 943 { 944 Compile* C = ra_->C; 945 MacroAssembler _masm(&cbuf); 946 947 if (generate_vzeroupper(C)) { 948 // Clear upper bits of YMM registers when current compiled code uses 949 // wide vectors to avoid AVX <-> SSE transition penalty during call. 950 __ vzeroupper(); 951 } 952 953 int framesize = C->output()->frame_size_in_bytes(); 954 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 955 // Remove word for return adr already pushed 956 // and RBP 957 framesize -= 2*wordSize; 958 959 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 960 961 if (framesize) { 962 emit_opcode(cbuf, Assembler::REX_W); 963 if (framesize < 0x80) { 964 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 965 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 966 emit_d8(cbuf, framesize); 967 } else { 968 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 969 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 970 emit_d32(cbuf, framesize); 971 } 972 } 973 974 // popq rbp 975 emit_opcode(cbuf, 0x58 | RBP_enc); 976 977 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 978 __ reserved_stack_check(); 979 } 980 981 if (do_polling() && C->is_method_compilation()) { 982 MacroAssembler _masm(&cbuf); 983 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 984 __ relocate(relocInfo::poll_return_type); 985 __ testl(rax, Address(rscratch1, 0)); 986 } 987 } 988 989 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 990 { 991 return MachNode::size(ra_); // too many variables; just compute it 992 // the hard way 993 } 994 995 int MachEpilogNode::reloc() const 996 { 997 return 2; // a large enough number 998 } 999 1000 const Pipeline* MachEpilogNode::pipeline() const 1001 { 1002 return MachNode::pipeline_class(); 1003 } 1004 1005 //============================================================================= 1006 1007 enum RC { 1008 rc_bad, 1009 rc_int, 1010 rc_float, 1011 rc_stack 1012 }; 1013 1014 static enum RC rc_class(OptoReg::Name reg) 1015 { 1016 if( !OptoReg::is_valid(reg) ) return rc_bad; 1017 1018 if (OptoReg::is_stack(reg)) return rc_stack; 1019 1020 VMReg r = OptoReg::as_VMReg(reg); 1021 1022 if (r->is_Register()) return rc_int; 1023 1024 assert(r->is_XMMRegister(), "must be"); 1025 return rc_float; 1026 } 1027 1028 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1029 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1030 int src_hi, int dst_hi, uint ireg, outputStream* st); 1031 1032 int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1033 int stack_offset, int reg, uint ireg, outputStream* st); 1034 1035 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1036 int dst_offset, uint ireg, outputStream* st) { 1037 if (cbuf) { 1038 MacroAssembler _masm(cbuf); 1039 switch (ireg) { 1040 case Op_VecS: 1041 __ movq(Address(rsp, -8), rax); 1042 __ movl(rax, Address(rsp, src_offset)); 1043 __ movl(Address(rsp, dst_offset), rax); 1044 __ movq(rax, Address(rsp, -8)); 1045 break; 1046 case Op_VecD: 1047 __ pushq(Address(rsp, src_offset)); 1048 __ popq (Address(rsp, dst_offset)); 1049 break; 1050 case Op_VecX: 1051 __ pushq(Address(rsp, src_offset)); 1052 __ popq (Address(rsp, dst_offset)); 1053 __ pushq(Address(rsp, src_offset+8)); 1054 __ popq (Address(rsp, dst_offset+8)); 1055 break; 1056 case Op_VecY: 1057 __ vmovdqu(Address(rsp, -32), xmm0); 1058 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1059 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1060 __ vmovdqu(xmm0, Address(rsp, -32)); 1061 break; 1062 case Op_VecZ: 1063 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1064 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1065 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1066 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1067 break; 1068 default: 1069 ShouldNotReachHere(); 1070 } 1071 #ifndef PRODUCT 1072 } else { 1073 switch (ireg) { 1074 case Op_VecS: 1075 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1076 "movl rax, [rsp + #%d]\n\t" 1077 "movl [rsp + #%d], rax\n\t" 1078 "movq rax, [rsp - #8]", 1079 src_offset, dst_offset); 1080 break; 1081 case Op_VecD: 1082 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1083 "popq [rsp + #%d]", 1084 src_offset, dst_offset); 1085 break; 1086 case Op_VecX: 1087 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1088 "popq [rsp + #%d]\n\t" 1089 "pushq [rsp + #%d]\n\t" 1090 "popq [rsp + #%d]", 1091 src_offset, dst_offset, src_offset+8, dst_offset+8); 1092 break; 1093 case Op_VecY: 1094 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1095 "vmovdqu xmm0, [rsp + #%d]\n\t" 1096 "vmovdqu [rsp + #%d], xmm0\n\t" 1097 "vmovdqu xmm0, [rsp - #32]", 1098 src_offset, dst_offset); 1099 break; 1100 case Op_VecZ: 1101 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1102 "vmovdqu xmm0, [rsp + #%d]\n\t" 1103 "vmovdqu [rsp + #%d], xmm0\n\t" 1104 "vmovdqu xmm0, [rsp - #64]", 1105 src_offset, dst_offset); 1106 break; 1107 default: 1108 ShouldNotReachHere(); 1109 } 1110 #endif 1111 } 1112 } 1113 1114 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1115 PhaseRegAlloc* ra_, 1116 bool do_size, 1117 outputStream* st) const { 1118 assert(cbuf != NULL || st != NULL, "sanity"); 1119 // Get registers to move 1120 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1121 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1122 OptoReg::Name dst_second = ra_->get_reg_second(this); 1123 OptoReg::Name dst_first = ra_->get_reg_first(this); 1124 1125 enum RC src_second_rc = rc_class(src_second); 1126 enum RC src_first_rc = rc_class(src_first); 1127 enum RC dst_second_rc = rc_class(dst_second); 1128 enum RC dst_first_rc = rc_class(dst_first); 1129 1130 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1131 "must move at least 1 register" ); 1132 1133 if (src_first == dst_first && src_second == dst_second) { 1134 // Self copy, no move 1135 return 0; 1136 } 1137 if (bottom_type()->isa_vect() != NULL) { 1138 uint ireg = ideal_reg(); 1139 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1140 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1141 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1142 // mem -> mem 1143 int src_offset = ra_->reg2offset(src_first); 1144 int dst_offset = ra_->reg2offset(dst_first); 1145 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1146 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1147 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1148 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1149 int stack_offset = ra_->reg2offset(dst_first); 1150 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1151 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1152 int stack_offset = ra_->reg2offset(src_first); 1153 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1154 } else { 1155 ShouldNotReachHere(); 1156 } 1157 return 0; 1158 } 1159 if (src_first_rc == rc_stack) { 1160 // mem -> 1161 if (dst_first_rc == rc_stack) { 1162 // mem -> mem 1163 assert(src_second != dst_first, "overlap"); 1164 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1165 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1166 // 64-bit 1167 int src_offset = ra_->reg2offset(src_first); 1168 int dst_offset = ra_->reg2offset(dst_first); 1169 if (cbuf) { 1170 MacroAssembler _masm(cbuf); 1171 __ pushq(Address(rsp, src_offset)); 1172 __ popq (Address(rsp, dst_offset)); 1173 #ifndef PRODUCT 1174 } else { 1175 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1176 "popq [rsp + #%d]", 1177 src_offset, dst_offset); 1178 #endif 1179 } 1180 } else { 1181 // 32-bit 1182 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1183 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1184 // No pushl/popl, so: 1185 int src_offset = ra_->reg2offset(src_first); 1186 int dst_offset = ra_->reg2offset(dst_first); 1187 if (cbuf) { 1188 MacroAssembler _masm(cbuf); 1189 __ movq(Address(rsp, -8), rax); 1190 __ movl(rax, Address(rsp, src_offset)); 1191 __ movl(Address(rsp, dst_offset), rax); 1192 __ movq(rax, Address(rsp, -8)); 1193 #ifndef PRODUCT 1194 } else { 1195 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1196 "movl rax, [rsp + #%d]\n\t" 1197 "movl [rsp + #%d], rax\n\t" 1198 "movq rax, [rsp - #8]", 1199 src_offset, dst_offset); 1200 #endif 1201 } 1202 } 1203 return 0; 1204 } else if (dst_first_rc == rc_int) { 1205 // mem -> gpr 1206 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1207 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1208 // 64-bit 1209 int offset = ra_->reg2offset(src_first); 1210 if (cbuf) { 1211 MacroAssembler _masm(cbuf); 1212 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1213 #ifndef PRODUCT 1214 } else { 1215 st->print("movq %s, [rsp + #%d]\t# spill", 1216 Matcher::regName[dst_first], 1217 offset); 1218 #endif 1219 } 1220 } else { 1221 // 32-bit 1222 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1223 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1224 int offset = ra_->reg2offset(src_first); 1225 if (cbuf) { 1226 MacroAssembler _masm(cbuf); 1227 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1228 #ifndef PRODUCT 1229 } else { 1230 st->print("movl %s, [rsp + #%d]\t# spill", 1231 Matcher::regName[dst_first], 1232 offset); 1233 #endif 1234 } 1235 } 1236 return 0; 1237 } else if (dst_first_rc == rc_float) { 1238 // mem-> xmm 1239 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1240 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1241 // 64-bit 1242 int offset = ra_->reg2offset(src_first); 1243 if (cbuf) { 1244 MacroAssembler _masm(cbuf); 1245 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1246 #ifndef PRODUCT 1247 } else { 1248 st->print("%s %s, [rsp + #%d]\t# spill", 1249 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1250 Matcher::regName[dst_first], 1251 offset); 1252 #endif 1253 } 1254 } else { 1255 // 32-bit 1256 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1257 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1258 int offset = ra_->reg2offset(src_first); 1259 if (cbuf) { 1260 MacroAssembler _masm(cbuf); 1261 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1262 #ifndef PRODUCT 1263 } else { 1264 st->print("movss %s, [rsp + #%d]\t# spill", 1265 Matcher::regName[dst_first], 1266 offset); 1267 #endif 1268 } 1269 } 1270 return 0; 1271 } 1272 } else if (src_first_rc == rc_int) { 1273 // gpr -> 1274 if (dst_first_rc == rc_stack) { 1275 // gpr -> mem 1276 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1277 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1278 // 64-bit 1279 int offset = ra_->reg2offset(dst_first); 1280 if (cbuf) { 1281 MacroAssembler _masm(cbuf); 1282 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1283 #ifndef PRODUCT 1284 } else { 1285 st->print("movq [rsp + #%d], %s\t# spill", 1286 offset, 1287 Matcher::regName[src_first]); 1288 #endif 1289 } 1290 } else { 1291 // 32-bit 1292 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1293 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1294 int offset = ra_->reg2offset(dst_first); 1295 if (cbuf) { 1296 MacroAssembler _masm(cbuf); 1297 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1298 #ifndef PRODUCT 1299 } else { 1300 st->print("movl [rsp + #%d], %s\t# spill", 1301 offset, 1302 Matcher::regName[src_first]); 1303 #endif 1304 } 1305 } 1306 return 0; 1307 } else if (dst_first_rc == rc_int) { 1308 // gpr -> gpr 1309 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1310 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1311 // 64-bit 1312 if (cbuf) { 1313 MacroAssembler _masm(cbuf); 1314 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1315 as_Register(Matcher::_regEncode[src_first])); 1316 #ifndef PRODUCT 1317 } else { 1318 st->print("movq %s, %s\t# spill", 1319 Matcher::regName[dst_first], 1320 Matcher::regName[src_first]); 1321 #endif 1322 } 1323 return 0; 1324 } else { 1325 // 32-bit 1326 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1327 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1328 if (cbuf) { 1329 MacroAssembler _masm(cbuf); 1330 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1331 as_Register(Matcher::_regEncode[src_first])); 1332 #ifndef PRODUCT 1333 } else { 1334 st->print("movl %s, %s\t# spill", 1335 Matcher::regName[dst_first], 1336 Matcher::regName[src_first]); 1337 #endif 1338 } 1339 return 0; 1340 } 1341 } else if (dst_first_rc == rc_float) { 1342 // gpr -> xmm 1343 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1344 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1345 // 64-bit 1346 if (cbuf) { 1347 MacroAssembler _masm(cbuf); 1348 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1349 #ifndef PRODUCT 1350 } else { 1351 st->print("movdq %s, %s\t# spill", 1352 Matcher::regName[dst_first], 1353 Matcher::regName[src_first]); 1354 #endif 1355 } 1356 } else { 1357 // 32-bit 1358 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1359 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1360 if (cbuf) { 1361 MacroAssembler _masm(cbuf); 1362 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1363 #ifndef PRODUCT 1364 } else { 1365 st->print("movdl %s, %s\t# spill", 1366 Matcher::regName[dst_first], 1367 Matcher::regName[src_first]); 1368 #endif 1369 } 1370 } 1371 return 0; 1372 } 1373 } else if (src_first_rc == rc_float) { 1374 // xmm -> 1375 if (dst_first_rc == rc_stack) { 1376 // xmm -> mem 1377 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1378 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1379 // 64-bit 1380 int offset = ra_->reg2offset(dst_first); 1381 if (cbuf) { 1382 MacroAssembler _masm(cbuf); 1383 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1384 #ifndef PRODUCT 1385 } else { 1386 st->print("movsd [rsp + #%d], %s\t# spill", 1387 offset, 1388 Matcher::regName[src_first]); 1389 #endif 1390 } 1391 } else { 1392 // 32-bit 1393 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1394 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1395 int offset = ra_->reg2offset(dst_first); 1396 if (cbuf) { 1397 MacroAssembler _masm(cbuf); 1398 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1399 #ifndef PRODUCT 1400 } else { 1401 st->print("movss [rsp + #%d], %s\t# spill", 1402 offset, 1403 Matcher::regName[src_first]); 1404 #endif 1405 } 1406 } 1407 return 0; 1408 } else if (dst_first_rc == rc_int) { 1409 // xmm -> gpr 1410 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1411 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1412 // 64-bit 1413 if (cbuf) { 1414 MacroAssembler _masm(cbuf); 1415 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1416 #ifndef PRODUCT 1417 } else { 1418 st->print("movdq %s, %s\t# spill", 1419 Matcher::regName[dst_first], 1420 Matcher::regName[src_first]); 1421 #endif 1422 } 1423 } else { 1424 // 32-bit 1425 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1426 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1427 if (cbuf) { 1428 MacroAssembler _masm(cbuf); 1429 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1430 #ifndef PRODUCT 1431 } else { 1432 st->print("movdl %s, %s\t# spill", 1433 Matcher::regName[dst_first], 1434 Matcher::regName[src_first]); 1435 #endif 1436 } 1437 } 1438 return 0; 1439 } else if (dst_first_rc == rc_float) { 1440 // xmm -> xmm 1441 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1442 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1443 // 64-bit 1444 if (cbuf) { 1445 MacroAssembler _masm(cbuf); 1446 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1447 #ifndef PRODUCT 1448 } else { 1449 st->print("%s %s, %s\t# spill", 1450 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1451 Matcher::regName[dst_first], 1452 Matcher::regName[src_first]); 1453 #endif 1454 } 1455 } else { 1456 // 32-bit 1457 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1458 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1459 if (cbuf) { 1460 MacroAssembler _masm(cbuf); 1461 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1462 #ifndef PRODUCT 1463 } else { 1464 st->print("%s %s, %s\t# spill", 1465 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1466 Matcher::regName[dst_first], 1467 Matcher::regName[src_first]); 1468 #endif 1469 } 1470 } 1471 return 0; 1472 } 1473 } 1474 1475 assert(0," foo "); 1476 Unimplemented(); 1477 return 0; 1478 } 1479 1480 #ifndef PRODUCT 1481 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1482 implementation(NULL, ra_, false, st); 1483 } 1484 #endif 1485 1486 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1487 implementation(&cbuf, ra_, false, NULL); 1488 } 1489 1490 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1491 return MachNode::size(ra_); 1492 } 1493 1494 //============================================================================= 1495 #ifndef PRODUCT 1496 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1497 { 1498 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1499 int reg = ra_->get_reg_first(this); 1500 st->print("leaq %s, [rsp + #%d]\t# box lock", 1501 Matcher::regName[reg], offset); 1502 } 1503 #endif 1504 1505 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1506 { 1507 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1508 int reg = ra_->get_encode(this); 1509 if (offset >= 0x80) { 1510 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1511 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1512 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1513 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1514 emit_d32(cbuf, offset); 1515 } else { 1516 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1517 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1518 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1519 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1520 emit_d8(cbuf, offset); 1521 } 1522 } 1523 1524 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1525 { 1526 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1527 return (offset < 0x80) ? 5 : 8; // REX 1528 } 1529 1530 //============================================================================= 1531 #ifndef PRODUCT 1532 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1533 { 1534 if (UseCompressedClassPointers) { 1535 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1536 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1537 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1538 } else { 1539 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1540 "# Inline cache check"); 1541 } 1542 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1543 st->print_cr("\tnop\t# nops to align entry point"); 1544 } 1545 #endif 1546 1547 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1548 { 1549 MacroAssembler masm(&cbuf); 1550 uint insts_size = cbuf.insts_size(); 1551 if (UseCompressedClassPointers) { 1552 masm.load_klass(rscratch1, j_rarg0, rscratch2); 1553 masm.cmpptr(rax, rscratch1); 1554 } else { 1555 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1556 } 1557 1558 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1559 1560 /* WARNING these NOPs are critical so that verified entry point is properly 1561 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1562 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1563 if (OptoBreakpoint) { 1564 // Leave space for int3 1565 nops_cnt -= 1; 1566 } 1567 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1568 if (nops_cnt > 0) 1569 masm.nop(nops_cnt); 1570 } 1571 1572 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1573 { 1574 return MachNode::size(ra_); // too many variables; just compute it 1575 // the hard way 1576 } 1577 1578 1579 //============================================================================= 1580 1581 int Matcher::regnum_to_fpu_offset(int regnum) 1582 { 1583 return regnum - 32; // The FP registers are in the second chunk 1584 } 1585 1586 // This is UltraSparc specific, true just means we have fast l2f conversion 1587 const bool Matcher::convL2FSupported(void) { 1588 return true; 1589 } 1590 1591 // Is this branch offset short enough that a short branch can be used? 1592 // 1593 // NOTE: If the platform does not provide any short branch variants, then 1594 // this method should return false for offset 0. 1595 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1596 // The passed offset is relative to address of the branch. 1597 // On 86 a branch displacement is calculated relative to address 1598 // of a next instruction. 1599 offset -= br_size; 1600 1601 // the short version of jmpConUCF2 contains multiple branches, 1602 // making the reach slightly less 1603 if (rule == jmpConUCF2_rule) 1604 return (-126 <= offset && offset <= 125); 1605 return (-128 <= offset && offset <= 127); 1606 } 1607 1608 const bool Matcher::isSimpleConstant64(jlong value) { 1609 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1610 //return value == (int) value; // Cf. storeImmL and immL32. 1611 1612 // Probably always true, even if a temp register is required. 1613 return true; 1614 } 1615 1616 // The ecx parameter to rep stosq for the ClearArray node is in words. 1617 const bool Matcher::init_array_count_is_in_bytes = false; 1618 1619 // No additional cost for CMOVL. 1620 const int Matcher::long_cmove_cost() { return 0; } 1621 1622 // No CMOVF/CMOVD with SSE2 1623 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1624 1625 // Does the CPU require late expand (see block.cpp for description of late expand)? 1626 const bool Matcher::require_postalloc_expand = false; 1627 1628 // Do we need to mask the count passed to shift instructions or does 1629 // the cpu only look at the lower 5/6 bits anyway? 1630 const bool Matcher::need_masked_shift_count = false; 1631 1632 bool Matcher::narrow_oop_use_complex_address() { 1633 assert(UseCompressedOops, "only for compressed oops code"); 1634 return (LogMinObjAlignmentInBytes <= 3); 1635 } 1636 1637 bool Matcher::narrow_klass_use_complex_address() { 1638 assert(UseCompressedClassPointers, "only for compressed klass code"); 1639 return (LogKlassAlignmentInBytes <= 3); 1640 } 1641 1642 bool Matcher::const_oop_prefer_decode() { 1643 // Prefer ConN+DecodeN over ConP. 1644 return true; 1645 } 1646 1647 bool Matcher::const_klass_prefer_decode() { 1648 // Prefer ConP over ConNKlass+DecodeNKlass. 1649 return false; 1650 } 1651 1652 // Is it better to copy float constants, or load them directly from 1653 // memory? Intel can load a float constant from a direct address, 1654 // requiring no extra registers. Most RISCs will have to materialize 1655 // an address into a register first, so they would do better to copy 1656 // the constant from stack. 1657 const bool Matcher::rematerialize_float_constants = true; // XXX 1658 1659 // If CPU can load and store mis-aligned doubles directly then no 1660 // fixup is needed. Else we split the double into 2 integer pieces 1661 // and move it piece-by-piece. Only happens when passing doubles into 1662 // C code as the Java calling convention forces doubles to be aligned. 1663 const bool Matcher::misaligned_doubles_ok = true; 1664 1665 // No-op on amd64 1666 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1667 1668 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 1669 const bool Matcher::strict_fp_requires_explicit_rounding = false; 1670 1671 // Are floats conerted to double when stored to stack during deoptimization? 1672 // On x64 it is stored without convertion so we can use normal access. 1673 bool Matcher::float_in_double() { return false; } 1674 1675 // Do ints take an entire long register or just half? 1676 const bool Matcher::int_in_long = true; 1677 1678 // Return whether or not this register is ever used as an argument. 1679 // This function is used on startup to build the trampoline stubs in 1680 // generateOptoStub. Registers not mentioned will be killed by the VM 1681 // call in the trampoline, and arguments in those registers not be 1682 // available to the callee. 1683 bool Matcher::can_be_java_arg(int reg) 1684 { 1685 return 1686 reg == RDI_num || reg == RDI_H_num || 1687 reg == RSI_num || reg == RSI_H_num || 1688 reg == RDX_num || reg == RDX_H_num || 1689 reg == RCX_num || reg == RCX_H_num || 1690 reg == R8_num || reg == R8_H_num || 1691 reg == R9_num || reg == R9_H_num || 1692 reg == R12_num || reg == R12_H_num || 1693 reg == XMM0_num || reg == XMM0b_num || 1694 reg == XMM1_num || reg == XMM1b_num || 1695 reg == XMM2_num || reg == XMM2b_num || 1696 reg == XMM3_num || reg == XMM3b_num || 1697 reg == XMM4_num || reg == XMM4b_num || 1698 reg == XMM5_num || reg == XMM5b_num || 1699 reg == XMM6_num || reg == XMM6b_num || 1700 reg == XMM7_num || reg == XMM7b_num; 1701 } 1702 1703 bool Matcher::is_spillable_arg(int reg) 1704 { 1705 return can_be_java_arg(reg); 1706 } 1707 1708 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1709 // In 64 bit mode a code which use multiply when 1710 // devisor is constant is faster than hardware 1711 // DIV instruction (it uses MulHiL). 1712 return false; 1713 } 1714 1715 // Register for DIVI projection of divmodI 1716 RegMask Matcher::divI_proj_mask() { 1717 return INT_RAX_REG_mask(); 1718 } 1719 1720 // Register for MODI projection of divmodI 1721 RegMask Matcher::modI_proj_mask() { 1722 return INT_RDX_REG_mask(); 1723 } 1724 1725 // Register for DIVL projection of divmodL 1726 RegMask Matcher::divL_proj_mask() { 1727 return LONG_RAX_REG_mask(); 1728 } 1729 1730 // Register for MODL projection of divmodL 1731 RegMask Matcher::modL_proj_mask() { 1732 return LONG_RDX_REG_mask(); 1733 } 1734 1735 // Register for saving SP into on method handle invokes. Not used on x86_64. 1736 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1737 return NO_REG_mask(); 1738 } 1739 1740 %} 1741 1742 //----------ENCODING BLOCK----------------------------------------------------- 1743 // This block specifies the encoding classes used by the compiler to 1744 // output byte streams. Encoding classes are parameterized macros 1745 // used by Machine Instruction Nodes in order to generate the bit 1746 // encoding of the instruction. Operands specify their base encoding 1747 // interface with the interface keyword. There are currently 1748 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1749 // COND_INTER. REG_INTER causes an operand to generate a function 1750 // which returns its register number when queried. CONST_INTER causes 1751 // an operand to generate a function which returns the value of the 1752 // constant when queried. MEMORY_INTER causes an operand to generate 1753 // four functions which return the Base Register, the Index Register, 1754 // the Scale Value, and the Offset Value of the operand when queried. 1755 // COND_INTER causes an operand to generate six functions which return 1756 // the encoding code (ie - encoding bits for the instruction) 1757 // associated with each basic boolean condition for a conditional 1758 // instruction. 1759 // 1760 // Instructions specify two basic values for encoding. Again, a 1761 // function is available to check if the constant displacement is an 1762 // oop. They use the ins_encode keyword to specify their encoding 1763 // classes (which must be a sequence of enc_class names, and their 1764 // parameters, specified in the encoding block), and they use the 1765 // opcode keyword to specify, in order, their primary, secondary, and 1766 // tertiary opcode. Only the opcode sections which a particular 1767 // instruction needs for encoding need to be specified. 1768 encode %{ 1769 // Build emit functions for each basic byte or larger field in the 1770 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1771 // from C++ code in the enc_class source block. Emit functions will 1772 // live in the main source block for now. In future, we can 1773 // generalize this by adding a syntax that specifies the sizes of 1774 // fields in an order, so that the adlc can build the emit functions 1775 // automagically 1776 1777 // Emit primary opcode 1778 enc_class OpcP 1779 %{ 1780 emit_opcode(cbuf, $primary); 1781 %} 1782 1783 // Emit secondary opcode 1784 enc_class OpcS 1785 %{ 1786 emit_opcode(cbuf, $secondary); 1787 %} 1788 1789 // Emit tertiary opcode 1790 enc_class OpcT 1791 %{ 1792 emit_opcode(cbuf, $tertiary); 1793 %} 1794 1795 // Emit opcode directly 1796 enc_class Opcode(immI d8) 1797 %{ 1798 emit_opcode(cbuf, $d8$$constant); 1799 %} 1800 1801 // Emit size prefix 1802 enc_class SizePrefix 1803 %{ 1804 emit_opcode(cbuf, 0x66); 1805 %} 1806 1807 enc_class reg(rRegI reg) 1808 %{ 1809 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1810 %} 1811 1812 enc_class reg_reg(rRegI dst, rRegI src) 1813 %{ 1814 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1815 %} 1816 1817 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1818 %{ 1819 emit_opcode(cbuf, $opcode$$constant); 1820 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1821 %} 1822 1823 enc_class cdql_enc(no_rax_rdx_RegI div) 1824 %{ 1825 // Full implementation of Java idiv and irem; checks for 1826 // special case as described in JVM spec., p.243 & p.271. 1827 // 1828 // normal case special case 1829 // 1830 // input : rax: dividend min_int 1831 // reg: divisor -1 1832 // 1833 // output: rax: quotient (= rax idiv reg) min_int 1834 // rdx: remainder (= rax irem reg) 0 1835 // 1836 // Code sequnce: 1837 // 1838 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1839 // 5: 75 07/08 jne e <normal> 1840 // 7: 33 d2 xor %edx,%edx 1841 // [div >= 8 -> offset + 1] 1842 // [REX_B] 1843 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1844 // c: 74 03/04 je 11 <done> 1845 // 000000000000000e <normal>: 1846 // e: 99 cltd 1847 // [div >= 8 -> offset + 1] 1848 // [REX_B] 1849 // f: f7 f9 idiv $div 1850 // 0000000000000011 <done>: 1851 1852 // cmp $0x80000000,%eax 1853 emit_opcode(cbuf, 0x3d); 1854 emit_d8(cbuf, 0x00); 1855 emit_d8(cbuf, 0x00); 1856 emit_d8(cbuf, 0x00); 1857 emit_d8(cbuf, 0x80); 1858 1859 // jne e <normal> 1860 emit_opcode(cbuf, 0x75); 1861 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1862 1863 // xor %edx,%edx 1864 emit_opcode(cbuf, 0x33); 1865 emit_d8(cbuf, 0xD2); 1866 1867 // cmp $0xffffffffffffffff,%ecx 1868 if ($div$$reg >= 8) { 1869 emit_opcode(cbuf, Assembler::REX_B); 1870 } 1871 emit_opcode(cbuf, 0x83); 1872 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1873 emit_d8(cbuf, 0xFF); 1874 1875 // je 11 <done> 1876 emit_opcode(cbuf, 0x74); 1877 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1878 1879 // <normal> 1880 // cltd 1881 emit_opcode(cbuf, 0x99); 1882 1883 // idivl (note: must be emitted by the user of this rule) 1884 // <done> 1885 %} 1886 1887 enc_class cdqq_enc(no_rax_rdx_RegL div) 1888 %{ 1889 // Full implementation of Java ldiv and lrem; checks for 1890 // special case as described in JVM spec., p.243 & p.271. 1891 // 1892 // normal case special case 1893 // 1894 // input : rax: dividend min_long 1895 // reg: divisor -1 1896 // 1897 // output: rax: quotient (= rax idiv reg) min_long 1898 // rdx: remainder (= rax irem reg) 0 1899 // 1900 // Code sequnce: 1901 // 1902 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1903 // 7: 00 00 80 1904 // a: 48 39 d0 cmp %rdx,%rax 1905 // d: 75 08 jne 17 <normal> 1906 // f: 33 d2 xor %edx,%edx 1907 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1908 // 15: 74 05 je 1c <done> 1909 // 0000000000000017 <normal>: 1910 // 17: 48 99 cqto 1911 // 19: 48 f7 f9 idiv $div 1912 // 000000000000001c <done>: 1913 1914 // mov $0x8000000000000000,%rdx 1915 emit_opcode(cbuf, Assembler::REX_W); 1916 emit_opcode(cbuf, 0xBA); 1917 emit_d8(cbuf, 0x00); 1918 emit_d8(cbuf, 0x00); 1919 emit_d8(cbuf, 0x00); 1920 emit_d8(cbuf, 0x00); 1921 emit_d8(cbuf, 0x00); 1922 emit_d8(cbuf, 0x00); 1923 emit_d8(cbuf, 0x00); 1924 emit_d8(cbuf, 0x80); 1925 1926 // cmp %rdx,%rax 1927 emit_opcode(cbuf, Assembler::REX_W); 1928 emit_opcode(cbuf, 0x39); 1929 emit_d8(cbuf, 0xD0); 1930 1931 // jne 17 <normal> 1932 emit_opcode(cbuf, 0x75); 1933 emit_d8(cbuf, 0x08); 1934 1935 // xor %edx,%edx 1936 emit_opcode(cbuf, 0x33); 1937 emit_d8(cbuf, 0xD2); 1938 1939 // cmp $0xffffffffffffffff,$div 1940 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1941 emit_opcode(cbuf, 0x83); 1942 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1943 emit_d8(cbuf, 0xFF); 1944 1945 // je 1e <done> 1946 emit_opcode(cbuf, 0x74); 1947 emit_d8(cbuf, 0x05); 1948 1949 // <normal> 1950 // cqto 1951 emit_opcode(cbuf, Assembler::REX_W); 1952 emit_opcode(cbuf, 0x99); 1953 1954 // idivq (note: must be emitted by the user of this rule) 1955 // <done> 1956 %} 1957 1958 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1959 enc_class OpcSE(immI imm) 1960 %{ 1961 // Emit primary opcode and set sign-extend bit 1962 // Check for 8-bit immediate, and set sign extend bit in opcode 1963 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1964 emit_opcode(cbuf, $primary | 0x02); 1965 } else { 1966 // 32-bit immediate 1967 emit_opcode(cbuf, $primary); 1968 } 1969 %} 1970 1971 enc_class OpcSErm(rRegI dst, immI imm) 1972 %{ 1973 // OpcSEr/m 1974 int dstenc = $dst$$reg; 1975 if (dstenc >= 8) { 1976 emit_opcode(cbuf, Assembler::REX_B); 1977 dstenc -= 8; 1978 } 1979 // Emit primary opcode and set sign-extend bit 1980 // Check for 8-bit immediate, and set sign extend bit in opcode 1981 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1982 emit_opcode(cbuf, $primary | 0x02); 1983 } else { 1984 // 32-bit immediate 1985 emit_opcode(cbuf, $primary); 1986 } 1987 // Emit r/m byte with secondary opcode, after primary opcode. 1988 emit_rm(cbuf, 0x3, $secondary, dstenc); 1989 %} 1990 1991 enc_class OpcSErm_wide(rRegL dst, immI imm) 1992 %{ 1993 // OpcSEr/m 1994 int dstenc = $dst$$reg; 1995 if (dstenc < 8) { 1996 emit_opcode(cbuf, Assembler::REX_W); 1997 } else { 1998 emit_opcode(cbuf, Assembler::REX_WB); 1999 dstenc -= 8; 2000 } 2001 // Emit primary opcode and set sign-extend bit 2002 // Check for 8-bit immediate, and set sign extend bit in opcode 2003 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2004 emit_opcode(cbuf, $primary | 0x02); 2005 } else { 2006 // 32-bit immediate 2007 emit_opcode(cbuf, $primary); 2008 } 2009 // Emit r/m byte with secondary opcode, after primary opcode. 2010 emit_rm(cbuf, 0x3, $secondary, dstenc); 2011 %} 2012 2013 enc_class Con8or32(immI imm) 2014 %{ 2015 // Check for 8-bit immediate, and set sign extend bit in opcode 2016 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2017 $$$emit8$imm$$constant; 2018 } else { 2019 // 32-bit immediate 2020 $$$emit32$imm$$constant; 2021 } 2022 %} 2023 2024 enc_class opc2_reg(rRegI dst) 2025 %{ 2026 // BSWAP 2027 emit_cc(cbuf, $secondary, $dst$$reg); 2028 %} 2029 2030 enc_class opc3_reg(rRegI dst) 2031 %{ 2032 // BSWAP 2033 emit_cc(cbuf, $tertiary, $dst$$reg); 2034 %} 2035 2036 enc_class reg_opc(rRegI div) 2037 %{ 2038 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2039 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2040 %} 2041 2042 enc_class enc_cmov(cmpOp cop) 2043 %{ 2044 // CMOV 2045 $$$emit8$primary; 2046 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2047 %} 2048 2049 enc_class enc_PartialSubtypeCheck() 2050 %{ 2051 Register Rrdi = as_Register(RDI_enc); // result register 2052 Register Rrax = as_Register(RAX_enc); // super class 2053 Register Rrcx = as_Register(RCX_enc); // killed 2054 Register Rrsi = as_Register(RSI_enc); // sub class 2055 Label miss; 2056 const bool set_cond_codes = true; 2057 2058 MacroAssembler _masm(&cbuf); 2059 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2060 NULL, &miss, 2061 /*set_cond_codes:*/ true); 2062 if ($primary) { 2063 __ xorptr(Rrdi, Rrdi); 2064 } 2065 __ bind(miss); 2066 %} 2067 2068 enc_class clear_avx %{ 2069 debug_only(int off0 = cbuf.insts_size()); 2070 if (generate_vzeroupper(Compile::current())) { 2071 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2072 // Clear upper bits of YMM registers when current compiled code uses 2073 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2074 MacroAssembler _masm(&cbuf); 2075 __ vzeroupper(); 2076 } 2077 debug_only(int off1 = cbuf.insts_size()); 2078 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2079 %} 2080 2081 enc_class Java_To_Runtime(method meth) %{ 2082 // No relocation needed 2083 MacroAssembler _masm(&cbuf); 2084 __ mov64(r10, (int64_t) $meth$$method); 2085 __ call(r10); 2086 %} 2087 2088 enc_class Java_To_Interpreter(method meth) 2089 %{ 2090 // CALL Java_To_Interpreter 2091 // This is the instruction starting address for relocation info. 2092 cbuf.set_insts_mark(); 2093 $$$emit8$primary; 2094 // CALL directly to the runtime 2095 emit_d32_reloc(cbuf, 2096 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2097 runtime_call_Relocation::spec(), 2098 RELOC_DISP32); 2099 %} 2100 2101 enc_class Java_Static_Call(method meth) 2102 %{ 2103 // JAVA STATIC CALL 2104 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2105 // determine who we intended to call. 2106 cbuf.set_insts_mark(); 2107 $$$emit8$primary; 2108 2109 if (!_method) { 2110 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2111 runtime_call_Relocation::spec(), 2112 RELOC_DISP32); 2113 } else { 2114 int method_index = resolved_method_index(cbuf); 2115 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2116 : static_call_Relocation::spec(method_index); 2117 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2118 rspec, RELOC_DISP32); 2119 // Emit stubs for static call. 2120 address mark = cbuf.insts_mark(); 2121 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2122 if (stub == NULL) { 2123 ciEnv::current()->record_failure("CodeCache is full"); 2124 return; 2125 } 2126 #if INCLUDE_AOT 2127 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2128 #endif 2129 } 2130 %} 2131 2132 enc_class Java_Dynamic_Call(method meth) %{ 2133 MacroAssembler _masm(&cbuf); 2134 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2135 %} 2136 2137 enc_class Java_Compiled_Call(method meth) 2138 %{ 2139 // JAVA COMPILED CALL 2140 int disp = in_bytes(Method:: from_compiled_offset()); 2141 2142 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2143 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2144 2145 // callq *disp(%rax) 2146 cbuf.set_insts_mark(); 2147 $$$emit8$primary; 2148 if (disp < 0x80) { 2149 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2150 emit_d8(cbuf, disp); // Displacement 2151 } else { 2152 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2153 emit_d32(cbuf, disp); // Displacement 2154 } 2155 %} 2156 2157 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2158 %{ 2159 // SAL, SAR, SHR 2160 int dstenc = $dst$$reg; 2161 if (dstenc >= 8) { 2162 emit_opcode(cbuf, Assembler::REX_B); 2163 dstenc -= 8; 2164 } 2165 $$$emit8$primary; 2166 emit_rm(cbuf, 0x3, $secondary, dstenc); 2167 $$$emit8$shift$$constant; 2168 %} 2169 2170 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2171 %{ 2172 // SAL, SAR, SHR 2173 int dstenc = $dst$$reg; 2174 if (dstenc < 8) { 2175 emit_opcode(cbuf, Assembler::REX_W); 2176 } else { 2177 emit_opcode(cbuf, Assembler::REX_WB); 2178 dstenc -= 8; 2179 } 2180 $$$emit8$primary; 2181 emit_rm(cbuf, 0x3, $secondary, dstenc); 2182 $$$emit8$shift$$constant; 2183 %} 2184 2185 enc_class load_immI(rRegI dst, immI src) 2186 %{ 2187 int dstenc = $dst$$reg; 2188 if (dstenc >= 8) { 2189 emit_opcode(cbuf, Assembler::REX_B); 2190 dstenc -= 8; 2191 } 2192 emit_opcode(cbuf, 0xB8 | dstenc); 2193 $$$emit32$src$$constant; 2194 %} 2195 2196 enc_class load_immL(rRegL dst, immL src) 2197 %{ 2198 int dstenc = $dst$$reg; 2199 if (dstenc < 8) { 2200 emit_opcode(cbuf, Assembler::REX_W); 2201 } else { 2202 emit_opcode(cbuf, Assembler::REX_WB); 2203 dstenc -= 8; 2204 } 2205 emit_opcode(cbuf, 0xB8 | dstenc); 2206 emit_d64(cbuf, $src$$constant); 2207 %} 2208 2209 enc_class load_immUL32(rRegL dst, immUL32 src) 2210 %{ 2211 // same as load_immI, but this time we care about zeroes in the high word 2212 int dstenc = $dst$$reg; 2213 if (dstenc >= 8) { 2214 emit_opcode(cbuf, Assembler::REX_B); 2215 dstenc -= 8; 2216 } 2217 emit_opcode(cbuf, 0xB8 | dstenc); 2218 $$$emit32$src$$constant; 2219 %} 2220 2221 enc_class load_immL32(rRegL dst, immL32 src) 2222 %{ 2223 int dstenc = $dst$$reg; 2224 if (dstenc < 8) { 2225 emit_opcode(cbuf, Assembler::REX_W); 2226 } else { 2227 emit_opcode(cbuf, Assembler::REX_WB); 2228 dstenc -= 8; 2229 } 2230 emit_opcode(cbuf, 0xC7); 2231 emit_rm(cbuf, 0x03, 0x00, dstenc); 2232 $$$emit32$src$$constant; 2233 %} 2234 2235 enc_class load_immP31(rRegP dst, immP32 src) 2236 %{ 2237 // same as load_immI, but this time we care about zeroes in the high word 2238 int dstenc = $dst$$reg; 2239 if (dstenc >= 8) { 2240 emit_opcode(cbuf, Assembler::REX_B); 2241 dstenc -= 8; 2242 } 2243 emit_opcode(cbuf, 0xB8 | dstenc); 2244 $$$emit32$src$$constant; 2245 %} 2246 2247 enc_class load_immP(rRegP dst, immP src) 2248 %{ 2249 int dstenc = $dst$$reg; 2250 if (dstenc < 8) { 2251 emit_opcode(cbuf, Assembler::REX_W); 2252 } else { 2253 emit_opcode(cbuf, Assembler::REX_WB); 2254 dstenc -= 8; 2255 } 2256 emit_opcode(cbuf, 0xB8 | dstenc); 2257 // This next line should be generated from ADLC 2258 if ($src->constant_reloc() != relocInfo::none) { 2259 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2260 } else { 2261 emit_d64(cbuf, $src$$constant); 2262 } 2263 %} 2264 2265 enc_class Con32(immI src) 2266 %{ 2267 // Output immediate 2268 $$$emit32$src$$constant; 2269 %} 2270 2271 enc_class Con32F_as_bits(immF src) 2272 %{ 2273 // Output Float immediate bits 2274 jfloat jf = $src$$constant; 2275 jint jf_as_bits = jint_cast(jf); 2276 emit_d32(cbuf, jf_as_bits); 2277 %} 2278 2279 enc_class Con16(immI src) 2280 %{ 2281 // Output immediate 2282 $$$emit16$src$$constant; 2283 %} 2284 2285 // How is this different from Con32??? XXX 2286 enc_class Con_d32(immI src) 2287 %{ 2288 emit_d32(cbuf,$src$$constant); 2289 %} 2290 2291 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2292 // Output immediate memory reference 2293 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2294 emit_d32(cbuf, 0x00); 2295 %} 2296 2297 enc_class lock_prefix() 2298 %{ 2299 emit_opcode(cbuf, 0xF0); // lock 2300 %} 2301 2302 enc_class REX_mem(memory mem) 2303 %{ 2304 if ($mem$$base >= 8) { 2305 if ($mem$$index < 8) { 2306 emit_opcode(cbuf, Assembler::REX_B); 2307 } else { 2308 emit_opcode(cbuf, Assembler::REX_XB); 2309 } 2310 } else { 2311 if ($mem$$index >= 8) { 2312 emit_opcode(cbuf, Assembler::REX_X); 2313 } 2314 } 2315 %} 2316 2317 enc_class REX_mem_wide(memory mem) 2318 %{ 2319 if ($mem$$base >= 8) { 2320 if ($mem$$index < 8) { 2321 emit_opcode(cbuf, Assembler::REX_WB); 2322 } else { 2323 emit_opcode(cbuf, Assembler::REX_WXB); 2324 } 2325 } else { 2326 if ($mem$$index < 8) { 2327 emit_opcode(cbuf, Assembler::REX_W); 2328 } else { 2329 emit_opcode(cbuf, Assembler::REX_WX); 2330 } 2331 } 2332 %} 2333 2334 // for byte regs 2335 enc_class REX_breg(rRegI reg) 2336 %{ 2337 if ($reg$$reg >= 4) { 2338 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2339 } 2340 %} 2341 2342 // for byte regs 2343 enc_class REX_reg_breg(rRegI dst, rRegI src) 2344 %{ 2345 if ($dst$$reg < 8) { 2346 if ($src$$reg >= 4) { 2347 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2348 } 2349 } else { 2350 if ($src$$reg < 8) { 2351 emit_opcode(cbuf, Assembler::REX_R); 2352 } else { 2353 emit_opcode(cbuf, Assembler::REX_RB); 2354 } 2355 } 2356 %} 2357 2358 // for byte regs 2359 enc_class REX_breg_mem(rRegI reg, memory mem) 2360 %{ 2361 if ($reg$$reg < 8) { 2362 if ($mem$$base < 8) { 2363 if ($mem$$index >= 8) { 2364 emit_opcode(cbuf, Assembler::REX_X); 2365 } else if ($reg$$reg >= 4) { 2366 emit_opcode(cbuf, Assembler::REX); 2367 } 2368 } else { 2369 if ($mem$$index < 8) { 2370 emit_opcode(cbuf, Assembler::REX_B); 2371 } else { 2372 emit_opcode(cbuf, Assembler::REX_XB); 2373 } 2374 } 2375 } else { 2376 if ($mem$$base < 8) { 2377 if ($mem$$index < 8) { 2378 emit_opcode(cbuf, Assembler::REX_R); 2379 } else { 2380 emit_opcode(cbuf, Assembler::REX_RX); 2381 } 2382 } else { 2383 if ($mem$$index < 8) { 2384 emit_opcode(cbuf, Assembler::REX_RB); 2385 } else { 2386 emit_opcode(cbuf, Assembler::REX_RXB); 2387 } 2388 } 2389 } 2390 %} 2391 2392 enc_class REX_reg(rRegI reg) 2393 %{ 2394 if ($reg$$reg >= 8) { 2395 emit_opcode(cbuf, Assembler::REX_B); 2396 } 2397 %} 2398 2399 enc_class REX_reg_wide(rRegI reg) 2400 %{ 2401 if ($reg$$reg < 8) { 2402 emit_opcode(cbuf, Assembler::REX_W); 2403 } else { 2404 emit_opcode(cbuf, Assembler::REX_WB); 2405 } 2406 %} 2407 2408 enc_class REX_reg_reg(rRegI dst, rRegI src) 2409 %{ 2410 if ($dst$$reg < 8) { 2411 if ($src$$reg >= 8) { 2412 emit_opcode(cbuf, Assembler::REX_B); 2413 } 2414 } else { 2415 if ($src$$reg < 8) { 2416 emit_opcode(cbuf, Assembler::REX_R); 2417 } else { 2418 emit_opcode(cbuf, Assembler::REX_RB); 2419 } 2420 } 2421 %} 2422 2423 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2424 %{ 2425 if ($dst$$reg < 8) { 2426 if ($src$$reg < 8) { 2427 emit_opcode(cbuf, Assembler::REX_W); 2428 } else { 2429 emit_opcode(cbuf, Assembler::REX_WB); 2430 } 2431 } else { 2432 if ($src$$reg < 8) { 2433 emit_opcode(cbuf, Assembler::REX_WR); 2434 } else { 2435 emit_opcode(cbuf, Assembler::REX_WRB); 2436 } 2437 } 2438 %} 2439 2440 enc_class REX_reg_mem(rRegI reg, memory mem) 2441 %{ 2442 if ($reg$$reg < 8) { 2443 if ($mem$$base < 8) { 2444 if ($mem$$index >= 8) { 2445 emit_opcode(cbuf, Assembler::REX_X); 2446 } 2447 } else { 2448 if ($mem$$index < 8) { 2449 emit_opcode(cbuf, Assembler::REX_B); 2450 } else { 2451 emit_opcode(cbuf, Assembler::REX_XB); 2452 } 2453 } 2454 } else { 2455 if ($mem$$base < 8) { 2456 if ($mem$$index < 8) { 2457 emit_opcode(cbuf, Assembler::REX_R); 2458 } else { 2459 emit_opcode(cbuf, Assembler::REX_RX); 2460 } 2461 } else { 2462 if ($mem$$index < 8) { 2463 emit_opcode(cbuf, Assembler::REX_RB); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_RXB); 2466 } 2467 } 2468 } 2469 %} 2470 2471 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2472 %{ 2473 if ($reg$$reg < 8) { 2474 if ($mem$$base < 8) { 2475 if ($mem$$index < 8) { 2476 emit_opcode(cbuf, Assembler::REX_W); 2477 } else { 2478 emit_opcode(cbuf, Assembler::REX_WX); 2479 } 2480 } else { 2481 if ($mem$$index < 8) { 2482 emit_opcode(cbuf, Assembler::REX_WB); 2483 } else { 2484 emit_opcode(cbuf, Assembler::REX_WXB); 2485 } 2486 } 2487 } else { 2488 if ($mem$$base < 8) { 2489 if ($mem$$index < 8) { 2490 emit_opcode(cbuf, Assembler::REX_WR); 2491 } else { 2492 emit_opcode(cbuf, Assembler::REX_WRX); 2493 } 2494 } else { 2495 if ($mem$$index < 8) { 2496 emit_opcode(cbuf, Assembler::REX_WRB); 2497 } else { 2498 emit_opcode(cbuf, Assembler::REX_WRXB); 2499 } 2500 } 2501 } 2502 %} 2503 2504 enc_class reg_mem(rRegI ereg, memory mem) 2505 %{ 2506 // High registers handle in encode_RegMem 2507 int reg = $ereg$$reg; 2508 int base = $mem$$base; 2509 int index = $mem$$index; 2510 int scale = $mem$$scale; 2511 int disp = $mem$$disp; 2512 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2513 2514 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2515 %} 2516 2517 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2518 %{ 2519 int rm_byte_opcode = $rm_opcode$$constant; 2520 2521 // High registers handle in encode_RegMem 2522 int base = $mem$$base; 2523 int index = $mem$$index; 2524 int scale = $mem$$scale; 2525 int displace = $mem$$disp; 2526 2527 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2528 // working with static 2529 // globals 2530 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2531 disp_reloc); 2532 %} 2533 2534 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2535 %{ 2536 int reg_encoding = $dst$$reg; 2537 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2538 int index = 0x04; // 0x04 indicates no index 2539 int scale = 0x00; // 0x00 indicates no scale 2540 int displace = $src1$$constant; // 0x00 indicates no displacement 2541 relocInfo::relocType disp_reloc = relocInfo::none; 2542 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2543 disp_reloc); 2544 %} 2545 2546 enc_class neg_reg(rRegI dst) 2547 %{ 2548 int dstenc = $dst$$reg; 2549 if (dstenc >= 8) { 2550 emit_opcode(cbuf, Assembler::REX_B); 2551 dstenc -= 8; 2552 } 2553 // NEG $dst 2554 emit_opcode(cbuf, 0xF7); 2555 emit_rm(cbuf, 0x3, 0x03, dstenc); 2556 %} 2557 2558 enc_class neg_reg_wide(rRegI dst) 2559 %{ 2560 int dstenc = $dst$$reg; 2561 if (dstenc < 8) { 2562 emit_opcode(cbuf, Assembler::REX_W); 2563 } else { 2564 emit_opcode(cbuf, Assembler::REX_WB); 2565 dstenc -= 8; 2566 } 2567 // NEG $dst 2568 emit_opcode(cbuf, 0xF7); 2569 emit_rm(cbuf, 0x3, 0x03, dstenc); 2570 %} 2571 2572 enc_class setLT_reg(rRegI dst) 2573 %{ 2574 int dstenc = $dst$$reg; 2575 if (dstenc >= 8) { 2576 emit_opcode(cbuf, Assembler::REX_B); 2577 dstenc -= 8; 2578 } else if (dstenc >= 4) { 2579 emit_opcode(cbuf, Assembler::REX); 2580 } 2581 // SETLT $dst 2582 emit_opcode(cbuf, 0x0F); 2583 emit_opcode(cbuf, 0x9C); 2584 emit_rm(cbuf, 0x3, 0x0, dstenc); 2585 %} 2586 2587 enc_class setNZ_reg(rRegI dst) 2588 %{ 2589 int dstenc = $dst$$reg; 2590 if (dstenc >= 8) { 2591 emit_opcode(cbuf, Assembler::REX_B); 2592 dstenc -= 8; 2593 } else if (dstenc >= 4) { 2594 emit_opcode(cbuf, Assembler::REX); 2595 } 2596 // SETNZ $dst 2597 emit_opcode(cbuf, 0x0F); 2598 emit_opcode(cbuf, 0x95); 2599 emit_rm(cbuf, 0x3, 0x0, dstenc); 2600 %} 2601 2602 2603 // Compare the lonogs and set -1, 0, or 1 into dst 2604 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2605 %{ 2606 int src1enc = $src1$$reg; 2607 int src2enc = $src2$$reg; 2608 int dstenc = $dst$$reg; 2609 2610 // cmpq $src1, $src2 2611 if (src1enc < 8) { 2612 if (src2enc < 8) { 2613 emit_opcode(cbuf, Assembler::REX_W); 2614 } else { 2615 emit_opcode(cbuf, Assembler::REX_WB); 2616 } 2617 } else { 2618 if (src2enc < 8) { 2619 emit_opcode(cbuf, Assembler::REX_WR); 2620 } else { 2621 emit_opcode(cbuf, Assembler::REX_WRB); 2622 } 2623 } 2624 emit_opcode(cbuf, 0x3B); 2625 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2626 2627 // movl $dst, -1 2628 if (dstenc >= 8) { 2629 emit_opcode(cbuf, Assembler::REX_B); 2630 } 2631 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2632 emit_d32(cbuf, -1); 2633 2634 // jl,s done 2635 emit_opcode(cbuf, 0x7C); 2636 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2637 2638 // setne $dst 2639 if (dstenc >= 4) { 2640 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2641 } 2642 emit_opcode(cbuf, 0x0F); 2643 emit_opcode(cbuf, 0x95); 2644 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2645 2646 // movzbl $dst, $dst 2647 if (dstenc >= 4) { 2648 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2649 } 2650 emit_opcode(cbuf, 0x0F); 2651 emit_opcode(cbuf, 0xB6); 2652 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2653 %} 2654 2655 enc_class Push_ResultXD(regD dst) %{ 2656 MacroAssembler _masm(&cbuf); 2657 __ fstp_d(Address(rsp, 0)); 2658 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2659 __ addptr(rsp, 8); 2660 %} 2661 2662 enc_class Push_SrcXD(regD src) %{ 2663 MacroAssembler _masm(&cbuf); 2664 __ subptr(rsp, 8); 2665 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2666 __ fld_d(Address(rsp, 0)); 2667 %} 2668 2669 2670 enc_class enc_rethrow() 2671 %{ 2672 cbuf.set_insts_mark(); 2673 emit_opcode(cbuf, 0xE9); // jmp entry 2674 emit_d32_reloc(cbuf, 2675 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2676 runtime_call_Relocation::spec(), 2677 RELOC_DISP32); 2678 %} 2679 2680 %} 2681 2682 2683 2684 //----------FRAME-------------------------------------------------------------- 2685 // Definition of frame structure and management information. 2686 // 2687 // S T A C K L A Y O U T Allocators stack-slot number 2688 // | (to get allocators register number 2689 // G Owned by | | v add OptoReg::stack0()) 2690 // r CALLER | | 2691 // o | +--------+ pad to even-align allocators stack-slot 2692 // w V | pad0 | numbers; owned by CALLER 2693 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2694 // h ^ | in | 5 2695 // | | args | 4 Holes in incoming args owned by SELF 2696 // | | | | 3 2697 // | | +--------+ 2698 // V | | old out| Empty on Intel, window on Sparc 2699 // | old |preserve| Must be even aligned. 2700 // | SP-+--------+----> Matcher::_old_SP, even aligned 2701 // | | in | 3 area for Intel ret address 2702 // Owned by |preserve| Empty on Sparc. 2703 // SELF +--------+ 2704 // | | pad2 | 2 pad to align old SP 2705 // | +--------+ 1 2706 // | | locks | 0 2707 // | +--------+----> OptoReg::stack0(), even aligned 2708 // | | pad1 | 11 pad to align new SP 2709 // | +--------+ 2710 // | | | 10 2711 // | | spills | 9 spills 2712 // V | | 8 (pad0 slot for callee) 2713 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2714 // ^ | out | 7 2715 // | | args | 6 Holes in outgoing args owned by CALLEE 2716 // Owned by +--------+ 2717 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2718 // | new |preserve| Must be even-aligned. 2719 // | SP-+--------+----> Matcher::_new_SP, even aligned 2720 // | | | 2721 // 2722 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2723 // known from SELF's arguments and the Java calling convention. 2724 // Region 6-7 is determined per call site. 2725 // Note 2: If the calling convention leaves holes in the incoming argument 2726 // area, those holes are owned by SELF. Holes in the outgoing area 2727 // are owned by the CALLEE. Holes should not be nessecary in the 2728 // incoming area, as the Java calling convention is completely under 2729 // the control of the AD file. Doubles can be sorted and packed to 2730 // avoid holes. Holes in the outgoing arguments may be nessecary for 2731 // varargs C calling conventions. 2732 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2733 // even aligned with pad0 as needed. 2734 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2735 // region 6-11 is even aligned; it may be padded out more so that 2736 // the region from SP to FP meets the minimum stack alignment. 2737 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2738 // alignment. Region 11, pad1, may be dynamically extended so that 2739 // SP meets the minimum alignment. 2740 2741 frame 2742 %{ 2743 // What direction does stack grow in (assumed to be same for C & Java) 2744 stack_direction(TOWARDS_LOW); 2745 2746 // These three registers define part of the calling convention 2747 // between compiled code and the interpreter. 2748 inline_cache_reg(RAX); // Inline Cache Register 2749 interpreter_method_oop_reg(RBX); // Method Oop Register when 2750 // calling interpreter 2751 2752 // Optional: name the operand used by cisc-spilling to access 2753 // [stack_pointer + offset] 2754 cisc_spilling_operand_name(indOffset32); 2755 2756 // Number of stack slots consumed by locking an object 2757 sync_stack_slots(2); 2758 2759 // Compiled code's Frame Pointer 2760 frame_pointer(RSP); 2761 2762 // Interpreter stores its frame pointer in a register which is 2763 // stored to the stack by I2CAdaptors. 2764 // I2CAdaptors convert from interpreted java to compiled java. 2765 interpreter_frame_pointer(RBP); 2766 2767 // Stack alignment requirement 2768 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2769 2770 // Number of stack slots between incoming argument block and the start of 2771 // a new frame. The PROLOG must add this many slots to the stack. The 2772 // EPILOG must remove this many slots. amd64 needs two slots for 2773 // return address. 2774 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2775 2776 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2777 // for calls to C. Supports the var-args backing area for register parms. 2778 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2779 2780 // The after-PROLOG location of the return address. Location of 2781 // return address specifies a type (REG or STACK) and a number 2782 // representing the register number (i.e. - use a register name) or 2783 // stack slot. 2784 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2785 // Otherwise, it is above the locks and verification slot and alignment word 2786 return_addr(STACK - 2 + 2787 align_up((Compile::current()->in_preserve_stack_slots() + 2788 Compile::current()->fixed_slots()), 2789 stack_alignment_in_slots())); 2790 2791 // Body of function which returns an integer array locating 2792 // arguments either in registers or in stack slots. Passed an array 2793 // of ideal registers called "sig" and a "length" count. Stack-slot 2794 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2795 // arguments for a CALLEE. Incoming stack arguments are 2796 // automatically biased by the preserve_stack_slots field above. 2797 2798 calling_convention 2799 %{ 2800 // No difference between ingoing/outgoing just pass false 2801 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2802 %} 2803 2804 c_calling_convention 2805 %{ 2806 // This is obviously always outgoing 2807 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2808 %} 2809 2810 // Location of compiled Java return values. Same as C for now. 2811 return_value 2812 %{ 2813 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2814 "only return normal values"); 2815 2816 static const int lo[Op_RegL + 1] = { 2817 0, 2818 0, 2819 RAX_num, // Op_RegN 2820 RAX_num, // Op_RegI 2821 RAX_num, // Op_RegP 2822 XMM0_num, // Op_RegF 2823 XMM0_num, // Op_RegD 2824 RAX_num // Op_RegL 2825 }; 2826 static const int hi[Op_RegL + 1] = { 2827 0, 2828 0, 2829 OptoReg::Bad, // Op_RegN 2830 OptoReg::Bad, // Op_RegI 2831 RAX_H_num, // Op_RegP 2832 OptoReg::Bad, // Op_RegF 2833 XMM0b_num, // Op_RegD 2834 RAX_H_num // Op_RegL 2835 }; 2836 // Excluded flags and vector registers. 2837 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2838 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2839 %} 2840 %} 2841 2842 //----------ATTRIBUTES--------------------------------------------------------- 2843 //----------Operand Attributes------------------------------------------------- 2844 op_attrib op_cost(0); // Required cost attribute 2845 2846 //----------Instruction Attributes--------------------------------------------- 2847 ins_attrib ins_cost(100); // Required cost attribute 2848 ins_attrib ins_size(8); // Required size attribute (in bits) 2849 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2850 // a non-matching short branch variant 2851 // of some long branch? 2852 ins_attrib ins_alignment(1); // Required alignment attribute (must 2853 // be a power of 2) specifies the 2854 // alignment that some part of the 2855 // instruction (not necessarily the 2856 // start) requires. If > 1, a 2857 // compute_padding() function must be 2858 // provided for the instruction 2859 2860 //----------OPERANDS----------------------------------------------------------- 2861 // Operand definitions must precede instruction definitions for correct parsing 2862 // in the ADLC because operands constitute user defined types which are used in 2863 // instruction definitions. 2864 2865 //----------Simple Operands---------------------------------------------------- 2866 // Immediate Operands 2867 // Integer Immediate 2868 operand immI() 2869 %{ 2870 match(ConI); 2871 2872 op_cost(10); 2873 format %{ %} 2874 interface(CONST_INTER); 2875 %} 2876 2877 // Constant for test vs zero 2878 operand immI0() 2879 %{ 2880 predicate(n->get_int() == 0); 2881 match(ConI); 2882 2883 op_cost(0); 2884 format %{ %} 2885 interface(CONST_INTER); 2886 %} 2887 2888 // Constant for increment 2889 operand immI1() 2890 %{ 2891 predicate(n->get_int() == 1); 2892 match(ConI); 2893 2894 op_cost(0); 2895 format %{ %} 2896 interface(CONST_INTER); 2897 %} 2898 2899 // Constant for decrement 2900 operand immI_M1() 2901 %{ 2902 predicate(n->get_int() == -1); 2903 match(ConI); 2904 2905 op_cost(0); 2906 format %{ %} 2907 interface(CONST_INTER); 2908 %} 2909 2910 // Valid scale values for addressing modes 2911 operand immI2() 2912 %{ 2913 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2914 match(ConI); 2915 2916 format %{ %} 2917 interface(CONST_INTER); 2918 %} 2919 2920 operand immI8() 2921 %{ 2922 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2923 match(ConI); 2924 2925 op_cost(5); 2926 format %{ %} 2927 interface(CONST_INTER); 2928 %} 2929 2930 operand immU8() 2931 %{ 2932 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2933 match(ConI); 2934 2935 op_cost(5); 2936 format %{ %} 2937 interface(CONST_INTER); 2938 %} 2939 2940 operand immI16() 2941 %{ 2942 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2943 match(ConI); 2944 2945 op_cost(10); 2946 format %{ %} 2947 interface(CONST_INTER); 2948 %} 2949 2950 // Int Immediate non-negative 2951 operand immU31() 2952 %{ 2953 predicate(n->get_int() >= 0); 2954 match(ConI); 2955 2956 op_cost(0); 2957 format %{ %} 2958 interface(CONST_INTER); 2959 %} 2960 2961 // Constant for long shifts 2962 operand immI_32() 2963 %{ 2964 predicate( n->get_int() == 32 ); 2965 match(ConI); 2966 2967 op_cost(0); 2968 format %{ %} 2969 interface(CONST_INTER); 2970 %} 2971 2972 // Constant for long shifts 2973 operand immI_64() 2974 %{ 2975 predicate( n->get_int() == 64 ); 2976 match(ConI); 2977 2978 op_cost(0); 2979 format %{ %} 2980 interface(CONST_INTER); 2981 %} 2982 2983 // Pointer Immediate 2984 operand immP() 2985 %{ 2986 match(ConP); 2987 2988 op_cost(10); 2989 format %{ %} 2990 interface(CONST_INTER); 2991 %} 2992 2993 // NULL Pointer Immediate 2994 operand immP0() 2995 %{ 2996 predicate(n->get_ptr() == 0); 2997 match(ConP); 2998 2999 op_cost(5); 3000 format %{ %} 3001 interface(CONST_INTER); 3002 %} 3003 3004 // Pointer Immediate 3005 operand immN() %{ 3006 match(ConN); 3007 3008 op_cost(10); 3009 format %{ %} 3010 interface(CONST_INTER); 3011 %} 3012 3013 operand immNKlass() %{ 3014 match(ConNKlass); 3015 3016 op_cost(10); 3017 format %{ %} 3018 interface(CONST_INTER); 3019 %} 3020 3021 // NULL Pointer Immediate 3022 operand immN0() %{ 3023 predicate(n->get_narrowcon() == 0); 3024 match(ConN); 3025 3026 op_cost(5); 3027 format %{ %} 3028 interface(CONST_INTER); 3029 %} 3030 3031 operand immP31() 3032 %{ 3033 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3034 && (n->get_ptr() >> 31) == 0); 3035 match(ConP); 3036 3037 op_cost(5); 3038 format %{ %} 3039 interface(CONST_INTER); 3040 %} 3041 3042 3043 // Long Immediate 3044 operand immL() 3045 %{ 3046 match(ConL); 3047 3048 op_cost(20); 3049 format %{ %} 3050 interface(CONST_INTER); 3051 %} 3052 3053 // Long Immediate 8-bit 3054 operand immL8() 3055 %{ 3056 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3057 match(ConL); 3058 3059 op_cost(5); 3060 format %{ %} 3061 interface(CONST_INTER); 3062 %} 3063 3064 // Long Immediate 32-bit unsigned 3065 operand immUL32() 3066 %{ 3067 predicate(n->get_long() == (unsigned int) (n->get_long())); 3068 match(ConL); 3069 3070 op_cost(10); 3071 format %{ %} 3072 interface(CONST_INTER); 3073 %} 3074 3075 // Long Immediate 32-bit signed 3076 operand immL32() 3077 %{ 3078 predicate(n->get_long() == (int) (n->get_long())); 3079 match(ConL); 3080 3081 op_cost(15); 3082 format %{ %} 3083 interface(CONST_INTER); 3084 %} 3085 3086 operand immL_Pow2() 3087 %{ 3088 predicate(is_power_of_2((julong)n->get_long())); 3089 match(ConL); 3090 3091 op_cost(15); 3092 format %{ %} 3093 interface(CONST_INTER); 3094 %} 3095 3096 operand immL_NotPow2() 3097 %{ 3098 predicate(is_power_of_2((julong)~n->get_long())); 3099 match(ConL); 3100 3101 op_cost(15); 3102 format %{ %} 3103 interface(CONST_INTER); 3104 %} 3105 3106 // Long Immediate zero 3107 operand immL0() 3108 %{ 3109 predicate(n->get_long() == 0L); 3110 match(ConL); 3111 3112 op_cost(10); 3113 format %{ %} 3114 interface(CONST_INTER); 3115 %} 3116 3117 // Constant for increment 3118 operand immL1() 3119 %{ 3120 predicate(n->get_long() == 1); 3121 match(ConL); 3122 3123 format %{ %} 3124 interface(CONST_INTER); 3125 %} 3126 3127 // Constant for decrement 3128 operand immL_M1() 3129 %{ 3130 predicate(n->get_long() == -1); 3131 match(ConL); 3132 3133 format %{ %} 3134 interface(CONST_INTER); 3135 %} 3136 3137 // Long Immediate: the value 10 3138 operand immL10() 3139 %{ 3140 predicate(n->get_long() == 10); 3141 match(ConL); 3142 3143 format %{ %} 3144 interface(CONST_INTER); 3145 %} 3146 3147 // Long immediate from 0 to 127. 3148 // Used for a shorter form of long mul by 10. 3149 operand immL_127() 3150 %{ 3151 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3152 match(ConL); 3153 3154 op_cost(10); 3155 format %{ %} 3156 interface(CONST_INTER); 3157 %} 3158 3159 // Long Immediate: low 32-bit mask 3160 operand immL_32bits() 3161 %{ 3162 predicate(n->get_long() == 0xFFFFFFFFL); 3163 match(ConL); 3164 op_cost(20); 3165 3166 format %{ %} 3167 interface(CONST_INTER); 3168 %} 3169 3170 // Float Immediate zero 3171 operand immF0() 3172 %{ 3173 predicate(jint_cast(n->getf()) == 0); 3174 match(ConF); 3175 3176 op_cost(5); 3177 format %{ %} 3178 interface(CONST_INTER); 3179 %} 3180 3181 // Float Immediate 3182 operand immF() 3183 %{ 3184 match(ConF); 3185 3186 op_cost(15); 3187 format %{ %} 3188 interface(CONST_INTER); 3189 %} 3190 3191 // Double Immediate zero 3192 operand immD0() 3193 %{ 3194 predicate(jlong_cast(n->getd()) == 0); 3195 match(ConD); 3196 3197 op_cost(5); 3198 format %{ %} 3199 interface(CONST_INTER); 3200 %} 3201 3202 // Double Immediate 3203 operand immD() 3204 %{ 3205 match(ConD); 3206 3207 op_cost(15); 3208 format %{ %} 3209 interface(CONST_INTER); 3210 %} 3211 3212 // Immediates for special shifts (sign extend) 3213 3214 // Constants for increment 3215 operand immI_16() 3216 %{ 3217 predicate(n->get_int() == 16); 3218 match(ConI); 3219 3220 format %{ %} 3221 interface(CONST_INTER); 3222 %} 3223 3224 operand immI_24() 3225 %{ 3226 predicate(n->get_int() == 24); 3227 match(ConI); 3228 3229 format %{ %} 3230 interface(CONST_INTER); 3231 %} 3232 3233 // Constant for byte-wide masking 3234 operand immI_255() 3235 %{ 3236 predicate(n->get_int() == 255); 3237 match(ConI); 3238 3239 format %{ %} 3240 interface(CONST_INTER); 3241 %} 3242 3243 // Constant for short-wide masking 3244 operand immI_65535() 3245 %{ 3246 predicate(n->get_int() == 65535); 3247 match(ConI); 3248 3249 format %{ %} 3250 interface(CONST_INTER); 3251 %} 3252 3253 // Constant for byte-wide masking 3254 operand immL_255() 3255 %{ 3256 predicate(n->get_long() == 255); 3257 match(ConL); 3258 3259 format %{ %} 3260 interface(CONST_INTER); 3261 %} 3262 3263 // Constant for short-wide masking 3264 operand immL_65535() 3265 %{ 3266 predicate(n->get_long() == 65535); 3267 match(ConL); 3268 3269 format %{ %} 3270 interface(CONST_INTER); 3271 %} 3272 3273 // Register Operands 3274 // Integer Register 3275 operand rRegI() 3276 %{ 3277 constraint(ALLOC_IN_RC(int_reg)); 3278 match(RegI); 3279 3280 match(rax_RegI); 3281 match(rbx_RegI); 3282 match(rcx_RegI); 3283 match(rdx_RegI); 3284 match(rdi_RegI); 3285 3286 format %{ %} 3287 interface(REG_INTER); 3288 %} 3289 3290 // Special Registers 3291 operand rax_RegI() 3292 %{ 3293 constraint(ALLOC_IN_RC(int_rax_reg)); 3294 match(RegI); 3295 match(rRegI); 3296 3297 format %{ "RAX" %} 3298 interface(REG_INTER); 3299 %} 3300 3301 // Special Registers 3302 operand rbx_RegI() 3303 %{ 3304 constraint(ALLOC_IN_RC(int_rbx_reg)); 3305 match(RegI); 3306 match(rRegI); 3307 3308 format %{ "RBX" %} 3309 interface(REG_INTER); 3310 %} 3311 3312 operand rcx_RegI() 3313 %{ 3314 constraint(ALLOC_IN_RC(int_rcx_reg)); 3315 match(RegI); 3316 match(rRegI); 3317 3318 format %{ "RCX" %} 3319 interface(REG_INTER); 3320 %} 3321 3322 operand rdx_RegI() 3323 %{ 3324 constraint(ALLOC_IN_RC(int_rdx_reg)); 3325 match(RegI); 3326 match(rRegI); 3327 3328 format %{ "RDX" %} 3329 interface(REG_INTER); 3330 %} 3331 3332 operand rdi_RegI() 3333 %{ 3334 constraint(ALLOC_IN_RC(int_rdi_reg)); 3335 match(RegI); 3336 match(rRegI); 3337 3338 format %{ "RDI" %} 3339 interface(REG_INTER); 3340 %} 3341 3342 operand no_rcx_RegI() 3343 %{ 3344 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3345 match(RegI); 3346 match(rax_RegI); 3347 match(rbx_RegI); 3348 match(rdx_RegI); 3349 match(rdi_RegI); 3350 3351 format %{ %} 3352 interface(REG_INTER); 3353 %} 3354 3355 operand no_rax_rdx_RegI() 3356 %{ 3357 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3358 match(RegI); 3359 match(rbx_RegI); 3360 match(rcx_RegI); 3361 match(rdi_RegI); 3362 3363 format %{ %} 3364 interface(REG_INTER); 3365 %} 3366 3367 // Pointer Register 3368 operand any_RegP() 3369 %{ 3370 constraint(ALLOC_IN_RC(any_reg)); 3371 match(RegP); 3372 match(rax_RegP); 3373 match(rbx_RegP); 3374 match(rdi_RegP); 3375 match(rsi_RegP); 3376 match(rbp_RegP); 3377 match(r15_RegP); 3378 match(rRegP); 3379 3380 format %{ %} 3381 interface(REG_INTER); 3382 %} 3383 3384 operand rRegP() 3385 %{ 3386 constraint(ALLOC_IN_RC(ptr_reg)); 3387 match(RegP); 3388 match(rax_RegP); 3389 match(rbx_RegP); 3390 match(rdi_RegP); 3391 match(rsi_RegP); 3392 match(rbp_RegP); // See Q&A below about 3393 match(r15_RegP); // r15_RegP and rbp_RegP. 3394 3395 format %{ %} 3396 interface(REG_INTER); 3397 %} 3398 3399 operand rRegN() %{ 3400 constraint(ALLOC_IN_RC(int_reg)); 3401 match(RegN); 3402 3403 format %{ %} 3404 interface(REG_INTER); 3405 %} 3406 3407 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3408 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3409 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3410 // The output of an instruction is controlled by the allocator, which respects 3411 // register class masks, not match rules. Unless an instruction mentions 3412 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3413 // by the allocator as an input. 3414 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3415 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3416 // result, RBP is not included in the output of the instruction either. 3417 3418 operand no_rax_RegP() 3419 %{ 3420 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3421 match(RegP); 3422 match(rbx_RegP); 3423 match(rsi_RegP); 3424 match(rdi_RegP); 3425 3426 format %{ %} 3427 interface(REG_INTER); 3428 %} 3429 3430 // This operand is not allowed to use RBP even if 3431 // RBP is not used to hold the frame pointer. 3432 operand no_rbp_RegP() 3433 %{ 3434 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3435 match(RegP); 3436 match(rbx_RegP); 3437 match(rsi_RegP); 3438 match(rdi_RegP); 3439 3440 format %{ %} 3441 interface(REG_INTER); 3442 %} 3443 3444 operand no_rax_rbx_RegP() 3445 %{ 3446 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3447 match(RegP); 3448 match(rsi_RegP); 3449 match(rdi_RegP); 3450 3451 format %{ %} 3452 interface(REG_INTER); 3453 %} 3454 3455 // Special Registers 3456 // Return a pointer value 3457 operand rax_RegP() 3458 %{ 3459 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3460 match(RegP); 3461 match(rRegP); 3462 3463 format %{ %} 3464 interface(REG_INTER); 3465 %} 3466 3467 // Special Registers 3468 // Return a compressed pointer value 3469 operand rax_RegN() 3470 %{ 3471 constraint(ALLOC_IN_RC(int_rax_reg)); 3472 match(RegN); 3473 match(rRegN); 3474 3475 format %{ %} 3476 interface(REG_INTER); 3477 %} 3478 3479 // Used in AtomicAdd 3480 operand rbx_RegP() 3481 %{ 3482 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3483 match(RegP); 3484 match(rRegP); 3485 3486 format %{ %} 3487 interface(REG_INTER); 3488 %} 3489 3490 operand rsi_RegP() 3491 %{ 3492 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3493 match(RegP); 3494 match(rRegP); 3495 3496 format %{ %} 3497 interface(REG_INTER); 3498 %} 3499 3500 operand rbp_RegP() 3501 %{ 3502 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3503 match(RegP); 3504 match(rRegP); 3505 3506 format %{ %} 3507 interface(REG_INTER); 3508 %} 3509 3510 // Used in rep stosq 3511 operand rdi_RegP() 3512 %{ 3513 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3514 match(RegP); 3515 match(rRegP); 3516 3517 format %{ %} 3518 interface(REG_INTER); 3519 %} 3520 3521 operand r15_RegP() 3522 %{ 3523 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3524 match(RegP); 3525 match(rRegP); 3526 3527 format %{ %} 3528 interface(REG_INTER); 3529 %} 3530 3531 operand rRegL() 3532 %{ 3533 constraint(ALLOC_IN_RC(long_reg)); 3534 match(RegL); 3535 match(rax_RegL); 3536 match(rdx_RegL); 3537 3538 format %{ %} 3539 interface(REG_INTER); 3540 %} 3541 3542 // Special Registers 3543 operand no_rax_rdx_RegL() 3544 %{ 3545 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3546 match(RegL); 3547 match(rRegL); 3548 3549 format %{ %} 3550 interface(REG_INTER); 3551 %} 3552 3553 operand no_rax_RegL() 3554 %{ 3555 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3556 match(RegL); 3557 match(rRegL); 3558 match(rdx_RegL); 3559 3560 format %{ %} 3561 interface(REG_INTER); 3562 %} 3563 3564 operand no_rcx_RegL() 3565 %{ 3566 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3567 match(RegL); 3568 match(rRegL); 3569 3570 format %{ %} 3571 interface(REG_INTER); 3572 %} 3573 3574 operand rax_RegL() 3575 %{ 3576 constraint(ALLOC_IN_RC(long_rax_reg)); 3577 match(RegL); 3578 match(rRegL); 3579 3580 format %{ "RAX" %} 3581 interface(REG_INTER); 3582 %} 3583 3584 operand rcx_RegL() 3585 %{ 3586 constraint(ALLOC_IN_RC(long_rcx_reg)); 3587 match(RegL); 3588 match(rRegL); 3589 3590 format %{ %} 3591 interface(REG_INTER); 3592 %} 3593 3594 operand rdx_RegL() 3595 %{ 3596 constraint(ALLOC_IN_RC(long_rdx_reg)); 3597 match(RegL); 3598 match(rRegL); 3599 3600 format %{ %} 3601 interface(REG_INTER); 3602 %} 3603 3604 // Flags register, used as output of compare instructions 3605 operand rFlagsReg() 3606 %{ 3607 constraint(ALLOC_IN_RC(int_flags)); 3608 match(RegFlags); 3609 3610 format %{ "RFLAGS" %} 3611 interface(REG_INTER); 3612 %} 3613 3614 // Flags register, used as output of FLOATING POINT compare instructions 3615 operand rFlagsRegU() 3616 %{ 3617 constraint(ALLOC_IN_RC(int_flags)); 3618 match(RegFlags); 3619 3620 format %{ "RFLAGS_U" %} 3621 interface(REG_INTER); 3622 %} 3623 3624 operand rFlagsRegUCF() %{ 3625 constraint(ALLOC_IN_RC(int_flags)); 3626 match(RegFlags); 3627 predicate(false); 3628 3629 format %{ "RFLAGS_U_CF" %} 3630 interface(REG_INTER); 3631 %} 3632 3633 // Float register operands 3634 operand regF() %{ 3635 constraint(ALLOC_IN_RC(float_reg)); 3636 match(RegF); 3637 3638 format %{ %} 3639 interface(REG_INTER); 3640 %} 3641 3642 // Float register operands 3643 operand legRegF() %{ 3644 constraint(ALLOC_IN_RC(float_reg_legacy)); 3645 match(RegF); 3646 3647 format %{ %} 3648 interface(REG_INTER); 3649 %} 3650 3651 // Float register operands 3652 operand vlRegF() %{ 3653 constraint(ALLOC_IN_RC(float_reg_vl)); 3654 match(RegF); 3655 3656 format %{ %} 3657 interface(REG_INTER); 3658 %} 3659 3660 // Double register operands 3661 operand regD() %{ 3662 constraint(ALLOC_IN_RC(double_reg)); 3663 match(RegD); 3664 3665 format %{ %} 3666 interface(REG_INTER); 3667 %} 3668 3669 // Double register operands 3670 operand legRegD() %{ 3671 constraint(ALLOC_IN_RC(double_reg_legacy)); 3672 match(RegD); 3673 3674 format %{ %} 3675 interface(REG_INTER); 3676 %} 3677 3678 // Double register operands 3679 operand vlRegD() %{ 3680 constraint(ALLOC_IN_RC(double_reg_vl)); 3681 match(RegD); 3682 3683 format %{ %} 3684 interface(REG_INTER); 3685 %} 3686 3687 //----------Memory Operands---------------------------------------------------- 3688 // Direct Memory Operand 3689 // operand direct(immP addr) 3690 // %{ 3691 // match(addr); 3692 3693 // format %{ "[$addr]" %} 3694 // interface(MEMORY_INTER) %{ 3695 // base(0xFFFFFFFF); 3696 // index(0x4); 3697 // scale(0x0); 3698 // disp($addr); 3699 // %} 3700 // %} 3701 3702 // Indirect Memory Operand 3703 operand indirect(any_RegP reg) 3704 %{ 3705 constraint(ALLOC_IN_RC(ptr_reg)); 3706 match(reg); 3707 3708 format %{ "[$reg]" %} 3709 interface(MEMORY_INTER) %{ 3710 base($reg); 3711 index(0x4); 3712 scale(0x0); 3713 disp(0x0); 3714 %} 3715 %} 3716 3717 // Indirect Memory Plus Short Offset Operand 3718 operand indOffset8(any_RegP reg, immL8 off) 3719 %{ 3720 constraint(ALLOC_IN_RC(ptr_reg)); 3721 match(AddP reg off); 3722 3723 format %{ "[$reg + $off (8-bit)]" %} 3724 interface(MEMORY_INTER) %{ 3725 base($reg); 3726 index(0x4); 3727 scale(0x0); 3728 disp($off); 3729 %} 3730 %} 3731 3732 // Indirect Memory Plus Long Offset Operand 3733 operand indOffset32(any_RegP reg, immL32 off) 3734 %{ 3735 constraint(ALLOC_IN_RC(ptr_reg)); 3736 match(AddP reg off); 3737 3738 format %{ "[$reg + $off (32-bit)]" %} 3739 interface(MEMORY_INTER) %{ 3740 base($reg); 3741 index(0x4); 3742 scale(0x0); 3743 disp($off); 3744 %} 3745 %} 3746 3747 // Indirect Memory Plus Index Register Plus Offset Operand 3748 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3749 %{ 3750 constraint(ALLOC_IN_RC(ptr_reg)); 3751 match(AddP (AddP reg lreg) off); 3752 3753 op_cost(10); 3754 format %{"[$reg + $off + $lreg]" %} 3755 interface(MEMORY_INTER) %{ 3756 base($reg); 3757 index($lreg); 3758 scale(0x0); 3759 disp($off); 3760 %} 3761 %} 3762 3763 // Indirect Memory Plus Index Register Plus Offset Operand 3764 operand indIndex(any_RegP reg, rRegL lreg) 3765 %{ 3766 constraint(ALLOC_IN_RC(ptr_reg)); 3767 match(AddP reg lreg); 3768 3769 op_cost(10); 3770 format %{"[$reg + $lreg]" %} 3771 interface(MEMORY_INTER) %{ 3772 base($reg); 3773 index($lreg); 3774 scale(0x0); 3775 disp(0x0); 3776 %} 3777 %} 3778 3779 // Indirect Memory Times Scale Plus Index Register 3780 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3781 %{ 3782 constraint(ALLOC_IN_RC(ptr_reg)); 3783 match(AddP reg (LShiftL lreg scale)); 3784 3785 op_cost(10); 3786 format %{"[$reg + $lreg << $scale]" %} 3787 interface(MEMORY_INTER) %{ 3788 base($reg); 3789 index($lreg); 3790 scale($scale); 3791 disp(0x0); 3792 %} 3793 %} 3794 3795 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3796 %{ 3797 constraint(ALLOC_IN_RC(ptr_reg)); 3798 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3799 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3800 3801 op_cost(10); 3802 format %{"[$reg + pos $idx << $scale]" %} 3803 interface(MEMORY_INTER) %{ 3804 base($reg); 3805 index($idx); 3806 scale($scale); 3807 disp(0x0); 3808 %} 3809 %} 3810 3811 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3812 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3813 %{ 3814 constraint(ALLOC_IN_RC(ptr_reg)); 3815 match(AddP (AddP reg (LShiftL lreg scale)) off); 3816 3817 op_cost(10); 3818 format %{"[$reg + $off + $lreg << $scale]" %} 3819 interface(MEMORY_INTER) %{ 3820 base($reg); 3821 index($lreg); 3822 scale($scale); 3823 disp($off); 3824 %} 3825 %} 3826 3827 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3828 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3829 %{ 3830 constraint(ALLOC_IN_RC(ptr_reg)); 3831 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3832 match(AddP (AddP reg (ConvI2L idx)) off); 3833 3834 op_cost(10); 3835 format %{"[$reg + $off + $idx]" %} 3836 interface(MEMORY_INTER) %{ 3837 base($reg); 3838 index($idx); 3839 scale(0x0); 3840 disp($off); 3841 %} 3842 %} 3843 3844 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3845 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3846 %{ 3847 constraint(ALLOC_IN_RC(ptr_reg)); 3848 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3849 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3850 3851 op_cost(10); 3852 format %{"[$reg + $off + $idx << $scale]" %} 3853 interface(MEMORY_INTER) %{ 3854 base($reg); 3855 index($idx); 3856 scale($scale); 3857 disp($off); 3858 %} 3859 %} 3860 3861 // Indirect Narrow Oop Plus Offset Operand 3862 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3863 // we can't free r12 even with CompressedOops::base() == NULL. 3864 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3865 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3866 constraint(ALLOC_IN_RC(ptr_reg)); 3867 match(AddP (DecodeN reg) off); 3868 3869 op_cost(10); 3870 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3871 interface(MEMORY_INTER) %{ 3872 base(0xc); // R12 3873 index($reg); 3874 scale(0x3); 3875 disp($off); 3876 %} 3877 %} 3878 3879 // Indirect Memory Operand 3880 operand indirectNarrow(rRegN reg) 3881 %{ 3882 predicate(CompressedOops::shift() == 0); 3883 constraint(ALLOC_IN_RC(ptr_reg)); 3884 match(DecodeN reg); 3885 3886 format %{ "[$reg]" %} 3887 interface(MEMORY_INTER) %{ 3888 base($reg); 3889 index(0x4); 3890 scale(0x0); 3891 disp(0x0); 3892 %} 3893 %} 3894 3895 // Indirect Memory Plus Short Offset Operand 3896 operand indOffset8Narrow(rRegN reg, immL8 off) 3897 %{ 3898 predicate(CompressedOops::shift() == 0); 3899 constraint(ALLOC_IN_RC(ptr_reg)); 3900 match(AddP (DecodeN reg) off); 3901 3902 format %{ "[$reg + $off (8-bit)]" %} 3903 interface(MEMORY_INTER) %{ 3904 base($reg); 3905 index(0x4); 3906 scale(0x0); 3907 disp($off); 3908 %} 3909 %} 3910 3911 // Indirect Memory Plus Long Offset Operand 3912 operand indOffset32Narrow(rRegN reg, immL32 off) 3913 %{ 3914 predicate(CompressedOops::shift() == 0); 3915 constraint(ALLOC_IN_RC(ptr_reg)); 3916 match(AddP (DecodeN reg) off); 3917 3918 format %{ "[$reg + $off (32-bit)]" %} 3919 interface(MEMORY_INTER) %{ 3920 base($reg); 3921 index(0x4); 3922 scale(0x0); 3923 disp($off); 3924 %} 3925 %} 3926 3927 // Indirect Memory Plus Index Register Plus Offset Operand 3928 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3929 %{ 3930 predicate(CompressedOops::shift() == 0); 3931 constraint(ALLOC_IN_RC(ptr_reg)); 3932 match(AddP (AddP (DecodeN reg) lreg) off); 3933 3934 op_cost(10); 3935 format %{"[$reg + $off + $lreg]" %} 3936 interface(MEMORY_INTER) %{ 3937 base($reg); 3938 index($lreg); 3939 scale(0x0); 3940 disp($off); 3941 %} 3942 %} 3943 3944 // Indirect Memory Plus Index Register Plus Offset Operand 3945 operand indIndexNarrow(rRegN reg, rRegL lreg) 3946 %{ 3947 predicate(CompressedOops::shift() == 0); 3948 constraint(ALLOC_IN_RC(ptr_reg)); 3949 match(AddP (DecodeN reg) lreg); 3950 3951 op_cost(10); 3952 format %{"[$reg + $lreg]" %} 3953 interface(MEMORY_INTER) %{ 3954 base($reg); 3955 index($lreg); 3956 scale(0x0); 3957 disp(0x0); 3958 %} 3959 %} 3960 3961 // Indirect Memory Times Scale Plus Index Register 3962 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3963 %{ 3964 predicate(CompressedOops::shift() == 0); 3965 constraint(ALLOC_IN_RC(ptr_reg)); 3966 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3967 3968 op_cost(10); 3969 format %{"[$reg + $lreg << $scale]" %} 3970 interface(MEMORY_INTER) %{ 3971 base($reg); 3972 index($lreg); 3973 scale($scale); 3974 disp(0x0); 3975 %} 3976 %} 3977 3978 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3979 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3980 %{ 3981 predicate(CompressedOops::shift() == 0); 3982 constraint(ALLOC_IN_RC(ptr_reg)); 3983 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3984 3985 op_cost(10); 3986 format %{"[$reg + $off + $lreg << $scale]" %} 3987 interface(MEMORY_INTER) %{ 3988 base($reg); 3989 index($lreg); 3990 scale($scale); 3991 disp($off); 3992 %} 3993 %} 3994 3995 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3996 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3997 %{ 3998 constraint(ALLOC_IN_RC(ptr_reg)); 3999 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4000 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4001 4002 op_cost(10); 4003 format %{"[$reg + $off + $idx]" %} 4004 interface(MEMORY_INTER) %{ 4005 base($reg); 4006 index($idx); 4007 scale(0x0); 4008 disp($off); 4009 %} 4010 %} 4011 4012 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4013 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4014 %{ 4015 constraint(ALLOC_IN_RC(ptr_reg)); 4016 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4017 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4018 4019 op_cost(10); 4020 format %{"[$reg + $off + $idx << $scale]" %} 4021 interface(MEMORY_INTER) %{ 4022 base($reg); 4023 index($idx); 4024 scale($scale); 4025 disp($off); 4026 %} 4027 %} 4028 4029 //----------Special Memory Operands-------------------------------------------- 4030 // Stack Slot Operand - This operand is used for loading and storing temporary 4031 // values on the stack where a match requires a value to 4032 // flow through memory. 4033 operand stackSlotP(sRegP reg) 4034 %{ 4035 constraint(ALLOC_IN_RC(stack_slots)); 4036 // No match rule because this operand is only generated in matching 4037 4038 format %{ "[$reg]" %} 4039 interface(MEMORY_INTER) %{ 4040 base(0x4); // RSP 4041 index(0x4); // No Index 4042 scale(0x0); // No Scale 4043 disp($reg); // Stack Offset 4044 %} 4045 %} 4046 4047 operand stackSlotI(sRegI reg) 4048 %{ 4049 constraint(ALLOC_IN_RC(stack_slots)); 4050 // No match rule because this operand is only generated in matching 4051 4052 format %{ "[$reg]" %} 4053 interface(MEMORY_INTER) %{ 4054 base(0x4); // RSP 4055 index(0x4); // No Index 4056 scale(0x0); // No Scale 4057 disp($reg); // Stack Offset 4058 %} 4059 %} 4060 4061 operand stackSlotF(sRegF reg) 4062 %{ 4063 constraint(ALLOC_IN_RC(stack_slots)); 4064 // No match rule because this operand is only generated in matching 4065 4066 format %{ "[$reg]" %} 4067 interface(MEMORY_INTER) %{ 4068 base(0x4); // RSP 4069 index(0x4); // No Index 4070 scale(0x0); // No Scale 4071 disp($reg); // Stack Offset 4072 %} 4073 %} 4074 4075 operand stackSlotD(sRegD reg) 4076 %{ 4077 constraint(ALLOC_IN_RC(stack_slots)); 4078 // No match rule because this operand is only generated in matching 4079 4080 format %{ "[$reg]" %} 4081 interface(MEMORY_INTER) %{ 4082 base(0x4); // RSP 4083 index(0x4); // No Index 4084 scale(0x0); // No Scale 4085 disp($reg); // Stack Offset 4086 %} 4087 %} 4088 operand stackSlotL(sRegL reg) 4089 %{ 4090 constraint(ALLOC_IN_RC(stack_slots)); 4091 // No match rule because this operand is only generated in matching 4092 4093 format %{ "[$reg]" %} 4094 interface(MEMORY_INTER) %{ 4095 base(0x4); // RSP 4096 index(0x4); // No Index 4097 scale(0x0); // No Scale 4098 disp($reg); // Stack Offset 4099 %} 4100 %} 4101 4102 //----------Conditional Branch Operands---------------------------------------- 4103 // Comparison Op - This is the operation of the comparison, and is limited to 4104 // the following set of codes: 4105 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4106 // 4107 // Other attributes of the comparison, such as unsignedness, are specified 4108 // by the comparison instruction that sets a condition code flags register. 4109 // That result is represented by a flags operand whose subtype is appropriate 4110 // to the unsignedness (etc.) of the comparison. 4111 // 4112 // Later, the instruction which matches both the Comparison Op (a Bool) and 4113 // the flags (produced by the Cmp) specifies the coding of the comparison op 4114 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4115 4116 // Comparision Code 4117 operand cmpOp() 4118 %{ 4119 match(Bool); 4120 4121 format %{ "" %} 4122 interface(COND_INTER) %{ 4123 equal(0x4, "e"); 4124 not_equal(0x5, "ne"); 4125 less(0xC, "l"); 4126 greater_equal(0xD, "ge"); 4127 less_equal(0xE, "le"); 4128 greater(0xF, "g"); 4129 overflow(0x0, "o"); 4130 no_overflow(0x1, "no"); 4131 %} 4132 %} 4133 4134 // Comparison Code, unsigned compare. Used by FP also, with 4135 // C2 (unordered) turned into GT or LT already. The other bits 4136 // C0 and C3 are turned into Carry & Zero flags. 4137 operand cmpOpU() 4138 %{ 4139 match(Bool); 4140 4141 format %{ "" %} 4142 interface(COND_INTER) %{ 4143 equal(0x4, "e"); 4144 not_equal(0x5, "ne"); 4145 less(0x2, "b"); 4146 greater_equal(0x3, "nb"); 4147 less_equal(0x6, "be"); 4148 greater(0x7, "nbe"); 4149 overflow(0x0, "o"); 4150 no_overflow(0x1, "no"); 4151 %} 4152 %} 4153 4154 4155 // Floating comparisons that don't require any fixup for the unordered case 4156 operand cmpOpUCF() %{ 4157 match(Bool); 4158 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4159 n->as_Bool()->_test._test == BoolTest::ge || 4160 n->as_Bool()->_test._test == BoolTest::le || 4161 n->as_Bool()->_test._test == BoolTest::gt); 4162 format %{ "" %} 4163 interface(COND_INTER) %{ 4164 equal(0x4, "e"); 4165 not_equal(0x5, "ne"); 4166 less(0x2, "b"); 4167 greater_equal(0x3, "nb"); 4168 less_equal(0x6, "be"); 4169 greater(0x7, "nbe"); 4170 overflow(0x0, "o"); 4171 no_overflow(0x1, "no"); 4172 %} 4173 %} 4174 4175 4176 // Floating comparisons that can be fixed up with extra conditional jumps 4177 operand cmpOpUCF2() %{ 4178 match(Bool); 4179 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4180 n->as_Bool()->_test._test == BoolTest::eq); 4181 format %{ "" %} 4182 interface(COND_INTER) %{ 4183 equal(0x4, "e"); 4184 not_equal(0x5, "ne"); 4185 less(0x2, "b"); 4186 greater_equal(0x3, "nb"); 4187 less_equal(0x6, "be"); 4188 greater(0x7, "nbe"); 4189 overflow(0x0, "o"); 4190 no_overflow(0x1, "no"); 4191 %} 4192 %} 4193 4194 //----------OPERAND CLASSES---------------------------------------------------- 4195 // Operand Classes are groups of operands that are used as to simplify 4196 // instruction definitions by not requiring the AD writer to specify separate 4197 // instructions for every form of operand when the instruction accepts 4198 // multiple operand types with the same basic encoding and format. The classic 4199 // case of this is memory operands. 4200 4201 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4202 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4203 indCompressedOopOffset, 4204 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4205 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4206 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4207 4208 //----------PIPELINE----------------------------------------------------------- 4209 // Rules which define the behavior of the target architectures pipeline. 4210 pipeline %{ 4211 4212 //----------ATTRIBUTES--------------------------------------------------------- 4213 attributes %{ 4214 variable_size_instructions; // Fixed size instructions 4215 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4216 instruction_unit_size = 1; // An instruction is 1 bytes long 4217 instruction_fetch_unit_size = 16; // The processor fetches one line 4218 instruction_fetch_units = 1; // of 16 bytes 4219 4220 // List of nop instructions 4221 nops( MachNop ); 4222 %} 4223 4224 //----------RESOURCES---------------------------------------------------------- 4225 // Resources are the functional units available to the machine 4226 4227 // Generic P2/P3 pipeline 4228 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4229 // 3 instructions decoded per cycle. 4230 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4231 // 3 ALU op, only ALU0 handles mul instructions. 4232 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4233 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4234 BR, FPU, 4235 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4236 4237 //----------PIPELINE DESCRIPTION----------------------------------------------- 4238 // Pipeline Description specifies the stages in the machine's pipeline 4239 4240 // Generic P2/P3 pipeline 4241 pipe_desc(S0, S1, S2, S3, S4, S5); 4242 4243 //----------PIPELINE CLASSES--------------------------------------------------- 4244 // Pipeline Classes describe the stages in which input and output are 4245 // referenced by the hardware pipeline. 4246 4247 // Naming convention: ialu or fpu 4248 // Then: _reg 4249 // Then: _reg if there is a 2nd register 4250 // Then: _long if it's a pair of instructions implementing a long 4251 // Then: _fat if it requires the big decoder 4252 // Or: _mem if it requires the big decoder and a memory unit. 4253 4254 // Integer ALU reg operation 4255 pipe_class ialu_reg(rRegI dst) 4256 %{ 4257 single_instruction; 4258 dst : S4(write); 4259 dst : S3(read); 4260 DECODE : S0; // any decoder 4261 ALU : S3; // any alu 4262 %} 4263 4264 // Long ALU reg operation 4265 pipe_class ialu_reg_long(rRegL dst) 4266 %{ 4267 instruction_count(2); 4268 dst : S4(write); 4269 dst : S3(read); 4270 DECODE : S0(2); // any 2 decoders 4271 ALU : S3(2); // both alus 4272 %} 4273 4274 // Integer ALU reg operation using big decoder 4275 pipe_class ialu_reg_fat(rRegI dst) 4276 %{ 4277 single_instruction; 4278 dst : S4(write); 4279 dst : S3(read); 4280 D0 : S0; // big decoder only 4281 ALU : S3; // any alu 4282 %} 4283 4284 // Long ALU reg operation using big decoder 4285 pipe_class ialu_reg_long_fat(rRegL dst) 4286 %{ 4287 instruction_count(2); 4288 dst : S4(write); 4289 dst : S3(read); 4290 D0 : S0(2); // big decoder only; twice 4291 ALU : S3(2); // any 2 alus 4292 %} 4293 4294 // Integer ALU reg-reg operation 4295 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4296 %{ 4297 single_instruction; 4298 dst : S4(write); 4299 src : S3(read); 4300 DECODE : S0; // any decoder 4301 ALU : S3; // any alu 4302 %} 4303 4304 // Long ALU reg-reg operation 4305 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4306 %{ 4307 instruction_count(2); 4308 dst : S4(write); 4309 src : S3(read); 4310 DECODE : S0(2); // any 2 decoders 4311 ALU : S3(2); // both alus 4312 %} 4313 4314 // Integer ALU reg-reg operation 4315 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4316 %{ 4317 single_instruction; 4318 dst : S4(write); 4319 src : S3(read); 4320 D0 : S0; // big decoder only 4321 ALU : S3; // any alu 4322 %} 4323 4324 // Long ALU reg-reg operation 4325 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4326 %{ 4327 instruction_count(2); 4328 dst : S4(write); 4329 src : S3(read); 4330 D0 : S0(2); // big decoder only; twice 4331 ALU : S3(2); // both alus 4332 %} 4333 4334 // Integer ALU reg-mem operation 4335 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4336 %{ 4337 single_instruction; 4338 dst : S5(write); 4339 mem : S3(read); 4340 D0 : S0; // big decoder only 4341 ALU : S4; // any alu 4342 MEM : S3; // any mem 4343 %} 4344 4345 // Integer mem operation (prefetch) 4346 pipe_class ialu_mem(memory mem) 4347 %{ 4348 single_instruction; 4349 mem : S3(read); 4350 D0 : S0; // big decoder only 4351 MEM : S3; // any mem 4352 %} 4353 4354 // Integer Store to Memory 4355 pipe_class ialu_mem_reg(memory mem, rRegI src) 4356 %{ 4357 single_instruction; 4358 mem : S3(read); 4359 src : S5(read); 4360 D0 : S0; // big decoder only 4361 ALU : S4; // any alu 4362 MEM : S3; 4363 %} 4364 4365 // // Long Store to Memory 4366 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4367 // %{ 4368 // instruction_count(2); 4369 // mem : S3(read); 4370 // src : S5(read); 4371 // D0 : S0(2); // big decoder only; twice 4372 // ALU : S4(2); // any 2 alus 4373 // MEM : S3(2); // Both mems 4374 // %} 4375 4376 // Integer Store to Memory 4377 pipe_class ialu_mem_imm(memory mem) 4378 %{ 4379 single_instruction; 4380 mem : S3(read); 4381 D0 : S0; // big decoder only 4382 ALU : S4; // any alu 4383 MEM : S3; 4384 %} 4385 4386 // Integer ALU0 reg-reg operation 4387 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4388 %{ 4389 single_instruction; 4390 dst : S4(write); 4391 src : S3(read); 4392 D0 : S0; // Big decoder only 4393 ALU0 : S3; // only alu0 4394 %} 4395 4396 // Integer ALU0 reg-mem operation 4397 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4398 %{ 4399 single_instruction; 4400 dst : S5(write); 4401 mem : S3(read); 4402 D0 : S0; // big decoder only 4403 ALU0 : S4; // ALU0 only 4404 MEM : S3; // any mem 4405 %} 4406 4407 // Integer ALU reg-reg operation 4408 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4409 %{ 4410 single_instruction; 4411 cr : S4(write); 4412 src1 : S3(read); 4413 src2 : S3(read); 4414 DECODE : S0; // any decoder 4415 ALU : S3; // any alu 4416 %} 4417 4418 // Integer ALU reg-imm operation 4419 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4420 %{ 4421 single_instruction; 4422 cr : S4(write); 4423 src1 : S3(read); 4424 DECODE : S0; // any decoder 4425 ALU : S3; // any alu 4426 %} 4427 4428 // Integer ALU reg-mem operation 4429 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4430 %{ 4431 single_instruction; 4432 cr : S4(write); 4433 src1 : S3(read); 4434 src2 : S3(read); 4435 D0 : S0; // big decoder only 4436 ALU : S4; // any alu 4437 MEM : S3; 4438 %} 4439 4440 // Conditional move reg-reg 4441 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4442 %{ 4443 instruction_count(4); 4444 y : S4(read); 4445 q : S3(read); 4446 p : S3(read); 4447 DECODE : S0(4); // any decoder 4448 %} 4449 4450 // Conditional move reg-reg 4451 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4452 %{ 4453 single_instruction; 4454 dst : S4(write); 4455 src : S3(read); 4456 cr : S3(read); 4457 DECODE : S0; // any decoder 4458 %} 4459 4460 // Conditional move reg-mem 4461 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4462 %{ 4463 single_instruction; 4464 dst : S4(write); 4465 src : S3(read); 4466 cr : S3(read); 4467 DECODE : S0; // any decoder 4468 MEM : S3; 4469 %} 4470 4471 // Conditional move reg-reg long 4472 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4473 %{ 4474 single_instruction; 4475 dst : S4(write); 4476 src : S3(read); 4477 cr : S3(read); 4478 DECODE : S0(2); // any 2 decoders 4479 %} 4480 4481 // XXX 4482 // // Conditional move double reg-reg 4483 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4484 // %{ 4485 // single_instruction; 4486 // dst : S4(write); 4487 // src : S3(read); 4488 // cr : S3(read); 4489 // DECODE : S0; // any decoder 4490 // %} 4491 4492 // Float reg-reg operation 4493 pipe_class fpu_reg(regD dst) 4494 %{ 4495 instruction_count(2); 4496 dst : S3(read); 4497 DECODE : S0(2); // any 2 decoders 4498 FPU : S3; 4499 %} 4500 4501 // Float reg-reg operation 4502 pipe_class fpu_reg_reg(regD dst, regD src) 4503 %{ 4504 instruction_count(2); 4505 dst : S4(write); 4506 src : S3(read); 4507 DECODE : S0(2); // any 2 decoders 4508 FPU : S3; 4509 %} 4510 4511 // Float reg-reg operation 4512 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4513 %{ 4514 instruction_count(3); 4515 dst : S4(write); 4516 src1 : S3(read); 4517 src2 : S3(read); 4518 DECODE : S0(3); // any 3 decoders 4519 FPU : S3(2); 4520 %} 4521 4522 // Float reg-reg operation 4523 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4524 %{ 4525 instruction_count(4); 4526 dst : S4(write); 4527 src1 : S3(read); 4528 src2 : S3(read); 4529 src3 : S3(read); 4530 DECODE : S0(4); // any 3 decoders 4531 FPU : S3(2); 4532 %} 4533 4534 // Float reg-reg operation 4535 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4536 %{ 4537 instruction_count(4); 4538 dst : S4(write); 4539 src1 : S3(read); 4540 src2 : S3(read); 4541 src3 : S3(read); 4542 DECODE : S1(3); // any 3 decoders 4543 D0 : S0; // Big decoder only 4544 FPU : S3(2); 4545 MEM : S3; 4546 %} 4547 4548 // Float reg-mem operation 4549 pipe_class fpu_reg_mem(regD dst, memory mem) 4550 %{ 4551 instruction_count(2); 4552 dst : S5(write); 4553 mem : S3(read); 4554 D0 : S0; // big decoder only 4555 DECODE : S1; // any decoder for FPU POP 4556 FPU : S4; 4557 MEM : S3; // any mem 4558 %} 4559 4560 // Float reg-mem operation 4561 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4562 %{ 4563 instruction_count(3); 4564 dst : S5(write); 4565 src1 : S3(read); 4566 mem : S3(read); 4567 D0 : S0; // big decoder only 4568 DECODE : S1(2); // any decoder for FPU POP 4569 FPU : S4; 4570 MEM : S3; // any mem 4571 %} 4572 4573 // Float mem-reg operation 4574 pipe_class fpu_mem_reg(memory mem, regD src) 4575 %{ 4576 instruction_count(2); 4577 src : S5(read); 4578 mem : S3(read); 4579 DECODE : S0; // any decoder for FPU PUSH 4580 D0 : S1; // big decoder only 4581 FPU : S4; 4582 MEM : S3; // any mem 4583 %} 4584 4585 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4586 %{ 4587 instruction_count(3); 4588 src1 : S3(read); 4589 src2 : S3(read); 4590 mem : S3(read); 4591 DECODE : S0(2); // any decoder for FPU PUSH 4592 D0 : S1; // big decoder only 4593 FPU : S4; 4594 MEM : S3; // any mem 4595 %} 4596 4597 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4598 %{ 4599 instruction_count(3); 4600 src1 : S3(read); 4601 src2 : S3(read); 4602 mem : S4(read); 4603 DECODE : S0; // any decoder for FPU PUSH 4604 D0 : S0(2); // big decoder only 4605 FPU : S4; 4606 MEM : S3(2); // any mem 4607 %} 4608 4609 pipe_class fpu_mem_mem(memory dst, memory src1) 4610 %{ 4611 instruction_count(2); 4612 src1 : S3(read); 4613 dst : S4(read); 4614 D0 : S0(2); // big decoder only 4615 MEM : S3(2); // any mem 4616 %} 4617 4618 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4619 %{ 4620 instruction_count(3); 4621 src1 : S3(read); 4622 src2 : S3(read); 4623 dst : S4(read); 4624 D0 : S0(3); // big decoder only 4625 FPU : S4; 4626 MEM : S3(3); // any mem 4627 %} 4628 4629 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4630 %{ 4631 instruction_count(3); 4632 src1 : S4(read); 4633 mem : S4(read); 4634 DECODE : S0; // any decoder for FPU PUSH 4635 D0 : S0(2); // big decoder only 4636 FPU : S4; 4637 MEM : S3(2); // any mem 4638 %} 4639 4640 // Float load constant 4641 pipe_class fpu_reg_con(regD dst) 4642 %{ 4643 instruction_count(2); 4644 dst : S5(write); 4645 D0 : S0; // big decoder only for the load 4646 DECODE : S1; // any decoder for FPU POP 4647 FPU : S4; 4648 MEM : S3; // any mem 4649 %} 4650 4651 // Float load constant 4652 pipe_class fpu_reg_reg_con(regD dst, regD src) 4653 %{ 4654 instruction_count(3); 4655 dst : S5(write); 4656 src : S3(read); 4657 D0 : S0; // big decoder only for the load 4658 DECODE : S1(2); // any decoder for FPU POP 4659 FPU : S4; 4660 MEM : S3; // any mem 4661 %} 4662 4663 // UnConditional branch 4664 pipe_class pipe_jmp(label labl) 4665 %{ 4666 single_instruction; 4667 BR : S3; 4668 %} 4669 4670 // Conditional branch 4671 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4672 %{ 4673 single_instruction; 4674 cr : S1(read); 4675 BR : S3; 4676 %} 4677 4678 // Allocation idiom 4679 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4680 %{ 4681 instruction_count(1); force_serialization; 4682 fixed_latency(6); 4683 heap_ptr : S3(read); 4684 DECODE : S0(3); 4685 D0 : S2; 4686 MEM : S3; 4687 ALU : S3(2); 4688 dst : S5(write); 4689 BR : S5; 4690 %} 4691 4692 // Generic big/slow expanded idiom 4693 pipe_class pipe_slow() 4694 %{ 4695 instruction_count(10); multiple_bundles; force_serialization; 4696 fixed_latency(100); 4697 D0 : S0(2); 4698 MEM : S3(2); 4699 %} 4700 4701 // The real do-nothing guy 4702 pipe_class empty() 4703 %{ 4704 instruction_count(0); 4705 %} 4706 4707 // Define the class for the Nop node 4708 define 4709 %{ 4710 MachNop = empty; 4711 %} 4712 4713 %} 4714 4715 //----------INSTRUCTIONS------------------------------------------------------- 4716 // 4717 // match -- States which machine-independent subtree may be replaced 4718 // by this instruction. 4719 // ins_cost -- The estimated cost of this instruction is used by instruction 4720 // selection to identify a minimum cost tree of machine 4721 // instructions that matches a tree of machine-independent 4722 // instructions. 4723 // format -- A string providing the disassembly for this instruction. 4724 // The value of an instruction's operand may be inserted 4725 // by referring to it with a '$' prefix. 4726 // opcode -- Three instruction opcodes may be provided. These are referred 4727 // to within an encode class as $primary, $secondary, and $tertiary 4728 // rrspectively. The primary opcode is commonly used to 4729 // indicate the type of machine instruction, while secondary 4730 // and tertiary are often used for prefix options or addressing 4731 // modes. 4732 // ins_encode -- A list of encode classes with parameters. The encode class 4733 // name must have been defined in an 'enc_class' specification 4734 // in the encode section of the architecture description. 4735 4736 4737 //----------Load/Store/Move Instructions--------------------------------------- 4738 //----------Load Instructions-------------------------------------------------- 4739 4740 // Load Byte (8 bit signed) 4741 instruct loadB(rRegI dst, memory mem) 4742 %{ 4743 match(Set dst (LoadB mem)); 4744 4745 ins_cost(125); 4746 format %{ "movsbl $dst, $mem\t# byte" %} 4747 4748 ins_encode %{ 4749 __ movsbl($dst$$Register, $mem$$Address); 4750 %} 4751 4752 ins_pipe(ialu_reg_mem); 4753 %} 4754 4755 // Load Byte (8 bit signed) into Long Register 4756 instruct loadB2L(rRegL dst, memory mem) 4757 %{ 4758 match(Set dst (ConvI2L (LoadB mem))); 4759 4760 ins_cost(125); 4761 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4762 4763 ins_encode %{ 4764 __ movsbq($dst$$Register, $mem$$Address); 4765 %} 4766 4767 ins_pipe(ialu_reg_mem); 4768 %} 4769 4770 // Load Unsigned Byte (8 bit UNsigned) 4771 instruct loadUB(rRegI dst, memory mem) 4772 %{ 4773 match(Set dst (LoadUB mem)); 4774 4775 ins_cost(125); 4776 format %{ "movzbl $dst, $mem\t# ubyte" %} 4777 4778 ins_encode %{ 4779 __ movzbl($dst$$Register, $mem$$Address); 4780 %} 4781 4782 ins_pipe(ialu_reg_mem); 4783 %} 4784 4785 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4786 instruct loadUB2L(rRegL dst, memory mem) 4787 %{ 4788 match(Set dst (ConvI2L (LoadUB mem))); 4789 4790 ins_cost(125); 4791 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4792 4793 ins_encode %{ 4794 __ movzbq($dst$$Register, $mem$$Address); 4795 %} 4796 4797 ins_pipe(ialu_reg_mem); 4798 %} 4799 4800 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4801 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4802 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4803 effect(KILL cr); 4804 4805 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4806 "andl $dst, right_n_bits($mask, 8)" %} 4807 ins_encode %{ 4808 Register Rdst = $dst$$Register; 4809 __ movzbq(Rdst, $mem$$Address); 4810 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4811 %} 4812 ins_pipe(ialu_reg_mem); 4813 %} 4814 4815 // Load Short (16 bit signed) 4816 instruct loadS(rRegI dst, memory mem) 4817 %{ 4818 match(Set dst (LoadS mem)); 4819 4820 ins_cost(125); 4821 format %{ "movswl $dst, $mem\t# short" %} 4822 4823 ins_encode %{ 4824 __ movswl($dst$$Register, $mem$$Address); 4825 %} 4826 4827 ins_pipe(ialu_reg_mem); 4828 %} 4829 4830 // Load Short (16 bit signed) to Byte (8 bit signed) 4831 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4832 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4833 4834 ins_cost(125); 4835 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4836 ins_encode %{ 4837 __ movsbl($dst$$Register, $mem$$Address); 4838 %} 4839 ins_pipe(ialu_reg_mem); 4840 %} 4841 4842 // Load Short (16 bit signed) into Long Register 4843 instruct loadS2L(rRegL dst, memory mem) 4844 %{ 4845 match(Set dst (ConvI2L (LoadS mem))); 4846 4847 ins_cost(125); 4848 format %{ "movswq $dst, $mem\t# short -> long" %} 4849 4850 ins_encode %{ 4851 __ movswq($dst$$Register, $mem$$Address); 4852 %} 4853 4854 ins_pipe(ialu_reg_mem); 4855 %} 4856 4857 // Load Unsigned Short/Char (16 bit UNsigned) 4858 instruct loadUS(rRegI dst, memory mem) 4859 %{ 4860 match(Set dst (LoadUS mem)); 4861 4862 ins_cost(125); 4863 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4864 4865 ins_encode %{ 4866 __ movzwl($dst$$Register, $mem$$Address); 4867 %} 4868 4869 ins_pipe(ialu_reg_mem); 4870 %} 4871 4872 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4873 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4874 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4875 4876 ins_cost(125); 4877 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4878 ins_encode %{ 4879 __ movsbl($dst$$Register, $mem$$Address); 4880 %} 4881 ins_pipe(ialu_reg_mem); 4882 %} 4883 4884 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4885 instruct loadUS2L(rRegL dst, memory mem) 4886 %{ 4887 match(Set dst (ConvI2L (LoadUS mem))); 4888 4889 ins_cost(125); 4890 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4891 4892 ins_encode %{ 4893 __ movzwq($dst$$Register, $mem$$Address); 4894 %} 4895 4896 ins_pipe(ialu_reg_mem); 4897 %} 4898 4899 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4900 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4901 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4902 4903 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4904 ins_encode %{ 4905 __ movzbq($dst$$Register, $mem$$Address); 4906 %} 4907 ins_pipe(ialu_reg_mem); 4908 %} 4909 4910 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4911 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4912 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4913 effect(KILL cr); 4914 4915 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4916 "andl $dst, right_n_bits($mask, 16)" %} 4917 ins_encode %{ 4918 Register Rdst = $dst$$Register; 4919 __ movzwq(Rdst, $mem$$Address); 4920 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4921 %} 4922 ins_pipe(ialu_reg_mem); 4923 %} 4924 4925 // Load Integer 4926 instruct loadI(rRegI dst, memory mem) 4927 %{ 4928 match(Set dst (LoadI mem)); 4929 4930 ins_cost(125); 4931 format %{ "movl $dst, $mem\t# int" %} 4932 4933 ins_encode %{ 4934 __ movl($dst$$Register, $mem$$Address); 4935 %} 4936 4937 ins_pipe(ialu_reg_mem); 4938 %} 4939 4940 // Load Integer (32 bit signed) to Byte (8 bit signed) 4941 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4942 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4943 4944 ins_cost(125); 4945 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4946 ins_encode %{ 4947 __ movsbl($dst$$Register, $mem$$Address); 4948 %} 4949 ins_pipe(ialu_reg_mem); 4950 %} 4951 4952 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4953 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4954 match(Set dst (AndI (LoadI mem) mask)); 4955 4956 ins_cost(125); 4957 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4958 ins_encode %{ 4959 __ movzbl($dst$$Register, $mem$$Address); 4960 %} 4961 ins_pipe(ialu_reg_mem); 4962 %} 4963 4964 // Load Integer (32 bit signed) to Short (16 bit signed) 4965 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4966 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4967 4968 ins_cost(125); 4969 format %{ "movswl $dst, $mem\t# int -> short" %} 4970 ins_encode %{ 4971 __ movswl($dst$$Register, $mem$$Address); 4972 %} 4973 ins_pipe(ialu_reg_mem); 4974 %} 4975 4976 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4977 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4978 match(Set dst (AndI (LoadI mem) mask)); 4979 4980 ins_cost(125); 4981 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4982 ins_encode %{ 4983 __ movzwl($dst$$Register, $mem$$Address); 4984 %} 4985 ins_pipe(ialu_reg_mem); 4986 %} 4987 4988 // Load Integer into Long Register 4989 instruct loadI2L(rRegL dst, memory mem) 4990 %{ 4991 match(Set dst (ConvI2L (LoadI mem))); 4992 4993 ins_cost(125); 4994 format %{ "movslq $dst, $mem\t# int -> long" %} 4995 4996 ins_encode %{ 4997 __ movslq($dst$$Register, $mem$$Address); 4998 %} 4999 5000 ins_pipe(ialu_reg_mem); 5001 %} 5002 5003 // Load Integer with mask 0xFF into Long Register 5004 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5005 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5006 5007 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5008 ins_encode %{ 5009 __ movzbq($dst$$Register, $mem$$Address); 5010 %} 5011 ins_pipe(ialu_reg_mem); 5012 %} 5013 5014 // Load Integer with mask 0xFFFF into Long Register 5015 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5016 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5017 5018 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5019 ins_encode %{ 5020 __ movzwq($dst$$Register, $mem$$Address); 5021 %} 5022 ins_pipe(ialu_reg_mem); 5023 %} 5024 5025 // Load Integer with a 31-bit mask into Long Register 5026 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5027 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5028 effect(KILL cr); 5029 5030 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5031 "andl $dst, $mask" %} 5032 ins_encode %{ 5033 Register Rdst = $dst$$Register; 5034 __ movl(Rdst, $mem$$Address); 5035 __ andl(Rdst, $mask$$constant); 5036 %} 5037 ins_pipe(ialu_reg_mem); 5038 %} 5039 5040 // Load Unsigned Integer into Long Register 5041 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5042 %{ 5043 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5044 5045 ins_cost(125); 5046 format %{ "movl $dst, $mem\t# uint -> long" %} 5047 5048 ins_encode %{ 5049 __ movl($dst$$Register, $mem$$Address); 5050 %} 5051 5052 ins_pipe(ialu_reg_mem); 5053 %} 5054 5055 // Load Long 5056 instruct loadL(rRegL dst, memory mem) 5057 %{ 5058 match(Set dst (LoadL mem)); 5059 5060 ins_cost(125); 5061 format %{ "movq $dst, $mem\t# long" %} 5062 5063 ins_encode %{ 5064 __ movq($dst$$Register, $mem$$Address); 5065 %} 5066 5067 ins_pipe(ialu_reg_mem); // XXX 5068 %} 5069 5070 // Load Range 5071 instruct loadRange(rRegI dst, memory mem) 5072 %{ 5073 match(Set dst (LoadRange mem)); 5074 5075 ins_cost(125); // XXX 5076 format %{ "movl $dst, $mem\t# range" %} 5077 opcode(0x8B); 5078 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5079 ins_pipe(ialu_reg_mem); 5080 %} 5081 5082 // Load Pointer 5083 instruct loadP(rRegP dst, memory mem) 5084 %{ 5085 match(Set dst (LoadP mem)); 5086 predicate(n->as_Load()->barrier_data() == 0); 5087 5088 ins_cost(125); // XXX 5089 format %{ "movq $dst, $mem\t# ptr" %} 5090 opcode(0x8B); 5091 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5092 ins_pipe(ialu_reg_mem); // XXX 5093 %} 5094 5095 // Load Compressed Pointer 5096 instruct loadN(rRegN dst, memory mem) 5097 %{ 5098 match(Set dst (LoadN mem)); 5099 5100 ins_cost(125); // XXX 5101 format %{ "movl $dst, $mem\t# compressed ptr" %} 5102 ins_encode %{ 5103 __ movl($dst$$Register, $mem$$Address); 5104 %} 5105 ins_pipe(ialu_reg_mem); // XXX 5106 %} 5107 5108 5109 // Load Klass Pointer 5110 instruct loadKlass(rRegP dst, memory mem) 5111 %{ 5112 match(Set dst (LoadKlass mem)); 5113 5114 ins_cost(125); // XXX 5115 format %{ "movq $dst, $mem\t# class" %} 5116 opcode(0x8B); 5117 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5118 ins_pipe(ialu_reg_mem); // XXX 5119 %} 5120 5121 // Load narrow Klass Pointer 5122 instruct loadNKlass(rRegN dst, memory mem) 5123 %{ 5124 match(Set dst (LoadNKlass mem)); 5125 5126 ins_cost(125); // XXX 5127 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5128 ins_encode %{ 5129 __ movl($dst$$Register, $mem$$Address); 5130 %} 5131 ins_pipe(ialu_reg_mem); // XXX 5132 %} 5133 5134 // Load Float 5135 instruct loadF(regF dst, memory mem) 5136 %{ 5137 match(Set dst (LoadF mem)); 5138 5139 ins_cost(145); // XXX 5140 format %{ "movss $dst, $mem\t# float" %} 5141 ins_encode %{ 5142 __ movflt($dst$$XMMRegister, $mem$$Address); 5143 %} 5144 ins_pipe(pipe_slow); // XXX 5145 %} 5146 5147 // Load Float 5148 instruct MoveF2VL(vlRegF dst, regF src) %{ 5149 match(Set dst src); 5150 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5151 ins_encode %{ 5152 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5153 %} 5154 ins_pipe( fpu_reg_reg ); 5155 %} 5156 5157 // Load Float 5158 instruct MoveF2LEG(legRegF dst, regF src) %{ 5159 match(Set dst src); 5160 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5161 ins_encode %{ 5162 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5163 %} 5164 ins_pipe( fpu_reg_reg ); 5165 %} 5166 5167 // Load Float 5168 instruct MoveVL2F(regF dst, vlRegF src) %{ 5169 match(Set dst src); 5170 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5171 ins_encode %{ 5172 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5173 %} 5174 ins_pipe( fpu_reg_reg ); 5175 %} 5176 5177 // Load Float 5178 instruct MoveLEG2F(regF dst, legRegF src) %{ 5179 match(Set dst src); 5180 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5181 ins_encode %{ 5182 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5183 %} 5184 ins_pipe( fpu_reg_reg ); 5185 %} 5186 5187 // Load Double 5188 instruct loadD_partial(regD dst, memory mem) 5189 %{ 5190 predicate(!UseXmmLoadAndClearUpper); 5191 match(Set dst (LoadD mem)); 5192 5193 ins_cost(145); // XXX 5194 format %{ "movlpd $dst, $mem\t# double" %} 5195 ins_encode %{ 5196 __ movdbl($dst$$XMMRegister, $mem$$Address); 5197 %} 5198 ins_pipe(pipe_slow); // XXX 5199 %} 5200 5201 instruct loadD(regD dst, memory mem) 5202 %{ 5203 predicate(UseXmmLoadAndClearUpper); 5204 match(Set dst (LoadD mem)); 5205 5206 ins_cost(145); // XXX 5207 format %{ "movsd $dst, $mem\t# double" %} 5208 ins_encode %{ 5209 __ movdbl($dst$$XMMRegister, $mem$$Address); 5210 %} 5211 ins_pipe(pipe_slow); // XXX 5212 %} 5213 5214 // Load Double 5215 instruct MoveD2VL(vlRegD dst, regD src) %{ 5216 match(Set dst src); 5217 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5218 ins_encode %{ 5219 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5220 %} 5221 ins_pipe( fpu_reg_reg ); 5222 %} 5223 5224 // Load Double 5225 instruct MoveD2LEG(legRegD dst, regD src) %{ 5226 match(Set dst src); 5227 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5228 ins_encode %{ 5229 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5230 %} 5231 ins_pipe( fpu_reg_reg ); 5232 %} 5233 5234 // Load Double 5235 instruct MoveVL2D(regD dst, vlRegD src) %{ 5236 match(Set dst src); 5237 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5238 ins_encode %{ 5239 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5240 %} 5241 ins_pipe( fpu_reg_reg ); 5242 %} 5243 5244 // Load Double 5245 instruct MoveLEG2D(regD dst, legRegD src) %{ 5246 match(Set dst src); 5247 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5248 ins_encode %{ 5249 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5250 %} 5251 ins_pipe( fpu_reg_reg ); 5252 %} 5253 5254 // Following pseudo code describes the algorithm for max[FD]: 5255 // Min algorithm is on similar lines 5256 // btmp = (b < +0.0) ? a : b 5257 // atmp = (b < +0.0) ? b : a 5258 // Tmp = Max_Float(atmp , btmp) 5259 // Res = (atmp == NaN) ? atmp : Tmp 5260 5261 // max = java.lang.Math.max(float a, float b) 5262 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5263 predicate(UseAVX > 0 && !n->is_reduction()); 5264 match(Set dst (MaxF a b)); 5265 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5266 format %{ 5267 "blendvps $btmp,$b,$a,$b \n\t" 5268 "blendvps $atmp,$a,$b,$b \n\t" 5269 "vmaxss $tmp,$atmp,$btmp \n\t" 5270 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5271 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5272 %} 5273 ins_encode %{ 5274 int vector_len = Assembler::AVX_128bit; 5275 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5276 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5277 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5278 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5279 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5280 %} 5281 ins_pipe( pipe_slow ); 5282 %} 5283 5284 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 5285 predicate(UseAVX > 0 && n->is_reduction()); 5286 match(Set dst (MaxF a b)); 5287 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5288 5289 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 5290 ins_encode %{ 5291 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5292 false /*min*/, true /*single*/); 5293 %} 5294 ins_pipe( pipe_slow ); 5295 %} 5296 5297 // max = java.lang.Math.max(double a, double b) 5298 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5299 predicate(UseAVX > 0 && !n->is_reduction()); 5300 match(Set dst (MaxD a b)); 5301 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 5302 format %{ 5303 "blendvpd $btmp,$b,$a,$b \n\t" 5304 "blendvpd $atmp,$a,$b,$b \n\t" 5305 "vmaxsd $tmp,$atmp,$btmp \n\t" 5306 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5307 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5308 %} 5309 ins_encode %{ 5310 int vector_len = Assembler::AVX_128bit; 5311 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5312 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5313 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5314 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5315 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5316 %} 5317 ins_pipe( pipe_slow ); 5318 %} 5319 5320 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 5321 predicate(UseAVX > 0 && n->is_reduction()); 5322 match(Set dst (MaxD a b)); 5323 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5324 5325 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 5326 ins_encode %{ 5327 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5328 false /*min*/, false /*single*/); 5329 %} 5330 ins_pipe( pipe_slow ); 5331 %} 5332 5333 // min = java.lang.Math.min(float a, float b) 5334 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5335 predicate(UseAVX > 0 && !n->is_reduction()); 5336 match(Set dst (MinF a b)); 5337 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5338 format %{ 5339 "blendvps $atmp,$a,$b,$a \n\t" 5340 "blendvps $btmp,$b,$a,$a \n\t" 5341 "vminss $tmp,$atmp,$btmp \n\t" 5342 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5343 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5344 %} 5345 ins_encode %{ 5346 int vector_len = Assembler::AVX_128bit; 5347 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5348 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5349 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5350 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5351 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5352 %} 5353 ins_pipe( pipe_slow ); 5354 %} 5355 5356 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 5357 predicate(UseAVX > 0 && n->is_reduction()); 5358 match(Set dst (MinF a b)); 5359 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5360 5361 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 5362 ins_encode %{ 5363 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5364 true /*min*/, true /*single*/); 5365 %} 5366 ins_pipe( pipe_slow ); 5367 %} 5368 5369 // min = java.lang.Math.min(double a, double b) 5370 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5371 predicate(UseAVX > 0 && !n->is_reduction()); 5372 match(Set dst (MinD a b)); 5373 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5374 format %{ 5375 "blendvpd $atmp,$a,$b,$a \n\t" 5376 "blendvpd $btmp,$b,$a,$a \n\t" 5377 "vminsd $tmp,$atmp,$btmp \n\t" 5378 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5379 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5380 %} 5381 ins_encode %{ 5382 int vector_len = Assembler::AVX_128bit; 5383 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5384 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5385 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5386 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5387 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5388 %} 5389 ins_pipe( pipe_slow ); 5390 %} 5391 5392 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 5393 predicate(UseAVX > 0 && n->is_reduction()); 5394 match(Set dst (MinD a b)); 5395 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5396 5397 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 5398 ins_encode %{ 5399 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5400 true /*min*/, false /*single*/); 5401 %} 5402 ins_pipe( pipe_slow ); 5403 %} 5404 5405 // Load Effective Address 5406 instruct leaP8(rRegP dst, indOffset8 mem) 5407 %{ 5408 match(Set dst mem); 5409 5410 ins_cost(110); // XXX 5411 format %{ "leaq $dst, $mem\t# ptr 8" %} 5412 opcode(0x8D); 5413 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5414 ins_pipe(ialu_reg_reg_fat); 5415 %} 5416 5417 instruct leaP32(rRegP dst, indOffset32 mem) 5418 %{ 5419 match(Set dst mem); 5420 5421 ins_cost(110); 5422 format %{ "leaq $dst, $mem\t# ptr 32" %} 5423 opcode(0x8D); 5424 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5425 ins_pipe(ialu_reg_reg_fat); 5426 %} 5427 5428 // instruct leaPIdx(rRegP dst, indIndex mem) 5429 // %{ 5430 // match(Set dst mem); 5431 5432 // ins_cost(110); 5433 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5434 // opcode(0x8D); 5435 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5436 // ins_pipe(ialu_reg_reg_fat); 5437 // %} 5438 5439 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5440 %{ 5441 match(Set dst mem); 5442 5443 ins_cost(110); 5444 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5445 opcode(0x8D); 5446 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5447 ins_pipe(ialu_reg_reg_fat); 5448 %} 5449 5450 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5451 %{ 5452 match(Set dst mem); 5453 5454 ins_cost(110); 5455 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5456 opcode(0x8D); 5457 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5458 ins_pipe(ialu_reg_reg_fat); 5459 %} 5460 5461 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5462 %{ 5463 match(Set dst mem); 5464 5465 ins_cost(110); 5466 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5467 opcode(0x8D); 5468 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5469 ins_pipe(ialu_reg_reg_fat); 5470 %} 5471 5472 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5473 %{ 5474 match(Set dst mem); 5475 5476 ins_cost(110); 5477 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5478 opcode(0x8D); 5479 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5480 ins_pipe(ialu_reg_reg_fat); 5481 %} 5482 5483 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5484 %{ 5485 match(Set dst mem); 5486 5487 ins_cost(110); 5488 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5489 opcode(0x8D); 5490 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5491 ins_pipe(ialu_reg_reg_fat); 5492 %} 5493 5494 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5495 %{ 5496 match(Set dst mem); 5497 5498 ins_cost(110); 5499 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5500 opcode(0x8D); 5501 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5502 ins_pipe(ialu_reg_reg_fat); 5503 %} 5504 5505 // Load Effective Address which uses Narrow (32-bits) oop 5506 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5507 %{ 5508 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 5509 match(Set dst mem); 5510 5511 ins_cost(110); 5512 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5513 opcode(0x8D); 5514 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5515 ins_pipe(ialu_reg_reg_fat); 5516 %} 5517 5518 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5519 %{ 5520 predicate(CompressedOops::shift() == 0); 5521 match(Set dst mem); 5522 5523 ins_cost(110); // XXX 5524 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5525 opcode(0x8D); 5526 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5527 ins_pipe(ialu_reg_reg_fat); 5528 %} 5529 5530 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5531 %{ 5532 predicate(CompressedOops::shift() == 0); 5533 match(Set dst mem); 5534 5535 ins_cost(110); 5536 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5537 opcode(0x8D); 5538 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5539 ins_pipe(ialu_reg_reg_fat); 5540 %} 5541 5542 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5543 %{ 5544 predicate(CompressedOops::shift() == 0); 5545 match(Set dst mem); 5546 5547 ins_cost(110); 5548 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5549 opcode(0x8D); 5550 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5551 ins_pipe(ialu_reg_reg_fat); 5552 %} 5553 5554 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5555 %{ 5556 predicate(CompressedOops::shift() == 0); 5557 match(Set dst mem); 5558 5559 ins_cost(110); 5560 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5561 opcode(0x8D); 5562 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5563 ins_pipe(ialu_reg_reg_fat); 5564 %} 5565 5566 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5567 %{ 5568 predicate(CompressedOops::shift() == 0); 5569 match(Set dst mem); 5570 5571 ins_cost(110); 5572 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5573 opcode(0x8D); 5574 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5575 ins_pipe(ialu_reg_reg_fat); 5576 %} 5577 5578 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5579 %{ 5580 predicate(CompressedOops::shift() == 0); 5581 match(Set dst mem); 5582 5583 ins_cost(110); 5584 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5585 opcode(0x8D); 5586 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5587 ins_pipe(ialu_reg_reg_fat); 5588 %} 5589 5590 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5591 %{ 5592 predicate(CompressedOops::shift() == 0); 5593 match(Set dst mem); 5594 5595 ins_cost(110); 5596 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5597 opcode(0x8D); 5598 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5599 ins_pipe(ialu_reg_reg_fat); 5600 %} 5601 5602 instruct loadConI(rRegI dst, immI src) 5603 %{ 5604 match(Set dst src); 5605 5606 format %{ "movl $dst, $src\t# int" %} 5607 ins_encode(load_immI(dst, src)); 5608 ins_pipe(ialu_reg_fat); // XXX 5609 %} 5610 5611 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5612 %{ 5613 match(Set dst src); 5614 effect(KILL cr); 5615 5616 ins_cost(50); 5617 format %{ "xorl $dst, $dst\t# int" %} 5618 opcode(0x33); /* + rd */ 5619 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5620 ins_pipe(ialu_reg); 5621 %} 5622 5623 instruct loadConL(rRegL dst, immL src) 5624 %{ 5625 match(Set dst src); 5626 5627 ins_cost(150); 5628 format %{ "movq $dst, $src\t# long" %} 5629 ins_encode(load_immL(dst, src)); 5630 ins_pipe(ialu_reg); 5631 %} 5632 5633 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5634 %{ 5635 match(Set dst src); 5636 effect(KILL cr); 5637 5638 ins_cost(50); 5639 format %{ "xorl $dst, $dst\t# long" %} 5640 opcode(0x33); /* + rd */ 5641 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5642 ins_pipe(ialu_reg); // XXX 5643 %} 5644 5645 instruct loadConUL32(rRegL dst, immUL32 src) 5646 %{ 5647 match(Set dst src); 5648 5649 ins_cost(60); 5650 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5651 ins_encode(load_immUL32(dst, src)); 5652 ins_pipe(ialu_reg); 5653 %} 5654 5655 instruct loadConL32(rRegL dst, immL32 src) 5656 %{ 5657 match(Set dst src); 5658 5659 ins_cost(70); 5660 format %{ "movq $dst, $src\t# long (32-bit)" %} 5661 ins_encode(load_immL32(dst, src)); 5662 ins_pipe(ialu_reg); 5663 %} 5664 5665 instruct loadConP(rRegP dst, immP con) %{ 5666 match(Set dst con); 5667 5668 format %{ "movq $dst, $con\t# ptr" %} 5669 ins_encode(load_immP(dst, con)); 5670 ins_pipe(ialu_reg_fat); // XXX 5671 %} 5672 5673 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5674 %{ 5675 match(Set dst src); 5676 effect(KILL cr); 5677 5678 ins_cost(50); 5679 format %{ "xorl $dst, $dst\t# ptr" %} 5680 opcode(0x33); /* + rd */ 5681 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5682 ins_pipe(ialu_reg); 5683 %} 5684 5685 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5686 %{ 5687 match(Set dst src); 5688 effect(KILL cr); 5689 5690 ins_cost(60); 5691 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5692 ins_encode(load_immP31(dst, src)); 5693 ins_pipe(ialu_reg); 5694 %} 5695 5696 instruct loadConF(regF dst, immF con) %{ 5697 match(Set dst con); 5698 ins_cost(125); 5699 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5700 ins_encode %{ 5701 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5702 %} 5703 ins_pipe(pipe_slow); 5704 %} 5705 5706 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5707 match(Set dst src); 5708 effect(KILL cr); 5709 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5710 ins_encode %{ 5711 __ xorq($dst$$Register, $dst$$Register); 5712 %} 5713 ins_pipe(ialu_reg); 5714 %} 5715 5716 instruct loadConN(rRegN dst, immN src) %{ 5717 match(Set dst src); 5718 5719 ins_cost(125); 5720 format %{ "movl $dst, $src\t# compressed ptr" %} 5721 ins_encode %{ 5722 address con = (address)$src$$constant; 5723 if (con == NULL) { 5724 ShouldNotReachHere(); 5725 } else { 5726 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5727 } 5728 %} 5729 ins_pipe(ialu_reg_fat); // XXX 5730 %} 5731 5732 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5733 match(Set dst src); 5734 5735 ins_cost(125); 5736 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5737 ins_encode %{ 5738 address con = (address)$src$$constant; 5739 if (con == NULL) { 5740 ShouldNotReachHere(); 5741 } else { 5742 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5743 } 5744 %} 5745 ins_pipe(ialu_reg_fat); // XXX 5746 %} 5747 5748 instruct loadConF0(regF dst, immF0 src) 5749 %{ 5750 match(Set dst src); 5751 ins_cost(100); 5752 5753 format %{ "xorps $dst, $dst\t# float 0.0" %} 5754 ins_encode %{ 5755 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5756 %} 5757 ins_pipe(pipe_slow); 5758 %} 5759 5760 // Use the same format since predicate() can not be used here. 5761 instruct loadConD(regD dst, immD con) %{ 5762 match(Set dst con); 5763 ins_cost(125); 5764 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5765 ins_encode %{ 5766 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5767 %} 5768 ins_pipe(pipe_slow); 5769 %} 5770 5771 instruct loadConD0(regD dst, immD0 src) 5772 %{ 5773 match(Set dst src); 5774 ins_cost(100); 5775 5776 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5777 ins_encode %{ 5778 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5779 %} 5780 ins_pipe(pipe_slow); 5781 %} 5782 5783 instruct loadSSI(rRegI dst, stackSlotI src) 5784 %{ 5785 match(Set dst src); 5786 5787 ins_cost(125); 5788 format %{ "movl $dst, $src\t# int stk" %} 5789 opcode(0x8B); 5790 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5791 ins_pipe(ialu_reg_mem); 5792 %} 5793 5794 instruct loadSSL(rRegL dst, stackSlotL src) 5795 %{ 5796 match(Set dst src); 5797 5798 ins_cost(125); 5799 format %{ "movq $dst, $src\t# long stk" %} 5800 opcode(0x8B); 5801 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5802 ins_pipe(ialu_reg_mem); 5803 %} 5804 5805 instruct loadSSP(rRegP dst, stackSlotP src) 5806 %{ 5807 match(Set dst src); 5808 5809 ins_cost(125); 5810 format %{ "movq $dst, $src\t# ptr stk" %} 5811 opcode(0x8B); 5812 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5813 ins_pipe(ialu_reg_mem); 5814 %} 5815 5816 instruct loadSSF(regF dst, stackSlotF src) 5817 %{ 5818 match(Set dst src); 5819 5820 ins_cost(125); 5821 format %{ "movss $dst, $src\t# float stk" %} 5822 ins_encode %{ 5823 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5824 %} 5825 ins_pipe(pipe_slow); // XXX 5826 %} 5827 5828 // Use the same format since predicate() can not be used here. 5829 instruct loadSSD(regD dst, stackSlotD src) 5830 %{ 5831 match(Set dst src); 5832 5833 ins_cost(125); 5834 format %{ "movsd $dst, $src\t# double stk" %} 5835 ins_encode %{ 5836 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5837 %} 5838 ins_pipe(pipe_slow); // XXX 5839 %} 5840 5841 // Prefetch instructions for allocation. 5842 // Must be safe to execute with invalid address (cannot fault). 5843 5844 instruct prefetchAlloc( memory mem ) %{ 5845 predicate(AllocatePrefetchInstr==3); 5846 match(PrefetchAllocation mem); 5847 ins_cost(125); 5848 5849 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5850 ins_encode %{ 5851 __ prefetchw($mem$$Address); 5852 %} 5853 ins_pipe(ialu_mem); 5854 %} 5855 5856 instruct prefetchAllocNTA( memory mem ) %{ 5857 predicate(AllocatePrefetchInstr==0); 5858 match(PrefetchAllocation mem); 5859 ins_cost(125); 5860 5861 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5862 ins_encode %{ 5863 __ prefetchnta($mem$$Address); 5864 %} 5865 ins_pipe(ialu_mem); 5866 %} 5867 5868 instruct prefetchAllocT0( memory mem ) %{ 5869 predicate(AllocatePrefetchInstr==1); 5870 match(PrefetchAllocation mem); 5871 ins_cost(125); 5872 5873 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5874 ins_encode %{ 5875 __ prefetcht0($mem$$Address); 5876 %} 5877 ins_pipe(ialu_mem); 5878 %} 5879 5880 instruct prefetchAllocT2( memory mem ) %{ 5881 predicate(AllocatePrefetchInstr==2); 5882 match(PrefetchAllocation mem); 5883 ins_cost(125); 5884 5885 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5886 ins_encode %{ 5887 __ prefetcht2($mem$$Address); 5888 %} 5889 ins_pipe(ialu_mem); 5890 %} 5891 5892 //----------Store Instructions------------------------------------------------- 5893 5894 // Store Byte 5895 instruct storeB(memory mem, rRegI src) 5896 %{ 5897 match(Set mem (StoreB mem src)); 5898 5899 ins_cost(125); // XXX 5900 format %{ "movb $mem, $src\t# byte" %} 5901 opcode(0x88); 5902 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5903 ins_pipe(ialu_mem_reg); 5904 %} 5905 5906 // Store Char/Short 5907 instruct storeC(memory mem, rRegI src) 5908 %{ 5909 match(Set mem (StoreC mem src)); 5910 5911 ins_cost(125); // XXX 5912 format %{ "movw $mem, $src\t# char/short" %} 5913 opcode(0x89); 5914 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5915 ins_pipe(ialu_mem_reg); 5916 %} 5917 5918 // Store Integer 5919 instruct storeI(memory mem, rRegI src) 5920 %{ 5921 match(Set mem (StoreI mem src)); 5922 5923 ins_cost(125); // XXX 5924 format %{ "movl $mem, $src\t# int" %} 5925 opcode(0x89); 5926 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5927 ins_pipe(ialu_mem_reg); 5928 %} 5929 5930 // Store Long 5931 instruct storeL(memory mem, rRegL src) 5932 %{ 5933 match(Set mem (StoreL mem src)); 5934 5935 ins_cost(125); // XXX 5936 format %{ "movq $mem, $src\t# long" %} 5937 opcode(0x89); 5938 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5939 ins_pipe(ialu_mem_reg); // XXX 5940 %} 5941 5942 // Store Pointer 5943 instruct storeP(memory mem, any_RegP src) 5944 %{ 5945 match(Set mem (StoreP mem src)); 5946 5947 ins_cost(125); // XXX 5948 format %{ "movq $mem, $src\t# ptr" %} 5949 opcode(0x89); 5950 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5951 ins_pipe(ialu_mem_reg); 5952 %} 5953 5954 instruct storeImmP0(memory mem, immP0 zero) 5955 %{ 5956 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 5957 match(Set mem (StoreP mem zero)); 5958 5959 ins_cost(125); // XXX 5960 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5961 ins_encode %{ 5962 __ movq($mem$$Address, r12); 5963 %} 5964 ins_pipe(ialu_mem_reg); 5965 %} 5966 5967 // Store NULL Pointer, mark word, or other simple pointer constant. 5968 instruct storeImmP(memory mem, immP31 src) 5969 %{ 5970 match(Set mem (StoreP mem src)); 5971 5972 ins_cost(150); // XXX 5973 format %{ "movq $mem, $src\t# ptr" %} 5974 opcode(0xC7); /* C7 /0 */ 5975 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5976 ins_pipe(ialu_mem_imm); 5977 %} 5978 5979 // Store Compressed Pointer 5980 instruct storeN(memory mem, rRegN src) 5981 %{ 5982 match(Set mem (StoreN mem src)); 5983 5984 ins_cost(125); // XXX 5985 format %{ "movl $mem, $src\t# compressed ptr" %} 5986 ins_encode %{ 5987 __ movl($mem$$Address, $src$$Register); 5988 %} 5989 ins_pipe(ialu_mem_reg); 5990 %} 5991 5992 instruct storeNKlass(memory mem, rRegN src) 5993 %{ 5994 match(Set mem (StoreNKlass mem src)); 5995 5996 ins_cost(125); // XXX 5997 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5998 ins_encode %{ 5999 __ movl($mem$$Address, $src$$Register); 6000 %} 6001 ins_pipe(ialu_mem_reg); 6002 %} 6003 6004 instruct storeImmN0(memory mem, immN0 zero) 6005 %{ 6006 predicate(CompressedOops::base() == NULL); 6007 match(Set mem (StoreN mem zero)); 6008 6009 ins_cost(125); // XXX 6010 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6011 ins_encode %{ 6012 __ movl($mem$$Address, r12); 6013 %} 6014 ins_pipe(ialu_mem_reg); 6015 %} 6016 6017 instruct storeImmN(memory mem, immN src) 6018 %{ 6019 match(Set mem (StoreN mem src)); 6020 6021 ins_cost(150); // XXX 6022 format %{ "movl $mem, $src\t# compressed ptr" %} 6023 ins_encode %{ 6024 address con = (address)$src$$constant; 6025 if (con == NULL) { 6026 __ movl($mem$$Address, (int32_t)0); 6027 } else { 6028 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6029 } 6030 %} 6031 ins_pipe(ialu_mem_imm); 6032 %} 6033 6034 instruct storeImmNKlass(memory mem, immNKlass src) 6035 %{ 6036 match(Set mem (StoreNKlass mem src)); 6037 6038 ins_cost(150); // XXX 6039 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6040 ins_encode %{ 6041 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6042 %} 6043 ins_pipe(ialu_mem_imm); 6044 %} 6045 6046 // Store Integer Immediate 6047 instruct storeImmI0(memory mem, immI0 zero) 6048 %{ 6049 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6050 match(Set mem (StoreI mem zero)); 6051 6052 ins_cost(125); // XXX 6053 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6054 ins_encode %{ 6055 __ movl($mem$$Address, r12); 6056 %} 6057 ins_pipe(ialu_mem_reg); 6058 %} 6059 6060 instruct storeImmI(memory mem, immI src) 6061 %{ 6062 match(Set mem (StoreI mem src)); 6063 6064 ins_cost(150); 6065 format %{ "movl $mem, $src\t# int" %} 6066 opcode(0xC7); /* C7 /0 */ 6067 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6068 ins_pipe(ialu_mem_imm); 6069 %} 6070 6071 // Store Long Immediate 6072 instruct storeImmL0(memory mem, immL0 zero) 6073 %{ 6074 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6075 match(Set mem (StoreL mem zero)); 6076 6077 ins_cost(125); // XXX 6078 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6079 ins_encode %{ 6080 __ movq($mem$$Address, r12); 6081 %} 6082 ins_pipe(ialu_mem_reg); 6083 %} 6084 6085 instruct storeImmL(memory mem, immL32 src) 6086 %{ 6087 match(Set mem (StoreL mem src)); 6088 6089 ins_cost(150); 6090 format %{ "movq $mem, $src\t# long" %} 6091 opcode(0xC7); /* C7 /0 */ 6092 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6093 ins_pipe(ialu_mem_imm); 6094 %} 6095 6096 // Store Short/Char Immediate 6097 instruct storeImmC0(memory mem, immI0 zero) 6098 %{ 6099 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6100 match(Set mem (StoreC mem zero)); 6101 6102 ins_cost(125); // XXX 6103 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6104 ins_encode %{ 6105 __ movw($mem$$Address, r12); 6106 %} 6107 ins_pipe(ialu_mem_reg); 6108 %} 6109 6110 instruct storeImmI16(memory mem, immI16 src) 6111 %{ 6112 predicate(UseStoreImmI16); 6113 match(Set mem (StoreC mem src)); 6114 6115 ins_cost(150); 6116 format %{ "movw $mem, $src\t# short/char" %} 6117 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6118 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6119 ins_pipe(ialu_mem_imm); 6120 %} 6121 6122 // Store Byte Immediate 6123 instruct storeImmB0(memory mem, immI0 zero) 6124 %{ 6125 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6126 match(Set mem (StoreB mem zero)); 6127 6128 ins_cost(125); // XXX 6129 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6130 ins_encode %{ 6131 __ movb($mem$$Address, r12); 6132 %} 6133 ins_pipe(ialu_mem_reg); 6134 %} 6135 6136 instruct storeImmB(memory mem, immI8 src) 6137 %{ 6138 match(Set mem (StoreB mem src)); 6139 6140 ins_cost(150); // XXX 6141 format %{ "movb $mem, $src\t# byte" %} 6142 opcode(0xC6); /* C6 /0 */ 6143 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6144 ins_pipe(ialu_mem_imm); 6145 %} 6146 6147 // Store CMS card-mark Immediate 6148 instruct storeImmCM0_reg(memory mem, immI0 zero) 6149 %{ 6150 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6151 match(Set mem (StoreCM mem zero)); 6152 6153 ins_cost(125); // XXX 6154 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6155 ins_encode %{ 6156 __ movb($mem$$Address, r12); 6157 %} 6158 ins_pipe(ialu_mem_reg); 6159 %} 6160 6161 instruct storeImmCM0(memory mem, immI0 src) 6162 %{ 6163 match(Set mem (StoreCM mem src)); 6164 6165 ins_cost(150); // XXX 6166 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6167 opcode(0xC6); /* C6 /0 */ 6168 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6169 ins_pipe(ialu_mem_imm); 6170 %} 6171 6172 // Store Float 6173 instruct storeF(memory mem, regF src) 6174 %{ 6175 match(Set mem (StoreF mem src)); 6176 6177 ins_cost(95); // XXX 6178 format %{ "movss $mem, $src\t# float" %} 6179 ins_encode %{ 6180 __ movflt($mem$$Address, $src$$XMMRegister); 6181 %} 6182 ins_pipe(pipe_slow); // XXX 6183 %} 6184 6185 // Store immediate Float value (it is faster than store from XMM register) 6186 instruct storeF0(memory mem, immF0 zero) 6187 %{ 6188 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6189 match(Set mem (StoreF mem zero)); 6190 6191 ins_cost(25); // XXX 6192 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6193 ins_encode %{ 6194 __ movl($mem$$Address, r12); 6195 %} 6196 ins_pipe(ialu_mem_reg); 6197 %} 6198 6199 instruct storeF_imm(memory mem, immF src) 6200 %{ 6201 match(Set mem (StoreF mem src)); 6202 6203 ins_cost(50); 6204 format %{ "movl $mem, $src\t# float" %} 6205 opcode(0xC7); /* C7 /0 */ 6206 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6207 ins_pipe(ialu_mem_imm); 6208 %} 6209 6210 // Store Double 6211 instruct storeD(memory mem, regD src) 6212 %{ 6213 match(Set mem (StoreD mem src)); 6214 6215 ins_cost(95); // XXX 6216 format %{ "movsd $mem, $src\t# double" %} 6217 ins_encode %{ 6218 __ movdbl($mem$$Address, $src$$XMMRegister); 6219 %} 6220 ins_pipe(pipe_slow); // XXX 6221 %} 6222 6223 // Store immediate double 0.0 (it is faster than store from XMM register) 6224 instruct storeD0_imm(memory mem, immD0 src) 6225 %{ 6226 predicate(!UseCompressedOops || (CompressedOops::base() != NULL)); 6227 match(Set mem (StoreD mem src)); 6228 6229 ins_cost(50); 6230 format %{ "movq $mem, $src\t# double 0." %} 6231 opcode(0xC7); /* C7 /0 */ 6232 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6233 ins_pipe(ialu_mem_imm); 6234 %} 6235 6236 instruct storeD0(memory mem, immD0 zero) 6237 %{ 6238 predicate(UseCompressedOops && (CompressedOops::base() == NULL)); 6239 match(Set mem (StoreD mem zero)); 6240 6241 ins_cost(25); // XXX 6242 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6243 ins_encode %{ 6244 __ movq($mem$$Address, r12); 6245 %} 6246 ins_pipe(ialu_mem_reg); 6247 %} 6248 6249 instruct storeSSI(stackSlotI dst, rRegI src) 6250 %{ 6251 match(Set dst src); 6252 6253 ins_cost(100); 6254 format %{ "movl $dst, $src\t# int stk" %} 6255 opcode(0x89); 6256 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6257 ins_pipe( ialu_mem_reg ); 6258 %} 6259 6260 instruct storeSSL(stackSlotL dst, rRegL src) 6261 %{ 6262 match(Set dst src); 6263 6264 ins_cost(100); 6265 format %{ "movq $dst, $src\t# long stk" %} 6266 opcode(0x89); 6267 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6268 ins_pipe(ialu_mem_reg); 6269 %} 6270 6271 instruct storeSSP(stackSlotP dst, rRegP src) 6272 %{ 6273 match(Set dst src); 6274 6275 ins_cost(100); 6276 format %{ "movq $dst, $src\t# ptr stk" %} 6277 opcode(0x89); 6278 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6279 ins_pipe(ialu_mem_reg); 6280 %} 6281 6282 instruct storeSSF(stackSlotF dst, regF src) 6283 %{ 6284 match(Set dst src); 6285 6286 ins_cost(95); // XXX 6287 format %{ "movss $dst, $src\t# float stk" %} 6288 ins_encode %{ 6289 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6290 %} 6291 ins_pipe(pipe_slow); // XXX 6292 %} 6293 6294 instruct storeSSD(stackSlotD dst, regD src) 6295 %{ 6296 match(Set dst src); 6297 6298 ins_cost(95); // XXX 6299 format %{ "movsd $dst, $src\t# double stk" %} 6300 ins_encode %{ 6301 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6302 %} 6303 ins_pipe(pipe_slow); // XXX 6304 %} 6305 6306 instruct cacheWB(indirect addr) 6307 %{ 6308 predicate(VM_Version::supports_data_cache_line_flush()); 6309 match(CacheWB addr); 6310 6311 ins_cost(100); 6312 format %{"cache wb $addr" %} 6313 ins_encode %{ 6314 assert($addr->index_position() < 0, "should be"); 6315 assert($addr$$disp == 0, "should be"); 6316 __ cache_wb(Address($addr$$base$$Register, 0)); 6317 %} 6318 ins_pipe(pipe_slow); // XXX 6319 %} 6320 6321 instruct cacheWBPreSync() 6322 %{ 6323 predicate(VM_Version::supports_data_cache_line_flush()); 6324 match(CacheWBPreSync); 6325 6326 ins_cost(100); 6327 format %{"cache wb presync" %} 6328 ins_encode %{ 6329 __ cache_wbsync(true); 6330 %} 6331 ins_pipe(pipe_slow); // XXX 6332 %} 6333 6334 instruct cacheWBPostSync() 6335 %{ 6336 predicate(VM_Version::supports_data_cache_line_flush()); 6337 match(CacheWBPostSync); 6338 6339 ins_cost(100); 6340 format %{"cache wb postsync" %} 6341 ins_encode %{ 6342 __ cache_wbsync(false); 6343 %} 6344 ins_pipe(pipe_slow); // XXX 6345 %} 6346 6347 //----------BSWAP Instructions------------------------------------------------- 6348 instruct bytes_reverse_int(rRegI dst) %{ 6349 match(Set dst (ReverseBytesI dst)); 6350 6351 format %{ "bswapl $dst" %} 6352 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6353 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6354 ins_pipe( ialu_reg ); 6355 %} 6356 6357 instruct bytes_reverse_long(rRegL dst) %{ 6358 match(Set dst (ReverseBytesL dst)); 6359 6360 format %{ "bswapq $dst" %} 6361 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6362 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6363 ins_pipe( ialu_reg); 6364 %} 6365 6366 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6367 match(Set dst (ReverseBytesUS dst)); 6368 effect(KILL cr); 6369 6370 format %{ "bswapl $dst\n\t" 6371 "shrl $dst,16\n\t" %} 6372 ins_encode %{ 6373 __ bswapl($dst$$Register); 6374 __ shrl($dst$$Register, 16); 6375 %} 6376 ins_pipe( ialu_reg ); 6377 %} 6378 6379 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6380 match(Set dst (ReverseBytesS dst)); 6381 effect(KILL cr); 6382 6383 format %{ "bswapl $dst\n\t" 6384 "sar $dst,16\n\t" %} 6385 ins_encode %{ 6386 __ bswapl($dst$$Register); 6387 __ sarl($dst$$Register, 16); 6388 %} 6389 ins_pipe( ialu_reg ); 6390 %} 6391 6392 //---------- Zeros Count Instructions ------------------------------------------ 6393 6394 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6395 predicate(UseCountLeadingZerosInstruction); 6396 match(Set dst (CountLeadingZerosI src)); 6397 effect(KILL cr); 6398 6399 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6400 ins_encode %{ 6401 __ lzcntl($dst$$Register, $src$$Register); 6402 %} 6403 ins_pipe(ialu_reg); 6404 %} 6405 6406 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6407 predicate(!UseCountLeadingZerosInstruction); 6408 match(Set dst (CountLeadingZerosI src)); 6409 effect(KILL cr); 6410 6411 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6412 "jnz skip\n\t" 6413 "movl $dst, -1\n" 6414 "skip:\n\t" 6415 "negl $dst\n\t" 6416 "addl $dst, 31" %} 6417 ins_encode %{ 6418 Register Rdst = $dst$$Register; 6419 Register Rsrc = $src$$Register; 6420 Label skip; 6421 __ bsrl(Rdst, Rsrc); 6422 __ jccb(Assembler::notZero, skip); 6423 __ movl(Rdst, -1); 6424 __ bind(skip); 6425 __ negl(Rdst); 6426 __ addl(Rdst, BitsPerInt - 1); 6427 %} 6428 ins_pipe(ialu_reg); 6429 %} 6430 6431 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6432 predicate(UseCountLeadingZerosInstruction); 6433 match(Set dst (CountLeadingZerosL src)); 6434 effect(KILL cr); 6435 6436 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6437 ins_encode %{ 6438 __ lzcntq($dst$$Register, $src$$Register); 6439 %} 6440 ins_pipe(ialu_reg); 6441 %} 6442 6443 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6444 predicate(!UseCountLeadingZerosInstruction); 6445 match(Set dst (CountLeadingZerosL src)); 6446 effect(KILL cr); 6447 6448 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6449 "jnz skip\n\t" 6450 "movl $dst, -1\n" 6451 "skip:\n\t" 6452 "negl $dst\n\t" 6453 "addl $dst, 63" %} 6454 ins_encode %{ 6455 Register Rdst = $dst$$Register; 6456 Register Rsrc = $src$$Register; 6457 Label skip; 6458 __ bsrq(Rdst, Rsrc); 6459 __ jccb(Assembler::notZero, skip); 6460 __ movl(Rdst, -1); 6461 __ bind(skip); 6462 __ negl(Rdst); 6463 __ addl(Rdst, BitsPerLong - 1); 6464 %} 6465 ins_pipe(ialu_reg); 6466 %} 6467 6468 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6469 predicate(UseCountTrailingZerosInstruction); 6470 match(Set dst (CountTrailingZerosI src)); 6471 effect(KILL cr); 6472 6473 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6474 ins_encode %{ 6475 __ tzcntl($dst$$Register, $src$$Register); 6476 %} 6477 ins_pipe(ialu_reg); 6478 %} 6479 6480 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6481 predicate(!UseCountTrailingZerosInstruction); 6482 match(Set dst (CountTrailingZerosI src)); 6483 effect(KILL cr); 6484 6485 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6486 "jnz done\n\t" 6487 "movl $dst, 32\n" 6488 "done:" %} 6489 ins_encode %{ 6490 Register Rdst = $dst$$Register; 6491 Label done; 6492 __ bsfl(Rdst, $src$$Register); 6493 __ jccb(Assembler::notZero, done); 6494 __ movl(Rdst, BitsPerInt); 6495 __ bind(done); 6496 %} 6497 ins_pipe(ialu_reg); 6498 %} 6499 6500 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6501 predicate(UseCountTrailingZerosInstruction); 6502 match(Set dst (CountTrailingZerosL src)); 6503 effect(KILL cr); 6504 6505 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6506 ins_encode %{ 6507 __ tzcntq($dst$$Register, $src$$Register); 6508 %} 6509 ins_pipe(ialu_reg); 6510 %} 6511 6512 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6513 predicate(!UseCountTrailingZerosInstruction); 6514 match(Set dst (CountTrailingZerosL src)); 6515 effect(KILL cr); 6516 6517 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6518 "jnz done\n\t" 6519 "movl $dst, 64\n" 6520 "done:" %} 6521 ins_encode %{ 6522 Register Rdst = $dst$$Register; 6523 Label done; 6524 __ bsfq(Rdst, $src$$Register); 6525 __ jccb(Assembler::notZero, done); 6526 __ movl(Rdst, BitsPerLong); 6527 __ bind(done); 6528 %} 6529 ins_pipe(ialu_reg); 6530 %} 6531 6532 6533 //---------- Population Count Instructions ------------------------------------- 6534 6535 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6536 predicate(UsePopCountInstruction); 6537 match(Set dst (PopCountI src)); 6538 effect(KILL cr); 6539 6540 format %{ "popcnt $dst, $src" %} 6541 ins_encode %{ 6542 __ popcntl($dst$$Register, $src$$Register); 6543 %} 6544 ins_pipe(ialu_reg); 6545 %} 6546 6547 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6548 predicate(UsePopCountInstruction); 6549 match(Set dst (PopCountI (LoadI mem))); 6550 effect(KILL cr); 6551 6552 format %{ "popcnt $dst, $mem" %} 6553 ins_encode %{ 6554 __ popcntl($dst$$Register, $mem$$Address); 6555 %} 6556 ins_pipe(ialu_reg); 6557 %} 6558 6559 // Note: Long.bitCount(long) returns an int. 6560 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6561 predicate(UsePopCountInstruction); 6562 match(Set dst (PopCountL src)); 6563 effect(KILL cr); 6564 6565 format %{ "popcnt $dst, $src" %} 6566 ins_encode %{ 6567 __ popcntq($dst$$Register, $src$$Register); 6568 %} 6569 ins_pipe(ialu_reg); 6570 %} 6571 6572 // Note: Long.bitCount(long) returns an int. 6573 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6574 predicate(UsePopCountInstruction); 6575 match(Set dst (PopCountL (LoadL mem))); 6576 effect(KILL cr); 6577 6578 format %{ "popcnt $dst, $mem" %} 6579 ins_encode %{ 6580 __ popcntq($dst$$Register, $mem$$Address); 6581 %} 6582 ins_pipe(ialu_reg); 6583 %} 6584 6585 6586 //----------MemBar Instructions----------------------------------------------- 6587 // Memory barrier flavors 6588 6589 instruct membar_acquire() 6590 %{ 6591 match(MemBarAcquire); 6592 match(LoadFence); 6593 ins_cost(0); 6594 6595 size(0); 6596 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6597 ins_encode(); 6598 ins_pipe(empty); 6599 %} 6600 6601 instruct membar_acquire_lock() 6602 %{ 6603 match(MemBarAcquireLock); 6604 ins_cost(0); 6605 6606 size(0); 6607 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6608 ins_encode(); 6609 ins_pipe(empty); 6610 %} 6611 6612 instruct membar_release() 6613 %{ 6614 match(MemBarRelease); 6615 match(StoreFence); 6616 ins_cost(0); 6617 6618 size(0); 6619 format %{ "MEMBAR-release ! (empty encoding)" %} 6620 ins_encode(); 6621 ins_pipe(empty); 6622 %} 6623 6624 instruct membar_release_lock() 6625 %{ 6626 match(MemBarReleaseLock); 6627 ins_cost(0); 6628 6629 size(0); 6630 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6631 ins_encode(); 6632 ins_pipe(empty); 6633 %} 6634 6635 instruct membar_volatile(rFlagsReg cr) %{ 6636 match(MemBarVolatile); 6637 effect(KILL cr); 6638 ins_cost(400); 6639 6640 format %{ 6641 $$template 6642 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6643 %} 6644 ins_encode %{ 6645 __ membar(Assembler::StoreLoad); 6646 %} 6647 ins_pipe(pipe_slow); 6648 %} 6649 6650 instruct unnecessary_membar_volatile() 6651 %{ 6652 match(MemBarVolatile); 6653 predicate(Matcher::post_store_load_barrier(n)); 6654 ins_cost(0); 6655 6656 size(0); 6657 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6658 ins_encode(); 6659 ins_pipe(empty); 6660 %} 6661 6662 instruct membar_storestore() %{ 6663 match(MemBarStoreStore); 6664 ins_cost(0); 6665 6666 size(0); 6667 format %{ "MEMBAR-storestore (empty encoding)" %} 6668 ins_encode( ); 6669 ins_pipe(empty); 6670 %} 6671 6672 //----------Move Instructions-------------------------------------------------- 6673 6674 instruct castX2P(rRegP dst, rRegL src) 6675 %{ 6676 match(Set dst (CastX2P src)); 6677 6678 format %{ "movq $dst, $src\t# long->ptr" %} 6679 ins_encode %{ 6680 if ($dst$$reg != $src$$reg) { 6681 __ movptr($dst$$Register, $src$$Register); 6682 } 6683 %} 6684 ins_pipe(ialu_reg_reg); // XXX 6685 %} 6686 6687 instruct castP2X(rRegL dst, rRegP src) 6688 %{ 6689 match(Set dst (CastP2X src)); 6690 6691 format %{ "movq $dst, $src\t# ptr -> long" %} 6692 ins_encode %{ 6693 if ($dst$$reg != $src$$reg) { 6694 __ movptr($dst$$Register, $src$$Register); 6695 } 6696 %} 6697 ins_pipe(ialu_reg_reg); // XXX 6698 %} 6699 6700 // Convert oop into int for vectors alignment masking 6701 instruct convP2I(rRegI dst, rRegP src) 6702 %{ 6703 match(Set dst (ConvL2I (CastP2X src))); 6704 6705 format %{ "movl $dst, $src\t# ptr -> int" %} 6706 ins_encode %{ 6707 __ movl($dst$$Register, $src$$Register); 6708 %} 6709 ins_pipe(ialu_reg_reg); // XXX 6710 %} 6711 6712 // Convert compressed oop into int for vectors alignment masking 6713 // in case of 32bit oops (heap < 4Gb). 6714 instruct convN2I(rRegI dst, rRegN src) 6715 %{ 6716 predicate(CompressedOops::shift() == 0); 6717 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6718 6719 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6720 ins_encode %{ 6721 __ movl($dst$$Register, $src$$Register); 6722 %} 6723 ins_pipe(ialu_reg_reg); // XXX 6724 %} 6725 6726 // Convert oop pointer into compressed form 6727 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6728 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6729 match(Set dst (EncodeP src)); 6730 effect(KILL cr); 6731 format %{ "encode_heap_oop $dst,$src" %} 6732 ins_encode %{ 6733 Register s = $src$$Register; 6734 Register d = $dst$$Register; 6735 if (s != d) { 6736 __ movq(d, s); 6737 } 6738 __ encode_heap_oop(d); 6739 %} 6740 ins_pipe(ialu_reg_long); 6741 %} 6742 6743 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6744 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6745 match(Set dst (EncodeP src)); 6746 effect(KILL cr); 6747 format %{ "encode_heap_oop_not_null $dst,$src" %} 6748 ins_encode %{ 6749 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6750 %} 6751 ins_pipe(ialu_reg_long); 6752 %} 6753 6754 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6755 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6756 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6757 match(Set dst (DecodeN src)); 6758 effect(KILL cr); 6759 format %{ "decode_heap_oop $dst,$src" %} 6760 ins_encode %{ 6761 Register s = $src$$Register; 6762 Register d = $dst$$Register; 6763 if (s != d) { 6764 __ movq(d, s); 6765 } 6766 __ decode_heap_oop(d); 6767 %} 6768 ins_pipe(ialu_reg_long); 6769 %} 6770 6771 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6772 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6773 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6774 match(Set dst (DecodeN src)); 6775 effect(KILL cr); 6776 format %{ "decode_heap_oop_not_null $dst,$src" %} 6777 ins_encode %{ 6778 Register s = $src$$Register; 6779 Register d = $dst$$Register; 6780 if (s != d) { 6781 __ decode_heap_oop_not_null(d, s); 6782 } else { 6783 __ decode_heap_oop_not_null(d); 6784 } 6785 %} 6786 ins_pipe(ialu_reg_long); 6787 %} 6788 6789 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6790 match(Set dst (EncodePKlass src)); 6791 effect(TEMP dst, KILL cr); 6792 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6793 ins_encode %{ 6794 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6795 %} 6796 ins_pipe(ialu_reg_long); 6797 %} 6798 6799 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6800 match(Set dst (DecodeNKlass src)); 6801 effect(TEMP dst, KILL cr); 6802 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6803 ins_encode %{ 6804 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6805 %} 6806 ins_pipe(ialu_reg_long); 6807 %} 6808 6809 //----------Conditional Move--------------------------------------------------- 6810 // Jump 6811 // dummy instruction for generating temp registers 6812 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6813 match(Jump (LShiftL switch_val shift)); 6814 ins_cost(350); 6815 predicate(false); 6816 effect(TEMP dest); 6817 6818 format %{ "leaq $dest, [$constantaddress]\n\t" 6819 "jmp [$dest + $switch_val << $shift]\n\t" %} 6820 ins_encode %{ 6821 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6822 // to do that and the compiler is using that register as one it can allocate. 6823 // So we build it all by hand. 6824 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6825 // ArrayAddress dispatch(table, index); 6826 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6827 __ lea($dest$$Register, $constantaddress); 6828 __ jmp(dispatch); 6829 %} 6830 ins_pipe(pipe_jmp); 6831 %} 6832 6833 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6834 match(Jump (AddL (LShiftL switch_val shift) offset)); 6835 ins_cost(350); 6836 effect(TEMP dest); 6837 6838 format %{ "leaq $dest, [$constantaddress]\n\t" 6839 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6840 ins_encode %{ 6841 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6842 // to do that and the compiler is using that register as one it can allocate. 6843 // So we build it all by hand. 6844 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6845 // ArrayAddress dispatch(table, index); 6846 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6847 __ lea($dest$$Register, $constantaddress); 6848 __ jmp(dispatch); 6849 %} 6850 ins_pipe(pipe_jmp); 6851 %} 6852 6853 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6854 match(Jump switch_val); 6855 ins_cost(350); 6856 effect(TEMP dest); 6857 6858 format %{ "leaq $dest, [$constantaddress]\n\t" 6859 "jmp [$dest + $switch_val]\n\t" %} 6860 ins_encode %{ 6861 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6862 // to do that and the compiler is using that register as one it can allocate. 6863 // So we build it all by hand. 6864 // Address index(noreg, switch_reg, Address::times_1); 6865 // ArrayAddress dispatch(table, index); 6866 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6867 __ lea($dest$$Register, $constantaddress); 6868 __ jmp(dispatch); 6869 %} 6870 ins_pipe(pipe_jmp); 6871 %} 6872 6873 // Conditional move 6874 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6875 %{ 6876 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6877 6878 ins_cost(200); // XXX 6879 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6880 opcode(0x0F, 0x40); 6881 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6882 ins_pipe(pipe_cmov_reg); 6883 %} 6884 6885 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6886 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6887 6888 ins_cost(200); // XXX 6889 format %{ "cmovl$cop $dst, $src\t# unsigned, 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_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6896 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6897 ins_cost(200); 6898 expand %{ 6899 cmovI_regU(cop, cr, dst, src); 6900 %} 6901 %} 6902 6903 // Conditional move 6904 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6905 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6906 6907 ins_cost(250); // XXX 6908 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6909 opcode(0x0F, 0x40); 6910 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6911 ins_pipe(pipe_cmov_mem); 6912 %} 6913 6914 // Conditional move 6915 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6916 %{ 6917 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6918 6919 ins_cost(250); // XXX 6920 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6921 opcode(0x0F, 0x40); 6922 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6923 ins_pipe(pipe_cmov_mem); 6924 %} 6925 6926 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6927 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6928 ins_cost(250); 6929 expand %{ 6930 cmovI_memU(cop, cr, dst, src); 6931 %} 6932 %} 6933 6934 // Conditional move 6935 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6936 %{ 6937 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6938 6939 ins_cost(200); // XXX 6940 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6941 opcode(0x0F, 0x40); 6942 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6943 ins_pipe(pipe_cmov_reg); 6944 %} 6945 6946 // Conditional move 6947 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6948 %{ 6949 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6950 6951 ins_cost(200); // XXX 6952 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6953 opcode(0x0F, 0x40); 6954 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6955 ins_pipe(pipe_cmov_reg); 6956 %} 6957 6958 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6959 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6960 ins_cost(200); 6961 expand %{ 6962 cmovN_regU(cop, cr, dst, src); 6963 %} 6964 %} 6965 6966 // Conditional move 6967 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6968 %{ 6969 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6970 6971 ins_cost(200); // XXX 6972 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6973 opcode(0x0F, 0x40); 6974 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6975 ins_pipe(pipe_cmov_reg); // XXX 6976 %} 6977 6978 // Conditional move 6979 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6980 %{ 6981 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6982 6983 ins_cost(200); // XXX 6984 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6985 opcode(0x0F, 0x40); 6986 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6987 ins_pipe(pipe_cmov_reg); // XXX 6988 %} 6989 6990 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6991 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6992 ins_cost(200); 6993 expand %{ 6994 cmovP_regU(cop, cr, dst, src); 6995 %} 6996 %} 6997 6998 // DISABLED: Requires the ADLC to emit a bottom_type call that 6999 // correctly meets the two pointer arguments; one is an incoming 7000 // register but the other is a memory operand. ALSO appears to 7001 // be buggy with implicit null checks. 7002 // 7003 //// Conditional move 7004 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7005 //%{ 7006 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7007 // ins_cost(250); 7008 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7009 // opcode(0x0F,0x40); 7010 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7011 // ins_pipe( pipe_cmov_mem ); 7012 //%} 7013 // 7014 //// Conditional move 7015 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7016 //%{ 7017 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7018 // ins_cost(250); 7019 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7020 // opcode(0x0F,0x40); 7021 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7022 // ins_pipe( pipe_cmov_mem ); 7023 //%} 7024 7025 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7026 %{ 7027 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7028 7029 ins_cost(200); // XXX 7030 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7031 opcode(0x0F, 0x40); 7032 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7033 ins_pipe(pipe_cmov_reg); // XXX 7034 %} 7035 7036 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7037 %{ 7038 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7039 7040 ins_cost(200); // XXX 7041 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7042 opcode(0x0F, 0x40); 7043 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7044 ins_pipe(pipe_cmov_mem); // XXX 7045 %} 7046 7047 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7048 %{ 7049 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7050 7051 ins_cost(200); // XXX 7052 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7053 opcode(0x0F, 0x40); 7054 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7055 ins_pipe(pipe_cmov_reg); // XXX 7056 %} 7057 7058 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7059 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7060 ins_cost(200); 7061 expand %{ 7062 cmovL_regU(cop, cr, dst, src); 7063 %} 7064 %} 7065 7066 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7067 %{ 7068 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7069 7070 ins_cost(200); // XXX 7071 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7072 opcode(0x0F, 0x40); 7073 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7074 ins_pipe(pipe_cmov_mem); // XXX 7075 %} 7076 7077 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7078 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7079 ins_cost(200); 7080 expand %{ 7081 cmovL_memU(cop, cr, dst, src); 7082 %} 7083 %} 7084 7085 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7086 %{ 7087 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7088 7089 ins_cost(200); // XXX 7090 format %{ "jn$cop skip\t# signed cmove float\n\t" 7091 "movss $dst, $src\n" 7092 "skip:" %} 7093 ins_encode %{ 7094 Label Lskip; 7095 // Invert sense of branch from sense of CMOV 7096 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7097 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7098 __ bind(Lskip); 7099 %} 7100 ins_pipe(pipe_slow); 7101 %} 7102 7103 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7104 // %{ 7105 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7106 7107 // ins_cost(200); // XXX 7108 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7109 // "movss $dst, $src\n" 7110 // "skip:" %} 7111 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7112 // ins_pipe(pipe_slow); 7113 // %} 7114 7115 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7116 %{ 7117 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7118 7119 ins_cost(200); // XXX 7120 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7121 "movss $dst, $src\n" 7122 "skip:" %} 7123 ins_encode %{ 7124 Label Lskip; 7125 // Invert sense of branch from sense of CMOV 7126 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7127 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7128 __ bind(Lskip); 7129 %} 7130 ins_pipe(pipe_slow); 7131 %} 7132 7133 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7134 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7135 ins_cost(200); 7136 expand %{ 7137 cmovF_regU(cop, cr, dst, src); 7138 %} 7139 %} 7140 7141 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7142 %{ 7143 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7144 7145 ins_cost(200); // XXX 7146 format %{ "jn$cop skip\t# signed cmove double\n\t" 7147 "movsd $dst, $src\n" 7148 "skip:" %} 7149 ins_encode %{ 7150 Label Lskip; 7151 // Invert sense of branch from sense of CMOV 7152 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7153 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7154 __ bind(Lskip); 7155 %} 7156 ins_pipe(pipe_slow); 7157 %} 7158 7159 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7160 %{ 7161 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7162 7163 ins_cost(200); // XXX 7164 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7165 "movsd $dst, $src\n" 7166 "skip:" %} 7167 ins_encode %{ 7168 Label Lskip; 7169 // Invert sense of branch from sense of CMOV 7170 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7171 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7172 __ bind(Lskip); 7173 %} 7174 ins_pipe(pipe_slow); 7175 %} 7176 7177 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7178 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7179 ins_cost(200); 7180 expand %{ 7181 cmovD_regU(cop, cr, dst, src); 7182 %} 7183 %} 7184 7185 //----------Arithmetic Instructions-------------------------------------------- 7186 //----------Addition Instructions---------------------------------------------- 7187 7188 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7189 %{ 7190 match(Set dst (AddI dst src)); 7191 effect(KILL cr); 7192 7193 format %{ "addl $dst, $src\t# int" %} 7194 opcode(0x03); 7195 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7196 ins_pipe(ialu_reg_reg); 7197 %} 7198 7199 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7200 %{ 7201 match(Set dst (AddI dst src)); 7202 effect(KILL cr); 7203 7204 format %{ "addl $dst, $src\t# int" %} 7205 opcode(0x81, 0x00); /* /0 id */ 7206 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7207 ins_pipe( ialu_reg ); 7208 %} 7209 7210 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7211 %{ 7212 match(Set dst (AddI dst (LoadI src))); 7213 effect(KILL cr); 7214 7215 ins_cost(125); // XXX 7216 format %{ "addl $dst, $src\t# int" %} 7217 opcode(0x03); 7218 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7219 ins_pipe(ialu_reg_mem); 7220 %} 7221 7222 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7223 %{ 7224 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7225 effect(KILL cr); 7226 7227 ins_cost(150); // XXX 7228 format %{ "addl $dst, $src\t# int" %} 7229 opcode(0x01); /* Opcode 01 /r */ 7230 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7231 ins_pipe(ialu_mem_reg); 7232 %} 7233 7234 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7235 %{ 7236 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7237 effect(KILL cr); 7238 7239 ins_cost(125); // XXX 7240 format %{ "addl $dst, $src\t# int" %} 7241 opcode(0x81); /* Opcode 81 /0 id */ 7242 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7243 ins_pipe(ialu_mem_imm); 7244 %} 7245 7246 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7247 %{ 7248 predicate(UseIncDec); 7249 match(Set dst (AddI dst src)); 7250 effect(KILL cr); 7251 7252 format %{ "incl $dst\t# int" %} 7253 opcode(0xFF, 0x00); // FF /0 7254 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7255 ins_pipe(ialu_reg); 7256 %} 7257 7258 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7259 %{ 7260 predicate(UseIncDec); 7261 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7262 effect(KILL cr); 7263 7264 ins_cost(125); // XXX 7265 format %{ "incl $dst\t# int" %} 7266 opcode(0xFF); /* Opcode FF /0 */ 7267 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7268 ins_pipe(ialu_mem_imm); 7269 %} 7270 7271 // XXX why does that use AddI 7272 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7273 %{ 7274 predicate(UseIncDec); 7275 match(Set dst (AddI dst src)); 7276 effect(KILL cr); 7277 7278 format %{ "decl $dst\t# int" %} 7279 opcode(0xFF, 0x01); // FF /1 7280 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7281 ins_pipe(ialu_reg); 7282 %} 7283 7284 // XXX why does that use AddI 7285 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7286 %{ 7287 predicate(UseIncDec); 7288 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7289 effect(KILL cr); 7290 7291 ins_cost(125); // XXX 7292 format %{ "decl $dst\t# int" %} 7293 opcode(0xFF); /* Opcode FF /1 */ 7294 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7295 ins_pipe(ialu_mem_imm); 7296 %} 7297 7298 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7299 %{ 7300 match(Set dst (AddI src0 src1)); 7301 7302 ins_cost(110); 7303 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7304 opcode(0x8D); /* 0x8D /r */ 7305 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7306 ins_pipe(ialu_reg_reg); 7307 %} 7308 7309 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7310 %{ 7311 match(Set dst (AddL dst src)); 7312 effect(KILL cr); 7313 7314 format %{ "addq $dst, $src\t# long" %} 7315 opcode(0x03); 7316 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7317 ins_pipe(ialu_reg_reg); 7318 %} 7319 7320 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7321 %{ 7322 match(Set dst (AddL dst src)); 7323 effect(KILL cr); 7324 7325 format %{ "addq $dst, $src\t# long" %} 7326 opcode(0x81, 0x00); /* /0 id */ 7327 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7328 ins_pipe( ialu_reg ); 7329 %} 7330 7331 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7332 %{ 7333 match(Set dst (AddL dst (LoadL src))); 7334 effect(KILL cr); 7335 7336 ins_cost(125); // XXX 7337 format %{ "addq $dst, $src\t# long" %} 7338 opcode(0x03); 7339 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7340 ins_pipe(ialu_reg_mem); 7341 %} 7342 7343 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7344 %{ 7345 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7346 effect(KILL cr); 7347 7348 ins_cost(150); // XXX 7349 format %{ "addq $dst, $src\t# long" %} 7350 opcode(0x01); /* Opcode 01 /r */ 7351 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7352 ins_pipe(ialu_mem_reg); 7353 %} 7354 7355 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7356 %{ 7357 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7358 effect(KILL cr); 7359 7360 ins_cost(125); // XXX 7361 format %{ "addq $dst, $src\t# long" %} 7362 opcode(0x81); /* Opcode 81 /0 id */ 7363 ins_encode(REX_mem_wide(dst), 7364 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7365 ins_pipe(ialu_mem_imm); 7366 %} 7367 7368 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7369 %{ 7370 predicate(UseIncDec); 7371 match(Set dst (AddL dst src)); 7372 effect(KILL cr); 7373 7374 format %{ "incq $dst\t# long" %} 7375 opcode(0xFF, 0x00); // FF /0 7376 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7377 ins_pipe(ialu_reg); 7378 %} 7379 7380 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7381 %{ 7382 predicate(UseIncDec); 7383 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7384 effect(KILL cr); 7385 7386 ins_cost(125); // XXX 7387 format %{ "incq $dst\t# long" %} 7388 opcode(0xFF); /* Opcode FF /0 */ 7389 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7390 ins_pipe(ialu_mem_imm); 7391 %} 7392 7393 // XXX why does that use AddL 7394 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7395 %{ 7396 predicate(UseIncDec); 7397 match(Set dst (AddL dst src)); 7398 effect(KILL cr); 7399 7400 format %{ "decq $dst\t# long" %} 7401 opcode(0xFF, 0x01); // FF /1 7402 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7403 ins_pipe(ialu_reg); 7404 %} 7405 7406 // XXX why does that use AddL 7407 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7408 %{ 7409 predicate(UseIncDec); 7410 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7411 effect(KILL cr); 7412 7413 ins_cost(125); // XXX 7414 format %{ "decq $dst\t# long" %} 7415 opcode(0xFF); /* Opcode FF /1 */ 7416 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7417 ins_pipe(ialu_mem_imm); 7418 %} 7419 7420 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7421 %{ 7422 match(Set dst (AddL src0 src1)); 7423 7424 ins_cost(110); 7425 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7426 opcode(0x8D); /* 0x8D /r */ 7427 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7428 ins_pipe(ialu_reg_reg); 7429 %} 7430 7431 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7432 %{ 7433 match(Set dst (AddP dst src)); 7434 effect(KILL cr); 7435 7436 format %{ "addq $dst, $src\t# ptr" %} 7437 opcode(0x03); 7438 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7439 ins_pipe(ialu_reg_reg); 7440 %} 7441 7442 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7443 %{ 7444 match(Set dst (AddP dst src)); 7445 effect(KILL cr); 7446 7447 format %{ "addq $dst, $src\t# ptr" %} 7448 opcode(0x81, 0x00); /* /0 id */ 7449 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7450 ins_pipe( ialu_reg ); 7451 %} 7452 7453 // XXX addP mem ops ???? 7454 7455 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7456 %{ 7457 match(Set dst (AddP src0 src1)); 7458 7459 ins_cost(110); 7460 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7461 opcode(0x8D); /* 0x8D /r */ 7462 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7463 ins_pipe(ialu_reg_reg); 7464 %} 7465 7466 instruct checkCastPP(rRegP dst) 7467 %{ 7468 match(Set dst (CheckCastPP dst)); 7469 7470 size(0); 7471 format %{ "# checkcastPP of $dst" %} 7472 ins_encode(/* empty encoding */); 7473 ins_pipe(empty); 7474 %} 7475 7476 instruct castPP(rRegP dst) 7477 %{ 7478 match(Set dst (CastPP dst)); 7479 7480 size(0); 7481 format %{ "# castPP of $dst" %} 7482 ins_encode(/* empty encoding */); 7483 ins_pipe(empty); 7484 %} 7485 7486 instruct castII(rRegI dst) 7487 %{ 7488 match(Set dst (CastII dst)); 7489 7490 size(0); 7491 format %{ "# castII of $dst" %} 7492 ins_encode(/* empty encoding */); 7493 ins_cost(0); 7494 ins_pipe(empty); 7495 %} 7496 7497 // LoadP-locked same as a regular LoadP when used with compare-swap 7498 instruct loadPLocked(rRegP dst, memory mem) 7499 %{ 7500 match(Set dst (LoadPLocked mem)); 7501 7502 ins_cost(125); // XXX 7503 format %{ "movq $dst, $mem\t# ptr locked" %} 7504 opcode(0x8B); 7505 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7506 ins_pipe(ialu_reg_mem); // XXX 7507 %} 7508 7509 // Conditional-store of the updated heap-top. 7510 // Used during allocation of the shared heap. 7511 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7512 7513 instruct storePConditional(memory heap_top_ptr, 7514 rax_RegP oldval, rRegP newval, 7515 rFlagsReg cr) 7516 %{ 7517 predicate(n->as_LoadStore()->barrier_data() == 0); 7518 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7519 7520 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7521 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7522 opcode(0x0F, 0xB1); 7523 ins_encode(lock_prefix, 7524 REX_reg_mem_wide(newval, heap_top_ptr), 7525 OpcP, OpcS, 7526 reg_mem(newval, heap_top_ptr)); 7527 ins_pipe(pipe_cmpxchg); 7528 %} 7529 7530 // Conditional-store of an int value. 7531 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7532 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7533 %{ 7534 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7535 effect(KILL oldval); 7536 7537 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7538 opcode(0x0F, 0xB1); 7539 ins_encode(lock_prefix, 7540 REX_reg_mem(newval, mem), 7541 OpcP, OpcS, 7542 reg_mem(newval, mem)); 7543 ins_pipe(pipe_cmpxchg); 7544 %} 7545 7546 // Conditional-store of a long value. 7547 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7548 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7549 %{ 7550 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7551 effect(KILL oldval); 7552 7553 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7554 opcode(0x0F, 0xB1); 7555 ins_encode(lock_prefix, 7556 REX_reg_mem_wide(newval, mem), 7557 OpcP, OpcS, 7558 reg_mem(newval, mem)); 7559 ins_pipe(pipe_cmpxchg); 7560 %} 7561 7562 7563 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7564 instruct compareAndSwapP(rRegI res, 7565 memory mem_ptr, 7566 rax_RegP oldval, rRegP newval, 7567 rFlagsReg cr) 7568 %{ 7569 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0); 7570 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7571 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7572 effect(KILL cr, KILL oldval); 7573 7574 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7575 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7576 "sete $res\n\t" 7577 "movzbl $res, $res" %} 7578 opcode(0x0F, 0xB1); 7579 ins_encode(lock_prefix, 7580 REX_reg_mem_wide(newval, mem_ptr), 7581 OpcP, OpcS, 7582 reg_mem(newval, mem_ptr), 7583 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7584 REX_reg_breg(res, res), // movzbl 7585 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7586 ins_pipe( pipe_cmpxchg ); 7587 %} 7588 7589 instruct compareAndSwapL(rRegI res, 7590 memory mem_ptr, 7591 rax_RegL oldval, rRegL newval, 7592 rFlagsReg cr) 7593 %{ 7594 predicate(VM_Version::supports_cx8()); 7595 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7596 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7597 effect(KILL cr, KILL oldval); 7598 7599 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7600 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7601 "sete $res\n\t" 7602 "movzbl $res, $res" %} 7603 opcode(0x0F, 0xB1); 7604 ins_encode(lock_prefix, 7605 REX_reg_mem_wide(newval, mem_ptr), 7606 OpcP, OpcS, 7607 reg_mem(newval, mem_ptr), 7608 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7609 REX_reg_breg(res, res), // movzbl 7610 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7611 ins_pipe( pipe_cmpxchg ); 7612 %} 7613 7614 instruct compareAndSwapI(rRegI res, 7615 memory mem_ptr, 7616 rax_RegI oldval, rRegI newval, 7617 rFlagsReg cr) 7618 %{ 7619 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7620 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7621 effect(KILL cr, KILL oldval); 7622 7623 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7624 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7625 "sete $res\n\t" 7626 "movzbl $res, $res" %} 7627 opcode(0x0F, 0xB1); 7628 ins_encode(lock_prefix, 7629 REX_reg_mem(newval, mem_ptr), 7630 OpcP, OpcS, 7631 reg_mem(newval, mem_ptr), 7632 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7633 REX_reg_breg(res, res), // movzbl 7634 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7635 ins_pipe( pipe_cmpxchg ); 7636 %} 7637 7638 instruct compareAndSwapB(rRegI res, 7639 memory mem_ptr, 7640 rax_RegI oldval, rRegI newval, 7641 rFlagsReg cr) 7642 %{ 7643 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7644 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7645 effect(KILL cr, KILL oldval); 7646 7647 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7648 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7649 "sete $res\n\t" 7650 "movzbl $res, $res" %} 7651 opcode(0x0F, 0xB0); 7652 ins_encode(lock_prefix, 7653 REX_breg_mem(newval, mem_ptr), 7654 OpcP, OpcS, 7655 reg_mem(newval, mem_ptr), 7656 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7657 REX_reg_breg(res, res), // movzbl 7658 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7659 ins_pipe( pipe_cmpxchg ); 7660 %} 7661 7662 instruct compareAndSwapS(rRegI res, 7663 memory mem_ptr, 7664 rax_RegI oldval, rRegI newval, 7665 rFlagsReg cr) 7666 %{ 7667 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7668 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7669 effect(KILL cr, KILL oldval); 7670 7671 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7672 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7673 "sete $res\n\t" 7674 "movzbl $res, $res" %} 7675 opcode(0x0F, 0xB1); 7676 ins_encode(lock_prefix, 7677 SizePrefix, 7678 REX_reg_mem(newval, mem_ptr), 7679 OpcP, OpcS, 7680 reg_mem(newval, mem_ptr), 7681 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7682 REX_reg_breg(res, res), // movzbl 7683 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7684 ins_pipe( pipe_cmpxchg ); 7685 %} 7686 7687 instruct compareAndSwapN(rRegI res, 7688 memory mem_ptr, 7689 rax_RegN oldval, rRegN newval, 7690 rFlagsReg cr) %{ 7691 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7692 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7693 effect(KILL cr, KILL oldval); 7694 7695 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7696 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7697 "sete $res\n\t" 7698 "movzbl $res, $res" %} 7699 opcode(0x0F, 0xB1); 7700 ins_encode(lock_prefix, 7701 REX_reg_mem(newval, mem_ptr), 7702 OpcP, OpcS, 7703 reg_mem(newval, mem_ptr), 7704 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7705 REX_reg_breg(res, res), // movzbl 7706 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7707 ins_pipe( pipe_cmpxchg ); 7708 %} 7709 7710 instruct compareAndExchangeB( 7711 memory mem_ptr, 7712 rax_RegI oldval, rRegI newval, 7713 rFlagsReg cr) 7714 %{ 7715 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7716 effect(KILL cr); 7717 7718 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7719 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7720 opcode(0x0F, 0xB0); 7721 ins_encode(lock_prefix, 7722 REX_breg_mem(newval, mem_ptr), 7723 OpcP, OpcS, 7724 reg_mem(newval, mem_ptr) // lock cmpxchg 7725 ); 7726 ins_pipe( pipe_cmpxchg ); 7727 %} 7728 7729 instruct compareAndExchangeS( 7730 memory mem_ptr, 7731 rax_RegI oldval, rRegI newval, 7732 rFlagsReg cr) 7733 %{ 7734 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7735 effect(KILL cr); 7736 7737 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7738 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7739 opcode(0x0F, 0xB1); 7740 ins_encode(lock_prefix, 7741 SizePrefix, 7742 REX_reg_mem(newval, mem_ptr), 7743 OpcP, OpcS, 7744 reg_mem(newval, mem_ptr) // lock cmpxchg 7745 ); 7746 ins_pipe( pipe_cmpxchg ); 7747 %} 7748 7749 instruct compareAndExchangeI( 7750 memory mem_ptr, 7751 rax_RegI oldval, rRegI newval, 7752 rFlagsReg cr) 7753 %{ 7754 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7755 effect(KILL cr); 7756 7757 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7758 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7759 opcode(0x0F, 0xB1); 7760 ins_encode(lock_prefix, 7761 REX_reg_mem(newval, mem_ptr), 7762 OpcP, OpcS, 7763 reg_mem(newval, mem_ptr) // lock cmpxchg 7764 ); 7765 ins_pipe( pipe_cmpxchg ); 7766 %} 7767 7768 instruct compareAndExchangeL( 7769 memory mem_ptr, 7770 rax_RegL oldval, rRegL newval, 7771 rFlagsReg cr) 7772 %{ 7773 predicate(VM_Version::supports_cx8()); 7774 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7775 effect(KILL cr); 7776 7777 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7778 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7779 opcode(0x0F, 0xB1); 7780 ins_encode(lock_prefix, 7781 REX_reg_mem_wide(newval, mem_ptr), 7782 OpcP, OpcS, 7783 reg_mem(newval, mem_ptr) // lock cmpxchg 7784 ); 7785 ins_pipe( pipe_cmpxchg ); 7786 %} 7787 7788 instruct compareAndExchangeN( 7789 memory mem_ptr, 7790 rax_RegN oldval, rRegN newval, 7791 rFlagsReg cr) %{ 7792 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7793 effect(KILL cr); 7794 7795 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7796 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7797 opcode(0x0F, 0xB1); 7798 ins_encode(lock_prefix, 7799 REX_reg_mem(newval, mem_ptr), 7800 OpcP, OpcS, 7801 reg_mem(newval, mem_ptr) // lock cmpxchg 7802 ); 7803 ins_pipe( pipe_cmpxchg ); 7804 %} 7805 7806 instruct compareAndExchangeP( 7807 memory mem_ptr, 7808 rax_RegP oldval, rRegP newval, 7809 rFlagsReg cr) 7810 %{ 7811 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0); 7812 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7813 effect(KILL cr); 7814 7815 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7816 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7817 opcode(0x0F, 0xB1); 7818 ins_encode(lock_prefix, 7819 REX_reg_mem_wide(newval, mem_ptr), 7820 OpcP, OpcS, 7821 reg_mem(newval, mem_ptr) // lock cmpxchg 7822 ); 7823 ins_pipe( pipe_cmpxchg ); 7824 %} 7825 7826 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7827 predicate(n->as_LoadStore()->result_not_used()); 7828 match(Set dummy (GetAndAddB mem add)); 7829 effect(KILL cr); 7830 format %{ "ADDB [$mem],$add" %} 7831 ins_encode %{ 7832 __ lock(); 7833 __ addb($mem$$Address, $add$$constant); 7834 %} 7835 ins_pipe( pipe_cmpxchg ); 7836 %} 7837 7838 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7839 match(Set newval (GetAndAddB mem newval)); 7840 effect(KILL cr); 7841 format %{ "XADDB [$mem],$newval" %} 7842 ins_encode %{ 7843 __ lock(); 7844 __ xaddb($mem$$Address, $newval$$Register); 7845 %} 7846 ins_pipe( pipe_cmpxchg ); 7847 %} 7848 7849 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7850 predicate(n->as_LoadStore()->result_not_used()); 7851 match(Set dummy (GetAndAddS mem add)); 7852 effect(KILL cr); 7853 format %{ "ADDW [$mem],$add" %} 7854 ins_encode %{ 7855 __ lock(); 7856 __ addw($mem$$Address, $add$$constant); 7857 %} 7858 ins_pipe( pipe_cmpxchg ); 7859 %} 7860 7861 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7862 match(Set newval (GetAndAddS mem newval)); 7863 effect(KILL cr); 7864 format %{ "XADDW [$mem],$newval" %} 7865 ins_encode %{ 7866 __ lock(); 7867 __ xaddw($mem$$Address, $newval$$Register); 7868 %} 7869 ins_pipe( pipe_cmpxchg ); 7870 %} 7871 7872 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7873 predicate(n->as_LoadStore()->result_not_used()); 7874 match(Set dummy (GetAndAddI mem add)); 7875 effect(KILL cr); 7876 format %{ "ADDL [$mem],$add" %} 7877 ins_encode %{ 7878 __ lock(); 7879 __ addl($mem$$Address, $add$$constant); 7880 %} 7881 ins_pipe( pipe_cmpxchg ); 7882 %} 7883 7884 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7885 match(Set newval (GetAndAddI mem newval)); 7886 effect(KILL cr); 7887 format %{ "XADDL [$mem],$newval" %} 7888 ins_encode %{ 7889 __ lock(); 7890 __ xaddl($mem$$Address, $newval$$Register); 7891 %} 7892 ins_pipe( pipe_cmpxchg ); 7893 %} 7894 7895 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7896 predicate(n->as_LoadStore()->result_not_used()); 7897 match(Set dummy (GetAndAddL mem add)); 7898 effect(KILL cr); 7899 format %{ "ADDQ [$mem],$add" %} 7900 ins_encode %{ 7901 __ lock(); 7902 __ addq($mem$$Address, $add$$constant); 7903 %} 7904 ins_pipe( pipe_cmpxchg ); 7905 %} 7906 7907 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7908 match(Set newval (GetAndAddL mem newval)); 7909 effect(KILL cr); 7910 format %{ "XADDQ [$mem],$newval" %} 7911 ins_encode %{ 7912 __ lock(); 7913 __ xaddq($mem$$Address, $newval$$Register); 7914 %} 7915 ins_pipe( pipe_cmpxchg ); 7916 %} 7917 7918 instruct xchgB( memory mem, rRegI newval) %{ 7919 match(Set newval (GetAndSetB mem newval)); 7920 format %{ "XCHGB $newval,[$mem]" %} 7921 ins_encode %{ 7922 __ xchgb($newval$$Register, $mem$$Address); 7923 %} 7924 ins_pipe( pipe_cmpxchg ); 7925 %} 7926 7927 instruct xchgS( memory mem, rRegI newval) %{ 7928 match(Set newval (GetAndSetS mem newval)); 7929 format %{ "XCHGW $newval,[$mem]" %} 7930 ins_encode %{ 7931 __ xchgw($newval$$Register, $mem$$Address); 7932 %} 7933 ins_pipe( pipe_cmpxchg ); 7934 %} 7935 7936 instruct xchgI( memory mem, rRegI newval) %{ 7937 match(Set newval (GetAndSetI mem newval)); 7938 format %{ "XCHGL $newval,[$mem]" %} 7939 ins_encode %{ 7940 __ xchgl($newval$$Register, $mem$$Address); 7941 %} 7942 ins_pipe( pipe_cmpxchg ); 7943 %} 7944 7945 instruct xchgL( memory mem, rRegL newval) %{ 7946 match(Set newval (GetAndSetL mem newval)); 7947 format %{ "XCHGL $newval,[$mem]" %} 7948 ins_encode %{ 7949 __ xchgq($newval$$Register, $mem$$Address); 7950 %} 7951 ins_pipe( pipe_cmpxchg ); 7952 %} 7953 7954 instruct xchgP( memory mem, rRegP newval) %{ 7955 match(Set newval (GetAndSetP mem newval)); 7956 predicate(n->as_LoadStore()->barrier_data() == 0); 7957 format %{ "XCHGQ $newval,[$mem]" %} 7958 ins_encode %{ 7959 __ xchgq($newval$$Register, $mem$$Address); 7960 %} 7961 ins_pipe( pipe_cmpxchg ); 7962 %} 7963 7964 instruct xchgN( memory mem, rRegN newval) %{ 7965 match(Set newval (GetAndSetN mem newval)); 7966 format %{ "XCHGL $newval,$mem]" %} 7967 ins_encode %{ 7968 __ xchgl($newval$$Register, $mem$$Address); 7969 %} 7970 ins_pipe( pipe_cmpxchg ); 7971 %} 7972 7973 //----------Abs Instructions------------------------------------------- 7974 7975 // Integer Absolute Instructions 7976 instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr) 7977 %{ 7978 match(Set dst (AbsI src)); 7979 effect(TEMP dst, TEMP tmp, KILL cr); 7980 format %{ "movl $tmp, $src\n\t" 7981 "sarl $tmp, 31\n\t" 7982 "movl $dst, $src\n\t" 7983 "xorl $dst, $tmp\n\t" 7984 "subl $dst, $tmp\n" 7985 %} 7986 ins_encode %{ 7987 __ movl($tmp$$Register, $src$$Register); 7988 __ sarl($tmp$$Register, 31); 7989 __ movl($dst$$Register, $src$$Register); 7990 __ xorl($dst$$Register, $tmp$$Register); 7991 __ subl($dst$$Register, $tmp$$Register); 7992 %} 7993 7994 ins_pipe(ialu_reg_reg); 7995 %} 7996 7997 // Long Absolute Instructions 7998 instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr) 7999 %{ 8000 match(Set dst (AbsL src)); 8001 effect(TEMP dst, TEMP tmp, KILL cr); 8002 format %{ "movq $tmp, $src\n\t" 8003 "sarq $tmp, 63\n\t" 8004 "movq $dst, $src\n\t" 8005 "xorq $dst, $tmp\n\t" 8006 "subq $dst, $tmp\n" 8007 %} 8008 ins_encode %{ 8009 __ movq($tmp$$Register, $src$$Register); 8010 __ sarq($tmp$$Register, 63); 8011 __ movq($dst$$Register, $src$$Register); 8012 __ xorq($dst$$Register, $tmp$$Register); 8013 __ subq($dst$$Register, $tmp$$Register); 8014 %} 8015 8016 ins_pipe(ialu_reg_reg); 8017 %} 8018 8019 //----------Subtraction Instructions------------------------------------------- 8020 8021 // Integer Subtraction Instructions 8022 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8023 %{ 8024 match(Set dst (SubI dst src)); 8025 effect(KILL cr); 8026 8027 format %{ "subl $dst, $src\t# int" %} 8028 opcode(0x2B); 8029 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8030 ins_pipe(ialu_reg_reg); 8031 %} 8032 8033 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8034 %{ 8035 match(Set dst (SubI dst src)); 8036 effect(KILL cr); 8037 8038 format %{ "subl $dst, $src\t# int" %} 8039 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8040 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8041 ins_pipe(ialu_reg); 8042 %} 8043 8044 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8045 %{ 8046 match(Set dst (SubI dst (LoadI src))); 8047 effect(KILL cr); 8048 8049 ins_cost(125); 8050 format %{ "subl $dst, $src\t# int" %} 8051 opcode(0x2B); 8052 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8053 ins_pipe(ialu_reg_mem); 8054 %} 8055 8056 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8057 %{ 8058 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8059 effect(KILL cr); 8060 8061 ins_cost(150); 8062 format %{ "subl $dst, $src\t# int" %} 8063 opcode(0x29); /* Opcode 29 /r */ 8064 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8065 ins_pipe(ialu_mem_reg); 8066 %} 8067 8068 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8069 %{ 8070 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8071 effect(KILL cr); 8072 8073 ins_cost(125); // XXX 8074 format %{ "subl $dst, $src\t# int" %} 8075 opcode(0x81); /* Opcode 81 /5 id */ 8076 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8077 ins_pipe(ialu_mem_imm); 8078 %} 8079 8080 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8081 %{ 8082 match(Set dst (SubL dst src)); 8083 effect(KILL cr); 8084 8085 format %{ "subq $dst, $src\t# long" %} 8086 opcode(0x2B); 8087 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8088 ins_pipe(ialu_reg_reg); 8089 %} 8090 8091 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8092 %{ 8093 match(Set dst (SubL dst src)); 8094 effect(KILL cr); 8095 8096 format %{ "subq $dst, $src\t# long" %} 8097 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8098 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8099 ins_pipe(ialu_reg); 8100 %} 8101 8102 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8103 %{ 8104 match(Set dst (SubL dst (LoadL src))); 8105 effect(KILL cr); 8106 8107 ins_cost(125); 8108 format %{ "subq $dst, $src\t# long" %} 8109 opcode(0x2B); 8110 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8111 ins_pipe(ialu_reg_mem); 8112 %} 8113 8114 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8115 %{ 8116 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8117 effect(KILL cr); 8118 8119 ins_cost(150); 8120 format %{ "subq $dst, $src\t# long" %} 8121 opcode(0x29); /* Opcode 29 /r */ 8122 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8123 ins_pipe(ialu_mem_reg); 8124 %} 8125 8126 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8127 %{ 8128 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8129 effect(KILL cr); 8130 8131 ins_cost(125); // XXX 8132 format %{ "subq $dst, $src\t# long" %} 8133 opcode(0x81); /* Opcode 81 /5 id */ 8134 ins_encode(REX_mem_wide(dst), 8135 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8136 ins_pipe(ialu_mem_imm); 8137 %} 8138 8139 // Subtract from a pointer 8140 // XXX hmpf??? 8141 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8142 %{ 8143 match(Set dst (AddP dst (SubI zero src))); 8144 effect(KILL cr); 8145 8146 format %{ "subq $dst, $src\t# ptr - int" %} 8147 opcode(0x2B); 8148 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8149 ins_pipe(ialu_reg_reg); 8150 %} 8151 8152 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8153 %{ 8154 match(Set dst (SubI zero dst)); 8155 effect(KILL cr); 8156 8157 format %{ "negl $dst\t# int" %} 8158 opcode(0xF7, 0x03); // Opcode F7 /3 8159 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8160 ins_pipe(ialu_reg); 8161 %} 8162 8163 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8164 %{ 8165 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8166 effect(KILL cr); 8167 8168 format %{ "negl $dst\t# int" %} 8169 opcode(0xF7, 0x03); // Opcode F7 /3 8170 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8171 ins_pipe(ialu_reg); 8172 %} 8173 8174 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8175 %{ 8176 match(Set dst (SubL zero dst)); 8177 effect(KILL cr); 8178 8179 format %{ "negq $dst\t# long" %} 8180 opcode(0xF7, 0x03); // Opcode F7 /3 8181 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8182 ins_pipe(ialu_reg); 8183 %} 8184 8185 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8186 %{ 8187 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8188 effect(KILL cr); 8189 8190 format %{ "negq $dst\t# long" %} 8191 opcode(0xF7, 0x03); // Opcode F7 /3 8192 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8193 ins_pipe(ialu_reg); 8194 %} 8195 8196 //----------Multiplication/Division Instructions------------------------------- 8197 // Integer Multiplication Instructions 8198 // Multiply Register 8199 8200 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8201 %{ 8202 match(Set dst (MulI dst src)); 8203 effect(KILL cr); 8204 8205 ins_cost(300); 8206 format %{ "imull $dst, $src\t# int" %} 8207 opcode(0x0F, 0xAF); 8208 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8209 ins_pipe(ialu_reg_reg_alu0); 8210 %} 8211 8212 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8213 %{ 8214 match(Set dst (MulI src imm)); 8215 effect(KILL cr); 8216 8217 ins_cost(300); 8218 format %{ "imull $dst, $src, $imm\t# int" %} 8219 opcode(0x69); /* 69 /r id */ 8220 ins_encode(REX_reg_reg(dst, src), 8221 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8222 ins_pipe(ialu_reg_reg_alu0); 8223 %} 8224 8225 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8226 %{ 8227 match(Set dst (MulI dst (LoadI src))); 8228 effect(KILL cr); 8229 8230 ins_cost(350); 8231 format %{ "imull $dst, $src\t# int" %} 8232 opcode(0x0F, 0xAF); 8233 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8234 ins_pipe(ialu_reg_mem_alu0); 8235 %} 8236 8237 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8238 %{ 8239 match(Set dst (MulI (LoadI src) imm)); 8240 effect(KILL cr); 8241 8242 ins_cost(300); 8243 format %{ "imull $dst, $src, $imm\t# int" %} 8244 opcode(0x69); /* 69 /r id */ 8245 ins_encode(REX_reg_mem(dst, src), 8246 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8247 ins_pipe(ialu_reg_mem_alu0); 8248 %} 8249 8250 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8251 %{ 8252 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8253 effect(KILL cr, KILL src2); 8254 8255 expand %{ mulI_rReg(dst, src1, cr); 8256 mulI_rReg(src2, src3, cr); 8257 addI_rReg(dst, src2, cr); %} 8258 %} 8259 8260 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8261 %{ 8262 match(Set dst (MulL dst src)); 8263 effect(KILL cr); 8264 8265 ins_cost(300); 8266 format %{ "imulq $dst, $src\t# long" %} 8267 opcode(0x0F, 0xAF); 8268 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8269 ins_pipe(ialu_reg_reg_alu0); 8270 %} 8271 8272 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8273 %{ 8274 match(Set dst (MulL src imm)); 8275 effect(KILL cr); 8276 8277 ins_cost(300); 8278 format %{ "imulq $dst, $src, $imm\t# long" %} 8279 opcode(0x69); /* 69 /r id */ 8280 ins_encode(REX_reg_reg_wide(dst, src), 8281 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8282 ins_pipe(ialu_reg_reg_alu0); 8283 %} 8284 8285 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8286 %{ 8287 match(Set dst (MulL dst (LoadL src))); 8288 effect(KILL cr); 8289 8290 ins_cost(350); 8291 format %{ "imulq $dst, $src\t# long" %} 8292 opcode(0x0F, 0xAF); 8293 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8294 ins_pipe(ialu_reg_mem_alu0); 8295 %} 8296 8297 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8298 %{ 8299 match(Set dst (MulL (LoadL src) imm)); 8300 effect(KILL cr); 8301 8302 ins_cost(300); 8303 format %{ "imulq $dst, $src, $imm\t# long" %} 8304 opcode(0x69); /* 69 /r id */ 8305 ins_encode(REX_reg_mem_wide(dst, src), 8306 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8307 ins_pipe(ialu_reg_mem_alu0); 8308 %} 8309 8310 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8311 %{ 8312 match(Set dst (MulHiL src rax)); 8313 effect(USE_KILL rax, KILL cr); 8314 8315 ins_cost(300); 8316 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8317 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8318 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8319 ins_pipe(ialu_reg_reg_alu0); 8320 %} 8321 8322 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8323 rFlagsReg cr) 8324 %{ 8325 match(Set rax (DivI rax div)); 8326 effect(KILL rdx, KILL cr); 8327 8328 ins_cost(30*100+10*100); // XXX 8329 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8330 "jne,s normal\n\t" 8331 "xorl rdx, rdx\n\t" 8332 "cmpl $div, -1\n\t" 8333 "je,s done\n" 8334 "normal: cdql\n\t" 8335 "idivl $div\n" 8336 "done:" %} 8337 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8338 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8339 ins_pipe(ialu_reg_reg_alu0); 8340 %} 8341 8342 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8343 rFlagsReg cr) 8344 %{ 8345 match(Set rax (DivL rax div)); 8346 effect(KILL rdx, KILL cr); 8347 8348 ins_cost(30*100+10*100); // XXX 8349 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8350 "cmpq rax, rdx\n\t" 8351 "jne,s normal\n\t" 8352 "xorl rdx, rdx\n\t" 8353 "cmpq $div, -1\n\t" 8354 "je,s done\n" 8355 "normal: cdqq\n\t" 8356 "idivq $div\n" 8357 "done:" %} 8358 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8359 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8360 ins_pipe(ialu_reg_reg_alu0); 8361 %} 8362 8363 // Integer DIVMOD with Register, both quotient and mod results 8364 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8365 rFlagsReg cr) 8366 %{ 8367 match(DivModI rax div); 8368 effect(KILL cr); 8369 8370 ins_cost(30*100+10*100); // XXX 8371 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8372 "jne,s normal\n\t" 8373 "xorl rdx, rdx\n\t" 8374 "cmpl $div, -1\n\t" 8375 "je,s done\n" 8376 "normal: cdql\n\t" 8377 "idivl $div\n" 8378 "done:" %} 8379 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8380 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8381 ins_pipe(pipe_slow); 8382 %} 8383 8384 // Long DIVMOD with Register, both quotient and mod results 8385 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8386 rFlagsReg cr) 8387 %{ 8388 match(DivModL rax div); 8389 effect(KILL cr); 8390 8391 ins_cost(30*100+10*100); // XXX 8392 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8393 "cmpq rax, rdx\n\t" 8394 "jne,s normal\n\t" 8395 "xorl rdx, rdx\n\t" 8396 "cmpq $div, -1\n\t" 8397 "je,s done\n" 8398 "normal: cdqq\n\t" 8399 "idivq $div\n" 8400 "done:" %} 8401 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8402 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8403 ins_pipe(pipe_slow); 8404 %} 8405 8406 //----------- DivL-By-Constant-Expansions-------------------------------------- 8407 // DivI cases are handled by the compiler 8408 8409 // Magic constant, reciprocal of 10 8410 instruct loadConL_0x6666666666666667(rRegL dst) 8411 %{ 8412 effect(DEF dst); 8413 8414 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8415 ins_encode(load_immL(dst, 0x6666666666666667)); 8416 ins_pipe(ialu_reg); 8417 %} 8418 8419 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8420 %{ 8421 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8422 8423 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8424 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8425 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8426 ins_pipe(ialu_reg_reg_alu0); 8427 %} 8428 8429 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8430 %{ 8431 effect(USE_DEF dst, KILL cr); 8432 8433 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8434 opcode(0xC1, 0x7); /* C1 /7 ib */ 8435 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8436 ins_pipe(ialu_reg); 8437 %} 8438 8439 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8440 %{ 8441 effect(USE_DEF dst, KILL cr); 8442 8443 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8444 opcode(0xC1, 0x7); /* C1 /7 ib */ 8445 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8446 ins_pipe(ialu_reg); 8447 %} 8448 8449 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8450 %{ 8451 match(Set dst (DivL src div)); 8452 8453 ins_cost((5+8)*100); 8454 expand %{ 8455 rax_RegL rax; // Killed temp 8456 rFlagsReg cr; // Killed 8457 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8458 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8459 sarL_rReg_63(src, cr); // sarq src, 63 8460 sarL_rReg_2(dst, cr); // sarq rdx, 2 8461 subL_rReg(dst, src, cr); // subl rdx, src 8462 %} 8463 %} 8464 8465 //----------------------------------------------------------------------------- 8466 8467 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8468 rFlagsReg cr) 8469 %{ 8470 match(Set rdx (ModI rax div)); 8471 effect(KILL rax, KILL cr); 8472 8473 ins_cost(300); // XXX 8474 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8475 "jne,s normal\n\t" 8476 "xorl rdx, rdx\n\t" 8477 "cmpl $div, -1\n\t" 8478 "je,s done\n" 8479 "normal: cdql\n\t" 8480 "idivl $div\n" 8481 "done:" %} 8482 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8483 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8484 ins_pipe(ialu_reg_reg_alu0); 8485 %} 8486 8487 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8488 rFlagsReg cr) 8489 %{ 8490 match(Set rdx (ModL rax div)); 8491 effect(KILL rax, KILL cr); 8492 8493 ins_cost(300); // XXX 8494 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8495 "cmpq rax, rdx\n\t" 8496 "jne,s normal\n\t" 8497 "xorl rdx, rdx\n\t" 8498 "cmpq $div, -1\n\t" 8499 "je,s done\n" 8500 "normal: cdqq\n\t" 8501 "idivq $div\n" 8502 "done:" %} 8503 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8504 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8505 ins_pipe(ialu_reg_reg_alu0); 8506 %} 8507 8508 // Integer Shift Instructions 8509 // Shift Left by one 8510 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8511 %{ 8512 match(Set dst (LShiftI dst shift)); 8513 effect(KILL cr); 8514 8515 format %{ "sall $dst, $shift" %} 8516 opcode(0xD1, 0x4); /* D1 /4 */ 8517 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8518 ins_pipe(ialu_reg); 8519 %} 8520 8521 // Shift Left by one 8522 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8523 %{ 8524 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8525 effect(KILL cr); 8526 8527 format %{ "sall $dst, $shift\t" %} 8528 opcode(0xD1, 0x4); /* D1 /4 */ 8529 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8530 ins_pipe(ialu_mem_imm); 8531 %} 8532 8533 // Shift Left by 8-bit immediate 8534 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8535 %{ 8536 match(Set dst (LShiftI dst shift)); 8537 effect(KILL cr); 8538 8539 format %{ "sall $dst, $shift" %} 8540 opcode(0xC1, 0x4); /* C1 /4 ib */ 8541 ins_encode(reg_opc_imm(dst, shift)); 8542 ins_pipe(ialu_reg); 8543 %} 8544 8545 // Shift Left by 8-bit immediate 8546 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8547 %{ 8548 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8549 effect(KILL cr); 8550 8551 format %{ "sall $dst, $shift" %} 8552 opcode(0xC1, 0x4); /* C1 /4 ib */ 8553 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8554 ins_pipe(ialu_mem_imm); 8555 %} 8556 8557 // Shift Left by variable 8558 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8559 %{ 8560 match(Set dst (LShiftI dst shift)); 8561 effect(KILL cr); 8562 8563 format %{ "sall $dst, $shift" %} 8564 opcode(0xD3, 0x4); /* D3 /4 */ 8565 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8566 ins_pipe(ialu_reg_reg); 8567 %} 8568 8569 // Shift Left by variable 8570 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8571 %{ 8572 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8573 effect(KILL cr); 8574 8575 format %{ "sall $dst, $shift" %} 8576 opcode(0xD3, 0x4); /* D3 /4 */ 8577 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8578 ins_pipe(ialu_mem_reg); 8579 %} 8580 8581 // Arithmetic shift right by one 8582 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8583 %{ 8584 match(Set dst (RShiftI dst shift)); 8585 effect(KILL cr); 8586 8587 format %{ "sarl $dst, $shift" %} 8588 opcode(0xD1, 0x7); /* D1 /7 */ 8589 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8590 ins_pipe(ialu_reg); 8591 %} 8592 8593 // Arithmetic shift right by one 8594 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8595 %{ 8596 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8597 effect(KILL cr); 8598 8599 format %{ "sarl $dst, $shift" %} 8600 opcode(0xD1, 0x7); /* D1 /7 */ 8601 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8602 ins_pipe(ialu_mem_imm); 8603 %} 8604 8605 // Arithmetic Shift Right by 8-bit immediate 8606 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8607 %{ 8608 match(Set dst (RShiftI dst shift)); 8609 effect(KILL cr); 8610 8611 format %{ "sarl $dst, $shift" %} 8612 opcode(0xC1, 0x7); /* C1 /7 ib */ 8613 ins_encode(reg_opc_imm(dst, shift)); 8614 ins_pipe(ialu_mem_imm); 8615 %} 8616 8617 // Arithmetic Shift Right by 8-bit immediate 8618 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8619 %{ 8620 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8621 effect(KILL cr); 8622 8623 format %{ "sarl $dst, $shift" %} 8624 opcode(0xC1, 0x7); /* C1 /7 ib */ 8625 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8626 ins_pipe(ialu_mem_imm); 8627 %} 8628 8629 // Arithmetic Shift Right by variable 8630 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8631 %{ 8632 match(Set dst (RShiftI dst shift)); 8633 effect(KILL cr); 8634 8635 format %{ "sarl $dst, $shift" %} 8636 opcode(0xD3, 0x7); /* D3 /7 */ 8637 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8638 ins_pipe(ialu_reg_reg); 8639 %} 8640 8641 // Arithmetic Shift Right by variable 8642 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8643 %{ 8644 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8645 effect(KILL cr); 8646 8647 format %{ "sarl $dst, $shift" %} 8648 opcode(0xD3, 0x7); /* D3 /7 */ 8649 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8650 ins_pipe(ialu_mem_reg); 8651 %} 8652 8653 // Logical shift right by one 8654 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8655 %{ 8656 match(Set dst (URShiftI dst shift)); 8657 effect(KILL cr); 8658 8659 format %{ "shrl $dst, $shift" %} 8660 opcode(0xD1, 0x5); /* D1 /5 */ 8661 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8662 ins_pipe(ialu_reg); 8663 %} 8664 8665 // Logical shift right by one 8666 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8667 %{ 8668 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8669 effect(KILL cr); 8670 8671 format %{ "shrl $dst, $shift" %} 8672 opcode(0xD1, 0x5); /* D1 /5 */ 8673 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8674 ins_pipe(ialu_mem_imm); 8675 %} 8676 8677 // Logical Shift Right by 8-bit immediate 8678 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8679 %{ 8680 match(Set dst (URShiftI dst shift)); 8681 effect(KILL cr); 8682 8683 format %{ "shrl $dst, $shift" %} 8684 opcode(0xC1, 0x5); /* C1 /5 ib */ 8685 ins_encode(reg_opc_imm(dst, shift)); 8686 ins_pipe(ialu_reg); 8687 %} 8688 8689 // Logical Shift Right by 8-bit immediate 8690 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8691 %{ 8692 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8693 effect(KILL cr); 8694 8695 format %{ "shrl $dst, $shift" %} 8696 opcode(0xC1, 0x5); /* C1 /5 ib */ 8697 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8698 ins_pipe(ialu_mem_imm); 8699 %} 8700 8701 // Logical Shift Right by variable 8702 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8703 %{ 8704 match(Set dst (URShiftI dst shift)); 8705 effect(KILL cr); 8706 8707 format %{ "shrl $dst, $shift" %} 8708 opcode(0xD3, 0x5); /* D3 /5 */ 8709 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8710 ins_pipe(ialu_reg_reg); 8711 %} 8712 8713 // Logical Shift Right by variable 8714 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8715 %{ 8716 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8717 effect(KILL cr); 8718 8719 format %{ "shrl $dst, $shift" %} 8720 opcode(0xD3, 0x5); /* D3 /5 */ 8721 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8722 ins_pipe(ialu_mem_reg); 8723 %} 8724 8725 // Long Shift Instructions 8726 // Shift Left by one 8727 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8728 %{ 8729 match(Set dst (LShiftL dst shift)); 8730 effect(KILL cr); 8731 8732 format %{ "salq $dst, $shift" %} 8733 opcode(0xD1, 0x4); /* D1 /4 */ 8734 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8735 ins_pipe(ialu_reg); 8736 %} 8737 8738 // Shift Left by one 8739 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8740 %{ 8741 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8742 effect(KILL cr); 8743 8744 format %{ "salq $dst, $shift" %} 8745 opcode(0xD1, 0x4); /* D1 /4 */ 8746 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8747 ins_pipe(ialu_mem_imm); 8748 %} 8749 8750 // Shift Left by 8-bit immediate 8751 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8752 %{ 8753 match(Set dst (LShiftL dst shift)); 8754 effect(KILL cr); 8755 8756 format %{ "salq $dst, $shift" %} 8757 opcode(0xC1, 0x4); /* C1 /4 ib */ 8758 ins_encode(reg_opc_imm_wide(dst, shift)); 8759 ins_pipe(ialu_reg); 8760 %} 8761 8762 // Shift Left by 8-bit immediate 8763 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8764 %{ 8765 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8766 effect(KILL cr); 8767 8768 format %{ "salq $dst, $shift" %} 8769 opcode(0xC1, 0x4); /* C1 /4 ib */ 8770 ins_encode(REX_mem_wide(dst), OpcP, 8771 RM_opc_mem(secondary, dst), Con8or32(shift)); 8772 ins_pipe(ialu_mem_imm); 8773 %} 8774 8775 // Shift Left by variable 8776 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8777 %{ 8778 match(Set dst (LShiftL dst shift)); 8779 effect(KILL cr); 8780 8781 format %{ "salq $dst, $shift" %} 8782 opcode(0xD3, 0x4); /* D3 /4 */ 8783 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8784 ins_pipe(ialu_reg_reg); 8785 %} 8786 8787 // Shift Left by variable 8788 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8789 %{ 8790 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8791 effect(KILL cr); 8792 8793 format %{ "salq $dst, $shift" %} 8794 opcode(0xD3, 0x4); /* D3 /4 */ 8795 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8796 ins_pipe(ialu_mem_reg); 8797 %} 8798 8799 // Arithmetic shift right by one 8800 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8801 %{ 8802 match(Set dst (RShiftL dst shift)); 8803 effect(KILL cr); 8804 8805 format %{ "sarq $dst, $shift" %} 8806 opcode(0xD1, 0x7); /* D1 /7 */ 8807 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8808 ins_pipe(ialu_reg); 8809 %} 8810 8811 // Arithmetic shift right by one 8812 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8813 %{ 8814 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8815 effect(KILL cr); 8816 8817 format %{ "sarq $dst, $shift" %} 8818 opcode(0xD1, 0x7); /* D1 /7 */ 8819 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8820 ins_pipe(ialu_mem_imm); 8821 %} 8822 8823 // Arithmetic Shift Right by 8-bit immediate 8824 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8825 %{ 8826 match(Set dst (RShiftL dst shift)); 8827 effect(KILL cr); 8828 8829 format %{ "sarq $dst, $shift" %} 8830 opcode(0xC1, 0x7); /* C1 /7 ib */ 8831 ins_encode(reg_opc_imm_wide(dst, shift)); 8832 ins_pipe(ialu_mem_imm); 8833 %} 8834 8835 // Arithmetic Shift Right by 8-bit immediate 8836 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8837 %{ 8838 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8839 effect(KILL cr); 8840 8841 format %{ "sarq $dst, $shift" %} 8842 opcode(0xC1, 0x7); /* C1 /7 ib */ 8843 ins_encode(REX_mem_wide(dst), OpcP, 8844 RM_opc_mem(secondary, dst), Con8or32(shift)); 8845 ins_pipe(ialu_mem_imm); 8846 %} 8847 8848 // Arithmetic Shift Right by variable 8849 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8850 %{ 8851 match(Set dst (RShiftL dst shift)); 8852 effect(KILL cr); 8853 8854 format %{ "sarq $dst, $shift" %} 8855 opcode(0xD3, 0x7); /* D3 /7 */ 8856 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8857 ins_pipe(ialu_reg_reg); 8858 %} 8859 8860 // Arithmetic Shift Right by variable 8861 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8862 %{ 8863 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8864 effect(KILL cr); 8865 8866 format %{ "sarq $dst, $shift" %} 8867 opcode(0xD3, 0x7); /* D3 /7 */ 8868 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8869 ins_pipe(ialu_mem_reg); 8870 %} 8871 8872 // Logical shift right by one 8873 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8874 %{ 8875 match(Set dst (URShiftL dst shift)); 8876 effect(KILL cr); 8877 8878 format %{ "shrq $dst, $shift" %} 8879 opcode(0xD1, 0x5); /* D1 /5 */ 8880 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8881 ins_pipe(ialu_reg); 8882 %} 8883 8884 // Logical shift right by one 8885 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8886 %{ 8887 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8888 effect(KILL cr); 8889 8890 format %{ "shrq $dst, $shift" %} 8891 opcode(0xD1, 0x5); /* D1 /5 */ 8892 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8893 ins_pipe(ialu_mem_imm); 8894 %} 8895 8896 // Logical Shift Right by 8-bit immediate 8897 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8898 %{ 8899 match(Set dst (URShiftL dst shift)); 8900 effect(KILL cr); 8901 8902 format %{ "shrq $dst, $shift" %} 8903 opcode(0xC1, 0x5); /* C1 /5 ib */ 8904 ins_encode(reg_opc_imm_wide(dst, shift)); 8905 ins_pipe(ialu_reg); 8906 %} 8907 8908 8909 // Logical Shift Right by 8-bit immediate 8910 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8911 %{ 8912 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8913 effect(KILL cr); 8914 8915 format %{ "shrq $dst, $shift" %} 8916 opcode(0xC1, 0x5); /* C1 /5 ib */ 8917 ins_encode(REX_mem_wide(dst), OpcP, 8918 RM_opc_mem(secondary, dst), Con8or32(shift)); 8919 ins_pipe(ialu_mem_imm); 8920 %} 8921 8922 // Logical Shift Right by variable 8923 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8924 %{ 8925 match(Set dst (URShiftL dst shift)); 8926 effect(KILL cr); 8927 8928 format %{ "shrq $dst, $shift" %} 8929 opcode(0xD3, 0x5); /* D3 /5 */ 8930 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8931 ins_pipe(ialu_reg_reg); 8932 %} 8933 8934 // Logical Shift Right by variable 8935 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8936 %{ 8937 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8938 effect(KILL cr); 8939 8940 format %{ "shrq $dst, $shift" %} 8941 opcode(0xD3, 0x5); /* D3 /5 */ 8942 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8943 ins_pipe(ialu_mem_reg); 8944 %} 8945 8946 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8947 // This idiom is used by the compiler for the i2b bytecode. 8948 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8949 %{ 8950 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8951 8952 format %{ "movsbl $dst, $src\t# i2b" %} 8953 opcode(0x0F, 0xBE); 8954 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8955 ins_pipe(ialu_reg_reg); 8956 %} 8957 8958 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8959 // This idiom is used by the compiler the i2s bytecode. 8960 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8961 %{ 8962 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8963 8964 format %{ "movswl $dst, $src\t# i2s" %} 8965 opcode(0x0F, 0xBF); 8966 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8967 ins_pipe(ialu_reg_reg); 8968 %} 8969 8970 // ROL/ROR instructions 8971 8972 // ROL expand 8973 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8974 effect(KILL cr, USE_DEF dst); 8975 8976 format %{ "roll $dst" %} 8977 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8978 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8979 ins_pipe(ialu_reg); 8980 %} 8981 8982 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8983 effect(USE_DEF dst, USE shift, KILL cr); 8984 8985 format %{ "roll $dst, $shift" %} 8986 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8987 ins_encode( reg_opc_imm(dst, shift) ); 8988 ins_pipe(ialu_reg); 8989 %} 8990 8991 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8992 %{ 8993 effect(USE_DEF dst, USE shift, KILL cr); 8994 8995 format %{ "roll $dst, $shift" %} 8996 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8997 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8998 ins_pipe(ialu_reg_reg); 8999 %} 9000 // end of ROL expand 9001 9002 // Rotate Left by one 9003 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9004 %{ 9005 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9006 9007 expand %{ 9008 rolI_rReg_imm1(dst, cr); 9009 %} 9010 %} 9011 9012 // Rotate Left by 8-bit immediate 9013 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9014 %{ 9015 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9016 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9017 9018 expand %{ 9019 rolI_rReg_imm8(dst, lshift, cr); 9020 %} 9021 %} 9022 9023 // Rotate Left by variable 9024 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9025 %{ 9026 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9027 9028 expand %{ 9029 rolI_rReg_CL(dst, shift, cr); 9030 %} 9031 %} 9032 9033 // Rotate Left by variable 9034 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9035 %{ 9036 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9037 9038 expand %{ 9039 rolI_rReg_CL(dst, shift, cr); 9040 %} 9041 %} 9042 9043 // ROR expand 9044 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9045 %{ 9046 effect(USE_DEF dst, KILL cr); 9047 9048 format %{ "rorl $dst" %} 9049 opcode(0xD1, 0x1); /* D1 /1 */ 9050 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9051 ins_pipe(ialu_reg); 9052 %} 9053 9054 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9055 %{ 9056 effect(USE_DEF dst, USE shift, KILL cr); 9057 9058 format %{ "rorl $dst, $shift" %} 9059 opcode(0xC1, 0x1); /* C1 /1 ib */ 9060 ins_encode(reg_opc_imm(dst, shift)); 9061 ins_pipe(ialu_reg); 9062 %} 9063 9064 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9065 %{ 9066 effect(USE_DEF dst, USE shift, KILL cr); 9067 9068 format %{ "rorl $dst, $shift" %} 9069 opcode(0xD3, 0x1); /* D3 /1 */ 9070 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9071 ins_pipe(ialu_reg_reg); 9072 %} 9073 // end of ROR expand 9074 9075 // Rotate Right by one 9076 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9077 %{ 9078 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9079 9080 expand %{ 9081 rorI_rReg_imm1(dst, cr); 9082 %} 9083 %} 9084 9085 // Rotate Right by 8-bit immediate 9086 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9087 %{ 9088 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9089 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9090 9091 expand %{ 9092 rorI_rReg_imm8(dst, rshift, cr); 9093 %} 9094 %} 9095 9096 // Rotate Right by variable 9097 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9098 %{ 9099 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9100 9101 expand %{ 9102 rorI_rReg_CL(dst, shift, cr); 9103 %} 9104 %} 9105 9106 // Rotate Right by variable 9107 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9108 %{ 9109 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9110 9111 expand %{ 9112 rorI_rReg_CL(dst, shift, cr); 9113 %} 9114 %} 9115 9116 // for long rotate 9117 // ROL expand 9118 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9119 effect(USE_DEF dst, KILL cr); 9120 9121 format %{ "rolq $dst" %} 9122 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9123 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9124 ins_pipe(ialu_reg); 9125 %} 9126 9127 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9128 effect(USE_DEF dst, USE shift, KILL cr); 9129 9130 format %{ "rolq $dst, $shift" %} 9131 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9132 ins_encode( reg_opc_imm_wide(dst, shift) ); 9133 ins_pipe(ialu_reg); 9134 %} 9135 9136 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9137 %{ 9138 effect(USE_DEF dst, USE shift, KILL cr); 9139 9140 format %{ "rolq $dst, $shift" %} 9141 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9142 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9143 ins_pipe(ialu_reg_reg); 9144 %} 9145 // end of ROL expand 9146 9147 // Rotate Left by one 9148 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9149 %{ 9150 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9151 9152 expand %{ 9153 rolL_rReg_imm1(dst, cr); 9154 %} 9155 %} 9156 9157 // Rotate Left by 8-bit immediate 9158 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9159 %{ 9160 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9161 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9162 9163 expand %{ 9164 rolL_rReg_imm8(dst, lshift, cr); 9165 %} 9166 %} 9167 9168 // Rotate Left by variable 9169 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9170 %{ 9171 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9172 9173 expand %{ 9174 rolL_rReg_CL(dst, shift, cr); 9175 %} 9176 %} 9177 9178 // Rotate Left by variable 9179 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9180 %{ 9181 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9182 9183 expand %{ 9184 rolL_rReg_CL(dst, shift, cr); 9185 %} 9186 %} 9187 9188 // ROR expand 9189 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9190 %{ 9191 effect(USE_DEF dst, KILL cr); 9192 9193 format %{ "rorq $dst" %} 9194 opcode(0xD1, 0x1); /* D1 /1 */ 9195 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9196 ins_pipe(ialu_reg); 9197 %} 9198 9199 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9200 %{ 9201 effect(USE_DEF dst, USE shift, KILL cr); 9202 9203 format %{ "rorq $dst, $shift" %} 9204 opcode(0xC1, 0x1); /* C1 /1 ib */ 9205 ins_encode(reg_opc_imm_wide(dst, shift)); 9206 ins_pipe(ialu_reg); 9207 %} 9208 9209 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9210 %{ 9211 effect(USE_DEF dst, USE shift, KILL cr); 9212 9213 format %{ "rorq $dst, $shift" %} 9214 opcode(0xD3, 0x1); /* D3 /1 */ 9215 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9216 ins_pipe(ialu_reg_reg); 9217 %} 9218 // end of ROR expand 9219 9220 // Rotate Right by one 9221 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9222 %{ 9223 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9224 9225 expand %{ 9226 rorL_rReg_imm1(dst, cr); 9227 %} 9228 %} 9229 9230 // Rotate Right by 8-bit immediate 9231 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9232 %{ 9233 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9234 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9235 9236 expand %{ 9237 rorL_rReg_imm8(dst, rshift, cr); 9238 %} 9239 %} 9240 9241 // Rotate Right by variable 9242 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9243 %{ 9244 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9245 9246 expand %{ 9247 rorL_rReg_CL(dst, shift, cr); 9248 %} 9249 %} 9250 9251 // Rotate Right by variable 9252 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9253 %{ 9254 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9255 9256 expand %{ 9257 rorL_rReg_CL(dst, shift, cr); 9258 %} 9259 %} 9260 9261 // Logical Instructions 9262 9263 // Integer Logical Instructions 9264 9265 // And Instructions 9266 // And Register with Register 9267 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9268 %{ 9269 match(Set dst (AndI dst src)); 9270 effect(KILL cr); 9271 9272 format %{ "andl $dst, $src\t# int" %} 9273 opcode(0x23); 9274 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9275 ins_pipe(ialu_reg_reg); 9276 %} 9277 9278 // And Register with Immediate 255 9279 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9280 %{ 9281 match(Set dst (AndI dst src)); 9282 9283 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9284 opcode(0x0F, 0xB6); 9285 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9286 ins_pipe(ialu_reg); 9287 %} 9288 9289 // And Register with Immediate 255 and promote to long 9290 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9291 %{ 9292 match(Set dst (ConvI2L (AndI src mask))); 9293 9294 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9295 opcode(0x0F, 0xB6); 9296 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9297 ins_pipe(ialu_reg); 9298 %} 9299 9300 // And Register with Immediate 65535 9301 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9302 %{ 9303 match(Set dst (AndI dst src)); 9304 9305 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9306 opcode(0x0F, 0xB7); 9307 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9308 ins_pipe(ialu_reg); 9309 %} 9310 9311 // And Register with Immediate 65535 and promote to long 9312 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9313 %{ 9314 match(Set dst (ConvI2L (AndI src mask))); 9315 9316 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9317 opcode(0x0F, 0xB7); 9318 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9319 ins_pipe(ialu_reg); 9320 %} 9321 9322 // And Register with Immediate 9323 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9324 %{ 9325 match(Set dst (AndI dst src)); 9326 effect(KILL cr); 9327 9328 format %{ "andl $dst, $src\t# int" %} 9329 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9330 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9331 ins_pipe(ialu_reg); 9332 %} 9333 9334 // And Register with Memory 9335 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9336 %{ 9337 match(Set dst (AndI dst (LoadI src))); 9338 effect(KILL cr); 9339 9340 ins_cost(125); 9341 format %{ "andl $dst, $src\t# int" %} 9342 opcode(0x23); 9343 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9344 ins_pipe(ialu_reg_mem); 9345 %} 9346 9347 // And Memory with Register 9348 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9349 %{ 9350 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9351 effect(KILL cr); 9352 9353 ins_cost(150); 9354 format %{ "andb $dst, $src\t# byte" %} 9355 opcode(0x20); 9356 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9357 ins_pipe(ialu_mem_reg); 9358 %} 9359 9360 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9361 %{ 9362 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9363 effect(KILL cr); 9364 9365 ins_cost(150); 9366 format %{ "andl $dst, $src\t# int" %} 9367 opcode(0x21); /* Opcode 21 /r */ 9368 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9369 ins_pipe(ialu_mem_reg); 9370 %} 9371 9372 // And Memory with Immediate 9373 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9374 %{ 9375 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9376 effect(KILL cr); 9377 9378 ins_cost(125); 9379 format %{ "andl $dst, $src\t# int" %} 9380 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9381 ins_encode(REX_mem(dst), OpcSE(src), 9382 RM_opc_mem(secondary, dst), Con8or32(src)); 9383 ins_pipe(ialu_mem_imm); 9384 %} 9385 9386 // BMI1 instructions 9387 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9388 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9389 predicate(UseBMI1Instructions); 9390 effect(KILL cr); 9391 9392 ins_cost(125); 9393 format %{ "andnl $dst, $src1, $src2" %} 9394 9395 ins_encode %{ 9396 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9397 %} 9398 ins_pipe(ialu_reg_mem); 9399 %} 9400 9401 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9402 match(Set dst (AndI (XorI src1 minus_1) src2)); 9403 predicate(UseBMI1Instructions); 9404 effect(KILL cr); 9405 9406 format %{ "andnl $dst, $src1, $src2" %} 9407 9408 ins_encode %{ 9409 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9410 %} 9411 ins_pipe(ialu_reg); 9412 %} 9413 9414 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9415 match(Set dst (AndI (SubI imm_zero src) src)); 9416 predicate(UseBMI1Instructions); 9417 effect(KILL cr); 9418 9419 format %{ "blsil $dst, $src" %} 9420 9421 ins_encode %{ 9422 __ blsil($dst$$Register, $src$$Register); 9423 %} 9424 ins_pipe(ialu_reg); 9425 %} 9426 9427 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9428 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9429 predicate(UseBMI1Instructions); 9430 effect(KILL cr); 9431 9432 ins_cost(125); 9433 format %{ "blsil $dst, $src" %} 9434 9435 ins_encode %{ 9436 __ blsil($dst$$Register, $src$$Address); 9437 %} 9438 ins_pipe(ialu_reg_mem); 9439 %} 9440 9441 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9442 %{ 9443 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9444 predicate(UseBMI1Instructions); 9445 effect(KILL cr); 9446 9447 ins_cost(125); 9448 format %{ "blsmskl $dst, $src" %} 9449 9450 ins_encode %{ 9451 __ blsmskl($dst$$Register, $src$$Address); 9452 %} 9453 ins_pipe(ialu_reg_mem); 9454 %} 9455 9456 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9457 %{ 9458 match(Set dst (XorI (AddI src minus_1) src)); 9459 predicate(UseBMI1Instructions); 9460 effect(KILL cr); 9461 9462 format %{ "blsmskl $dst, $src" %} 9463 9464 ins_encode %{ 9465 __ blsmskl($dst$$Register, $src$$Register); 9466 %} 9467 9468 ins_pipe(ialu_reg); 9469 %} 9470 9471 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9472 %{ 9473 match(Set dst (AndI (AddI src minus_1) src) ); 9474 predicate(UseBMI1Instructions); 9475 effect(KILL cr); 9476 9477 format %{ "blsrl $dst, $src" %} 9478 9479 ins_encode %{ 9480 __ blsrl($dst$$Register, $src$$Register); 9481 %} 9482 9483 ins_pipe(ialu_reg_mem); 9484 %} 9485 9486 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9487 %{ 9488 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9489 predicate(UseBMI1Instructions); 9490 effect(KILL cr); 9491 9492 ins_cost(125); 9493 format %{ "blsrl $dst, $src" %} 9494 9495 ins_encode %{ 9496 __ blsrl($dst$$Register, $src$$Address); 9497 %} 9498 9499 ins_pipe(ialu_reg); 9500 %} 9501 9502 // Or Instructions 9503 // Or Register with Register 9504 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9505 %{ 9506 match(Set dst (OrI dst src)); 9507 effect(KILL cr); 9508 9509 format %{ "orl $dst, $src\t# int" %} 9510 opcode(0x0B); 9511 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9512 ins_pipe(ialu_reg_reg); 9513 %} 9514 9515 // Or Register with Immediate 9516 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9517 %{ 9518 match(Set dst (OrI dst src)); 9519 effect(KILL cr); 9520 9521 format %{ "orl $dst, $src\t# int" %} 9522 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9523 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9524 ins_pipe(ialu_reg); 9525 %} 9526 9527 // Or Register with Memory 9528 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9529 %{ 9530 match(Set dst (OrI dst (LoadI src))); 9531 effect(KILL cr); 9532 9533 ins_cost(125); 9534 format %{ "orl $dst, $src\t# int" %} 9535 opcode(0x0B); 9536 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9537 ins_pipe(ialu_reg_mem); 9538 %} 9539 9540 // Or Memory with Register 9541 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9542 %{ 9543 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9544 effect(KILL cr); 9545 9546 ins_cost(150); 9547 format %{ "orb $dst, $src\t# byte" %} 9548 opcode(0x08); 9549 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9550 ins_pipe(ialu_mem_reg); 9551 %} 9552 9553 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9554 %{ 9555 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9556 effect(KILL cr); 9557 9558 ins_cost(150); 9559 format %{ "orl $dst, $src\t# int" %} 9560 opcode(0x09); /* Opcode 09 /r */ 9561 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9562 ins_pipe(ialu_mem_reg); 9563 %} 9564 9565 // Or Memory with Immediate 9566 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9567 %{ 9568 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9569 effect(KILL cr); 9570 9571 ins_cost(125); 9572 format %{ "orl $dst, $src\t# int" %} 9573 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9574 ins_encode(REX_mem(dst), OpcSE(src), 9575 RM_opc_mem(secondary, dst), Con8or32(src)); 9576 ins_pipe(ialu_mem_imm); 9577 %} 9578 9579 // Xor Instructions 9580 // Xor Register with Register 9581 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9582 %{ 9583 match(Set dst (XorI dst src)); 9584 effect(KILL cr); 9585 9586 format %{ "xorl $dst, $src\t# int" %} 9587 opcode(0x33); 9588 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9589 ins_pipe(ialu_reg_reg); 9590 %} 9591 9592 // Xor Register with Immediate -1 9593 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9594 match(Set dst (XorI dst imm)); 9595 9596 format %{ "not $dst" %} 9597 ins_encode %{ 9598 __ notl($dst$$Register); 9599 %} 9600 ins_pipe(ialu_reg); 9601 %} 9602 9603 // Xor Register with Immediate 9604 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9605 %{ 9606 match(Set dst (XorI dst src)); 9607 effect(KILL cr); 9608 9609 format %{ "xorl $dst, $src\t# int" %} 9610 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9611 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9612 ins_pipe(ialu_reg); 9613 %} 9614 9615 // Xor Register with Memory 9616 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9617 %{ 9618 match(Set dst (XorI dst (LoadI src))); 9619 effect(KILL cr); 9620 9621 ins_cost(125); 9622 format %{ "xorl $dst, $src\t# int" %} 9623 opcode(0x33); 9624 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9625 ins_pipe(ialu_reg_mem); 9626 %} 9627 9628 // Xor Memory with Register 9629 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9630 %{ 9631 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9632 effect(KILL cr); 9633 9634 ins_cost(150); 9635 format %{ "xorb $dst, $src\t# byte" %} 9636 opcode(0x30); 9637 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9638 ins_pipe(ialu_mem_reg); 9639 %} 9640 9641 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9642 %{ 9643 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9644 effect(KILL cr); 9645 9646 ins_cost(150); 9647 format %{ "xorl $dst, $src\t# int" %} 9648 opcode(0x31); /* Opcode 31 /r */ 9649 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9650 ins_pipe(ialu_mem_reg); 9651 %} 9652 9653 // Xor Memory with Immediate 9654 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9655 %{ 9656 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9657 effect(KILL cr); 9658 9659 ins_cost(125); 9660 format %{ "xorl $dst, $src\t# int" %} 9661 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9662 ins_encode(REX_mem(dst), OpcSE(src), 9663 RM_opc_mem(secondary, dst), Con8or32(src)); 9664 ins_pipe(ialu_mem_imm); 9665 %} 9666 9667 9668 // Long Logical Instructions 9669 9670 // And Instructions 9671 // And Register with Register 9672 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9673 %{ 9674 match(Set dst (AndL dst src)); 9675 effect(KILL cr); 9676 9677 format %{ "andq $dst, $src\t# long" %} 9678 opcode(0x23); 9679 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9680 ins_pipe(ialu_reg_reg); 9681 %} 9682 9683 // And Register with Immediate 255 9684 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9685 %{ 9686 match(Set dst (AndL dst src)); 9687 9688 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9689 opcode(0x0F, 0xB6); 9690 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9691 ins_pipe(ialu_reg); 9692 %} 9693 9694 // And Register with Immediate 65535 9695 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9696 %{ 9697 match(Set dst (AndL dst src)); 9698 9699 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9700 opcode(0x0F, 0xB7); 9701 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9702 ins_pipe(ialu_reg); 9703 %} 9704 9705 // And Register with Immediate 9706 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9707 %{ 9708 match(Set dst (AndL dst src)); 9709 effect(KILL cr); 9710 9711 format %{ "andq $dst, $src\t# long" %} 9712 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9713 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9714 ins_pipe(ialu_reg); 9715 %} 9716 9717 // And Register with Memory 9718 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9719 %{ 9720 match(Set dst (AndL dst (LoadL src))); 9721 effect(KILL cr); 9722 9723 ins_cost(125); 9724 format %{ "andq $dst, $src\t# long" %} 9725 opcode(0x23); 9726 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9727 ins_pipe(ialu_reg_mem); 9728 %} 9729 9730 // And Memory with Register 9731 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9732 %{ 9733 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9734 effect(KILL cr); 9735 9736 ins_cost(150); 9737 format %{ "andq $dst, $src\t# long" %} 9738 opcode(0x21); /* Opcode 21 /r */ 9739 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9740 ins_pipe(ialu_mem_reg); 9741 %} 9742 9743 // And Memory with Immediate 9744 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9745 %{ 9746 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9747 effect(KILL cr); 9748 9749 ins_cost(125); 9750 format %{ "andq $dst, $src\t# long" %} 9751 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9752 ins_encode(REX_mem_wide(dst), OpcSE(src), 9753 RM_opc_mem(secondary, dst), Con8or32(src)); 9754 ins_pipe(ialu_mem_imm); 9755 %} 9756 9757 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9758 %{ 9759 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9760 // because AND/OR works well enough for 8/32-bit values. 9761 predicate(log2_long(~n->in(3)->in(2)->get_long()) > 30); 9762 9763 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9764 effect(KILL cr); 9765 9766 ins_cost(125); 9767 format %{ "btrq $dst, log2(not($con))\t# long" %} 9768 ins_encode %{ 9769 __ btrq($dst$$Address, log2_long(~$con$$constant)); 9770 %} 9771 ins_pipe(ialu_mem_imm); 9772 %} 9773 9774 // BMI1 instructions 9775 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9776 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9777 predicate(UseBMI1Instructions); 9778 effect(KILL cr); 9779 9780 ins_cost(125); 9781 format %{ "andnq $dst, $src1, $src2" %} 9782 9783 ins_encode %{ 9784 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9785 %} 9786 ins_pipe(ialu_reg_mem); 9787 %} 9788 9789 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9790 match(Set dst (AndL (XorL src1 minus_1) src2)); 9791 predicate(UseBMI1Instructions); 9792 effect(KILL cr); 9793 9794 format %{ "andnq $dst, $src1, $src2" %} 9795 9796 ins_encode %{ 9797 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9798 %} 9799 ins_pipe(ialu_reg_mem); 9800 %} 9801 9802 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9803 match(Set dst (AndL (SubL imm_zero src) src)); 9804 predicate(UseBMI1Instructions); 9805 effect(KILL cr); 9806 9807 format %{ "blsiq $dst, $src" %} 9808 9809 ins_encode %{ 9810 __ blsiq($dst$$Register, $src$$Register); 9811 %} 9812 ins_pipe(ialu_reg); 9813 %} 9814 9815 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9816 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9817 predicate(UseBMI1Instructions); 9818 effect(KILL cr); 9819 9820 ins_cost(125); 9821 format %{ "blsiq $dst, $src" %} 9822 9823 ins_encode %{ 9824 __ blsiq($dst$$Register, $src$$Address); 9825 %} 9826 ins_pipe(ialu_reg_mem); 9827 %} 9828 9829 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9830 %{ 9831 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9832 predicate(UseBMI1Instructions); 9833 effect(KILL cr); 9834 9835 ins_cost(125); 9836 format %{ "blsmskq $dst, $src" %} 9837 9838 ins_encode %{ 9839 __ blsmskq($dst$$Register, $src$$Address); 9840 %} 9841 ins_pipe(ialu_reg_mem); 9842 %} 9843 9844 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9845 %{ 9846 match(Set dst (XorL (AddL src minus_1) src)); 9847 predicate(UseBMI1Instructions); 9848 effect(KILL cr); 9849 9850 format %{ "blsmskq $dst, $src" %} 9851 9852 ins_encode %{ 9853 __ blsmskq($dst$$Register, $src$$Register); 9854 %} 9855 9856 ins_pipe(ialu_reg); 9857 %} 9858 9859 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9860 %{ 9861 match(Set dst (AndL (AddL src minus_1) src) ); 9862 predicate(UseBMI1Instructions); 9863 effect(KILL cr); 9864 9865 format %{ "blsrq $dst, $src" %} 9866 9867 ins_encode %{ 9868 __ blsrq($dst$$Register, $src$$Register); 9869 %} 9870 9871 ins_pipe(ialu_reg); 9872 %} 9873 9874 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9875 %{ 9876 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9877 predicate(UseBMI1Instructions); 9878 effect(KILL cr); 9879 9880 ins_cost(125); 9881 format %{ "blsrq $dst, $src" %} 9882 9883 ins_encode %{ 9884 __ blsrq($dst$$Register, $src$$Address); 9885 %} 9886 9887 ins_pipe(ialu_reg); 9888 %} 9889 9890 // Or Instructions 9891 // Or Register with Register 9892 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9893 %{ 9894 match(Set dst (OrL dst src)); 9895 effect(KILL cr); 9896 9897 format %{ "orq $dst, $src\t# long" %} 9898 opcode(0x0B); 9899 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9900 ins_pipe(ialu_reg_reg); 9901 %} 9902 9903 // Use any_RegP to match R15 (TLS register) without spilling. 9904 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9905 match(Set dst (OrL dst (CastP2X src))); 9906 effect(KILL cr); 9907 9908 format %{ "orq $dst, $src\t# long" %} 9909 opcode(0x0B); 9910 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9911 ins_pipe(ialu_reg_reg); 9912 %} 9913 9914 9915 // Or Register with Immediate 9916 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9917 %{ 9918 match(Set dst (OrL dst src)); 9919 effect(KILL cr); 9920 9921 format %{ "orq $dst, $src\t# long" %} 9922 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9923 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9924 ins_pipe(ialu_reg); 9925 %} 9926 9927 // Or Register with Memory 9928 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9929 %{ 9930 match(Set dst (OrL dst (LoadL src))); 9931 effect(KILL cr); 9932 9933 ins_cost(125); 9934 format %{ "orq $dst, $src\t# long" %} 9935 opcode(0x0B); 9936 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9937 ins_pipe(ialu_reg_mem); 9938 %} 9939 9940 // Or Memory with Register 9941 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9942 %{ 9943 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9944 effect(KILL cr); 9945 9946 ins_cost(150); 9947 format %{ "orq $dst, $src\t# long" %} 9948 opcode(0x09); /* Opcode 09 /r */ 9949 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9950 ins_pipe(ialu_mem_reg); 9951 %} 9952 9953 // Or Memory with Immediate 9954 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9955 %{ 9956 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9957 effect(KILL cr); 9958 9959 ins_cost(125); 9960 format %{ "orq $dst, $src\t# long" %} 9961 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9962 ins_encode(REX_mem_wide(dst), OpcSE(src), 9963 RM_opc_mem(secondary, dst), Con8or32(src)); 9964 ins_pipe(ialu_mem_imm); 9965 %} 9966 9967 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9968 %{ 9969 // con should be a pure 64-bit power of 2 immediate 9970 // because AND/OR works well enough for 8/32-bit values. 9971 predicate(log2_long(n->in(3)->in(2)->get_long()) > 31); 9972 9973 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9974 effect(KILL cr); 9975 9976 ins_cost(125); 9977 format %{ "btsq $dst, log2($con)\t# long" %} 9978 ins_encode %{ 9979 __ btsq($dst$$Address, log2_long((julong)$con$$constant)); 9980 %} 9981 ins_pipe(ialu_mem_imm); 9982 %} 9983 9984 // Xor Instructions 9985 // Xor Register with Register 9986 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9987 %{ 9988 match(Set dst (XorL dst src)); 9989 effect(KILL cr); 9990 9991 format %{ "xorq $dst, $src\t# long" %} 9992 opcode(0x33); 9993 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9994 ins_pipe(ialu_reg_reg); 9995 %} 9996 9997 // Xor Register with Immediate -1 9998 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9999 match(Set dst (XorL dst imm)); 10000 10001 format %{ "notq $dst" %} 10002 ins_encode %{ 10003 __ notq($dst$$Register); 10004 %} 10005 ins_pipe(ialu_reg); 10006 %} 10007 10008 // Xor Register with Immediate 10009 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10010 %{ 10011 match(Set dst (XorL dst src)); 10012 effect(KILL cr); 10013 10014 format %{ "xorq $dst, $src\t# long" %} 10015 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10016 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10017 ins_pipe(ialu_reg); 10018 %} 10019 10020 // Xor Register with Memory 10021 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10022 %{ 10023 match(Set dst (XorL dst (LoadL src))); 10024 effect(KILL cr); 10025 10026 ins_cost(125); 10027 format %{ "xorq $dst, $src\t# long" %} 10028 opcode(0x33); 10029 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10030 ins_pipe(ialu_reg_mem); 10031 %} 10032 10033 // Xor Memory with Register 10034 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10035 %{ 10036 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10037 effect(KILL cr); 10038 10039 ins_cost(150); 10040 format %{ "xorq $dst, $src\t# long" %} 10041 opcode(0x31); /* Opcode 31 /r */ 10042 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10043 ins_pipe(ialu_mem_reg); 10044 %} 10045 10046 // Xor Memory with Immediate 10047 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10048 %{ 10049 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10050 effect(KILL cr); 10051 10052 ins_cost(125); 10053 format %{ "xorq $dst, $src\t# long" %} 10054 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10055 ins_encode(REX_mem_wide(dst), OpcSE(src), 10056 RM_opc_mem(secondary, dst), Con8or32(src)); 10057 ins_pipe(ialu_mem_imm); 10058 %} 10059 10060 // Convert Int to Boolean 10061 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10062 %{ 10063 match(Set dst (Conv2B src)); 10064 effect(KILL cr); 10065 10066 format %{ "testl $src, $src\t# ci2b\n\t" 10067 "setnz $dst\n\t" 10068 "movzbl $dst, $dst" %} 10069 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10070 setNZ_reg(dst), 10071 REX_reg_breg(dst, dst), // movzbl 10072 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10073 ins_pipe(pipe_slow); // XXX 10074 %} 10075 10076 // Convert Pointer to Boolean 10077 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10078 %{ 10079 match(Set dst (Conv2B src)); 10080 effect(KILL cr); 10081 10082 format %{ "testq $src, $src\t# cp2b\n\t" 10083 "setnz $dst\n\t" 10084 "movzbl $dst, $dst" %} 10085 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10086 setNZ_reg(dst), 10087 REX_reg_breg(dst, dst), // movzbl 10088 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10089 ins_pipe(pipe_slow); // XXX 10090 %} 10091 10092 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10093 %{ 10094 match(Set dst (CmpLTMask p q)); 10095 effect(KILL cr); 10096 10097 ins_cost(400); 10098 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10099 "setlt $dst\n\t" 10100 "movzbl $dst, $dst\n\t" 10101 "negl $dst" %} 10102 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10103 setLT_reg(dst), 10104 REX_reg_breg(dst, dst), // movzbl 10105 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10106 neg_reg(dst)); 10107 ins_pipe(pipe_slow); 10108 %} 10109 10110 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10111 %{ 10112 match(Set dst (CmpLTMask dst zero)); 10113 effect(KILL cr); 10114 10115 ins_cost(100); 10116 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10117 ins_encode %{ 10118 __ sarl($dst$$Register, 31); 10119 %} 10120 ins_pipe(ialu_reg); 10121 %} 10122 10123 /* Better to save a register than avoid a branch */ 10124 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10125 %{ 10126 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10127 effect(KILL cr); 10128 ins_cost(300); 10129 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10130 "jge done\n\t" 10131 "addl $p,$y\n" 10132 "done: " %} 10133 ins_encode %{ 10134 Register Rp = $p$$Register; 10135 Register Rq = $q$$Register; 10136 Register Ry = $y$$Register; 10137 Label done; 10138 __ subl(Rp, Rq); 10139 __ jccb(Assembler::greaterEqual, done); 10140 __ addl(Rp, Ry); 10141 __ bind(done); 10142 %} 10143 ins_pipe(pipe_cmplt); 10144 %} 10145 10146 /* Better to save a register than avoid a branch */ 10147 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10148 %{ 10149 match(Set y (AndI (CmpLTMask p q) y)); 10150 effect(KILL cr); 10151 10152 ins_cost(300); 10153 10154 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10155 "jlt done\n\t" 10156 "xorl $y, $y\n" 10157 "done: " %} 10158 ins_encode %{ 10159 Register Rp = $p$$Register; 10160 Register Rq = $q$$Register; 10161 Register Ry = $y$$Register; 10162 Label done; 10163 __ cmpl(Rp, Rq); 10164 __ jccb(Assembler::less, done); 10165 __ xorl(Ry, Ry); 10166 __ bind(done); 10167 %} 10168 ins_pipe(pipe_cmplt); 10169 %} 10170 10171 10172 //---------- FP Instructions------------------------------------------------ 10173 10174 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10175 %{ 10176 match(Set cr (CmpF src1 src2)); 10177 10178 ins_cost(145); 10179 format %{ "ucomiss $src1, $src2\n\t" 10180 "jnp,s exit\n\t" 10181 "pushfq\t# saw NaN, set CF\n\t" 10182 "andq [rsp], #0xffffff2b\n\t" 10183 "popfq\n" 10184 "exit:" %} 10185 ins_encode %{ 10186 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10187 emit_cmpfp_fixup(_masm); 10188 %} 10189 ins_pipe(pipe_slow); 10190 %} 10191 10192 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10193 match(Set cr (CmpF src1 src2)); 10194 10195 ins_cost(100); 10196 format %{ "ucomiss $src1, $src2" %} 10197 ins_encode %{ 10198 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10199 %} 10200 ins_pipe(pipe_slow); 10201 %} 10202 10203 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10204 %{ 10205 match(Set cr (CmpF src1 (LoadF src2))); 10206 10207 ins_cost(145); 10208 format %{ "ucomiss $src1, $src2\n\t" 10209 "jnp,s exit\n\t" 10210 "pushfq\t# saw NaN, set CF\n\t" 10211 "andq [rsp], #0xffffff2b\n\t" 10212 "popfq\n" 10213 "exit:" %} 10214 ins_encode %{ 10215 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10216 emit_cmpfp_fixup(_masm); 10217 %} 10218 ins_pipe(pipe_slow); 10219 %} 10220 10221 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10222 match(Set cr (CmpF src1 (LoadF src2))); 10223 10224 ins_cost(100); 10225 format %{ "ucomiss $src1, $src2" %} 10226 ins_encode %{ 10227 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10228 %} 10229 ins_pipe(pipe_slow); 10230 %} 10231 10232 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10233 match(Set cr (CmpF src con)); 10234 10235 ins_cost(145); 10236 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10237 "jnp,s exit\n\t" 10238 "pushfq\t# saw NaN, set CF\n\t" 10239 "andq [rsp], #0xffffff2b\n\t" 10240 "popfq\n" 10241 "exit:" %} 10242 ins_encode %{ 10243 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10244 emit_cmpfp_fixup(_masm); 10245 %} 10246 ins_pipe(pipe_slow); 10247 %} 10248 10249 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10250 match(Set cr (CmpF src con)); 10251 ins_cost(100); 10252 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10253 ins_encode %{ 10254 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10255 %} 10256 ins_pipe(pipe_slow); 10257 %} 10258 10259 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10260 %{ 10261 match(Set cr (CmpD src1 src2)); 10262 10263 ins_cost(145); 10264 format %{ "ucomisd $src1, $src2\n\t" 10265 "jnp,s exit\n\t" 10266 "pushfq\t# saw NaN, set CF\n\t" 10267 "andq [rsp], #0xffffff2b\n\t" 10268 "popfq\n" 10269 "exit:" %} 10270 ins_encode %{ 10271 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10272 emit_cmpfp_fixup(_masm); 10273 %} 10274 ins_pipe(pipe_slow); 10275 %} 10276 10277 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10278 match(Set cr (CmpD src1 src2)); 10279 10280 ins_cost(100); 10281 format %{ "ucomisd $src1, $src2 test" %} 10282 ins_encode %{ 10283 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10284 %} 10285 ins_pipe(pipe_slow); 10286 %} 10287 10288 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10289 %{ 10290 match(Set cr (CmpD src1 (LoadD src2))); 10291 10292 ins_cost(145); 10293 format %{ "ucomisd $src1, $src2\n\t" 10294 "jnp,s exit\n\t" 10295 "pushfq\t# saw NaN, set CF\n\t" 10296 "andq [rsp], #0xffffff2b\n\t" 10297 "popfq\n" 10298 "exit:" %} 10299 ins_encode %{ 10300 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10301 emit_cmpfp_fixup(_masm); 10302 %} 10303 ins_pipe(pipe_slow); 10304 %} 10305 10306 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10307 match(Set cr (CmpD src1 (LoadD src2))); 10308 10309 ins_cost(100); 10310 format %{ "ucomisd $src1, $src2" %} 10311 ins_encode %{ 10312 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10313 %} 10314 ins_pipe(pipe_slow); 10315 %} 10316 10317 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10318 match(Set cr (CmpD src con)); 10319 10320 ins_cost(145); 10321 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10322 "jnp,s exit\n\t" 10323 "pushfq\t# saw NaN, set CF\n\t" 10324 "andq [rsp], #0xffffff2b\n\t" 10325 "popfq\n" 10326 "exit:" %} 10327 ins_encode %{ 10328 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10329 emit_cmpfp_fixup(_masm); 10330 %} 10331 ins_pipe(pipe_slow); 10332 %} 10333 10334 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10335 match(Set cr (CmpD src con)); 10336 ins_cost(100); 10337 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10338 ins_encode %{ 10339 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10340 %} 10341 ins_pipe(pipe_slow); 10342 %} 10343 10344 // Compare into -1,0,1 10345 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10346 %{ 10347 match(Set dst (CmpF3 src1 src2)); 10348 effect(KILL cr); 10349 10350 ins_cost(275); 10351 format %{ "ucomiss $src1, $src2\n\t" 10352 "movl $dst, #-1\n\t" 10353 "jp,s done\n\t" 10354 "jb,s done\n\t" 10355 "setne $dst\n\t" 10356 "movzbl $dst, $dst\n" 10357 "done:" %} 10358 ins_encode %{ 10359 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10360 emit_cmpfp3(_masm, $dst$$Register); 10361 %} 10362 ins_pipe(pipe_slow); 10363 %} 10364 10365 // Compare into -1,0,1 10366 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10367 %{ 10368 match(Set dst (CmpF3 src1 (LoadF 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$$Address); 10381 emit_cmpfp3(_masm, $dst$$Register); 10382 %} 10383 ins_pipe(pipe_slow); 10384 %} 10385 10386 // Compare into -1,0,1 10387 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10388 match(Set dst (CmpF3 src con)); 10389 effect(KILL cr); 10390 10391 ins_cost(275); 10392 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10393 "movl $dst, #-1\n\t" 10394 "jp,s done\n\t" 10395 "jb,s done\n\t" 10396 "setne $dst\n\t" 10397 "movzbl $dst, $dst\n" 10398 "done:" %} 10399 ins_encode %{ 10400 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10401 emit_cmpfp3(_masm, $dst$$Register); 10402 %} 10403 ins_pipe(pipe_slow); 10404 %} 10405 10406 // Compare into -1,0,1 10407 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10408 %{ 10409 match(Set dst (CmpD3 src1 src2)); 10410 effect(KILL cr); 10411 10412 ins_cost(275); 10413 format %{ "ucomisd $src1, $src2\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 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10422 emit_cmpfp3(_masm, $dst$$Register); 10423 %} 10424 ins_pipe(pipe_slow); 10425 %} 10426 10427 // Compare into -1,0,1 10428 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10429 %{ 10430 match(Set dst (CmpD3 src1 (LoadD 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$$Address); 10443 emit_cmpfp3(_masm, $dst$$Register); 10444 %} 10445 ins_pipe(pipe_slow); 10446 %} 10447 10448 // Compare into -1,0,1 10449 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10450 match(Set dst (CmpD3 src con)); 10451 effect(KILL cr); 10452 10453 ins_cost(275); 10454 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10455 "movl $dst, #-1\n\t" 10456 "jp,s done\n\t" 10457 "jb,s done\n\t" 10458 "setne $dst\n\t" 10459 "movzbl $dst, $dst\n" 10460 "done:" %} 10461 ins_encode %{ 10462 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10463 emit_cmpfp3(_masm, $dst$$Register); 10464 %} 10465 ins_pipe(pipe_slow); 10466 %} 10467 10468 //----------Arithmetic Conversion Instructions--------------------------------- 10469 10470 instruct convF2D_reg_reg(regD dst, regF src) 10471 %{ 10472 match(Set dst (ConvF2D src)); 10473 10474 format %{ "cvtss2sd $dst, $src" %} 10475 ins_encode %{ 10476 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10477 %} 10478 ins_pipe(pipe_slow); // XXX 10479 %} 10480 10481 instruct convF2D_reg_mem(regD dst, memory src) 10482 %{ 10483 match(Set dst (ConvF2D (LoadF src))); 10484 10485 format %{ "cvtss2sd $dst, $src" %} 10486 ins_encode %{ 10487 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10488 %} 10489 ins_pipe(pipe_slow); // XXX 10490 %} 10491 10492 instruct convD2F_reg_reg(regF dst, regD src) 10493 %{ 10494 match(Set dst (ConvD2F src)); 10495 10496 format %{ "cvtsd2ss $dst, $src" %} 10497 ins_encode %{ 10498 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10499 %} 10500 ins_pipe(pipe_slow); // XXX 10501 %} 10502 10503 instruct convD2F_reg_mem(regF dst, memory src) 10504 %{ 10505 match(Set dst (ConvD2F (LoadD src))); 10506 10507 format %{ "cvtsd2ss $dst, $src" %} 10508 ins_encode %{ 10509 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10510 %} 10511 ins_pipe(pipe_slow); // XXX 10512 %} 10513 10514 // XXX do mem variants 10515 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10516 %{ 10517 match(Set dst (ConvF2I src)); 10518 effect(KILL cr); 10519 format %{ "convert_f2i $dst,$src" %} 10520 ins_encode %{ 10521 __ convert_f2i($dst$$Register, $src$$XMMRegister); 10522 %} 10523 ins_pipe(pipe_slow); 10524 %} 10525 10526 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10527 %{ 10528 match(Set dst (ConvF2L src)); 10529 effect(KILL cr); 10530 format %{ "convert_f2l $dst,$src"%} 10531 ins_encode %{ 10532 __ convert_f2l($dst$$Register, $src$$XMMRegister); 10533 %} 10534 ins_pipe(pipe_slow); 10535 %} 10536 10537 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10538 %{ 10539 match(Set dst (ConvD2I src)); 10540 effect(KILL cr); 10541 format %{ "convert_d2i $dst,$src"%} 10542 ins_encode %{ 10543 __ convert_d2i($dst$$Register, $src$$XMMRegister); 10544 %} 10545 ins_pipe(pipe_slow); 10546 %} 10547 10548 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10549 %{ 10550 match(Set dst (ConvD2L src)); 10551 effect(KILL cr); 10552 format %{ "convert_d2l $dst,$src"%} 10553 ins_encode %{ 10554 __ convert_d2l($dst$$Register, $src$$XMMRegister); 10555 %} 10556 ins_pipe(pipe_slow); 10557 %} 10558 10559 instruct convI2F_reg_reg(regF dst, rRegI src) 10560 %{ 10561 predicate(!UseXmmI2F); 10562 match(Set dst (ConvI2F src)); 10563 10564 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10565 ins_encode %{ 10566 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10567 %} 10568 ins_pipe(pipe_slow); // XXX 10569 %} 10570 10571 instruct convI2F_reg_mem(regF dst, memory src) 10572 %{ 10573 match(Set dst (ConvI2F (LoadI src))); 10574 10575 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10576 ins_encode %{ 10577 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10578 %} 10579 ins_pipe(pipe_slow); // XXX 10580 %} 10581 10582 instruct convI2D_reg_reg(regD dst, rRegI src) 10583 %{ 10584 predicate(!UseXmmI2D); 10585 match(Set dst (ConvI2D src)); 10586 10587 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10588 ins_encode %{ 10589 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10590 %} 10591 ins_pipe(pipe_slow); // XXX 10592 %} 10593 10594 instruct convI2D_reg_mem(regD dst, memory src) 10595 %{ 10596 match(Set dst (ConvI2D (LoadI src))); 10597 10598 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10599 ins_encode %{ 10600 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10601 %} 10602 ins_pipe(pipe_slow); // XXX 10603 %} 10604 10605 instruct convXI2F_reg(regF dst, rRegI src) 10606 %{ 10607 predicate(UseXmmI2F); 10608 match(Set dst (ConvI2F src)); 10609 10610 format %{ "movdl $dst, $src\n\t" 10611 "cvtdq2psl $dst, $dst\t# i2f" %} 10612 ins_encode %{ 10613 __ movdl($dst$$XMMRegister, $src$$Register); 10614 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10615 %} 10616 ins_pipe(pipe_slow); // XXX 10617 %} 10618 10619 instruct convXI2D_reg(regD dst, rRegI src) 10620 %{ 10621 predicate(UseXmmI2D); 10622 match(Set dst (ConvI2D src)); 10623 10624 format %{ "movdl $dst, $src\n\t" 10625 "cvtdq2pdl $dst, $dst\t# i2d" %} 10626 ins_encode %{ 10627 __ movdl($dst$$XMMRegister, $src$$Register); 10628 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10629 %} 10630 ins_pipe(pipe_slow); // XXX 10631 %} 10632 10633 instruct convL2F_reg_reg(regF dst, rRegL src) 10634 %{ 10635 match(Set dst (ConvL2F src)); 10636 10637 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10638 ins_encode %{ 10639 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10640 %} 10641 ins_pipe(pipe_slow); // XXX 10642 %} 10643 10644 instruct convL2F_reg_mem(regF dst, memory src) 10645 %{ 10646 match(Set dst (ConvL2F (LoadL src))); 10647 10648 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10649 ins_encode %{ 10650 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10651 %} 10652 ins_pipe(pipe_slow); // XXX 10653 %} 10654 10655 instruct convL2D_reg_reg(regD dst, rRegL src) 10656 %{ 10657 match(Set dst (ConvL2D src)); 10658 10659 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10660 ins_encode %{ 10661 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10662 %} 10663 ins_pipe(pipe_slow); // XXX 10664 %} 10665 10666 instruct convL2D_reg_mem(regD dst, memory src) 10667 %{ 10668 match(Set dst (ConvL2D (LoadL src))); 10669 10670 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10671 ins_encode %{ 10672 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10673 %} 10674 ins_pipe(pipe_slow); // XXX 10675 %} 10676 10677 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10678 %{ 10679 match(Set dst (ConvI2L src)); 10680 10681 ins_cost(125); 10682 format %{ "movslq $dst, $src\t# i2l" %} 10683 ins_encode %{ 10684 __ movslq($dst$$Register, $src$$Register); 10685 %} 10686 ins_pipe(ialu_reg_reg); 10687 %} 10688 10689 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10690 // %{ 10691 // match(Set dst (ConvI2L src)); 10692 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10693 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10694 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10695 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10696 // ((const TypeNode*) n)->type()->is_long()->_lo == 10697 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10698 10699 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10700 // ins_encode(enc_copy(dst, src)); 10701 // // opcode(0x63); // needs REX.W 10702 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10703 // ins_pipe(ialu_reg_reg); 10704 // %} 10705 10706 // Zero-extend convert int to long 10707 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10708 %{ 10709 match(Set dst (AndL (ConvI2L src) mask)); 10710 10711 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10712 ins_encode %{ 10713 if ($dst$$reg != $src$$reg) { 10714 __ movl($dst$$Register, $src$$Register); 10715 } 10716 %} 10717 ins_pipe(ialu_reg_reg); 10718 %} 10719 10720 // Zero-extend convert int to long 10721 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10722 %{ 10723 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10724 10725 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10726 ins_encode %{ 10727 __ movl($dst$$Register, $src$$Address); 10728 %} 10729 ins_pipe(ialu_reg_mem); 10730 %} 10731 10732 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10733 %{ 10734 match(Set dst (AndL src mask)); 10735 10736 format %{ "movl $dst, $src\t# zero-extend long" %} 10737 ins_encode %{ 10738 __ movl($dst$$Register, $src$$Register); 10739 %} 10740 ins_pipe(ialu_reg_reg); 10741 %} 10742 10743 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10744 %{ 10745 match(Set dst (ConvL2I src)); 10746 10747 format %{ "movl $dst, $src\t# l2i" %} 10748 ins_encode %{ 10749 __ movl($dst$$Register, $src$$Register); 10750 %} 10751 ins_pipe(ialu_reg_reg); 10752 %} 10753 10754 10755 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10756 match(Set dst (MoveF2I src)); 10757 effect(DEF dst, USE src); 10758 10759 ins_cost(125); 10760 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10761 ins_encode %{ 10762 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10763 %} 10764 ins_pipe(ialu_reg_mem); 10765 %} 10766 10767 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10768 match(Set dst (MoveI2F src)); 10769 effect(DEF dst, USE src); 10770 10771 ins_cost(125); 10772 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10773 ins_encode %{ 10774 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10775 %} 10776 ins_pipe(pipe_slow); 10777 %} 10778 10779 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10780 match(Set dst (MoveD2L src)); 10781 effect(DEF dst, USE src); 10782 10783 ins_cost(125); 10784 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10785 ins_encode %{ 10786 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10787 %} 10788 ins_pipe(ialu_reg_mem); 10789 %} 10790 10791 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10792 predicate(!UseXmmLoadAndClearUpper); 10793 match(Set dst (MoveL2D src)); 10794 effect(DEF dst, USE src); 10795 10796 ins_cost(125); 10797 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10798 ins_encode %{ 10799 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10800 %} 10801 ins_pipe(pipe_slow); 10802 %} 10803 10804 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10805 predicate(UseXmmLoadAndClearUpper); 10806 match(Set dst (MoveL2D src)); 10807 effect(DEF dst, USE src); 10808 10809 ins_cost(125); 10810 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10811 ins_encode %{ 10812 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10813 %} 10814 ins_pipe(pipe_slow); 10815 %} 10816 10817 10818 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10819 match(Set dst (MoveF2I src)); 10820 effect(DEF dst, USE src); 10821 10822 ins_cost(95); // XXX 10823 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10824 ins_encode %{ 10825 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10826 %} 10827 ins_pipe(pipe_slow); 10828 %} 10829 10830 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10831 match(Set dst (MoveI2F src)); 10832 effect(DEF dst, USE src); 10833 10834 ins_cost(100); 10835 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10836 ins_encode %{ 10837 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10838 %} 10839 ins_pipe( ialu_mem_reg ); 10840 %} 10841 10842 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10843 match(Set dst (MoveD2L src)); 10844 effect(DEF dst, USE src); 10845 10846 ins_cost(95); // XXX 10847 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10848 ins_encode %{ 10849 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10850 %} 10851 ins_pipe(pipe_slow); 10852 %} 10853 10854 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10855 match(Set dst (MoveL2D src)); 10856 effect(DEF dst, USE src); 10857 10858 ins_cost(100); 10859 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10860 ins_encode %{ 10861 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10862 %} 10863 ins_pipe(ialu_mem_reg); 10864 %} 10865 10866 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10867 match(Set dst (MoveF2I src)); 10868 effect(DEF dst, USE src); 10869 ins_cost(85); 10870 format %{ "movd $dst,$src\t# MoveF2I" %} 10871 ins_encode %{ 10872 __ movdl($dst$$Register, $src$$XMMRegister); 10873 %} 10874 ins_pipe( pipe_slow ); 10875 %} 10876 10877 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10878 match(Set dst (MoveD2L src)); 10879 effect(DEF dst, USE src); 10880 ins_cost(85); 10881 format %{ "movd $dst,$src\t# MoveD2L" %} 10882 ins_encode %{ 10883 __ movdq($dst$$Register, $src$$XMMRegister); 10884 %} 10885 ins_pipe( pipe_slow ); 10886 %} 10887 10888 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10889 match(Set dst (MoveI2F src)); 10890 effect(DEF dst, USE src); 10891 ins_cost(100); 10892 format %{ "movd $dst,$src\t# MoveI2F" %} 10893 ins_encode %{ 10894 __ movdl($dst$$XMMRegister, $src$$Register); 10895 %} 10896 ins_pipe( pipe_slow ); 10897 %} 10898 10899 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10900 match(Set dst (MoveL2D src)); 10901 effect(DEF dst, USE src); 10902 ins_cost(100); 10903 format %{ "movd $dst,$src\t# MoveL2D" %} 10904 ins_encode %{ 10905 __ movdq($dst$$XMMRegister, $src$$Register); 10906 %} 10907 ins_pipe( pipe_slow ); 10908 %} 10909 10910 10911 // ======================================================================= 10912 // fast clearing of an array 10913 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10914 Universe dummy, rFlagsReg cr) 10915 %{ 10916 predicate(!((ClearArrayNode*)n)->is_large()); 10917 match(Set dummy (ClearArray cnt base)); 10918 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10919 10920 format %{ $$template 10921 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10922 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10923 $$emit$$"jg LARGE\n\t" 10924 $$emit$$"dec rcx\n\t" 10925 $$emit$$"js DONE\t# Zero length\n\t" 10926 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10927 $$emit$$"dec rcx\n\t" 10928 $$emit$$"jge LOOP\n\t" 10929 $$emit$$"jmp DONE\n\t" 10930 $$emit$$"# LARGE:\n\t" 10931 if (UseFastStosb) { 10932 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10933 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10934 } else if (UseXMMForObjInit) { 10935 $$emit$$"mov rdi,rax\n\t" 10936 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10937 $$emit$$"jmpq L_zero_64_bytes\n\t" 10938 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10939 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10940 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10941 $$emit$$"add 0x40,rax\n\t" 10942 $$emit$$"# L_zero_64_bytes:\n\t" 10943 $$emit$$"sub 0x8,rcx\n\t" 10944 $$emit$$"jge L_loop\n\t" 10945 $$emit$$"add 0x4,rcx\n\t" 10946 $$emit$$"jl L_tail\n\t" 10947 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10948 $$emit$$"add 0x20,rax\n\t" 10949 $$emit$$"sub 0x4,rcx\n\t" 10950 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10951 $$emit$$"add 0x4,rcx\n\t" 10952 $$emit$$"jle L_end\n\t" 10953 $$emit$$"dec rcx\n\t" 10954 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10955 $$emit$$"vmovq xmm0,(rax)\n\t" 10956 $$emit$$"add 0x8,rax\n\t" 10957 $$emit$$"dec rcx\n\t" 10958 $$emit$$"jge L_sloop\n\t" 10959 $$emit$$"# L_end:\n\t" 10960 } else { 10961 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10962 } 10963 $$emit$$"# DONE" 10964 %} 10965 ins_encode %{ 10966 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10967 $tmp$$XMMRegister, false); 10968 %} 10969 ins_pipe(pipe_slow); 10970 %} 10971 10972 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10973 Universe dummy, rFlagsReg cr) 10974 %{ 10975 predicate(((ClearArrayNode*)n)->is_large()); 10976 match(Set dummy (ClearArray cnt base)); 10977 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10978 10979 format %{ $$template 10980 if (UseFastStosb) { 10981 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10982 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10983 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10984 } else if (UseXMMForObjInit) { 10985 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10986 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10987 $$emit$$"jmpq L_zero_64_bytes\n\t" 10988 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10989 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10990 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10991 $$emit$$"add 0x40,rax\n\t" 10992 $$emit$$"# L_zero_64_bytes:\n\t" 10993 $$emit$$"sub 0x8,rcx\n\t" 10994 $$emit$$"jge L_loop\n\t" 10995 $$emit$$"add 0x4,rcx\n\t" 10996 $$emit$$"jl L_tail\n\t" 10997 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10998 $$emit$$"add 0x20,rax\n\t" 10999 $$emit$$"sub 0x4,rcx\n\t" 11000 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11001 $$emit$$"add 0x4,rcx\n\t" 11002 $$emit$$"jle L_end\n\t" 11003 $$emit$$"dec rcx\n\t" 11004 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11005 $$emit$$"vmovq xmm0,(rax)\n\t" 11006 $$emit$$"add 0x8,rax\n\t" 11007 $$emit$$"dec rcx\n\t" 11008 $$emit$$"jge L_sloop\n\t" 11009 $$emit$$"# L_end:\n\t" 11010 } else { 11011 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11012 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11013 } 11014 %} 11015 ins_encode %{ 11016 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11017 $tmp$$XMMRegister, true); 11018 %} 11019 ins_pipe(pipe_slow); 11020 %} 11021 11022 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11023 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11024 %{ 11025 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11026 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11027 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11028 11029 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11030 ins_encode %{ 11031 __ string_compare($str1$$Register, $str2$$Register, 11032 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11033 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11034 %} 11035 ins_pipe( pipe_slow ); 11036 %} 11037 11038 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11039 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11040 %{ 11041 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11042 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11043 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11044 11045 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11046 ins_encode %{ 11047 __ string_compare($str1$$Register, $str2$$Register, 11048 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11049 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11050 %} 11051 ins_pipe( pipe_slow ); 11052 %} 11053 11054 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11055 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11056 %{ 11057 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11058 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11059 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11060 11061 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11062 ins_encode %{ 11063 __ string_compare($str1$$Register, $str2$$Register, 11064 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11065 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11066 %} 11067 ins_pipe( pipe_slow ); 11068 %} 11069 11070 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11071 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11072 %{ 11073 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11074 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11075 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11076 11077 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11078 ins_encode %{ 11079 __ string_compare($str2$$Register, $str1$$Register, 11080 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11081 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11082 %} 11083 ins_pipe( pipe_slow ); 11084 %} 11085 11086 // fast search of substring with known size. 11087 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11088 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11089 %{ 11090 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11091 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11092 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11093 11094 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11095 ins_encode %{ 11096 int icnt2 = (int)$int_cnt2$$constant; 11097 if (icnt2 >= 16) { 11098 // IndexOf for constant substrings with size >= 16 elements 11099 // which don't need to be loaded through stack. 11100 __ string_indexofC8($str1$$Register, $str2$$Register, 11101 $cnt1$$Register, $cnt2$$Register, 11102 icnt2, $result$$Register, 11103 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11104 } else { 11105 // Small strings are loaded through stack if they cross page boundary. 11106 __ string_indexof($str1$$Register, $str2$$Register, 11107 $cnt1$$Register, $cnt2$$Register, 11108 icnt2, $result$$Register, 11109 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11110 } 11111 %} 11112 ins_pipe( pipe_slow ); 11113 %} 11114 11115 // fast search of substring with known size. 11116 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11117 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11118 %{ 11119 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11120 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11121 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11122 11123 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11124 ins_encode %{ 11125 int icnt2 = (int)$int_cnt2$$constant; 11126 if (icnt2 >= 8) { 11127 // IndexOf for constant substrings with size >= 8 elements 11128 // which don't need to be loaded through stack. 11129 __ string_indexofC8($str1$$Register, $str2$$Register, 11130 $cnt1$$Register, $cnt2$$Register, 11131 icnt2, $result$$Register, 11132 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11133 } else { 11134 // Small strings are loaded through stack if they cross page boundary. 11135 __ string_indexof($str1$$Register, $str2$$Register, 11136 $cnt1$$Register, $cnt2$$Register, 11137 icnt2, $result$$Register, 11138 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11139 } 11140 %} 11141 ins_pipe( pipe_slow ); 11142 %} 11143 11144 // fast search of substring with known size. 11145 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11146 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11147 %{ 11148 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11149 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11150 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11151 11152 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11153 ins_encode %{ 11154 int icnt2 = (int)$int_cnt2$$constant; 11155 if (icnt2 >= 8) { 11156 // IndexOf for constant substrings with size >= 8 elements 11157 // which don't need to be loaded through stack. 11158 __ string_indexofC8($str1$$Register, $str2$$Register, 11159 $cnt1$$Register, $cnt2$$Register, 11160 icnt2, $result$$Register, 11161 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11162 } else { 11163 // Small strings are loaded through stack if they cross page boundary. 11164 __ string_indexof($str1$$Register, $str2$$Register, 11165 $cnt1$$Register, $cnt2$$Register, 11166 icnt2, $result$$Register, 11167 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11168 } 11169 %} 11170 ins_pipe( pipe_slow ); 11171 %} 11172 11173 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11174 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11175 %{ 11176 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11177 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11178 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11179 11180 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11181 ins_encode %{ 11182 __ string_indexof($str1$$Register, $str2$$Register, 11183 $cnt1$$Register, $cnt2$$Register, 11184 (-1), $result$$Register, 11185 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11186 %} 11187 ins_pipe( pipe_slow ); 11188 %} 11189 11190 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11191 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11192 %{ 11193 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11194 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11195 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11196 11197 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11198 ins_encode %{ 11199 __ string_indexof($str1$$Register, $str2$$Register, 11200 $cnt1$$Register, $cnt2$$Register, 11201 (-1), $result$$Register, 11202 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11203 %} 11204 ins_pipe( pipe_slow ); 11205 %} 11206 11207 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11208 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11209 %{ 11210 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11211 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11212 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11213 11214 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11215 ins_encode %{ 11216 __ string_indexof($str1$$Register, $str2$$Register, 11217 $cnt1$$Register, $cnt2$$Register, 11218 (-1), $result$$Register, 11219 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11220 %} 11221 ins_pipe( pipe_slow ); 11222 %} 11223 11224 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11225 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11226 %{ 11227 predicate(UseSSE42Intrinsics); 11228 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11229 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11230 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11231 ins_encode %{ 11232 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11233 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11234 %} 11235 ins_pipe( pipe_slow ); 11236 %} 11237 11238 // fast string equals 11239 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11240 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11241 %{ 11242 match(Set result (StrEquals (Binary str1 str2) cnt)); 11243 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11244 11245 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11246 ins_encode %{ 11247 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11248 $cnt$$Register, $result$$Register, $tmp3$$Register, 11249 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11250 %} 11251 ins_pipe( pipe_slow ); 11252 %} 11253 11254 // fast array equals 11255 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11256 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11257 %{ 11258 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11259 match(Set result (AryEq ary1 ary2)); 11260 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11261 11262 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11263 ins_encode %{ 11264 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11265 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11266 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11267 %} 11268 ins_pipe( pipe_slow ); 11269 %} 11270 11271 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11272 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11273 %{ 11274 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11275 match(Set result (AryEq ary1 ary2)); 11276 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11277 11278 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11279 ins_encode %{ 11280 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11281 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11282 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11283 %} 11284 ins_pipe( pipe_slow ); 11285 %} 11286 11287 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11288 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11289 %{ 11290 match(Set result (HasNegatives ary1 len)); 11291 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11292 11293 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11294 ins_encode %{ 11295 __ has_negatives($ary1$$Register, $len$$Register, 11296 $result$$Register, $tmp3$$Register, 11297 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11298 %} 11299 ins_pipe( pipe_slow ); 11300 %} 11301 11302 // fast char[] to byte[] compression 11303 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11304 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11305 match(Set result (StrCompressedCopy src (Binary dst len))); 11306 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11307 11308 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11309 ins_encode %{ 11310 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11311 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11312 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11313 %} 11314 ins_pipe( pipe_slow ); 11315 %} 11316 11317 // fast byte[] to char[] inflation 11318 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11319 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11320 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11321 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11322 11323 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11324 ins_encode %{ 11325 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11326 $tmp1$$XMMRegister, $tmp2$$Register); 11327 %} 11328 ins_pipe( pipe_slow ); 11329 %} 11330 11331 // encode char[] to byte[] in ISO_8859_1 11332 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11333 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11334 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11335 match(Set result (EncodeISOArray src (Binary dst len))); 11336 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11337 11338 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11339 ins_encode %{ 11340 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11341 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11342 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11343 %} 11344 ins_pipe( pipe_slow ); 11345 %} 11346 11347 //----------Overflow Math Instructions----------------------------------------- 11348 11349 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11350 %{ 11351 match(Set cr (OverflowAddI op1 op2)); 11352 effect(DEF cr, USE_KILL op1, USE op2); 11353 11354 format %{ "addl $op1, $op2\t# overflow check int" %} 11355 11356 ins_encode %{ 11357 __ addl($op1$$Register, $op2$$Register); 11358 %} 11359 ins_pipe(ialu_reg_reg); 11360 %} 11361 11362 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11363 %{ 11364 match(Set cr (OverflowAddI op1 op2)); 11365 effect(DEF cr, USE_KILL op1, USE op2); 11366 11367 format %{ "addl $op1, $op2\t# overflow check int" %} 11368 11369 ins_encode %{ 11370 __ addl($op1$$Register, $op2$$constant); 11371 %} 11372 ins_pipe(ialu_reg_reg); 11373 %} 11374 11375 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11376 %{ 11377 match(Set cr (OverflowAddL op1 op2)); 11378 effect(DEF cr, USE_KILL op1, USE op2); 11379 11380 format %{ "addq $op1, $op2\t# overflow check long" %} 11381 ins_encode %{ 11382 __ addq($op1$$Register, $op2$$Register); 11383 %} 11384 ins_pipe(ialu_reg_reg); 11385 %} 11386 11387 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11388 %{ 11389 match(Set cr (OverflowAddL op1 op2)); 11390 effect(DEF cr, USE_KILL op1, USE op2); 11391 11392 format %{ "addq $op1, $op2\t# overflow check long" %} 11393 ins_encode %{ 11394 __ addq($op1$$Register, $op2$$constant); 11395 %} 11396 ins_pipe(ialu_reg_reg); 11397 %} 11398 11399 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11400 %{ 11401 match(Set cr (OverflowSubI op1 op2)); 11402 11403 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11404 ins_encode %{ 11405 __ cmpl($op1$$Register, $op2$$Register); 11406 %} 11407 ins_pipe(ialu_reg_reg); 11408 %} 11409 11410 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11411 %{ 11412 match(Set cr (OverflowSubI op1 op2)); 11413 11414 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11415 ins_encode %{ 11416 __ cmpl($op1$$Register, $op2$$constant); 11417 %} 11418 ins_pipe(ialu_reg_reg); 11419 %} 11420 11421 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11422 %{ 11423 match(Set cr (OverflowSubL op1 op2)); 11424 11425 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11426 ins_encode %{ 11427 __ cmpq($op1$$Register, $op2$$Register); 11428 %} 11429 ins_pipe(ialu_reg_reg); 11430 %} 11431 11432 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11433 %{ 11434 match(Set cr (OverflowSubL op1 op2)); 11435 11436 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11437 ins_encode %{ 11438 __ cmpq($op1$$Register, $op2$$constant); 11439 %} 11440 ins_pipe(ialu_reg_reg); 11441 %} 11442 11443 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11444 %{ 11445 match(Set cr (OverflowSubI zero op2)); 11446 effect(DEF cr, USE_KILL op2); 11447 11448 format %{ "negl $op2\t# overflow check int" %} 11449 ins_encode %{ 11450 __ negl($op2$$Register); 11451 %} 11452 ins_pipe(ialu_reg_reg); 11453 %} 11454 11455 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11456 %{ 11457 match(Set cr (OverflowSubL zero op2)); 11458 effect(DEF cr, USE_KILL op2); 11459 11460 format %{ "negq $op2\t# overflow check long" %} 11461 ins_encode %{ 11462 __ negq($op2$$Register); 11463 %} 11464 ins_pipe(ialu_reg_reg); 11465 %} 11466 11467 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11468 %{ 11469 match(Set cr (OverflowMulI op1 op2)); 11470 effect(DEF cr, USE_KILL op1, USE op2); 11471 11472 format %{ "imull $op1, $op2\t# overflow check int" %} 11473 ins_encode %{ 11474 __ imull($op1$$Register, $op2$$Register); 11475 %} 11476 ins_pipe(ialu_reg_reg_alu0); 11477 %} 11478 11479 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11480 %{ 11481 match(Set cr (OverflowMulI op1 op2)); 11482 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11483 11484 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11485 ins_encode %{ 11486 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11487 %} 11488 ins_pipe(ialu_reg_reg_alu0); 11489 %} 11490 11491 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11492 %{ 11493 match(Set cr (OverflowMulL op1 op2)); 11494 effect(DEF cr, USE_KILL op1, USE op2); 11495 11496 format %{ "imulq $op1, $op2\t# overflow check long" %} 11497 ins_encode %{ 11498 __ imulq($op1$$Register, $op2$$Register); 11499 %} 11500 ins_pipe(ialu_reg_reg_alu0); 11501 %} 11502 11503 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11504 %{ 11505 match(Set cr (OverflowMulL op1 op2)); 11506 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11507 11508 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11509 ins_encode %{ 11510 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11511 %} 11512 ins_pipe(ialu_reg_reg_alu0); 11513 %} 11514 11515 11516 //----------Control Flow Instructions------------------------------------------ 11517 // Signed compare Instructions 11518 11519 // XXX more variants!! 11520 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11521 %{ 11522 match(Set cr (CmpI op1 op2)); 11523 effect(DEF cr, USE op1, USE op2); 11524 11525 format %{ "cmpl $op1, $op2" %} 11526 opcode(0x3B); /* Opcode 3B /r */ 11527 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11528 ins_pipe(ialu_cr_reg_reg); 11529 %} 11530 11531 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11532 %{ 11533 match(Set cr (CmpI op1 op2)); 11534 11535 format %{ "cmpl $op1, $op2" %} 11536 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11537 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11538 ins_pipe(ialu_cr_reg_imm); 11539 %} 11540 11541 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11542 %{ 11543 match(Set cr (CmpI op1 (LoadI op2))); 11544 11545 ins_cost(500); // XXX 11546 format %{ "cmpl $op1, $op2" %} 11547 opcode(0x3B); /* Opcode 3B /r */ 11548 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11549 ins_pipe(ialu_cr_reg_mem); 11550 %} 11551 11552 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11553 %{ 11554 match(Set cr (CmpI src zero)); 11555 11556 format %{ "testl $src, $src" %} 11557 opcode(0x85); 11558 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11559 ins_pipe(ialu_cr_reg_imm); 11560 %} 11561 11562 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11563 %{ 11564 match(Set cr (CmpI (AndI src con) zero)); 11565 11566 format %{ "testl $src, $con" %} 11567 opcode(0xF7, 0x00); 11568 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11569 ins_pipe(ialu_cr_reg_imm); 11570 %} 11571 11572 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11573 %{ 11574 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11575 11576 format %{ "testl $src, $mem" %} 11577 opcode(0x85); 11578 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11579 ins_pipe(ialu_cr_reg_mem); 11580 %} 11581 11582 // Unsigned compare Instructions; really, same as signed except they 11583 // produce an rFlagsRegU instead of rFlagsReg. 11584 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11585 %{ 11586 match(Set cr (CmpU op1 op2)); 11587 11588 format %{ "cmpl $op1, $op2\t# unsigned" %} 11589 opcode(0x3B); /* Opcode 3B /r */ 11590 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11591 ins_pipe(ialu_cr_reg_reg); 11592 %} 11593 11594 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11595 %{ 11596 match(Set cr (CmpU op1 op2)); 11597 11598 format %{ "cmpl $op1, $op2\t# unsigned" %} 11599 opcode(0x81,0x07); /* Opcode 81 /7 */ 11600 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11601 ins_pipe(ialu_cr_reg_imm); 11602 %} 11603 11604 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11605 %{ 11606 match(Set cr (CmpU op1 (LoadI op2))); 11607 11608 ins_cost(500); // XXX 11609 format %{ "cmpl $op1, $op2\t# unsigned" %} 11610 opcode(0x3B); /* Opcode 3B /r */ 11611 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11612 ins_pipe(ialu_cr_reg_mem); 11613 %} 11614 11615 // // // Cisc-spilled version of cmpU_rReg 11616 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11617 // //%{ 11618 // // match(Set cr (CmpU (LoadI op1) op2)); 11619 // // 11620 // // format %{ "CMPu $op1,$op2" %} 11621 // // ins_cost(500); 11622 // // opcode(0x39); /* Opcode 39 /r */ 11623 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11624 // //%} 11625 11626 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11627 %{ 11628 match(Set cr (CmpU src zero)); 11629 11630 format %{ "testl $src, $src\t# unsigned" %} 11631 opcode(0x85); 11632 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11633 ins_pipe(ialu_cr_reg_imm); 11634 %} 11635 11636 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11637 %{ 11638 match(Set cr (CmpP op1 op2)); 11639 11640 format %{ "cmpq $op1, $op2\t# ptr" %} 11641 opcode(0x3B); /* Opcode 3B /r */ 11642 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11643 ins_pipe(ialu_cr_reg_reg); 11644 %} 11645 11646 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11647 %{ 11648 match(Set cr (CmpP op1 (LoadP op2))); 11649 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11650 11651 ins_cost(500); // XXX 11652 format %{ "cmpq $op1, $op2\t# ptr" %} 11653 opcode(0x3B); /* Opcode 3B /r */ 11654 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11655 ins_pipe(ialu_cr_reg_mem); 11656 %} 11657 11658 // // // Cisc-spilled version of cmpP_rReg 11659 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11660 // //%{ 11661 // // match(Set cr (CmpP (LoadP op1) op2)); 11662 // // 11663 // // format %{ "CMPu $op1,$op2" %} 11664 // // ins_cost(500); 11665 // // opcode(0x39); /* Opcode 39 /r */ 11666 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11667 // //%} 11668 11669 // XXX this is generalized by compP_rReg_mem??? 11670 // Compare raw pointer (used in out-of-heap check). 11671 // Only works because non-oop pointers must be raw pointers 11672 // and raw pointers have no anti-dependencies. 11673 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11674 %{ 11675 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11676 n->in(2)->as_Load()->barrier_data() == 0); 11677 match(Set cr (CmpP op1 (LoadP op2))); 11678 11679 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11680 opcode(0x3B); /* Opcode 3B /r */ 11681 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11682 ins_pipe(ialu_cr_reg_mem); 11683 %} 11684 11685 // This will generate a signed flags result. This should be OK since 11686 // any compare to a zero should be eq/neq. 11687 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11688 %{ 11689 match(Set cr (CmpP src zero)); 11690 11691 format %{ "testq $src, $src\t# ptr" %} 11692 opcode(0x85); 11693 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11694 ins_pipe(ialu_cr_reg_imm); 11695 %} 11696 11697 // This will generate a signed flags result. This should be OK since 11698 // any compare to a zero should be eq/neq. 11699 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11700 %{ 11701 predicate((!UseCompressedOops || (CompressedOops::base() != NULL)) && 11702 n->in(1)->as_Load()->barrier_data() == 0); 11703 match(Set cr (CmpP (LoadP op) zero)); 11704 11705 ins_cost(500); // XXX 11706 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11707 opcode(0xF7); /* Opcode F7 /0 */ 11708 ins_encode(REX_mem_wide(op), 11709 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11710 ins_pipe(ialu_cr_reg_imm); 11711 %} 11712 11713 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11714 %{ 11715 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && 11716 n->in(1)->as_Load()->barrier_data() == 0); 11717 match(Set cr (CmpP (LoadP mem) zero)); 11718 11719 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11720 ins_encode %{ 11721 __ cmpq(r12, $mem$$Address); 11722 %} 11723 ins_pipe(ialu_cr_reg_mem); 11724 %} 11725 11726 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11727 %{ 11728 match(Set cr (CmpN op1 op2)); 11729 11730 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11731 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11732 ins_pipe(ialu_cr_reg_reg); 11733 %} 11734 11735 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11736 %{ 11737 match(Set cr (CmpN src (LoadN mem))); 11738 11739 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11740 ins_encode %{ 11741 __ cmpl($src$$Register, $mem$$Address); 11742 %} 11743 ins_pipe(ialu_cr_reg_mem); 11744 %} 11745 11746 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11747 match(Set cr (CmpN op1 op2)); 11748 11749 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11750 ins_encode %{ 11751 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11752 %} 11753 ins_pipe(ialu_cr_reg_imm); 11754 %} 11755 11756 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11757 %{ 11758 match(Set cr (CmpN src (LoadN mem))); 11759 11760 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11761 ins_encode %{ 11762 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11763 %} 11764 ins_pipe(ialu_cr_reg_mem); 11765 %} 11766 11767 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11768 match(Set cr (CmpN op1 op2)); 11769 11770 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11771 ins_encode %{ 11772 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11773 %} 11774 ins_pipe(ialu_cr_reg_imm); 11775 %} 11776 11777 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11778 %{ 11779 match(Set cr (CmpN src (LoadNKlass mem))); 11780 11781 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11782 ins_encode %{ 11783 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11784 %} 11785 ins_pipe(ialu_cr_reg_mem); 11786 %} 11787 11788 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11789 match(Set cr (CmpN src zero)); 11790 11791 format %{ "testl $src, $src\t# compressed ptr" %} 11792 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11793 ins_pipe(ialu_cr_reg_imm); 11794 %} 11795 11796 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11797 %{ 11798 predicate(CompressedOops::base() != NULL); 11799 match(Set cr (CmpN (LoadN mem) zero)); 11800 11801 ins_cost(500); // XXX 11802 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11803 ins_encode %{ 11804 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11805 %} 11806 ins_pipe(ialu_cr_reg_mem); 11807 %} 11808 11809 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11810 %{ 11811 predicate(CompressedOops::base() == NULL); 11812 match(Set cr (CmpN (LoadN mem) zero)); 11813 11814 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11815 ins_encode %{ 11816 __ cmpl(r12, $mem$$Address); 11817 %} 11818 ins_pipe(ialu_cr_reg_mem); 11819 %} 11820 11821 // Yanked all unsigned pointer compare operations. 11822 // Pointer compares are done with CmpP which is already unsigned. 11823 11824 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11825 %{ 11826 match(Set cr (CmpL op1 op2)); 11827 11828 format %{ "cmpq $op1, $op2" %} 11829 opcode(0x3B); /* Opcode 3B /r */ 11830 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11831 ins_pipe(ialu_cr_reg_reg); 11832 %} 11833 11834 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11835 %{ 11836 match(Set cr (CmpL op1 op2)); 11837 11838 format %{ "cmpq $op1, $op2" %} 11839 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11840 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11841 ins_pipe(ialu_cr_reg_imm); 11842 %} 11843 11844 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11845 %{ 11846 match(Set cr (CmpL op1 (LoadL op2))); 11847 11848 format %{ "cmpq $op1, $op2" %} 11849 opcode(0x3B); /* Opcode 3B /r */ 11850 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11851 ins_pipe(ialu_cr_reg_mem); 11852 %} 11853 11854 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11855 %{ 11856 match(Set cr (CmpL src zero)); 11857 11858 format %{ "testq $src, $src" %} 11859 opcode(0x85); 11860 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11861 ins_pipe(ialu_cr_reg_imm); 11862 %} 11863 11864 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11865 %{ 11866 match(Set cr (CmpL (AndL src con) zero)); 11867 11868 format %{ "testq $src, $con\t# long" %} 11869 opcode(0xF7, 0x00); 11870 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11871 ins_pipe(ialu_cr_reg_imm); 11872 %} 11873 11874 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11875 %{ 11876 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11877 11878 format %{ "testq $src, $mem" %} 11879 opcode(0x85); 11880 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11881 ins_pipe(ialu_cr_reg_mem); 11882 %} 11883 11884 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11885 %{ 11886 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11887 11888 format %{ "testq $src, $mem" %} 11889 opcode(0x85); 11890 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11891 ins_pipe(ialu_cr_reg_mem); 11892 %} 11893 11894 // Manifest a CmpL result in an integer register. Very painful. 11895 // This is the test to avoid. 11896 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11897 %{ 11898 match(Set dst (CmpL3 src1 src2)); 11899 effect(KILL flags); 11900 11901 ins_cost(275); // XXX 11902 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11903 "movl $dst, -1\n\t" 11904 "jl,s done\n\t" 11905 "setne $dst\n\t" 11906 "movzbl $dst, $dst\n\t" 11907 "done:" %} 11908 ins_encode(cmpl3_flag(src1, src2, dst)); 11909 ins_pipe(pipe_slow); 11910 %} 11911 11912 // Unsigned long compare Instructions; really, same as signed long except they 11913 // produce an rFlagsRegU instead of rFlagsReg. 11914 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11915 %{ 11916 match(Set cr (CmpUL op1 op2)); 11917 11918 format %{ "cmpq $op1, $op2\t# unsigned" %} 11919 opcode(0x3B); /* Opcode 3B /r */ 11920 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11921 ins_pipe(ialu_cr_reg_reg); 11922 %} 11923 11924 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11925 %{ 11926 match(Set cr (CmpUL op1 op2)); 11927 11928 format %{ "cmpq $op1, $op2\t# unsigned" %} 11929 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11930 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11931 ins_pipe(ialu_cr_reg_imm); 11932 %} 11933 11934 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11935 %{ 11936 match(Set cr (CmpUL op1 (LoadL op2))); 11937 11938 format %{ "cmpq $op1, $op2\t# unsigned" %} 11939 opcode(0x3B); /* Opcode 3B /r */ 11940 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11941 ins_pipe(ialu_cr_reg_mem); 11942 %} 11943 11944 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11945 %{ 11946 match(Set cr (CmpUL src zero)); 11947 11948 format %{ "testq $src, $src\t# unsigned" %} 11949 opcode(0x85); 11950 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11951 ins_pipe(ialu_cr_reg_imm); 11952 %} 11953 11954 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11955 %{ 11956 match(Set cr (CmpI (LoadB mem) imm)); 11957 11958 ins_cost(125); 11959 format %{ "cmpb $mem, $imm" %} 11960 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11961 ins_pipe(ialu_cr_reg_mem); 11962 %} 11963 11964 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 11965 %{ 11966 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11967 11968 ins_cost(125); 11969 format %{ "testb $mem, $imm\t# ubyte" %} 11970 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11971 ins_pipe(ialu_cr_reg_mem); 11972 %} 11973 11974 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11975 %{ 11976 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11977 11978 ins_cost(125); 11979 format %{ "testb $mem, $imm\t# byte" %} 11980 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11981 ins_pipe(ialu_cr_reg_mem); 11982 %} 11983 11984 //----------Max and Min-------------------------------------------------------- 11985 // Min Instructions 11986 11987 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11988 %{ 11989 effect(USE_DEF dst, USE src, USE cr); 11990 11991 format %{ "cmovlgt $dst, $src\t# min" %} 11992 opcode(0x0F, 0x4F); 11993 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11994 ins_pipe(pipe_cmov_reg); 11995 %} 11996 11997 11998 instruct minI_rReg(rRegI dst, rRegI src) 11999 %{ 12000 match(Set dst (MinI dst src)); 12001 12002 ins_cost(200); 12003 expand %{ 12004 rFlagsReg cr; 12005 compI_rReg(cr, dst, src); 12006 cmovI_reg_g(dst, src, cr); 12007 %} 12008 %} 12009 12010 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12011 %{ 12012 effect(USE_DEF dst, USE src, USE cr); 12013 12014 format %{ "cmovllt $dst, $src\t# max" %} 12015 opcode(0x0F, 0x4C); 12016 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12017 ins_pipe(pipe_cmov_reg); 12018 %} 12019 12020 12021 instruct maxI_rReg(rRegI dst, rRegI src) 12022 %{ 12023 match(Set dst (MaxI dst src)); 12024 12025 ins_cost(200); 12026 expand %{ 12027 rFlagsReg cr; 12028 compI_rReg(cr, dst, src); 12029 cmovI_reg_l(dst, src, cr); 12030 %} 12031 %} 12032 12033 // ============================================================================ 12034 // Branch Instructions 12035 12036 // Jump Direct - Label defines a relative address from JMP+1 12037 instruct jmpDir(label labl) 12038 %{ 12039 match(Goto); 12040 effect(USE labl); 12041 12042 ins_cost(300); 12043 format %{ "jmp $labl" %} 12044 size(5); 12045 ins_encode %{ 12046 Label* L = $labl$$label; 12047 __ jmp(*L, false); // Always long jump 12048 %} 12049 ins_pipe(pipe_jmp); 12050 %} 12051 12052 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12053 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12054 %{ 12055 match(If cop cr); 12056 effect(USE labl); 12057 12058 ins_cost(300); 12059 format %{ "j$cop $labl" %} 12060 size(6); 12061 ins_encode %{ 12062 Label* L = $labl$$label; 12063 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12064 %} 12065 ins_pipe(pipe_jcc); 12066 %} 12067 12068 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12069 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12070 %{ 12071 predicate(!n->has_vector_mask_set()); 12072 match(CountedLoopEnd cop cr); 12073 effect(USE labl); 12074 12075 ins_cost(300); 12076 format %{ "j$cop $labl\t# loop end" %} 12077 size(6); 12078 ins_encode %{ 12079 Label* L = $labl$$label; 12080 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12081 %} 12082 ins_pipe(pipe_jcc); 12083 %} 12084 12085 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12086 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12087 predicate(!n->has_vector_mask_set()); 12088 match(CountedLoopEnd cop cmp); 12089 effect(USE labl); 12090 12091 ins_cost(300); 12092 format %{ "j$cop,u $labl\t# loop end" %} 12093 size(6); 12094 ins_encode %{ 12095 Label* L = $labl$$label; 12096 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12097 %} 12098 ins_pipe(pipe_jcc); 12099 %} 12100 12101 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12102 predicate(!n->has_vector_mask_set()); 12103 match(CountedLoopEnd cop cmp); 12104 effect(USE labl); 12105 12106 ins_cost(200); 12107 format %{ "j$cop,u $labl\t# loop end" %} 12108 size(6); 12109 ins_encode %{ 12110 Label* L = $labl$$label; 12111 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12112 %} 12113 ins_pipe(pipe_jcc); 12114 %} 12115 12116 // mask version 12117 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12118 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12119 %{ 12120 predicate(n->has_vector_mask_set()); 12121 match(CountedLoopEnd cop cr); 12122 effect(USE labl); 12123 12124 ins_cost(400); 12125 format %{ "j$cop $labl\t# loop end\n\t" 12126 "restorevectmask \t# vector mask restore for loops" %} 12127 size(10); 12128 ins_encode %{ 12129 Label* L = $labl$$label; 12130 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12131 __ restorevectmask(); 12132 %} 12133 ins_pipe(pipe_jcc); 12134 %} 12135 12136 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12137 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12138 predicate(n->has_vector_mask_set()); 12139 match(CountedLoopEnd cop cmp); 12140 effect(USE labl); 12141 12142 ins_cost(400); 12143 format %{ "j$cop,u $labl\t# loop end\n\t" 12144 "restorevectmask \t# vector mask restore for loops" %} 12145 size(10); 12146 ins_encode %{ 12147 Label* L = $labl$$label; 12148 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12149 __ restorevectmask(); 12150 %} 12151 ins_pipe(pipe_jcc); 12152 %} 12153 12154 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12155 predicate(n->has_vector_mask_set()); 12156 match(CountedLoopEnd cop cmp); 12157 effect(USE labl); 12158 12159 ins_cost(300); 12160 format %{ "j$cop,u $labl\t# loop end\n\t" 12161 "restorevectmask \t# vector mask restore for loops" %} 12162 size(10); 12163 ins_encode %{ 12164 Label* L = $labl$$label; 12165 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12166 __ restorevectmask(); 12167 %} 12168 ins_pipe(pipe_jcc); 12169 %} 12170 12171 // Jump Direct Conditional - using unsigned comparison 12172 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12173 match(If cop cmp); 12174 effect(USE labl); 12175 12176 ins_cost(300); 12177 format %{ "j$cop,u $labl" %} 12178 size(6); 12179 ins_encode %{ 12180 Label* L = $labl$$label; 12181 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12182 %} 12183 ins_pipe(pipe_jcc); 12184 %} 12185 12186 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12187 match(If cop cmp); 12188 effect(USE labl); 12189 12190 ins_cost(200); 12191 format %{ "j$cop,u $labl" %} 12192 size(6); 12193 ins_encode %{ 12194 Label* L = $labl$$label; 12195 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12196 %} 12197 ins_pipe(pipe_jcc); 12198 %} 12199 12200 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12201 match(If cop cmp); 12202 effect(USE labl); 12203 12204 ins_cost(200); 12205 format %{ $$template 12206 if ($cop$$cmpcode == Assembler::notEqual) { 12207 $$emit$$"jp,u $labl\n\t" 12208 $$emit$$"j$cop,u $labl" 12209 } else { 12210 $$emit$$"jp,u done\n\t" 12211 $$emit$$"j$cop,u $labl\n\t" 12212 $$emit$$"done:" 12213 } 12214 %} 12215 ins_encode %{ 12216 Label* l = $labl$$label; 12217 if ($cop$$cmpcode == Assembler::notEqual) { 12218 __ jcc(Assembler::parity, *l, false); 12219 __ jcc(Assembler::notEqual, *l, false); 12220 } else if ($cop$$cmpcode == Assembler::equal) { 12221 Label done; 12222 __ jccb(Assembler::parity, done); 12223 __ jcc(Assembler::equal, *l, false); 12224 __ bind(done); 12225 } else { 12226 ShouldNotReachHere(); 12227 } 12228 %} 12229 ins_pipe(pipe_jcc); 12230 %} 12231 12232 // ============================================================================ 12233 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12234 // superklass array for an instance of the superklass. Set a hidden 12235 // internal cache on a hit (cache is checked with exposed code in 12236 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12237 // encoding ALSO sets flags. 12238 12239 instruct partialSubtypeCheck(rdi_RegP result, 12240 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12241 rFlagsReg cr) 12242 %{ 12243 match(Set result (PartialSubtypeCheck sub super)); 12244 effect(KILL rcx, KILL cr); 12245 12246 ins_cost(1100); // slightly larger than the next version 12247 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12248 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12249 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12250 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12251 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12252 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12253 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12254 "miss:\t" %} 12255 12256 opcode(0x1); // Force a XOR of RDI 12257 ins_encode(enc_PartialSubtypeCheck()); 12258 ins_pipe(pipe_slow); 12259 %} 12260 12261 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12262 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12263 immP0 zero, 12264 rdi_RegP result) 12265 %{ 12266 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12267 effect(KILL rcx, KILL result); 12268 12269 ins_cost(1000); 12270 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12271 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12272 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12273 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12274 "jne,s miss\t\t# Missed: flags nz\n\t" 12275 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12276 "miss:\t" %} 12277 12278 opcode(0x0); // No need to XOR RDI 12279 ins_encode(enc_PartialSubtypeCheck()); 12280 ins_pipe(pipe_slow); 12281 %} 12282 12283 // ============================================================================ 12284 // Branch Instructions -- short offset versions 12285 // 12286 // These instructions are used to replace jumps of a long offset (the default 12287 // match) with jumps of a shorter offset. These instructions are all tagged 12288 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12289 // match rules in general matching. Instead, the ADLC generates a conversion 12290 // method in the MachNode which can be used to do in-place replacement of the 12291 // long variant with the shorter variant. The compiler will determine if a 12292 // branch can be taken by the is_short_branch_offset() predicate in the machine 12293 // specific code section of the file. 12294 12295 // Jump Direct - Label defines a relative address from JMP+1 12296 instruct jmpDir_short(label labl) %{ 12297 match(Goto); 12298 effect(USE labl); 12299 12300 ins_cost(300); 12301 format %{ "jmp,s $labl" %} 12302 size(2); 12303 ins_encode %{ 12304 Label* L = $labl$$label; 12305 __ jmpb(*L); 12306 %} 12307 ins_pipe(pipe_jmp); 12308 ins_short_branch(1); 12309 %} 12310 12311 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12312 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12313 match(If cop cr); 12314 effect(USE labl); 12315 12316 ins_cost(300); 12317 format %{ "j$cop,s $labl" %} 12318 size(2); 12319 ins_encode %{ 12320 Label* L = $labl$$label; 12321 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12322 %} 12323 ins_pipe(pipe_jcc); 12324 ins_short_branch(1); 12325 %} 12326 12327 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12328 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12329 match(CountedLoopEnd cop cr); 12330 effect(USE labl); 12331 12332 ins_cost(300); 12333 format %{ "j$cop,s $labl\t# loop end" %} 12334 size(2); 12335 ins_encode %{ 12336 Label* L = $labl$$label; 12337 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12338 %} 12339 ins_pipe(pipe_jcc); 12340 ins_short_branch(1); 12341 %} 12342 12343 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12344 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12345 match(CountedLoopEnd cop cmp); 12346 effect(USE labl); 12347 12348 ins_cost(300); 12349 format %{ "j$cop,us $labl\t# loop end" %} 12350 size(2); 12351 ins_encode %{ 12352 Label* L = $labl$$label; 12353 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12354 %} 12355 ins_pipe(pipe_jcc); 12356 ins_short_branch(1); 12357 %} 12358 12359 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12360 match(CountedLoopEnd cop cmp); 12361 effect(USE labl); 12362 12363 ins_cost(300); 12364 format %{ "j$cop,us $labl\t# loop end" %} 12365 size(2); 12366 ins_encode %{ 12367 Label* L = $labl$$label; 12368 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12369 %} 12370 ins_pipe(pipe_jcc); 12371 ins_short_branch(1); 12372 %} 12373 12374 // Jump Direct Conditional - using unsigned comparison 12375 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12376 match(If cop cmp); 12377 effect(USE labl); 12378 12379 ins_cost(300); 12380 format %{ "j$cop,us $labl" %} 12381 size(2); 12382 ins_encode %{ 12383 Label* L = $labl$$label; 12384 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12385 %} 12386 ins_pipe(pipe_jcc); 12387 ins_short_branch(1); 12388 %} 12389 12390 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12391 match(If cop cmp); 12392 effect(USE labl); 12393 12394 ins_cost(300); 12395 format %{ "j$cop,us $labl" %} 12396 size(2); 12397 ins_encode %{ 12398 Label* L = $labl$$label; 12399 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12400 %} 12401 ins_pipe(pipe_jcc); 12402 ins_short_branch(1); 12403 %} 12404 12405 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12406 match(If cop cmp); 12407 effect(USE labl); 12408 12409 ins_cost(300); 12410 format %{ $$template 12411 if ($cop$$cmpcode == Assembler::notEqual) { 12412 $$emit$$"jp,u,s $labl\n\t" 12413 $$emit$$"j$cop,u,s $labl" 12414 } else { 12415 $$emit$$"jp,u,s done\n\t" 12416 $$emit$$"j$cop,u,s $labl\n\t" 12417 $$emit$$"done:" 12418 } 12419 %} 12420 size(4); 12421 ins_encode %{ 12422 Label* l = $labl$$label; 12423 if ($cop$$cmpcode == Assembler::notEqual) { 12424 __ jccb(Assembler::parity, *l); 12425 __ jccb(Assembler::notEqual, *l); 12426 } else if ($cop$$cmpcode == Assembler::equal) { 12427 Label done; 12428 __ jccb(Assembler::parity, done); 12429 __ jccb(Assembler::equal, *l); 12430 __ bind(done); 12431 } else { 12432 ShouldNotReachHere(); 12433 } 12434 %} 12435 ins_pipe(pipe_jcc); 12436 ins_short_branch(1); 12437 %} 12438 12439 // ============================================================================ 12440 // inlined locking and unlocking 12441 12442 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12443 predicate(Compile::current()->use_rtm()); 12444 match(Set cr (FastLock object box)); 12445 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12446 ins_cost(300); 12447 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12448 ins_encode %{ 12449 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12450 $scr$$Register, $cx1$$Register, $cx2$$Register, 12451 _counters, _rtm_counters, _stack_rtm_counters, 12452 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12453 true, ra_->C->profile_rtm()); 12454 %} 12455 ins_pipe(pipe_slow); 12456 %} 12457 12458 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr, rRegP cx1) %{ 12459 predicate(!Compile::current()->use_rtm()); 12460 match(Set cr (FastLock object box)); 12461 effect(TEMP tmp, TEMP scr, TEMP cx1, USE_KILL box); 12462 ins_cost(300); 12463 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12464 ins_encode %{ 12465 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12466 $scr$$Register, $cx1$$Register, noreg, _counters, NULL, NULL, NULL, false, false); 12467 %} 12468 ins_pipe(pipe_slow); 12469 %} 12470 12471 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12472 match(Set cr (FastUnlock object box)); 12473 effect(TEMP tmp, USE_KILL box); 12474 ins_cost(300); 12475 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12476 ins_encode %{ 12477 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12478 %} 12479 ins_pipe(pipe_slow); 12480 %} 12481 12482 12483 // ============================================================================ 12484 // Safepoint Instructions 12485 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12486 %{ 12487 match(SafePoint poll); 12488 effect(KILL cr, USE poll); 12489 12490 format %{ "testl rax, [$poll]\t" 12491 "# Safepoint: poll for GC" %} 12492 ins_cost(125); 12493 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12494 ins_encode %{ 12495 __ relocate(relocInfo::poll_type); 12496 address pre_pc = __ pc(); 12497 __ testl(rax, Address($poll$$Register, 0)); 12498 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12499 %} 12500 ins_pipe(ialu_reg_mem); 12501 %} 12502 12503 // ============================================================================ 12504 // Procedure Call/Return Instructions 12505 // Call Java Static Instruction 12506 // Note: If this code changes, the corresponding ret_addr_offset() and 12507 // compute_padding() functions will have to be adjusted. 12508 instruct CallStaticJavaDirect(method meth) %{ 12509 match(CallStaticJava); 12510 effect(USE meth); 12511 12512 ins_cost(300); 12513 format %{ "call,static " %} 12514 opcode(0xE8); /* E8 cd */ 12515 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12516 ins_pipe(pipe_slow); 12517 ins_alignment(4); 12518 %} 12519 12520 // Call Java Dynamic Instruction 12521 // Note: If this code changes, the corresponding ret_addr_offset() and 12522 // compute_padding() functions will have to be adjusted. 12523 instruct CallDynamicJavaDirect(method meth) 12524 %{ 12525 match(CallDynamicJava); 12526 effect(USE meth); 12527 12528 ins_cost(300); 12529 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12530 "call,dynamic " %} 12531 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12532 ins_pipe(pipe_slow); 12533 ins_alignment(4); 12534 %} 12535 12536 // Call Runtime Instruction 12537 instruct CallRuntimeDirect(method meth) 12538 %{ 12539 match(CallRuntime); 12540 effect(USE meth); 12541 12542 ins_cost(300); 12543 format %{ "call,runtime " %} 12544 ins_encode(clear_avx, Java_To_Runtime(meth)); 12545 ins_pipe(pipe_slow); 12546 %} 12547 12548 // Call runtime without safepoint 12549 instruct CallLeafDirect(method meth) 12550 %{ 12551 match(CallLeaf); 12552 effect(USE meth); 12553 12554 ins_cost(300); 12555 format %{ "call_leaf,runtime " %} 12556 ins_encode(clear_avx, Java_To_Runtime(meth)); 12557 ins_pipe(pipe_slow); 12558 %} 12559 12560 // Call runtime without safepoint 12561 instruct CallLeafNoFPDirect(method meth) 12562 %{ 12563 match(CallLeafNoFP); 12564 effect(USE meth); 12565 12566 ins_cost(300); 12567 format %{ "call_leaf_nofp,runtime " %} 12568 ins_encode(clear_avx, Java_To_Runtime(meth)); 12569 ins_pipe(pipe_slow); 12570 %} 12571 12572 // Return Instruction 12573 // Remove the return address & jump to it. 12574 // Notice: We always emit a nop after a ret to make sure there is room 12575 // for safepoint patching 12576 instruct Ret() 12577 %{ 12578 match(Return); 12579 12580 format %{ "ret" %} 12581 opcode(0xC3); 12582 ins_encode(OpcP); 12583 ins_pipe(pipe_jmp); 12584 %} 12585 12586 // Tail Call; Jump from runtime stub to Java code. 12587 // Also known as an 'interprocedural jump'. 12588 // Target of jump will eventually return to caller. 12589 // TailJump below removes the return address. 12590 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12591 %{ 12592 match(TailCall jump_target method_oop); 12593 12594 ins_cost(300); 12595 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12596 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12597 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12598 ins_pipe(pipe_jmp); 12599 %} 12600 12601 // Tail Jump; remove the return address; jump to target. 12602 // TailCall above leaves the return address around. 12603 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12604 %{ 12605 match(TailJump jump_target ex_oop); 12606 12607 ins_cost(300); 12608 format %{ "popq rdx\t# pop return address\n\t" 12609 "jmp $jump_target" %} 12610 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12611 ins_encode(Opcode(0x5a), // popq rdx 12612 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12613 ins_pipe(pipe_jmp); 12614 %} 12615 12616 // Create exception oop: created by stack-crawling runtime code. 12617 // Created exception is now available to this handler, and is setup 12618 // just prior to jumping to this handler. No code emitted. 12619 instruct CreateException(rax_RegP ex_oop) 12620 %{ 12621 match(Set ex_oop (CreateEx)); 12622 12623 size(0); 12624 // use the following format syntax 12625 format %{ "# exception oop is in rax; no code emitted" %} 12626 ins_encode(); 12627 ins_pipe(empty); 12628 %} 12629 12630 // Rethrow exception: 12631 // The exception oop will come in the first argument position. 12632 // Then JUMP (not call) to the rethrow stub code. 12633 instruct RethrowException() 12634 %{ 12635 match(Rethrow); 12636 12637 // use the following format syntax 12638 format %{ "jmp rethrow_stub" %} 12639 ins_encode(enc_rethrow); 12640 ins_pipe(pipe_jmp); 12641 %} 12642 12643 // ============================================================================ 12644 // This name is KNOWN by the ADLC and cannot be changed. 12645 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12646 // for this guy. 12647 instruct tlsLoadP(r15_RegP dst) %{ 12648 match(Set dst (ThreadLocal)); 12649 effect(DEF dst); 12650 12651 size(0); 12652 format %{ "# TLS is in R15" %} 12653 ins_encode( /*empty encoding*/ ); 12654 ins_pipe(ialu_reg_reg); 12655 %} 12656 12657 12658 //----------PEEPHOLE RULES----------------------------------------------------- 12659 // These must follow all instruction definitions as they use the names 12660 // defined in the instructions definitions. 12661 // 12662 // peepmatch ( root_instr_name [preceding_instruction]* ); 12663 // 12664 // peepconstraint %{ 12665 // (instruction_number.operand_name relational_op instruction_number.operand_name 12666 // [, ...] ); 12667 // // instruction numbers are zero-based using left to right order in peepmatch 12668 // 12669 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12670 // // provide an instruction_number.operand_name for each operand that appears 12671 // // in the replacement instruction's match rule 12672 // 12673 // ---------VM FLAGS--------------------------------------------------------- 12674 // 12675 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12676 // 12677 // Each peephole rule is given an identifying number starting with zero and 12678 // increasing by one in the order seen by the parser. An individual peephole 12679 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12680 // on the command-line. 12681 // 12682 // ---------CURRENT LIMITATIONS---------------------------------------------- 12683 // 12684 // Only match adjacent instructions in same basic block 12685 // Only equality constraints 12686 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12687 // Only one replacement instruction 12688 // 12689 // ---------EXAMPLE---------------------------------------------------------- 12690 // 12691 // // pertinent parts of existing instructions in architecture description 12692 // instruct movI(rRegI dst, rRegI src) 12693 // %{ 12694 // match(Set dst (CopyI src)); 12695 // %} 12696 // 12697 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12698 // %{ 12699 // match(Set dst (AddI dst src)); 12700 // effect(KILL cr); 12701 // %} 12702 // 12703 // // Change (inc mov) to lea 12704 // peephole %{ 12705 // // increment preceeded by register-register move 12706 // peepmatch ( incI_rReg movI ); 12707 // // require that the destination register of the increment 12708 // // match the destination register of the move 12709 // peepconstraint ( 0.dst == 1.dst ); 12710 // // construct a replacement instruction that sets 12711 // // the destination to ( move's source register + one ) 12712 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12713 // %} 12714 // 12715 12716 // Implementation no longer uses movX instructions since 12717 // machine-independent system no longer uses CopyX nodes. 12718 // 12719 // peephole 12720 // %{ 12721 // peepmatch (incI_rReg movI); 12722 // peepconstraint (0.dst == 1.dst); 12723 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12724 // %} 12725 12726 // peephole 12727 // %{ 12728 // peepmatch (decI_rReg movI); 12729 // peepconstraint (0.dst == 1.dst); 12730 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12731 // %} 12732 12733 // peephole 12734 // %{ 12735 // peepmatch (addI_rReg_imm movI); 12736 // peepconstraint (0.dst == 1.dst); 12737 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12738 // %} 12739 12740 // peephole 12741 // %{ 12742 // peepmatch (incL_rReg movL); 12743 // peepconstraint (0.dst == 1.dst); 12744 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12745 // %} 12746 12747 // peephole 12748 // %{ 12749 // peepmatch (decL_rReg movL); 12750 // peepconstraint (0.dst == 1.dst); 12751 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12752 // %} 12753 12754 // peephole 12755 // %{ 12756 // peepmatch (addL_rReg_imm movL); 12757 // peepconstraint (0.dst == 1.dst); 12758 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12759 // %} 12760 12761 // peephole 12762 // %{ 12763 // peepmatch (addP_rReg_imm movP); 12764 // peepconstraint (0.dst == 1.dst); 12765 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12766 // %} 12767 12768 // // Change load of spilled value to only a spill 12769 // instruct storeI(memory mem, rRegI src) 12770 // %{ 12771 // match(Set mem (StoreI mem src)); 12772 // %} 12773 // 12774 // instruct loadI(rRegI dst, memory mem) 12775 // %{ 12776 // match(Set dst (LoadI mem)); 12777 // %} 12778 // 12779 12780 peephole 12781 %{ 12782 peepmatch (loadI storeI); 12783 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12784 peepreplace (storeI(1.mem 1.mem 1.src)); 12785 %} 12786 12787 peephole 12788 %{ 12789 peepmatch (loadL storeL); 12790 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12791 peepreplace (storeL(1.mem 1.mem 1.src)); 12792 %} 12793 12794 //----------SMARTSPILL RULES--------------------------------------------------- 12795 // These must follow all instruction definitions as they use the names 12796 // defined in the instructions definitions.