1 // 2 // Copyright (c) 2003, 2019, 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 RDI pointer register 271 reg_class ptr_rdi_reg(RDI, RDI_H); 272 273 // Singleton class for stack pointer 274 reg_class ptr_rsp_reg(RSP, RSP_H); 275 276 // Singleton class for TLS pointer 277 reg_class ptr_r15_reg(R15, R15_H); 278 279 // Singleton class for RAX long register 280 reg_class long_rax_reg(RAX, RAX_H); 281 282 // Singleton class for RCX long register 283 reg_class long_rcx_reg(RCX, RCX_H); 284 285 // Singleton class for RDX long register 286 reg_class long_rdx_reg(RDX, RDX_H); 287 288 // Singleton class for RAX int register 289 reg_class int_rax_reg(RAX); 290 291 // Singleton class for RBX int register 292 reg_class int_rbx_reg(RBX); 293 294 // Singleton class for RCX int register 295 reg_class int_rcx_reg(RCX); 296 297 // Singleton class for RCX int register 298 reg_class int_rdx_reg(RDX); 299 300 // Singleton class for RCX int register 301 reg_class int_rdi_reg(RDI); 302 303 // Singleton class for instruction pointer 304 // reg_class ip_reg(RIP); 305 306 %} 307 308 //----------SOURCE BLOCK------------------------------------------------------- 309 // This is a block of C++ code which provides values, functions, and 310 // definitions necessary in the rest of the architecture description 311 source_hpp %{ 312 313 extern RegMask _ANY_REG_mask; 314 extern RegMask _PTR_REG_mask; 315 extern RegMask _PTR_REG_NO_RBP_mask; 316 extern RegMask _PTR_NO_RAX_REG_mask; 317 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 318 extern RegMask _LONG_REG_mask; 319 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 320 extern RegMask _LONG_NO_RCX_REG_mask; 321 extern RegMask _INT_REG_mask; 322 extern RegMask _INT_NO_RAX_RDX_REG_mask; 323 extern RegMask _INT_NO_RCX_REG_mask; 324 325 extern RegMask _STACK_OR_PTR_REG_mask; 326 extern RegMask _STACK_OR_LONG_REG_mask; 327 extern RegMask _STACK_OR_INT_REG_mask; 328 329 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 330 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 331 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 332 333 %} 334 335 source %{ 336 #define RELOC_IMM64 Assembler::imm_operand 337 #define RELOC_DISP32 Assembler::disp32_operand 338 339 #define __ _masm. 340 341 RegMask _ANY_REG_mask; 342 RegMask _PTR_REG_mask; 343 RegMask _PTR_REG_NO_RBP_mask; 344 RegMask _PTR_NO_RAX_REG_mask; 345 RegMask _PTR_NO_RAX_RBX_REG_mask; 346 RegMask _LONG_REG_mask; 347 RegMask _LONG_NO_RAX_RDX_REG_mask; 348 RegMask _LONG_NO_RCX_REG_mask; 349 RegMask _INT_REG_mask; 350 RegMask _INT_NO_RAX_RDX_REG_mask; 351 RegMask _INT_NO_RCX_REG_mask; 352 RegMask _STACK_OR_PTR_REG_mask; 353 RegMask _STACK_OR_LONG_REG_mask; 354 RegMask _STACK_OR_INT_REG_mask; 355 356 static bool need_r12_heapbase() { 357 return UseCompressedOops || UseCompressedClassPointers; 358 } 359 360 void reg_mask_init() { 361 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 362 // We derive a number of subsets from it. 363 _ANY_REG_mask = _ALL_REG_mask; 364 365 if (PreserveFramePointer) { 366 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 367 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 368 } 369 if (need_r12_heapbase()) { 370 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 371 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 372 } 373 374 _PTR_REG_mask = _ANY_REG_mask; 375 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 376 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 377 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 378 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 379 380 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 381 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 382 383 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 384 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 385 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 386 387 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 388 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 389 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 390 391 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 392 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 393 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 394 395 _LONG_REG_mask = _PTR_REG_mask; 396 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 397 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 398 399 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 400 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 401 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 402 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 403 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 404 405 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 406 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 407 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 408 409 _INT_REG_mask = _ALL_INT_REG_mask; 410 if (PreserveFramePointer) { 411 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 412 } 413 if (need_r12_heapbase()) { 414 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 415 } 416 417 _STACK_OR_INT_REG_mask = _INT_REG_mask; 418 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 419 420 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 421 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 422 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 423 424 _INT_NO_RCX_REG_mask = _INT_REG_mask; 425 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 426 } 427 428 static bool generate_vzeroupper(Compile* C) { 429 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 430 } 431 432 static int clear_avx_size() { 433 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 434 } 435 436 // !!!!! Special hack to get all types of calls to specify the byte offset 437 // from the start of the call to the point where the return address 438 // will point. 439 int MachCallStaticJavaNode::ret_addr_offset() 440 { 441 int offset = 5; // 5 bytes from start of call to where return address points 442 offset += clear_avx_size(); 443 return offset; 444 } 445 446 int MachCallDynamicJavaNode::ret_addr_offset() 447 { 448 int offset = 15; // 15 bytes from start of call to where return address points 449 offset += clear_avx_size(); 450 return offset; 451 } 452 453 int MachCallRuntimeNode::ret_addr_offset() { 454 int offset = 13; // movq r10,#addr; callq (r10) 455 offset += clear_avx_size(); 456 return offset; 457 } 458 459 // Indicate if the safepoint node needs the polling page as an input, 460 // it does if the polling page is more than disp32 away. 461 bool SafePointNode::needs_polling_address_input() 462 { 463 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 464 } 465 466 // 467 // Compute padding required for nodes which need alignment 468 // 469 470 // The address of the call instruction needs to be 4-byte aligned to 471 // ensure that it does not span a cache line so that it can be patched. 472 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 473 { 474 current_offset += clear_avx_size(); // skip vzeroupper 475 current_offset += 1; // skip call opcode byte 476 return align_up(current_offset, alignment_required()) - current_offset; 477 } 478 479 // The address of the call instruction needs to be 4-byte aligned to 480 // ensure that it does not span a cache line so that it can be patched. 481 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 482 { 483 current_offset += clear_avx_size(); // skip vzeroupper 484 current_offset += 11; // skip movq instruction + call opcode byte 485 return align_up(current_offset, alignment_required()) - current_offset; 486 } 487 488 // EMIT_RM() 489 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 490 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 491 cbuf.insts()->emit_int8(c); 492 } 493 494 // EMIT_CC() 495 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 496 unsigned char c = (unsigned char) (f1 | f2); 497 cbuf.insts()->emit_int8(c); 498 } 499 500 // EMIT_OPCODE() 501 void emit_opcode(CodeBuffer &cbuf, int code) { 502 cbuf.insts()->emit_int8((unsigned char) code); 503 } 504 505 // EMIT_OPCODE() w/ relocation information 506 void emit_opcode(CodeBuffer &cbuf, 507 int code, relocInfo::relocType reloc, int offset, int format) 508 { 509 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 510 emit_opcode(cbuf, code); 511 } 512 513 // EMIT_D8() 514 void emit_d8(CodeBuffer &cbuf, int d8) { 515 cbuf.insts()->emit_int8((unsigned char) d8); 516 } 517 518 // EMIT_D16() 519 void emit_d16(CodeBuffer &cbuf, int d16) { 520 cbuf.insts()->emit_int16(d16); 521 } 522 523 // EMIT_D32() 524 void emit_d32(CodeBuffer &cbuf, int d32) { 525 cbuf.insts()->emit_int32(d32); 526 } 527 528 // EMIT_D64() 529 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 530 cbuf.insts()->emit_int64(d64); 531 } 532 533 // emit 32 bit value and construct relocation entry from relocInfo::relocType 534 void emit_d32_reloc(CodeBuffer& cbuf, 535 int d32, 536 relocInfo::relocType reloc, 537 int format) 538 { 539 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 540 cbuf.relocate(cbuf.insts_mark(), reloc, format); 541 cbuf.insts()->emit_int32(d32); 542 } 543 544 // emit 32 bit value and construct relocation entry from RelocationHolder 545 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 546 #ifdef ASSERT 547 if (rspec.reloc()->type() == relocInfo::oop_type && 548 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 549 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 550 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)), "cannot embed broken oops in code"); 551 } 552 #endif 553 cbuf.relocate(cbuf.insts_mark(), rspec, format); 554 cbuf.insts()->emit_int32(d32); 555 } 556 557 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 558 address next_ip = cbuf.insts_end() + 4; 559 emit_d32_reloc(cbuf, (int) (addr - next_ip), 560 external_word_Relocation::spec(addr), 561 RELOC_DISP32); 562 } 563 564 565 // emit 64 bit value and construct relocation entry from relocInfo::relocType 566 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 567 cbuf.relocate(cbuf.insts_mark(), reloc, format); 568 cbuf.insts()->emit_int64(d64); 569 } 570 571 // emit 64 bit value and construct relocation entry from RelocationHolder 572 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 573 #ifdef ASSERT 574 if (rspec.reloc()->type() == relocInfo::oop_type && 575 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 576 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 577 assert(oopDesc::is_oop(cast_to_oop(d64)), "cannot embed broken oops in code"); 578 } 579 #endif 580 cbuf.relocate(cbuf.insts_mark(), rspec, format); 581 cbuf.insts()->emit_int64(d64); 582 } 583 584 // Access stack slot for load or store 585 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 586 { 587 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 588 if (-0x80 <= disp && disp < 0x80) { 589 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 590 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 591 emit_d8(cbuf, disp); // Displacement // R/M byte 592 } else { 593 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 594 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 595 emit_d32(cbuf, disp); // Displacement // R/M byte 596 } 597 } 598 599 // rRegI ereg, memory mem) %{ // emit_reg_mem 600 void encode_RegMem(CodeBuffer &cbuf, 601 int reg, 602 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 603 { 604 assert(disp_reloc == relocInfo::none, "cannot have disp"); 605 int regenc = reg & 7; 606 int baseenc = base & 7; 607 int indexenc = index & 7; 608 609 // There is no index & no scale, use form without SIB byte 610 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 611 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 612 if (disp == 0 && base != RBP_enc && base != R13_enc) { 613 emit_rm(cbuf, 0x0, regenc, baseenc); // * 614 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 615 // If 8-bit displacement, mode 0x1 616 emit_rm(cbuf, 0x1, regenc, baseenc); // * 617 emit_d8(cbuf, disp); 618 } else { 619 // If 32-bit displacement 620 if (base == -1) { // Special flag for absolute address 621 emit_rm(cbuf, 0x0, regenc, 0x5); // * 622 if (disp_reloc != relocInfo::none) { 623 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 624 } else { 625 emit_d32(cbuf, disp); 626 } 627 } else { 628 // Normal base + offset 629 emit_rm(cbuf, 0x2, regenc, baseenc); // * 630 if (disp_reloc != relocInfo::none) { 631 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 632 } else { 633 emit_d32(cbuf, disp); 634 } 635 } 636 } 637 } else { 638 // Else, encode with the SIB byte 639 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 640 if (disp == 0 && base != RBP_enc && base != R13_enc) { 641 // If no displacement 642 emit_rm(cbuf, 0x0, regenc, 0x4); // * 643 emit_rm(cbuf, scale, indexenc, baseenc); 644 } else { 645 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 646 // If 8-bit displacement, mode 0x1 647 emit_rm(cbuf, 0x1, regenc, 0x4); // * 648 emit_rm(cbuf, scale, indexenc, baseenc); 649 emit_d8(cbuf, disp); 650 } else { 651 // If 32-bit displacement 652 if (base == 0x04 ) { 653 emit_rm(cbuf, 0x2, regenc, 0x4); 654 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 655 } else { 656 emit_rm(cbuf, 0x2, regenc, 0x4); 657 emit_rm(cbuf, scale, indexenc, baseenc); // * 658 } 659 if (disp_reloc != relocInfo::none) { 660 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 661 } else { 662 emit_d32(cbuf, disp); 663 } 664 } 665 } 666 } 667 } 668 669 // This could be in MacroAssembler but it's fairly C2 specific 670 void emit_cmpfp_fixup(MacroAssembler& _masm) { 671 Label exit; 672 __ jccb(Assembler::noParity, exit); 673 __ pushf(); 674 // 675 // comiss/ucomiss instructions set ZF,PF,CF flags and 676 // zero OF,AF,SF for NaN values. 677 // Fixup flags by zeroing ZF,PF so that compare of NaN 678 // values returns 'less than' result (CF is set). 679 // Leave the rest of flags unchanged. 680 // 681 // 7 6 5 4 3 2 1 0 682 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 683 // 0 0 1 0 1 0 1 1 (0x2B) 684 // 685 __ andq(Address(rsp, 0), 0xffffff2b); 686 __ popf(); 687 __ bind(exit); 688 } 689 690 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 691 Label done; 692 __ movl(dst, -1); 693 __ jcc(Assembler::parity, done); 694 __ jcc(Assembler::below, done); 695 __ setb(Assembler::notEqual, dst); 696 __ movzbl(dst, dst); 697 __ bind(done); 698 } 699 700 // Math.min() # Math.max() 701 // -------------------------- 702 // ucomis[s/d] # 703 // ja -> b # a 704 // jp -> NaN # NaN 705 // jb -> a # b 706 // je # 707 // |-jz -> a | b # a & b 708 // | -> a # 709 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst, 710 XMMRegister a, XMMRegister b, 711 XMMRegister xmmt, Register rt, 712 bool min, bool single) { 713 714 Label nan, zero, below, above, done; 715 716 if (single) 717 __ ucomiss(a, b); 718 else 719 __ ucomisd(a, b); 720 721 if (dst->encoding() != (min ? b : a)->encoding()) 722 __ jccb(Assembler::above, above); // CF=0 & ZF=0 723 else 724 __ jccb(Assembler::above, done); 725 726 __ jccb(Assembler::parity, nan); // PF=1 727 __ jccb(Assembler::below, below); // CF=1 728 729 // equal 730 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 731 if (single) { 732 __ ucomiss(a, xmmt); 733 __ jccb(Assembler::equal, zero); 734 735 __ movflt(dst, a); 736 __ jmp(done); 737 } 738 else { 739 __ ucomisd(a, xmmt); 740 __ jccb(Assembler::equal, zero); 741 742 __ movdbl(dst, a); 743 __ jmp(done); 744 } 745 746 __ bind(zero); 747 if (min) 748 __ vpor(dst, a, b, Assembler::AVX_128bit); 749 else 750 __ vpand(dst, a, b, Assembler::AVX_128bit); 751 752 __ jmp(done); 753 754 __ bind(above); 755 if (single) 756 __ movflt(dst, min ? b : a); 757 else 758 __ movdbl(dst, min ? b : a); 759 760 __ jmp(done); 761 762 __ bind(nan); 763 if (single) { 764 __ movl(rt, 0x7fc00000); // Float.NaN 765 __ movdl(dst, rt); 766 } 767 else { 768 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 769 __ movdq(dst, rt); 770 } 771 __ jmp(done); 772 773 __ bind(below); 774 if (single) 775 __ movflt(dst, min ? a : b); 776 else 777 __ movdbl(dst, min ? a : b); 778 779 __ bind(done); 780 } 781 782 //============================================================================= 783 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 784 785 int Compile::ConstantTable::calculate_table_base_offset() const { 786 return 0; // absolute addressing, no offset 787 } 788 789 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 790 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 791 ShouldNotReachHere(); 792 } 793 794 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 795 // Empty encoding 796 } 797 798 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 799 return 0; 800 } 801 802 #ifndef PRODUCT 803 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 804 st->print("# MachConstantBaseNode (empty encoding)"); 805 } 806 #endif 807 808 809 //============================================================================= 810 #ifndef PRODUCT 811 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 812 Compile* C = ra_->C; 813 814 int framesize = C->frame_size_in_bytes(); 815 int bangsize = C->bang_size_in_bytes(); 816 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 817 // Remove wordSize for return addr which is already pushed. 818 framesize -= wordSize; 819 820 if (C->need_stack_bang(bangsize)) { 821 framesize -= wordSize; 822 st->print("# stack bang (%d bytes)", bangsize); 823 st->print("\n\t"); 824 st->print("pushq rbp\t# Save rbp"); 825 if (PreserveFramePointer) { 826 st->print("\n\t"); 827 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 828 } 829 if (framesize) { 830 st->print("\n\t"); 831 st->print("subq rsp, #%d\t# Create frame",framesize); 832 } 833 } else { 834 st->print("subq rsp, #%d\t# Create frame",framesize); 835 st->print("\n\t"); 836 framesize -= wordSize; 837 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 838 if (PreserveFramePointer) { 839 st->print("\n\t"); 840 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 841 if (framesize > 0) { 842 st->print("\n\t"); 843 st->print("addq rbp, #%d", framesize); 844 } 845 } 846 } 847 848 if (VerifyStackAtCalls) { 849 st->print("\n\t"); 850 framesize -= wordSize; 851 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 852 #ifdef ASSERT 853 st->print("\n\t"); 854 st->print("# stack alignment check"); 855 #endif 856 } 857 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 858 st->print("\n\t"); 859 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t"); 860 st->print("\n\t"); 861 st->print("je fast_entry\t"); 862 st->print("\n\t"); 863 st->print("call #nmethod_entry_barrier_stub\t"); 864 st->print("\n\tfast_entry:"); 865 } 866 st->cr(); 867 } 868 #endif 869 870 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 871 Compile* C = ra_->C; 872 MacroAssembler _masm(&cbuf); 873 874 __ verified_entry(C); 875 __ bind(*_verified_entry); 876 877 C->set_frame_complete(cbuf.insts_size()); 878 879 if (C->has_mach_constant_base_node()) { 880 // NOTE: We set the table base offset here because users might be 881 // emitted before MachConstantBaseNode. 882 Compile::ConstantTable& constant_table = C->constant_table(); 883 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 884 } 885 } 886 887 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 888 { 889 return MachNode::size(ra_); // too many variables; just compute it 890 // the hard way 891 } 892 893 int MachPrologNode::reloc() const 894 { 895 return 0; // a large enough number 896 } 897 898 //============================================================================= 899 #ifndef PRODUCT 900 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 901 { 902 Compile* C = ra_->C; 903 if (generate_vzeroupper(C)) { 904 st->print("vzeroupper"); 905 st->cr(); st->print("\t"); 906 } 907 908 int framesize = C->frame_size_in_bytes(); 909 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 910 // Remove word for return adr already pushed 911 // and RBP 912 framesize -= 2*wordSize; 913 914 if (framesize) { 915 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 916 st->print("\t"); 917 } 918 919 st->print_cr("popq rbp"); 920 if (do_polling() && C->is_method_compilation()) { 921 st->print("\t"); 922 if (SafepointMechanism::uses_thread_local_poll()) { 923 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 924 "testl rax, [rscratch1]\t" 925 "# Safepoint: poll for GC"); 926 } else if (Assembler::is_polling_page_far()) { 927 st->print_cr("movq rscratch1, #polling_page_address\n\t" 928 "testl rax, [rscratch1]\t" 929 "# Safepoint: poll for GC"); 930 } else { 931 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 932 "# Safepoint: poll for GC"); 933 } 934 } 935 } 936 #endif 937 938 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 939 { 940 Compile* C = ra_->C; 941 MacroAssembler _masm(&cbuf); 942 943 if (generate_vzeroupper(C)) { 944 // Clear upper bits of YMM registers when current compiled code uses 945 // wide vectors to avoid AVX <-> SSE transition penalty during call. 946 __ vzeroupper(); 947 } 948 949 __ restore_stack(C); 950 951 952 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 953 __ reserved_stack_check(); 954 } 955 956 if (do_polling() && C->is_method_compilation()) { 957 MacroAssembler _masm(&cbuf); 958 if (SafepointMechanism::uses_thread_local_poll()) { 959 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 960 __ relocate(relocInfo::poll_return_type); 961 __ testl(rax, Address(rscratch1, 0)); 962 } else { 963 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 964 if (Assembler::is_polling_page_far()) { 965 __ lea(rscratch1, polling_page); 966 __ relocate(relocInfo::poll_return_type); 967 __ testl(rax, Address(rscratch1, 0)); 968 } else { 969 __ testl(rax, polling_page); 970 } 971 } 972 } 973 } 974 975 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 976 { 977 return MachNode::size(ra_); // too many variables; just compute it 978 // the hard way 979 } 980 981 int MachEpilogNode::reloc() const 982 { 983 return 2; // a large enough number 984 } 985 986 const Pipeline* MachEpilogNode::pipeline() const 987 { 988 return MachNode::pipeline_class(); 989 } 990 991 int MachEpilogNode::safepoint_offset() const 992 { 993 return 0; 994 } 995 996 //============================================================================= 997 998 enum RC { 999 rc_bad, 1000 rc_int, 1001 rc_float, 1002 rc_stack 1003 }; 1004 1005 static enum RC rc_class(OptoReg::Name reg) 1006 { 1007 if( !OptoReg::is_valid(reg) ) return rc_bad; 1008 1009 if (OptoReg::is_stack(reg)) return rc_stack; 1010 1011 VMReg r = OptoReg::as_VMReg(reg); 1012 1013 if (r->is_Register()) return rc_int; 1014 1015 assert(r->is_XMMRegister(), "must be"); 1016 return rc_float; 1017 } 1018 1019 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1020 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1021 int src_hi, int dst_hi, uint ireg, outputStream* st); 1022 1023 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1024 int stack_offset, int reg, uint ireg, outputStream* st); 1025 1026 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1027 int dst_offset, uint ireg, outputStream* st) { 1028 if (cbuf) { 1029 MacroAssembler _masm(cbuf); 1030 switch (ireg) { 1031 case Op_VecS: 1032 __ movq(Address(rsp, -8), rax); 1033 __ movl(rax, Address(rsp, src_offset)); 1034 __ movl(Address(rsp, dst_offset), rax); 1035 __ movq(rax, Address(rsp, -8)); 1036 break; 1037 case Op_VecD: 1038 __ pushq(Address(rsp, src_offset)); 1039 __ popq (Address(rsp, dst_offset)); 1040 break; 1041 case Op_VecX: 1042 __ pushq(Address(rsp, src_offset)); 1043 __ popq (Address(rsp, dst_offset)); 1044 __ pushq(Address(rsp, src_offset+8)); 1045 __ popq (Address(rsp, dst_offset+8)); 1046 break; 1047 case Op_VecY: 1048 __ vmovdqu(Address(rsp, -32), xmm0); 1049 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1050 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1051 __ vmovdqu(xmm0, Address(rsp, -32)); 1052 break; 1053 case Op_VecZ: 1054 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1055 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1056 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1057 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1058 break; 1059 default: 1060 ShouldNotReachHere(); 1061 } 1062 #ifndef PRODUCT 1063 } else { 1064 switch (ireg) { 1065 case Op_VecS: 1066 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1067 "movl rax, [rsp + #%d]\n\t" 1068 "movl [rsp + #%d], rax\n\t" 1069 "movq rax, [rsp - #8]", 1070 src_offset, dst_offset); 1071 break; 1072 case Op_VecD: 1073 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1074 "popq [rsp + #%d]", 1075 src_offset, dst_offset); 1076 break; 1077 case Op_VecX: 1078 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1079 "popq [rsp + #%d]\n\t" 1080 "pushq [rsp + #%d]\n\t" 1081 "popq [rsp + #%d]", 1082 src_offset, dst_offset, src_offset+8, dst_offset+8); 1083 break; 1084 case Op_VecY: 1085 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1086 "vmovdqu xmm0, [rsp + #%d]\n\t" 1087 "vmovdqu [rsp + #%d], xmm0\n\t" 1088 "vmovdqu xmm0, [rsp - #32]", 1089 src_offset, dst_offset); 1090 break; 1091 case Op_VecZ: 1092 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1093 "vmovdqu xmm0, [rsp + #%d]\n\t" 1094 "vmovdqu [rsp + #%d], xmm0\n\t" 1095 "vmovdqu xmm0, [rsp - #64]", 1096 src_offset, dst_offset); 1097 break; 1098 default: 1099 ShouldNotReachHere(); 1100 } 1101 #endif 1102 } 1103 } 1104 1105 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1106 PhaseRegAlloc* ra_, 1107 bool do_size, 1108 outputStream* st) const { 1109 assert(cbuf != NULL || st != NULL, "sanity"); 1110 // Get registers to move 1111 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1112 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1113 OptoReg::Name dst_second = ra_->get_reg_second(this); 1114 OptoReg::Name dst_first = ra_->get_reg_first(this); 1115 1116 enum RC src_second_rc = rc_class(src_second); 1117 enum RC src_first_rc = rc_class(src_first); 1118 enum RC dst_second_rc = rc_class(dst_second); 1119 enum RC dst_first_rc = rc_class(dst_first); 1120 1121 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1122 "must move at least 1 register" ); 1123 1124 if (src_first == dst_first && src_second == dst_second) { 1125 // Self copy, no move 1126 return 0; 1127 } 1128 if (bottom_type()->isa_vect() != NULL) { 1129 uint ireg = ideal_reg(); 1130 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1131 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1132 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1133 // mem -> mem 1134 int src_offset = ra_->reg2offset(src_first); 1135 int dst_offset = ra_->reg2offset(dst_first); 1136 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1137 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1138 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1139 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1140 int stack_offset = ra_->reg2offset(dst_first); 1141 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1142 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1143 int stack_offset = ra_->reg2offset(src_first); 1144 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1145 } else { 1146 ShouldNotReachHere(); 1147 } 1148 return 0; 1149 } 1150 if (src_first_rc == rc_stack) { 1151 // mem -> 1152 if (dst_first_rc == rc_stack) { 1153 // mem -> mem 1154 assert(src_second != dst_first, "overlap"); 1155 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1156 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1157 // 64-bit 1158 int src_offset = ra_->reg2offset(src_first); 1159 int dst_offset = ra_->reg2offset(dst_first); 1160 if (cbuf) { 1161 MacroAssembler _masm(cbuf); 1162 __ pushq(Address(rsp, src_offset)); 1163 __ popq (Address(rsp, dst_offset)); 1164 #ifndef PRODUCT 1165 } else { 1166 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1167 "popq [rsp + #%d]", 1168 src_offset, dst_offset); 1169 #endif 1170 } 1171 } else { 1172 // 32-bit 1173 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1174 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1175 // No pushl/popl, so: 1176 int src_offset = ra_->reg2offset(src_first); 1177 int dst_offset = ra_->reg2offset(dst_first); 1178 if (cbuf) { 1179 MacroAssembler _masm(cbuf); 1180 __ movq(Address(rsp, -8), rax); 1181 __ movl(rax, Address(rsp, src_offset)); 1182 __ movl(Address(rsp, dst_offset), rax); 1183 __ movq(rax, Address(rsp, -8)); 1184 #ifndef PRODUCT 1185 } else { 1186 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1187 "movl rax, [rsp + #%d]\n\t" 1188 "movl [rsp + #%d], rax\n\t" 1189 "movq rax, [rsp - #8]", 1190 src_offset, dst_offset); 1191 #endif 1192 } 1193 } 1194 return 0; 1195 } else if (dst_first_rc == rc_int) { 1196 // mem -> gpr 1197 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1198 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1199 // 64-bit 1200 int offset = ra_->reg2offset(src_first); 1201 if (cbuf) { 1202 MacroAssembler _masm(cbuf); 1203 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1204 #ifndef PRODUCT 1205 } else { 1206 st->print("movq %s, [rsp + #%d]\t# spill", 1207 Matcher::regName[dst_first], 1208 offset); 1209 #endif 1210 } 1211 } else { 1212 // 32-bit 1213 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1214 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1215 int offset = ra_->reg2offset(src_first); 1216 if (cbuf) { 1217 MacroAssembler _masm(cbuf); 1218 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1219 #ifndef PRODUCT 1220 } else { 1221 st->print("movl %s, [rsp + #%d]\t# spill", 1222 Matcher::regName[dst_first], 1223 offset); 1224 #endif 1225 } 1226 } 1227 return 0; 1228 } else if (dst_first_rc == rc_float) { 1229 // mem-> xmm 1230 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1231 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1232 // 64-bit 1233 int offset = ra_->reg2offset(src_first); 1234 if (cbuf) { 1235 MacroAssembler _masm(cbuf); 1236 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1237 #ifndef PRODUCT 1238 } else { 1239 st->print("%s %s, [rsp + #%d]\t# spill", 1240 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1241 Matcher::regName[dst_first], 1242 offset); 1243 #endif 1244 } 1245 } else { 1246 // 32-bit 1247 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1248 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1249 int offset = ra_->reg2offset(src_first); 1250 if (cbuf) { 1251 MacroAssembler _masm(cbuf); 1252 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1253 #ifndef PRODUCT 1254 } else { 1255 st->print("movss %s, [rsp + #%d]\t# spill", 1256 Matcher::regName[dst_first], 1257 offset); 1258 #endif 1259 } 1260 } 1261 return 0; 1262 } 1263 } else if (src_first_rc == rc_int) { 1264 // gpr -> 1265 if (dst_first_rc == rc_stack) { 1266 // gpr -> mem 1267 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1268 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1269 // 64-bit 1270 int offset = ra_->reg2offset(dst_first); 1271 if (cbuf) { 1272 MacroAssembler _masm(cbuf); 1273 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1274 #ifndef PRODUCT 1275 } else { 1276 st->print("movq [rsp + #%d], %s\t# spill", 1277 offset, 1278 Matcher::regName[src_first]); 1279 #endif 1280 } 1281 } else { 1282 // 32-bit 1283 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1284 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1285 int offset = ra_->reg2offset(dst_first); 1286 if (cbuf) { 1287 MacroAssembler _masm(cbuf); 1288 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1289 #ifndef PRODUCT 1290 } else { 1291 st->print("movl [rsp + #%d], %s\t# spill", 1292 offset, 1293 Matcher::regName[src_first]); 1294 #endif 1295 } 1296 } 1297 return 0; 1298 } else if (dst_first_rc == rc_int) { 1299 // gpr -> gpr 1300 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1301 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1302 // 64-bit 1303 if (cbuf) { 1304 MacroAssembler _masm(cbuf); 1305 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1306 as_Register(Matcher::_regEncode[src_first])); 1307 #ifndef PRODUCT 1308 } else { 1309 st->print("movq %s, %s\t# spill", 1310 Matcher::regName[dst_first], 1311 Matcher::regName[src_first]); 1312 #endif 1313 } 1314 return 0; 1315 } else { 1316 // 32-bit 1317 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1318 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1319 if (cbuf) { 1320 MacroAssembler _masm(cbuf); 1321 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1322 as_Register(Matcher::_regEncode[src_first])); 1323 #ifndef PRODUCT 1324 } else { 1325 st->print("movl %s, %s\t# spill", 1326 Matcher::regName[dst_first], 1327 Matcher::regName[src_first]); 1328 #endif 1329 } 1330 return 0; 1331 } 1332 } else if (dst_first_rc == rc_float) { 1333 // gpr -> xmm 1334 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1335 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1336 // 64-bit 1337 if (cbuf) { 1338 MacroAssembler _masm(cbuf); 1339 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1340 #ifndef PRODUCT 1341 } else { 1342 st->print("movdq %s, %s\t# spill", 1343 Matcher::regName[dst_first], 1344 Matcher::regName[src_first]); 1345 #endif 1346 } 1347 } else { 1348 // 32-bit 1349 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1350 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1351 if (cbuf) { 1352 MacroAssembler _masm(cbuf); 1353 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1354 #ifndef PRODUCT 1355 } else { 1356 st->print("movdl %s, %s\t# spill", 1357 Matcher::regName[dst_first], 1358 Matcher::regName[src_first]); 1359 #endif 1360 } 1361 } 1362 return 0; 1363 } 1364 } else if (src_first_rc == rc_float) { 1365 // xmm -> 1366 if (dst_first_rc == rc_stack) { 1367 // xmm -> mem 1368 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1369 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1370 // 64-bit 1371 int offset = ra_->reg2offset(dst_first); 1372 if (cbuf) { 1373 MacroAssembler _masm(cbuf); 1374 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1375 #ifndef PRODUCT 1376 } else { 1377 st->print("movsd [rsp + #%d], %s\t# spill", 1378 offset, 1379 Matcher::regName[src_first]); 1380 #endif 1381 } 1382 } else { 1383 // 32-bit 1384 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1385 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1386 int offset = ra_->reg2offset(dst_first); 1387 if (cbuf) { 1388 MacroAssembler _masm(cbuf); 1389 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1390 #ifndef PRODUCT 1391 } else { 1392 st->print("movss [rsp + #%d], %s\t# spill", 1393 offset, 1394 Matcher::regName[src_first]); 1395 #endif 1396 } 1397 } 1398 return 0; 1399 } else if (dst_first_rc == rc_int) { 1400 // xmm -> gpr 1401 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1402 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1403 // 64-bit 1404 if (cbuf) { 1405 MacroAssembler _masm(cbuf); 1406 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1407 #ifndef PRODUCT 1408 } else { 1409 st->print("movdq %s, %s\t# spill", 1410 Matcher::regName[dst_first], 1411 Matcher::regName[src_first]); 1412 #endif 1413 } 1414 } else { 1415 // 32-bit 1416 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1417 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1418 if (cbuf) { 1419 MacroAssembler _masm(cbuf); 1420 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1421 #ifndef PRODUCT 1422 } else { 1423 st->print("movdl %s, %s\t# spill", 1424 Matcher::regName[dst_first], 1425 Matcher::regName[src_first]); 1426 #endif 1427 } 1428 } 1429 return 0; 1430 } else if (dst_first_rc == rc_float) { 1431 // xmm -> xmm 1432 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1433 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1434 // 64-bit 1435 if (cbuf) { 1436 MacroAssembler _masm(cbuf); 1437 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1438 #ifndef PRODUCT 1439 } else { 1440 st->print("%s %s, %s\t# spill", 1441 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1442 Matcher::regName[dst_first], 1443 Matcher::regName[src_first]); 1444 #endif 1445 } 1446 } else { 1447 // 32-bit 1448 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1449 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1450 if (cbuf) { 1451 MacroAssembler _masm(cbuf); 1452 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1453 #ifndef PRODUCT 1454 } else { 1455 st->print("%s %s, %s\t# spill", 1456 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1457 Matcher::regName[dst_first], 1458 Matcher::regName[src_first]); 1459 #endif 1460 } 1461 } 1462 return 0; 1463 } 1464 } 1465 1466 assert(0," foo "); 1467 Unimplemented(); 1468 return 0; 1469 } 1470 1471 #ifndef PRODUCT 1472 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1473 implementation(NULL, ra_, false, st); 1474 } 1475 #endif 1476 1477 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1478 implementation(&cbuf, ra_, false, NULL); 1479 } 1480 1481 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1482 return MachNode::size(ra_); 1483 } 1484 1485 //============================================================================= 1486 #ifndef PRODUCT 1487 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1488 { 1489 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1490 int reg = ra_->get_reg_first(this); 1491 st->print("leaq %s, [rsp + #%d]\t# box lock", 1492 Matcher::regName[reg], offset); 1493 } 1494 #endif 1495 1496 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1497 { 1498 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1499 int reg = ra_->get_encode(this); 1500 if (offset >= 0x80) { 1501 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1502 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1503 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1504 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1505 emit_d32(cbuf, offset); 1506 } else { 1507 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1508 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1509 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1510 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1511 emit_d8(cbuf, offset); 1512 } 1513 } 1514 1515 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1516 { 1517 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1518 return (offset < 0x80) ? 5 : 8; // REX 1519 } 1520 1521 //============================================================================= 1522 #ifndef PRODUCT 1523 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1524 { 1525 st->print_cr("MachVEPNode"); 1526 } 1527 #endif 1528 1529 void MachVEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1530 { 1531 MacroAssembler masm(&cbuf); 1532 if (!_verified) { 1533 uint insts_size = cbuf.insts_size(); 1534 if (UseCompressedClassPointers) { 1535 masm.load_klass(rscratch1, j_rarg0); 1536 masm.cmpptr(rax, rscratch1); 1537 } else { 1538 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1539 } 1540 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1541 } else { 1542 // Unpack value type args passed as oop and then jump to 1543 // the verified entry point (skipping the unverified entry). 1544 masm.unpack_value_args(ra_->C, _receiver_only); 1545 masm.jmp(*_verified_entry); 1546 } 1547 } 1548 1549 uint MachVEPNode::size(PhaseRegAlloc* ra_) const 1550 { 1551 return MachNode::size(ra_); // too many variables; just compute it the hard way 1552 } 1553 1554 //============================================================================= 1555 #ifndef PRODUCT 1556 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1557 { 1558 if (UseCompressedClassPointers) { 1559 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1560 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1561 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1562 } else { 1563 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1564 "# Inline cache check"); 1565 } 1566 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1567 st->print_cr("\tnop\t# nops to align entry point"); 1568 } 1569 #endif 1570 1571 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1572 { 1573 MacroAssembler masm(&cbuf); 1574 uint insts_size = cbuf.insts_size(); 1575 if (UseCompressedClassPointers) { 1576 masm.load_klass(rscratch1, j_rarg0); 1577 masm.cmpptr(rax, rscratch1); 1578 } else { 1579 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1580 } 1581 1582 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1583 1584 /* WARNING these NOPs are critical so that verified entry point is properly 1585 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1586 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1587 if (OptoBreakpoint) { 1588 // Leave space for int3 1589 nops_cnt -= 1; 1590 } 1591 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1592 if (nops_cnt > 0) 1593 masm.nop(nops_cnt); 1594 } 1595 1596 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1597 { 1598 return MachNode::size(ra_); // too many variables; just compute it 1599 // the hard way 1600 } 1601 1602 1603 //============================================================================= 1604 1605 int Matcher::regnum_to_fpu_offset(int regnum) 1606 { 1607 return regnum - 32; // The FP registers are in the second chunk 1608 } 1609 1610 // This is UltraSparc specific, true just means we have fast l2f conversion 1611 const bool Matcher::convL2FSupported(void) { 1612 return true; 1613 } 1614 1615 // Is this branch offset short enough that a short branch can be used? 1616 // 1617 // NOTE: If the platform does not provide any short branch variants, then 1618 // this method should return false for offset 0. 1619 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1620 // The passed offset is relative to address of the branch. 1621 // On 86 a branch displacement is calculated relative to address 1622 // of a next instruction. 1623 offset -= br_size; 1624 1625 // the short version of jmpConUCF2 contains multiple branches, 1626 // making the reach slightly less 1627 if (rule == jmpConUCF2_rule) 1628 return (-126 <= offset && offset <= 125); 1629 return (-128 <= offset && offset <= 127); 1630 } 1631 1632 const bool Matcher::isSimpleConstant64(jlong value) { 1633 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1634 //return value == (int) value; // Cf. storeImmL and immL32. 1635 1636 // Probably always true, even if a temp register is required. 1637 return true; 1638 } 1639 1640 // The ecx parameter to rep stosq for the ClearArray node is in words. 1641 const bool Matcher::init_array_count_is_in_bytes = false; 1642 1643 // No additional cost for CMOVL. 1644 const int Matcher::long_cmove_cost() { return 0; } 1645 1646 // No CMOVF/CMOVD with SSE2 1647 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1648 1649 // Does the CPU require late expand (see block.cpp for description of late expand)? 1650 const bool Matcher::require_postalloc_expand = false; 1651 1652 // Do we need to mask the count passed to shift instructions or does 1653 // the cpu only look at the lower 5/6 bits anyway? 1654 const bool Matcher::need_masked_shift_count = false; 1655 1656 bool Matcher::narrow_oop_use_complex_address() { 1657 assert(UseCompressedOops, "only for compressed oops code"); 1658 return (LogMinObjAlignmentInBytes <= 3); 1659 } 1660 1661 bool Matcher::narrow_klass_use_complex_address() { 1662 assert(UseCompressedClassPointers, "only for compressed klass code"); 1663 return (LogKlassAlignmentInBytes <= 3); 1664 } 1665 1666 bool Matcher::const_oop_prefer_decode() { 1667 // Prefer ConN+DecodeN over ConP. 1668 return true; 1669 } 1670 1671 bool Matcher::const_klass_prefer_decode() { 1672 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1673 // or condisider the following: 1674 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1675 //return CompressedKlassPointers::base() == NULL; 1676 return true; 1677 } 1678 1679 // Is it better to copy float constants, or load them directly from 1680 // memory? Intel can load a float constant from a direct address, 1681 // requiring no extra registers. Most RISCs will have to materialize 1682 // an address into a register first, so they would do better to copy 1683 // the constant from stack. 1684 const bool Matcher::rematerialize_float_constants = true; // XXX 1685 1686 // If CPU can load and store mis-aligned doubles directly then no 1687 // fixup is needed. Else we split the double into 2 integer pieces 1688 // and move it piece-by-piece. Only happens when passing doubles into 1689 // C code as the Java calling convention forces doubles to be aligned. 1690 const bool Matcher::misaligned_doubles_ok = true; 1691 1692 // No-op on amd64 1693 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1694 1695 // Advertise here if the CPU requires explicit rounding operations to 1696 // implement the UseStrictFP mode. 1697 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1698 1699 // Are floats conerted to double when stored to stack during deoptimization? 1700 // On x64 it is stored without convertion so we can use normal access. 1701 bool Matcher::float_in_double() { return false; } 1702 1703 // Do ints take an entire long register or just half? 1704 const bool Matcher::int_in_long = true; 1705 1706 // Return whether or not this register is ever used as an argument. 1707 // This function is used on startup to build the trampoline stubs in 1708 // generateOptoStub. Registers not mentioned will be killed by the VM 1709 // call in the trampoline, and arguments in those registers not be 1710 // available to the callee. 1711 bool Matcher::can_be_java_arg(int reg) 1712 { 1713 return 1714 reg == RDI_num || reg == RDI_H_num || 1715 reg == RSI_num || reg == RSI_H_num || 1716 reg == RDX_num || reg == RDX_H_num || 1717 reg == RCX_num || reg == RCX_H_num || 1718 reg == R8_num || reg == R8_H_num || 1719 reg == R9_num || reg == R9_H_num || 1720 reg == R12_num || reg == R12_H_num || 1721 reg == XMM0_num || reg == XMM0b_num || 1722 reg == XMM1_num || reg == XMM1b_num || 1723 reg == XMM2_num || reg == XMM2b_num || 1724 reg == XMM3_num || reg == XMM3b_num || 1725 reg == XMM4_num || reg == XMM4b_num || 1726 reg == XMM5_num || reg == XMM5b_num || 1727 reg == XMM6_num || reg == XMM6b_num || 1728 reg == XMM7_num || reg == XMM7b_num; 1729 } 1730 1731 bool Matcher::is_spillable_arg(int reg) 1732 { 1733 return can_be_java_arg(reg); 1734 } 1735 1736 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1737 // In 64 bit mode a code which use multiply when 1738 // devisor is constant is faster than hardware 1739 // DIV instruction (it uses MulHiL). 1740 return false; 1741 } 1742 1743 // Register for DIVI projection of divmodI 1744 RegMask Matcher::divI_proj_mask() { 1745 return INT_RAX_REG_mask(); 1746 } 1747 1748 // Register for MODI projection of divmodI 1749 RegMask Matcher::modI_proj_mask() { 1750 return INT_RDX_REG_mask(); 1751 } 1752 1753 // Register for DIVL projection of divmodL 1754 RegMask Matcher::divL_proj_mask() { 1755 return LONG_RAX_REG_mask(); 1756 } 1757 1758 // Register for MODL projection of divmodL 1759 RegMask Matcher::modL_proj_mask() { 1760 return LONG_RDX_REG_mask(); 1761 } 1762 1763 // Register for saving SP into on method handle invokes. Not used on x86_64. 1764 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1765 return NO_REG_mask(); 1766 } 1767 1768 %} 1769 1770 //----------ENCODING BLOCK----------------------------------------------------- 1771 // This block specifies the encoding classes used by the compiler to 1772 // output byte streams. Encoding classes are parameterized macros 1773 // used by Machine Instruction Nodes in order to generate the bit 1774 // encoding of the instruction. Operands specify their base encoding 1775 // interface with the interface keyword. There are currently 1776 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1777 // COND_INTER. REG_INTER causes an operand to generate a function 1778 // which returns its register number when queried. CONST_INTER causes 1779 // an operand to generate a function which returns the value of the 1780 // constant when queried. MEMORY_INTER causes an operand to generate 1781 // four functions which return the Base Register, the Index Register, 1782 // the Scale Value, and the Offset Value of the operand when queried. 1783 // COND_INTER causes an operand to generate six functions which return 1784 // the encoding code (ie - encoding bits for the instruction) 1785 // associated with each basic boolean condition for a conditional 1786 // instruction. 1787 // 1788 // Instructions specify two basic values for encoding. Again, a 1789 // function is available to check if the constant displacement is an 1790 // oop. They use the ins_encode keyword to specify their encoding 1791 // classes (which must be a sequence of enc_class names, and their 1792 // parameters, specified in the encoding block), and they use the 1793 // opcode keyword to specify, in order, their primary, secondary, and 1794 // tertiary opcode. Only the opcode sections which a particular 1795 // instruction needs for encoding need to be specified. 1796 encode %{ 1797 // Build emit functions for each basic byte or larger field in the 1798 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1799 // from C++ code in the enc_class source block. Emit functions will 1800 // live in the main source block for now. In future, we can 1801 // generalize this by adding a syntax that specifies the sizes of 1802 // fields in an order, so that the adlc can build the emit functions 1803 // automagically 1804 1805 // Emit primary opcode 1806 enc_class OpcP 1807 %{ 1808 emit_opcode(cbuf, $primary); 1809 %} 1810 1811 // Emit secondary opcode 1812 enc_class OpcS 1813 %{ 1814 emit_opcode(cbuf, $secondary); 1815 %} 1816 1817 // Emit tertiary opcode 1818 enc_class OpcT 1819 %{ 1820 emit_opcode(cbuf, $tertiary); 1821 %} 1822 1823 // Emit opcode directly 1824 enc_class Opcode(immI d8) 1825 %{ 1826 emit_opcode(cbuf, $d8$$constant); 1827 %} 1828 1829 // Emit size prefix 1830 enc_class SizePrefix 1831 %{ 1832 emit_opcode(cbuf, 0x66); 1833 %} 1834 1835 enc_class reg(rRegI reg) 1836 %{ 1837 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1838 %} 1839 1840 enc_class reg_reg(rRegI dst, rRegI src) 1841 %{ 1842 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1843 %} 1844 1845 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1846 %{ 1847 emit_opcode(cbuf, $opcode$$constant); 1848 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1849 %} 1850 1851 enc_class cdql_enc(no_rax_rdx_RegI div) 1852 %{ 1853 // Full implementation of Java idiv and irem; checks for 1854 // special case as described in JVM spec., p.243 & p.271. 1855 // 1856 // normal case special case 1857 // 1858 // input : rax: dividend min_int 1859 // reg: divisor -1 1860 // 1861 // output: rax: quotient (= rax idiv reg) min_int 1862 // rdx: remainder (= rax irem reg) 0 1863 // 1864 // Code sequnce: 1865 // 1866 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1867 // 5: 75 07/08 jne e <normal> 1868 // 7: 33 d2 xor %edx,%edx 1869 // [div >= 8 -> offset + 1] 1870 // [REX_B] 1871 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1872 // c: 74 03/04 je 11 <done> 1873 // 000000000000000e <normal>: 1874 // e: 99 cltd 1875 // [div >= 8 -> offset + 1] 1876 // [REX_B] 1877 // f: f7 f9 idiv $div 1878 // 0000000000000011 <done>: 1879 1880 // cmp $0x80000000,%eax 1881 emit_opcode(cbuf, 0x3d); 1882 emit_d8(cbuf, 0x00); 1883 emit_d8(cbuf, 0x00); 1884 emit_d8(cbuf, 0x00); 1885 emit_d8(cbuf, 0x80); 1886 1887 // jne e <normal> 1888 emit_opcode(cbuf, 0x75); 1889 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1890 1891 // xor %edx,%edx 1892 emit_opcode(cbuf, 0x33); 1893 emit_d8(cbuf, 0xD2); 1894 1895 // cmp $0xffffffffffffffff,%ecx 1896 if ($div$$reg >= 8) { 1897 emit_opcode(cbuf, Assembler::REX_B); 1898 } 1899 emit_opcode(cbuf, 0x83); 1900 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1901 emit_d8(cbuf, 0xFF); 1902 1903 // je 11 <done> 1904 emit_opcode(cbuf, 0x74); 1905 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1906 1907 // <normal> 1908 // cltd 1909 emit_opcode(cbuf, 0x99); 1910 1911 // idivl (note: must be emitted by the user of this rule) 1912 // <done> 1913 %} 1914 1915 enc_class cdqq_enc(no_rax_rdx_RegL div) 1916 %{ 1917 // Full implementation of Java ldiv and lrem; checks for 1918 // special case as described in JVM spec., p.243 & p.271. 1919 // 1920 // normal case special case 1921 // 1922 // input : rax: dividend min_long 1923 // reg: divisor -1 1924 // 1925 // output: rax: quotient (= rax idiv reg) min_long 1926 // rdx: remainder (= rax irem reg) 0 1927 // 1928 // Code sequnce: 1929 // 1930 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1931 // 7: 00 00 80 1932 // a: 48 39 d0 cmp %rdx,%rax 1933 // d: 75 08 jne 17 <normal> 1934 // f: 33 d2 xor %edx,%edx 1935 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1936 // 15: 74 05 je 1c <done> 1937 // 0000000000000017 <normal>: 1938 // 17: 48 99 cqto 1939 // 19: 48 f7 f9 idiv $div 1940 // 000000000000001c <done>: 1941 1942 // mov $0x8000000000000000,%rdx 1943 emit_opcode(cbuf, Assembler::REX_W); 1944 emit_opcode(cbuf, 0xBA); 1945 emit_d8(cbuf, 0x00); 1946 emit_d8(cbuf, 0x00); 1947 emit_d8(cbuf, 0x00); 1948 emit_d8(cbuf, 0x00); 1949 emit_d8(cbuf, 0x00); 1950 emit_d8(cbuf, 0x00); 1951 emit_d8(cbuf, 0x00); 1952 emit_d8(cbuf, 0x80); 1953 1954 // cmp %rdx,%rax 1955 emit_opcode(cbuf, Assembler::REX_W); 1956 emit_opcode(cbuf, 0x39); 1957 emit_d8(cbuf, 0xD0); 1958 1959 // jne 17 <normal> 1960 emit_opcode(cbuf, 0x75); 1961 emit_d8(cbuf, 0x08); 1962 1963 // xor %edx,%edx 1964 emit_opcode(cbuf, 0x33); 1965 emit_d8(cbuf, 0xD2); 1966 1967 // cmp $0xffffffffffffffff,$div 1968 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1969 emit_opcode(cbuf, 0x83); 1970 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1971 emit_d8(cbuf, 0xFF); 1972 1973 // je 1e <done> 1974 emit_opcode(cbuf, 0x74); 1975 emit_d8(cbuf, 0x05); 1976 1977 // <normal> 1978 // cqto 1979 emit_opcode(cbuf, Assembler::REX_W); 1980 emit_opcode(cbuf, 0x99); 1981 1982 // idivq (note: must be emitted by the user of this rule) 1983 // <done> 1984 %} 1985 1986 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1987 enc_class OpcSE(immI imm) 1988 %{ 1989 // Emit primary opcode and set sign-extend bit 1990 // Check for 8-bit immediate, and set sign extend bit in opcode 1991 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1992 emit_opcode(cbuf, $primary | 0x02); 1993 } else { 1994 // 32-bit immediate 1995 emit_opcode(cbuf, $primary); 1996 } 1997 %} 1998 1999 enc_class OpcSErm(rRegI dst, immI imm) 2000 %{ 2001 // OpcSEr/m 2002 int dstenc = $dst$$reg; 2003 if (dstenc >= 8) { 2004 emit_opcode(cbuf, Assembler::REX_B); 2005 dstenc -= 8; 2006 } 2007 // Emit primary opcode and set sign-extend bit 2008 // Check for 8-bit immediate, and set sign extend bit in opcode 2009 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2010 emit_opcode(cbuf, $primary | 0x02); 2011 } else { 2012 // 32-bit immediate 2013 emit_opcode(cbuf, $primary); 2014 } 2015 // Emit r/m byte with secondary opcode, after primary opcode. 2016 emit_rm(cbuf, 0x3, $secondary, dstenc); 2017 %} 2018 2019 enc_class OpcSErm_wide(rRegL dst, immI imm) 2020 %{ 2021 // OpcSEr/m 2022 int dstenc = $dst$$reg; 2023 if (dstenc < 8) { 2024 emit_opcode(cbuf, Assembler::REX_W); 2025 } else { 2026 emit_opcode(cbuf, Assembler::REX_WB); 2027 dstenc -= 8; 2028 } 2029 // Emit primary opcode and set sign-extend bit 2030 // Check for 8-bit immediate, and set sign extend bit in opcode 2031 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2032 emit_opcode(cbuf, $primary | 0x02); 2033 } else { 2034 // 32-bit immediate 2035 emit_opcode(cbuf, $primary); 2036 } 2037 // Emit r/m byte with secondary opcode, after primary opcode. 2038 emit_rm(cbuf, 0x3, $secondary, dstenc); 2039 %} 2040 2041 enc_class Con8or32(immI imm) 2042 %{ 2043 // Check for 8-bit immediate, and set sign extend bit in opcode 2044 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2045 $$$emit8$imm$$constant; 2046 } else { 2047 // 32-bit immediate 2048 $$$emit32$imm$$constant; 2049 } 2050 %} 2051 2052 enc_class opc2_reg(rRegI dst) 2053 %{ 2054 // BSWAP 2055 emit_cc(cbuf, $secondary, $dst$$reg); 2056 %} 2057 2058 enc_class opc3_reg(rRegI dst) 2059 %{ 2060 // BSWAP 2061 emit_cc(cbuf, $tertiary, $dst$$reg); 2062 %} 2063 2064 enc_class reg_opc(rRegI div) 2065 %{ 2066 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2067 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2068 %} 2069 2070 enc_class enc_cmov(cmpOp cop) 2071 %{ 2072 // CMOV 2073 $$$emit8$primary; 2074 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2075 %} 2076 2077 enc_class enc_PartialSubtypeCheck() 2078 %{ 2079 Register Rrdi = as_Register(RDI_enc); // result register 2080 Register Rrax = as_Register(RAX_enc); // super class 2081 Register Rrcx = as_Register(RCX_enc); // killed 2082 Register Rrsi = as_Register(RSI_enc); // sub class 2083 Label miss; 2084 const bool set_cond_codes = true; 2085 2086 MacroAssembler _masm(&cbuf); 2087 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2088 NULL, &miss, 2089 /*set_cond_codes:*/ true); 2090 if ($primary) { 2091 __ xorptr(Rrdi, Rrdi); 2092 } 2093 __ bind(miss); 2094 %} 2095 2096 enc_class clear_avx %{ 2097 debug_only(int off0 = cbuf.insts_size()); 2098 if (generate_vzeroupper(Compile::current())) { 2099 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2100 // Clear upper bits of YMM registers when current compiled code uses 2101 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2102 MacroAssembler _masm(&cbuf); 2103 __ vzeroupper(); 2104 } 2105 debug_only(int off1 = cbuf.insts_size()); 2106 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2107 %} 2108 2109 enc_class Java_To_Runtime(method meth) %{ 2110 // No relocation needed 2111 MacroAssembler _masm(&cbuf); 2112 __ mov64(r10, (int64_t) $meth$$method); 2113 __ call(r10); 2114 %} 2115 2116 enc_class Java_To_Interpreter(method meth) 2117 %{ 2118 // CALL Java_To_Interpreter 2119 // This is the instruction starting address for relocation info. 2120 cbuf.set_insts_mark(); 2121 $$$emit8$primary; 2122 // CALL directly to the runtime 2123 emit_d32_reloc(cbuf, 2124 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2125 runtime_call_Relocation::spec(), 2126 RELOC_DISP32); 2127 %} 2128 2129 enc_class Java_Static_Call(method meth) 2130 %{ 2131 // JAVA STATIC CALL 2132 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2133 // determine who we intended to call. 2134 cbuf.set_insts_mark(); 2135 $$$emit8$primary; 2136 2137 if (!_method) { 2138 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2139 runtime_call_Relocation::spec(), 2140 RELOC_DISP32); 2141 } else { 2142 int method_index = resolved_method_index(cbuf); 2143 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2144 : static_call_Relocation::spec(method_index); 2145 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2146 rspec, RELOC_DISP32); 2147 // Emit stubs for static call. 2148 address mark = cbuf.insts_mark(); 2149 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2150 if (stub == NULL) { 2151 ciEnv::current()->record_failure("CodeCache is full"); 2152 return; 2153 } 2154 #if INCLUDE_AOT 2155 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2156 #endif 2157 } 2158 %} 2159 2160 enc_class Java_Dynamic_Call(method meth) %{ 2161 MacroAssembler _masm(&cbuf); 2162 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2163 %} 2164 2165 enc_class Java_Compiled_Call(method meth) 2166 %{ 2167 // JAVA COMPILED CALL 2168 int disp = in_bytes(Method:: from_compiled_offset()); 2169 2170 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2171 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2172 2173 // callq *disp(%rax) 2174 cbuf.set_insts_mark(); 2175 $$$emit8$primary; 2176 if (disp < 0x80) { 2177 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2178 emit_d8(cbuf, disp); // Displacement 2179 } else { 2180 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2181 emit_d32(cbuf, disp); // Displacement 2182 } 2183 %} 2184 2185 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2186 %{ 2187 // SAL, SAR, SHR 2188 int dstenc = $dst$$reg; 2189 if (dstenc >= 8) { 2190 emit_opcode(cbuf, Assembler::REX_B); 2191 dstenc -= 8; 2192 } 2193 $$$emit8$primary; 2194 emit_rm(cbuf, 0x3, $secondary, dstenc); 2195 $$$emit8$shift$$constant; 2196 %} 2197 2198 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2199 %{ 2200 // SAL, SAR, SHR 2201 int dstenc = $dst$$reg; 2202 if (dstenc < 8) { 2203 emit_opcode(cbuf, Assembler::REX_W); 2204 } else { 2205 emit_opcode(cbuf, Assembler::REX_WB); 2206 dstenc -= 8; 2207 } 2208 $$$emit8$primary; 2209 emit_rm(cbuf, 0x3, $secondary, dstenc); 2210 $$$emit8$shift$$constant; 2211 %} 2212 2213 enc_class load_immI(rRegI dst, immI src) 2214 %{ 2215 int dstenc = $dst$$reg; 2216 if (dstenc >= 8) { 2217 emit_opcode(cbuf, Assembler::REX_B); 2218 dstenc -= 8; 2219 } 2220 emit_opcode(cbuf, 0xB8 | dstenc); 2221 $$$emit32$src$$constant; 2222 %} 2223 2224 enc_class load_immL(rRegL dst, immL src) 2225 %{ 2226 int dstenc = $dst$$reg; 2227 if (dstenc < 8) { 2228 emit_opcode(cbuf, Assembler::REX_W); 2229 } else { 2230 emit_opcode(cbuf, Assembler::REX_WB); 2231 dstenc -= 8; 2232 } 2233 emit_opcode(cbuf, 0xB8 | dstenc); 2234 emit_d64(cbuf, $src$$constant); 2235 %} 2236 2237 enc_class load_immUL32(rRegL dst, immUL32 src) 2238 %{ 2239 // same as load_immI, but this time we care about zeroes in the high word 2240 int dstenc = $dst$$reg; 2241 if (dstenc >= 8) { 2242 emit_opcode(cbuf, Assembler::REX_B); 2243 dstenc -= 8; 2244 } 2245 emit_opcode(cbuf, 0xB8 | dstenc); 2246 $$$emit32$src$$constant; 2247 %} 2248 2249 enc_class load_immL32(rRegL dst, immL32 src) 2250 %{ 2251 int dstenc = $dst$$reg; 2252 if (dstenc < 8) { 2253 emit_opcode(cbuf, Assembler::REX_W); 2254 } else { 2255 emit_opcode(cbuf, Assembler::REX_WB); 2256 dstenc -= 8; 2257 } 2258 emit_opcode(cbuf, 0xC7); 2259 emit_rm(cbuf, 0x03, 0x00, dstenc); 2260 $$$emit32$src$$constant; 2261 %} 2262 2263 enc_class load_immP31(rRegP dst, immP32 src) 2264 %{ 2265 // same as load_immI, but this time we care about zeroes in the high word 2266 int dstenc = $dst$$reg; 2267 if (dstenc >= 8) { 2268 emit_opcode(cbuf, Assembler::REX_B); 2269 dstenc -= 8; 2270 } 2271 emit_opcode(cbuf, 0xB8 | dstenc); 2272 $$$emit32$src$$constant; 2273 %} 2274 2275 enc_class load_immP(rRegP dst, immP src) 2276 %{ 2277 int dstenc = $dst$$reg; 2278 if (dstenc < 8) { 2279 emit_opcode(cbuf, Assembler::REX_W); 2280 } else { 2281 emit_opcode(cbuf, Assembler::REX_WB); 2282 dstenc -= 8; 2283 } 2284 emit_opcode(cbuf, 0xB8 | dstenc); 2285 // This next line should be generated from ADLC 2286 if ($src->constant_reloc() != relocInfo::none) { 2287 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2288 } else { 2289 emit_d64(cbuf, $src$$constant); 2290 } 2291 %} 2292 2293 enc_class Con32(immI src) 2294 %{ 2295 // Output immediate 2296 $$$emit32$src$$constant; 2297 %} 2298 2299 enc_class Con32F_as_bits(immF src) 2300 %{ 2301 // Output Float immediate bits 2302 jfloat jf = $src$$constant; 2303 jint jf_as_bits = jint_cast(jf); 2304 emit_d32(cbuf, jf_as_bits); 2305 %} 2306 2307 enc_class Con16(immI src) 2308 %{ 2309 // Output immediate 2310 $$$emit16$src$$constant; 2311 %} 2312 2313 // How is this different from Con32??? XXX 2314 enc_class Con_d32(immI src) 2315 %{ 2316 emit_d32(cbuf,$src$$constant); 2317 %} 2318 2319 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2320 // Output immediate memory reference 2321 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2322 emit_d32(cbuf, 0x00); 2323 %} 2324 2325 enc_class lock_prefix() 2326 %{ 2327 emit_opcode(cbuf, 0xF0); // lock 2328 %} 2329 2330 enc_class REX_mem(memory mem) 2331 %{ 2332 if ($mem$$base >= 8) { 2333 if ($mem$$index < 8) { 2334 emit_opcode(cbuf, Assembler::REX_B); 2335 } else { 2336 emit_opcode(cbuf, Assembler::REX_XB); 2337 } 2338 } else { 2339 if ($mem$$index >= 8) { 2340 emit_opcode(cbuf, Assembler::REX_X); 2341 } 2342 } 2343 %} 2344 2345 enc_class REX_mem_wide(memory mem) 2346 %{ 2347 if ($mem$$base >= 8) { 2348 if ($mem$$index < 8) { 2349 emit_opcode(cbuf, Assembler::REX_WB); 2350 } else { 2351 emit_opcode(cbuf, Assembler::REX_WXB); 2352 } 2353 } else { 2354 if ($mem$$index < 8) { 2355 emit_opcode(cbuf, Assembler::REX_W); 2356 } else { 2357 emit_opcode(cbuf, Assembler::REX_WX); 2358 } 2359 } 2360 %} 2361 2362 // for byte regs 2363 enc_class REX_breg(rRegI reg) 2364 %{ 2365 if ($reg$$reg >= 4) { 2366 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2367 } 2368 %} 2369 2370 // for byte regs 2371 enc_class REX_reg_breg(rRegI dst, rRegI src) 2372 %{ 2373 if ($dst$$reg < 8) { 2374 if ($src$$reg >= 4) { 2375 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2376 } 2377 } else { 2378 if ($src$$reg < 8) { 2379 emit_opcode(cbuf, Assembler::REX_R); 2380 } else { 2381 emit_opcode(cbuf, Assembler::REX_RB); 2382 } 2383 } 2384 %} 2385 2386 // for byte regs 2387 enc_class REX_breg_mem(rRegI reg, memory mem) 2388 %{ 2389 if ($reg$$reg < 8) { 2390 if ($mem$$base < 8) { 2391 if ($mem$$index >= 8) { 2392 emit_opcode(cbuf, Assembler::REX_X); 2393 } else if ($reg$$reg >= 4) { 2394 emit_opcode(cbuf, Assembler::REX); 2395 } 2396 } else { 2397 if ($mem$$index < 8) { 2398 emit_opcode(cbuf, Assembler::REX_B); 2399 } else { 2400 emit_opcode(cbuf, Assembler::REX_XB); 2401 } 2402 } 2403 } else { 2404 if ($mem$$base < 8) { 2405 if ($mem$$index < 8) { 2406 emit_opcode(cbuf, Assembler::REX_R); 2407 } else { 2408 emit_opcode(cbuf, Assembler::REX_RX); 2409 } 2410 } else { 2411 if ($mem$$index < 8) { 2412 emit_opcode(cbuf, Assembler::REX_RB); 2413 } else { 2414 emit_opcode(cbuf, Assembler::REX_RXB); 2415 } 2416 } 2417 } 2418 %} 2419 2420 enc_class REX_reg(rRegI reg) 2421 %{ 2422 if ($reg$$reg >= 8) { 2423 emit_opcode(cbuf, Assembler::REX_B); 2424 } 2425 %} 2426 2427 enc_class REX_reg_wide(rRegI reg) 2428 %{ 2429 if ($reg$$reg < 8) { 2430 emit_opcode(cbuf, Assembler::REX_W); 2431 } else { 2432 emit_opcode(cbuf, Assembler::REX_WB); 2433 } 2434 %} 2435 2436 enc_class REX_reg_reg(rRegI dst, rRegI src) 2437 %{ 2438 if ($dst$$reg < 8) { 2439 if ($src$$reg >= 8) { 2440 emit_opcode(cbuf, Assembler::REX_B); 2441 } 2442 } else { 2443 if ($src$$reg < 8) { 2444 emit_opcode(cbuf, Assembler::REX_R); 2445 } else { 2446 emit_opcode(cbuf, Assembler::REX_RB); 2447 } 2448 } 2449 %} 2450 2451 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2452 %{ 2453 if ($dst$$reg < 8) { 2454 if ($src$$reg < 8) { 2455 emit_opcode(cbuf, Assembler::REX_W); 2456 } else { 2457 emit_opcode(cbuf, Assembler::REX_WB); 2458 } 2459 } else { 2460 if ($src$$reg < 8) { 2461 emit_opcode(cbuf, Assembler::REX_WR); 2462 } else { 2463 emit_opcode(cbuf, Assembler::REX_WRB); 2464 } 2465 } 2466 %} 2467 2468 enc_class REX_reg_mem(rRegI reg, memory mem) 2469 %{ 2470 if ($reg$$reg < 8) { 2471 if ($mem$$base < 8) { 2472 if ($mem$$index >= 8) { 2473 emit_opcode(cbuf, Assembler::REX_X); 2474 } 2475 } else { 2476 if ($mem$$index < 8) { 2477 emit_opcode(cbuf, Assembler::REX_B); 2478 } else { 2479 emit_opcode(cbuf, Assembler::REX_XB); 2480 } 2481 } 2482 } else { 2483 if ($mem$$base < 8) { 2484 if ($mem$$index < 8) { 2485 emit_opcode(cbuf, Assembler::REX_R); 2486 } else { 2487 emit_opcode(cbuf, Assembler::REX_RX); 2488 } 2489 } else { 2490 if ($mem$$index < 8) { 2491 emit_opcode(cbuf, Assembler::REX_RB); 2492 } else { 2493 emit_opcode(cbuf, Assembler::REX_RXB); 2494 } 2495 } 2496 } 2497 %} 2498 2499 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2500 %{ 2501 if ($reg$$reg < 8) { 2502 if ($mem$$base < 8) { 2503 if ($mem$$index < 8) { 2504 emit_opcode(cbuf, Assembler::REX_W); 2505 } else { 2506 emit_opcode(cbuf, Assembler::REX_WX); 2507 } 2508 } else { 2509 if ($mem$$index < 8) { 2510 emit_opcode(cbuf, Assembler::REX_WB); 2511 } else { 2512 emit_opcode(cbuf, Assembler::REX_WXB); 2513 } 2514 } 2515 } else { 2516 if ($mem$$base < 8) { 2517 if ($mem$$index < 8) { 2518 emit_opcode(cbuf, Assembler::REX_WR); 2519 } else { 2520 emit_opcode(cbuf, Assembler::REX_WRX); 2521 } 2522 } else { 2523 if ($mem$$index < 8) { 2524 emit_opcode(cbuf, Assembler::REX_WRB); 2525 } else { 2526 emit_opcode(cbuf, Assembler::REX_WRXB); 2527 } 2528 } 2529 } 2530 %} 2531 2532 enc_class reg_mem(rRegI ereg, memory mem) 2533 %{ 2534 // High registers handle in encode_RegMem 2535 int reg = $ereg$$reg; 2536 int base = $mem$$base; 2537 int index = $mem$$index; 2538 int scale = $mem$$scale; 2539 int disp = $mem$$disp; 2540 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2541 2542 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2543 %} 2544 2545 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2546 %{ 2547 int rm_byte_opcode = $rm_opcode$$constant; 2548 2549 // High registers handle in encode_RegMem 2550 int base = $mem$$base; 2551 int index = $mem$$index; 2552 int scale = $mem$$scale; 2553 int displace = $mem$$disp; 2554 2555 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2556 // working with static 2557 // globals 2558 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2559 disp_reloc); 2560 %} 2561 2562 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2563 %{ 2564 int reg_encoding = $dst$$reg; 2565 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2566 int index = 0x04; // 0x04 indicates no index 2567 int scale = 0x00; // 0x00 indicates no scale 2568 int displace = $src1$$constant; // 0x00 indicates no displacement 2569 relocInfo::relocType disp_reloc = relocInfo::none; 2570 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2571 disp_reloc); 2572 %} 2573 2574 enc_class neg_reg(rRegI dst) 2575 %{ 2576 int dstenc = $dst$$reg; 2577 if (dstenc >= 8) { 2578 emit_opcode(cbuf, Assembler::REX_B); 2579 dstenc -= 8; 2580 } 2581 // NEG $dst 2582 emit_opcode(cbuf, 0xF7); 2583 emit_rm(cbuf, 0x3, 0x03, dstenc); 2584 %} 2585 2586 enc_class neg_reg_wide(rRegI dst) 2587 %{ 2588 int dstenc = $dst$$reg; 2589 if (dstenc < 8) { 2590 emit_opcode(cbuf, Assembler::REX_W); 2591 } else { 2592 emit_opcode(cbuf, Assembler::REX_WB); 2593 dstenc -= 8; 2594 } 2595 // NEG $dst 2596 emit_opcode(cbuf, 0xF7); 2597 emit_rm(cbuf, 0x3, 0x03, dstenc); 2598 %} 2599 2600 enc_class setLT_reg(rRegI dst) 2601 %{ 2602 int dstenc = $dst$$reg; 2603 if (dstenc >= 8) { 2604 emit_opcode(cbuf, Assembler::REX_B); 2605 dstenc -= 8; 2606 } else if (dstenc >= 4) { 2607 emit_opcode(cbuf, Assembler::REX); 2608 } 2609 // SETLT $dst 2610 emit_opcode(cbuf, 0x0F); 2611 emit_opcode(cbuf, 0x9C); 2612 emit_rm(cbuf, 0x3, 0x0, dstenc); 2613 %} 2614 2615 enc_class setNZ_reg(rRegI dst) 2616 %{ 2617 int dstenc = $dst$$reg; 2618 if (dstenc >= 8) { 2619 emit_opcode(cbuf, Assembler::REX_B); 2620 dstenc -= 8; 2621 } else if (dstenc >= 4) { 2622 emit_opcode(cbuf, Assembler::REX); 2623 } 2624 // SETNZ $dst 2625 emit_opcode(cbuf, 0x0F); 2626 emit_opcode(cbuf, 0x95); 2627 emit_rm(cbuf, 0x3, 0x0, dstenc); 2628 %} 2629 2630 2631 // Compare the lonogs and set -1, 0, or 1 into dst 2632 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2633 %{ 2634 int src1enc = $src1$$reg; 2635 int src2enc = $src2$$reg; 2636 int dstenc = $dst$$reg; 2637 2638 // cmpq $src1, $src2 2639 if (src1enc < 8) { 2640 if (src2enc < 8) { 2641 emit_opcode(cbuf, Assembler::REX_W); 2642 } else { 2643 emit_opcode(cbuf, Assembler::REX_WB); 2644 } 2645 } else { 2646 if (src2enc < 8) { 2647 emit_opcode(cbuf, Assembler::REX_WR); 2648 } else { 2649 emit_opcode(cbuf, Assembler::REX_WRB); 2650 } 2651 } 2652 emit_opcode(cbuf, 0x3B); 2653 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2654 2655 // movl $dst, -1 2656 if (dstenc >= 8) { 2657 emit_opcode(cbuf, Assembler::REX_B); 2658 } 2659 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2660 emit_d32(cbuf, -1); 2661 2662 // jl,s done 2663 emit_opcode(cbuf, 0x7C); 2664 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2665 2666 // setne $dst 2667 if (dstenc >= 4) { 2668 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2669 } 2670 emit_opcode(cbuf, 0x0F); 2671 emit_opcode(cbuf, 0x95); 2672 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2673 2674 // movzbl $dst, $dst 2675 if (dstenc >= 4) { 2676 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2677 } 2678 emit_opcode(cbuf, 0x0F); 2679 emit_opcode(cbuf, 0xB6); 2680 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2681 %} 2682 2683 enc_class Push_ResultXD(regD dst) %{ 2684 MacroAssembler _masm(&cbuf); 2685 __ fstp_d(Address(rsp, 0)); 2686 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2687 __ addptr(rsp, 8); 2688 %} 2689 2690 enc_class Push_SrcXD(regD src) %{ 2691 MacroAssembler _masm(&cbuf); 2692 __ subptr(rsp, 8); 2693 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2694 __ fld_d(Address(rsp, 0)); 2695 %} 2696 2697 2698 enc_class enc_rethrow() 2699 %{ 2700 cbuf.set_insts_mark(); 2701 emit_opcode(cbuf, 0xE9); // jmp entry 2702 emit_d32_reloc(cbuf, 2703 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2704 runtime_call_Relocation::spec(), 2705 RELOC_DISP32); 2706 %} 2707 2708 %} 2709 2710 2711 2712 //----------FRAME-------------------------------------------------------------- 2713 // Definition of frame structure and management information. 2714 // 2715 // S T A C K L A Y O U T Allocators stack-slot number 2716 // | (to get allocators register number 2717 // G Owned by | | v add OptoReg::stack0()) 2718 // r CALLER | | 2719 // o | +--------+ pad to even-align allocators stack-slot 2720 // w V | pad0 | numbers; owned by CALLER 2721 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2722 // h ^ | in | 5 2723 // | | args | 4 Holes in incoming args owned by SELF 2724 // | | | | 3 2725 // | | +--------+ 2726 // V | | old out| Empty on Intel, window on Sparc 2727 // | old |preserve| Must be even aligned. 2728 // | SP-+--------+----> Matcher::_old_SP, even aligned 2729 // | | in | 3 area for Intel ret address 2730 // Owned by |preserve| Empty on Sparc. 2731 // SELF +--------+ 2732 // | | pad2 | 2 pad to align old SP 2733 // | +--------+ 1 2734 // | | locks | 0 2735 // | +--------+----> OptoReg::stack0(), even aligned 2736 // | | pad1 | 11 pad to align new SP 2737 // | +--------+ 2738 // | | | 10 2739 // | | spills | 9 spills 2740 // V | | 8 (pad0 slot for callee) 2741 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2742 // ^ | out | 7 2743 // | | args | 6 Holes in outgoing args owned by CALLEE 2744 // Owned by +--------+ 2745 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2746 // | new |preserve| Must be even-aligned. 2747 // | SP-+--------+----> Matcher::_new_SP, even aligned 2748 // | | | 2749 // 2750 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2751 // known from SELF's arguments and the Java calling convention. 2752 // Region 6-7 is determined per call site. 2753 // Note 2: If the calling convention leaves holes in the incoming argument 2754 // area, those holes are owned by SELF. Holes in the outgoing area 2755 // are owned by the CALLEE. Holes should not be nessecary in the 2756 // incoming area, as the Java calling convention is completely under 2757 // the control of the AD file. Doubles can be sorted and packed to 2758 // avoid holes. Holes in the outgoing arguments may be nessecary for 2759 // varargs C calling conventions. 2760 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2761 // even aligned with pad0 as needed. 2762 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2763 // region 6-11 is even aligned; it may be padded out more so that 2764 // the region from SP to FP meets the minimum stack alignment. 2765 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2766 // alignment. Region 11, pad1, may be dynamically extended so that 2767 // SP meets the minimum alignment. 2768 2769 frame 2770 %{ 2771 // What direction does stack grow in (assumed to be same for C & Java) 2772 stack_direction(TOWARDS_LOW); 2773 2774 // These three registers define part of the calling convention 2775 // between compiled code and the interpreter. 2776 inline_cache_reg(RAX); // Inline Cache Register 2777 interpreter_method_oop_reg(RBX); // Method Oop Register when 2778 // calling interpreter 2779 2780 // Optional: name the operand used by cisc-spilling to access 2781 // [stack_pointer + offset] 2782 cisc_spilling_operand_name(indOffset32); 2783 2784 // Number of stack slots consumed by locking an object 2785 sync_stack_slots(2); 2786 2787 // Compiled code's Frame Pointer 2788 frame_pointer(RSP); 2789 2790 // Interpreter stores its frame pointer in a register which is 2791 // stored to the stack by I2CAdaptors. 2792 // I2CAdaptors convert from interpreted java to compiled java. 2793 interpreter_frame_pointer(RBP); 2794 2795 // Stack alignment requirement 2796 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2797 2798 // Number of stack slots between incoming argument block and the start of 2799 // a new frame. The PROLOG must add this many slots to the stack. The 2800 // EPILOG must remove this many slots. amd64 needs two slots for 2801 // return address. 2802 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2803 2804 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2805 // for calls to C. Supports the var-args backing area for register parms. 2806 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2807 2808 // The after-PROLOG location of the return address. Location of 2809 // return address specifies a type (REG or STACK) and a number 2810 // representing the register number (i.e. - use a register name) or 2811 // stack slot. 2812 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2813 // Otherwise, it is above the locks and verification slot and alignment word 2814 return_addr(STACK - 2 + 2815 align_up((Compile::current()->in_preserve_stack_slots() + 2816 Compile::current()->fixed_slots()), 2817 stack_alignment_in_slots())); 2818 2819 // Body of function which returns an integer array locating 2820 // arguments either in registers or in stack slots. Passed an array 2821 // of ideal registers called "sig" and a "length" count. Stack-slot 2822 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2823 // arguments for a CALLEE. Incoming stack arguments are 2824 // automatically biased by the preserve_stack_slots field above. 2825 2826 calling_convention 2827 %{ 2828 // No difference between ingoing/outgoing just pass false 2829 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2830 %} 2831 2832 c_calling_convention 2833 %{ 2834 // This is obviously always outgoing 2835 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2836 %} 2837 2838 // Location of compiled Java return values. Same as C for now. 2839 return_value 2840 %{ 2841 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2842 "only return normal values"); 2843 2844 static const int lo[Op_RegL + 1] = { 2845 0, 2846 0, 2847 RAX_num, // Op_RegN 2848 RAX_num, // Op_RegI 2849 RAX_num, // Op_RegP 2850 XMM0_num, // Op_RegF 2851 XMM0_num, // Op_RegD 2852 RAX_num // Op_RegL 2853 }; 2854 static const int hi[Op_RegL + 1] = { 2855 0, 2856 0, 2857 OptoReg::Bad, // Op_RegN 2858 OptoReg::Bad, // Op_RegI 2859 RAX_H_num, // Op_RegP 2860 OptoReg::Bad, // Op_RegF 2861 XMM0b_num, // Op_RegD 2862 RAX_H_num // Op_RegL 2863 }; 2864 // Excluded flags and vector registers. 2865 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2866 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2867 %} 2868 %} 2869 2870 //----------ATTRIBUTES--------------------------------------------------------- 2871 //----------Operand Attributes------------------------------------------------- 2872 op_attrib op_cost(0); // Required cost attribute 2873 2874 //----------Instruction Attributes--------------------------------------------- 2875 ins_attrib ins_cost(100); // Required cost attribute 2876 ins_attrib ins_size(8); // Required size attribute (in bits) 2877 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2878 // a non-matching short branch variant 2879 // of some long branch? 2880 ins_attrib ins_alignment(1); // Required alignment attribute (must 2881 // be a power of 2) specifies the 2882 // alignment that some part of the 2883 // instruction (not necessarily the 2884 // start) requires. If > 1, a 2885 // compute_padding() function must be 2886 // provided for the instruction 2887 2888 //----------OPERANDS----------------------------------------------------------- 2889 // Operand definitions must precede instruction definitions for correct parsing 2890 // in the ADLC because operands constitute user defined types which are used in 2891 // instruction definitions. 2892 2893 //----------Simple Operands---------------------------------------------------- 2894 // Immediate Operands 2895 // Integer Immediate 2896 operand immI() 2897 %{ 2898 match(ConI); 2899 2900 op_cost(10); 2901 format %{ %} 2902 interface(CONST_INTER); 2903 %} 2904 2905 // Constant for test vs zero 2906 operand immI0() 2907 %{ 2908 predicate(n->get_int() == 0); 2909 match(ConI); 2910 2911 op_cost(0); 2912 format %{ %} 2913 interface(CONST_INTER); 2914 %} 2915 2916 // Constant for increment 2917 operand immI1() 2918 %{ 2919 predicate(n->get_int() == 1); 2920 match(ConI); 2921 2922 op_cost(0); 2923 format %{ %} 2924 interface(CONST_INTER); 2925 %} 2926 2927 // Constant for decrement 2928 operand immI_M1() 2929 %{ 2930 predicate(n->get_int() == -1); 2931 match(ConI); 2932 2933 op_cost(0); 2934 format %{ %} 2935 interface(CONST_INTER); 2936 %} 2937 2938 // Valid scale values for addressing modes 2939 operand immI2() 2940 %{ 2941 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2942 match(ConI); 2943 2944 format %{ %} 2945 interface(CONST_INTER); 2946 %} 2947 2948 operand immI8() 2949 %{ 2950 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2951 match(ConI); 2952 2953 op_cost(5); 2954 format %{ %} 2955 interface(CONST_INTER); 2956 %} 2957 2958 operand immU8() 2959 %{ 2960 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2961 match(ConI); 2962 2963 op_cost(5); 2964 format %{ %} 2965 interface(CONST_INTER); 2966 %} 2967 2968 operand immI16() 2969 %{ 2970 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2971 match(ConI); 2972 2973 op_cost(10); 2974 format %{ %} 2975 interface(CONST_INTER); 2976 %} 2977 2978 // Int Immediate non-negative 2979 operand immU31() 2980 %{ 2981 predicate(n->get_int() >= 0); 2982 match(ConI); 2983 2984 op_cost(0); 2985 format %{ %} 2986 interface(CONST_INTER); 2987 %} 2988 2989 // Constant for long shifts 2990 operand immI_32() 2991 %{ 2992 predicate( n->get_int() == 32 ); 2993 match(ConI); 2994 2995 op_cost(0); 2996 format %{ %} 2997 interface(CONST_INTER); 2998 %} 2999 3000 // Constant for long shifts 3001 operand immI_64() 3002 %{ 3003 predicate( n->get_int() == 64 ); 3004 match(ConI); 3005 3006 op_cost(0); 3007 format %{ %} 3008 interface(CONST_INTER); 3009 %} 3010 3011 // Pointer Immediate 3012 operand immP() 3013 %{ 3014 match(ConP); 3015 3016 op_cost(10); 3017 format %{ %} 3018 interface(CONST_INTER); 3019 %} 3020 3021 // NULL Pointer Immediate 3022 operand immP0() 3023 %{ 3024 predicate(n->get_ptr() == 0); 3025 match(ConP); 3026 3027 op_cost(5); 3028 format %{ %} 3029 interface(CONST_INTER); 3030 %} 3031 3032 // Pointer Immediate 3033 operand immN() %{ 3034 match(ConN); 3035 3036 op_cost(10); 3037 format %{ %} 3038 interface(CONST_INTER); 3039 %} 3040 3041 operand immNKlass() %{ 3042 match(ConNKlass); 3043 3044 op_cost(10); 3045 format %{ %} 3046 interface(CONST_INTER); 3047 %} 3048 3049 // NULL Pointer Immediate 3050 operand immN0() %{ 3051 predicate(n->get_narrowcon() == 0); 3052 match(ConN); 3053 3054 op_cost(5); 3055 format %{ %} 3056 interface(CONST_INTER); 3057 %} 3058 3059 operand immP31() 3060 %{ 3061 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3062 && (n->get_ptr() >> 31) == 0); 3063 match(ConP); 3064 3065 op_cost(5); 3066 format %{ %} 3067 interface(CONST_INTER); 3068 %} 3069 3070 3071 // Long Immediate 3072 operand immL() 3073 %{ 3074 match(ConL); 3075 3076 op_cost(20); 3077 format %{ %} 3078 interface(CONST_INTER); 3079 %} 3080 3081 // Long Immediate 8-bit 3082 operand immL8() 3083 %{ 3084 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3085 match(ConL); 3086 3087 op_cost(5); 3088 format %{ %} 3089 interface(CONST_INTER); 3090 %} 3091 3092 // Long Immediate 32-bit unsigned 3093 operand immUL32() 3094 %{ 3095 predicate(n->get_long() == (unsigned int) (n->get_long())); 3096 match(ConL); 3097 3098 op_cost(10); 3099 format %{ %} 3100 interface(CONST_INTER); 3101 %} 3102 3103 // Long Immediate 32-bit signed 3104 operand immL32() 3105 %{ 3106 predicate(n->get_long() == (int) (n->get_long())); 3107 match(ConL); 3108 3109 op_cost(15); 3110 format %{ %} 3111 interface(CONST_INTER); 3112 %} 3113 3114 // Long Immediate zero 3115 operand immL0() 3116 %{ 3117 predicate(n->get_long() == 0L); 3118 match(ConL); 3119 3120 op_cost(10); 3121 format %{ %} 3122 interface(CONST_INTER); 3123 %} 3124 3125 // Constant for increment 3126 operand immL1() 3127 %{ 3128 predicate(n->get_long() == 1); 3129 match(ConL); 3130 3131 format %{ %} 3132 interface(CONST_INTER); 3133 %} 3134 3135 // Constant for decrement 3136 operand immL_M1() 3137 %{ 3138 predicate(n->get_long() == -1); 3139 match(ConL); 3140 3141 format %{ %} 3142 interface(CONST_INTER); 3143 %} 3144 3145 // Long Immediate: the value 10 3146 operand immL10() 3147 %{ 3148 predicate(n->get_long() == 10); 3149 match(ConL); 3150 3151 format %{ %} 3152 interface(CONST_INTER); 3153 %} 3154 3155 // Long immediate from 0 to 127. 3156 // Used for a shorter form of long mul by 10. 3157 operand immL_127() 3158 %{ 3159 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3160 match(ConL); 3161 3162 op_cost(10); 3163 format %{ %} 3164 interface(CONST_INTER); 3165 %} 3166 3167 // Long Immediate: low 32-bit mask 3168 operand immL_32bits() 3169 %{ 3170 predicate(n->get_long() == 0xFFFFFFFFL); 3171 match(ConL); 3172 op_cost(20); 3173 3174 format %{ %} 3175 interface(CONST_INTER); 3176 %} 3177 3178 // Float Immediate zero 3179 operand immF0() 3180 %{ 3181 predicate(jint_cast(n->getf()) == 0); 3182 match(ConF); 3183 3184 op_cost(5); 3185 format %{ %} 3186 interface(CONST_INTER); 3187 %} 3188 3189 // Float Immediate 3190 operand immF() 3191 %{ 3192 match(ConF); 3193 3194 op_cost(15); 3195 format %{ %} 3196 interface(CONST_INTER); 3197 %} 3198 3199 // Double Immediate zero 3200 operand immD0() 3201 %{ 3202 predicate(jlong_cast(n->getd()) == 0); 3203 match(ConD); 3204 3205 op_cost(5); 3206 format %{ %} 3207 interface(CONST_INTER); 3208 %} 3209 3210 // Double Immediate 3211 operand immD() 3212 %{ 3213 match(ConD); 3214 3215 op_cost(15); 3216 format %{ %} 3217 interface(CONST_INTER); 3218 %} 3219 3220 // Immediates for special shifts (sign extend) 3221 3222 // Constants for increment 3223 operand immI_16() 3224 %{ 3225 predicate(n->get_int() == 16); 3226 match(ConI); 3227 3228 format %{ %} 3229 interface(CONST_INTER); 3230 %} 3231 3232 operand immI_24() 3233 %{ 3234 predicate(n->get_int() == 24); 3235 match(ConI); 3236 3237 format %{ %} 3238 interface(CONST_INTER); 3239 %} 3240 3241 // Constant for byte-wide masking 3242 operand immI_255() 3243 %{ 3244 predicate(n->get_int() == 255); 3245 match(ConI); 3246 3247 format %{ %} 3248 interface(CONST_INTER); 3249 %} 3250 3251 // Constant for short-wide masking 3252 operand immI_65535() 3253 %{ 3254 predicate(n->get_int() == 65535); 3255 match(ConI); 3256 3257 format %{ %} 3258 interface(CONST_INTER); 3259 %} 3260 3261 // Constant for byte-wide masking 3262 operand immL_255() 3263 %{ 3264 predicate(n->get_long() == 255); 3265 match(ConL); 3266 3267 format %{ %} 3268 interface(CONST_INTER); 3269 %} 3270 3271 // Constant for short-wide masking 3272 operand immL_65535() 3273 %{ 3274 predicate(n->get_long() == 65535); 3275 match(ConL); 3276 3277 format %{ %} 3278 interface(CONST_INTER); 3279 %} 3280 3281 // Register Operands 3282 // Integer Register 3283 operand rRegI() 3284 %{ 3285 constraint(ALLOC_IN_RC(int_reg)); 3286 match(RegI); 3287 3288 match(rax_RegI); 3289 match(rbx_RegI); 3290 match(rcx_RegI); 3291 match(rdx_RegI); 3292 match(rdi_RegI); 3293 3294 format %{ %} 3295 interface(REG_INTER); 3296 %} 3297 3298 // Special Registers 3299 operand rax_RegI() 3300 %{ 3301 constraint(ALLOC_IN_RC(int_rax_reg)); 3302 match(RegI); 3303 match(rRegI); 3304 3305 format %{ "RAX" %} 3306 interface(REG_INTER); 3307 %} 3308 3309 // Special Registers 3310 operand rbx_RegI() 3311 %{ 3312 constraint(ALLOC_IN_RC(int_rbx_reg)); 3313 match(RegI); 3314 match(rRegI); 3315 3316 format %{ "RBX" %} 3317 interface(REG_INTER); 3318 %} 3319 3320 operand rcx_RegI() 3321 %{ 3322 constraint(ALLOC_IN_RC(int_rcx_reg)); 3323 match(RegI); 3324 match(rRegI); 3325 3326 format %{ "RCX" %} 3327 interface(REG_INTER); 3328 %} 3329 3330 operand rdx_RegI() 3331 %{ 3332 constraint(ALLOC_IN_RC(int_rdx_reg)); 3333 match(RegI); 3334 match(rRegI); 3335 3336 format %{ "RDX" %} 3337 interface(REG_INTER); 3338 %} 3339 3340 operand rdi_RegI() 3341 %{ 3342 constraint(ALLOC_IN_RC(int_rdi_reg)); 3343 match(RegI); 3344 match(rRegI); 3345 3346 format %{ "RDI" %} 3347 interface(REG_INTER); 3348 %} 3349 3350 operand no_rcx_RegI() 3351 %{ 3352 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3353 match(RegI); 3354 match(rax_RegI); 3355 match(rbx_RegI); 3356 match(rdx_RegI); 3357 match(rdi_RegI); 3358 3359 format %{ %} 3360 interface(REG_INTER); 3361 %} 3362 3363 operand no_rax_rdx_RegI() 3364 %{ 3365 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3366 match(RegI); 3367 match(rbx_RegI); 3368 match(rcx_RegI); 3369 match(rdi_RegI); 3370 3371 format %{ %} 3372 interface(REG_INTER); 3373 %} 3374 3375 // Pointer Register 3376 operand any_RegP() 3377 %{ 3378 constraint(ALLOC_IN_RC(any_reg)); 3379 match(RegP); 3380 match(rax_RegP); 3381 match(rbx_RegP); 3382 match(rdi_RegP); 3383 match(rsi_RegP); 3384 match(rbp_RegP); 3385 match(r15_RegP); 3386 match(rRegP); 3387 3388 format %{ %} 3389 interface(REG_INTER); 3390 %} 3391 3392 operand rRegP() 3393 %{ 3394 constraint(ALLOC_IN_RC(ptr_reg)); 3395 match(RegP); 3396 match(rax_RegP); 3397 match(rbx_RegP); 3398 match(rdi_RegP); 3399 match(rsi_RegP); 3400 match(rbp_RegP); // See Q&A below about 3401 match(r15_RegP); // r15_RegP and rbp_RegP. 3402 3403 format %{ %} 3404 interface(REG_INTER); 3405 %} 3406 3407 operand rRegN() %{ 3408 constraint(ALLOC_IN_RC(int_reg)); 3409 match(RegN); 3410 3411 format %{ %} 3412 interface(REG_INTER); 3413 %} 3414 3415 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3416 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3417 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3418 // The output of an instruction is controlled by the allocator, which respects 3419 // register class masks, not match rules. Unless an instruction mentions 3420 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3421 // by the allocator as an input. 3422 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3423 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3424 // result, RBP is not included in the output of the instruction either. 3425 3426 operand no_rax_RegP() 3427 %{ 3428 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3429 match(RegP); 3430 match(rbx_RegP); 3431 match(rsi_RegP); 3432 match(rdi_RegP); 3433 3434 format %{ %} 3435 interface(REG_INTER); 3436 %} 3437 3438 // This operand is not allowed to use RBP even if 3439 // RBP is not used to hold the frame pointer. 3440 operand no_rbp_RegP() 3441 %{ 3442 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3443 match(RegP); 3444 match(rbx_RegP); 3445 match(rsi_RegP); 3446 match(rdi_RegP); 3447 3448 format %{ %} 3449 interface(REG_INTER); 3450 %} 3451 3452 operand no_rax_rbx_RegP() 3453 %{ 3454 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3455 match(RegP); 3456 match(rsi_RegP); 3457 match(rdi_RegP); 3458 3459 format %{ %} 3460 interface(REG_INTER); 3461 %} 3462 3463 // Special Registers 3464 // Return a pointer value 3465 operand rax_RegP() 3466 %{ 3467 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3468 match(RegP); 3469 match(rRegP); 3470 3471 format %{ %} 3472 interface(REG_INTER); 3473 %} 3474 3475 // Special Registers 3476 // Return a compressed pointer value 3477 operand rax_RegN() 3478 %{ 3479 constraint(ALLOC_IN_RC(int_rax_reg)); 3480 match(RegN); 3481 match(rRegN); 3482 3483 format %{ %} 3484 interface(REG_INTER); 3485 %} 3486 3487 // Used in AtomicAdd 3488 operand rbx_RegP() 3489 %{ 3490 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3491 match(RegP); 3492 match(rRegP); 3493 3494 format %{ %} 3495 interface(REG_INTER); 3496 %} 3497 3498 operand rsi_RegP() 3499 %{ 3500 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3501 match(RegP); 3502 match(rRegP); 3503 3504 format %{ %} 3505 interface(REG_INTER); 3506 %} 3507 3508 // Used in rep stosq 3509 operand rdi_RegP() 3510 %{ 3511 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3512 match(RegP); 3513 match(rRegP); 3514 3515 format %{ %} 3516 interface(REG_INTER); 3517 %} 3518 3519 operand r15_RegP() 3520 %{ 3521 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3522 match(RegP); 3523 match(rRegP); 3524 3525 format %{ %} 3526 interface(REG_INTER); 3527 %} 3528 3529 operand rRegL() 3530 %{ 3531 constraint(ALLOC_IN_RC(long_reg)); 3532 match(RegL); 3533 match(rax_RegL); 3534 match(rdx_RegL); 3535 3536 format %{ %} 3537 interface(REG_INTER); 3538 %} 3539 3540 // Special Registers 3541 operand no_rax_rdx_RegL() 3542 %{ 3543 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3544 match(RegL); 3545 match(rRegL); 3546 3547 format %{ %} 3548 interface(REG_INTER); 3549 %} 3550 3551 operand no_rax_RegL() 3552 %{ 3553 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3554 match(RegL); 3555 match(rRegL); 3556 match(rdx_RegL); 3557 3558 format %{ %} 3559 interface(REG_INTER); 3560 %} 3561 3562 operand no_rcx_RegL() 3563 %{ 3564 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3565 match(RegL); 3566 match(rRegL); 3567 3568 format %{ %} 3569 interface(REG_INTER); 3570 %} 3571 3572 operand rax_RegL() 3573 %{ 3574 constraint(ALLOC_IN_RC(long_rax_reg)); 3575 match(RegL); 3576 match(rRegL); 3577 3578 format %{ "RAX" %} 3579 interface(REG_INTER); 3580 %} 3581 3582 operand rcx_RegL() 3583 %{ 3584 constraint(ALLOC_IN_RC(long_rcx_reg)); 3585 match(RegL); 3586 match(rRegL); 3587 3588 format %{ %} 3589 interface(REG_INTER); 3590 %} 3591 3592 operand rdx_RegL() 3593 %{ 3594 constraint(ALLOC_IN_RC(long_rdx_reg)); 3595 match(RegL); 3596 match(rRegL); 3597 3598 format %{ %} 3599 interface(REG_INTER); 3600 %} 3601 3602 // Flags register, used as output of compare instructions 3603 operand rFlagsReg() 3604 %{ 3605 constraint(ALLOC_IN_RC(int_flags)); 3606 match(RegFlags); 3607 3608 format %{ "RFLAGS" %} 3609 interface(REG_INTER); 3610 %} 3611 3612 // Flags register, used as output of FLOATING POINT compare instructions 3613 operand rFlagsRegU() 3614 %{ 3615 constraint(ALLOC_IN_RC(int_flags)); 3616 match(RegFlags); 3617 3618 format %{ "RFLAGS_U" %} 3619 interface(REG_INTER); 3620 %} 3621 3622 operand rFlagsRegUCF() %{ 3623 constraint(ALLOC_IN_RC(int_flags)); 3624 match(RegFlags); 3625 predicate(false); 3626 3627 format %{ "RFLAGS_U_CF" %} 3628 interface(REG_INTER); 3629 %} 3630 3631 // Float register operands 3632 operand regF() %{ 3633 constraint(ALLOC_IN_RC(float_reg)); 3634 match(RegF); 3635 3636 format %{ %} 3637 interface(REG_INTER); 3638 %} 3639 3640 // Float register operands 3641 operand legRegF() %{ 3642 constraint(ALLOC_IN_RC(float_reg_legacy)); 3643 match(RegF); 3644 3645 format %{ %} 3646 interface(REG_INTER); 3647 %} 3648 3649 // Float register operands 3650 operand vlRegF() %{ 3651 constraint(ALLOC_IN_RC(float_reg_vl)); 3652 match(RegF); 3653 3654 format %{ %} 3655 interface(REG_INTER); 3656 %} 3657 3658 // Double register operands 3659 operand regD() %{ 3660 constraint(ALLOC_IN_RC(double_reg)); 3661 match(RegD); 3662 3663 format %{ %} 3664 interface(REG_INTER); 3665 %} 3666 3667 // Double register operands 3668 operand legRegD() %{ 3669 constraint(ALLOC_IN_RC(double_reg_legacy)); 3670 match(RegD); 3671 3672 format %{ %} 3673 interface(REG_INTER); 3674 %} 3675 3676 // Double register operands 3677 operand vlRegD() %{ 3678 constraint(ALLOC_IN_RC(double_reg_vl)); 3679 match(RegD); 3680 3681 format %{ %} 3682 interface(REG_INTER); 3683 %} 3684 3685 // Vectors 3686 operand vecS() %{ 3687 constraint(ALLOC_IN_RC(vectors_reg_vlbwdq)); 3688 match(VecS); 3689 3690 format %{ %} 3691 interface(REG_INTER); 3692 %} 3693 3694 // Vectors 3695 operand legVecS() %{ 3696 constraint(ALLOC_IN_RC(vectors_reg_legacy)); 3697 match(VecS); 3698 3699 format %{ %} 3700 interface(REG_INTER); 3701 %} 3702 3703 operand vecD() %{ 3704 constraint(ALLOC_IN_RC(vectord_reg_vlbwdq)); 3705 match(VecD); 3706 3707 format %{ %} 3708 interface(REG_INTER); 3709 %} 3710 3711 operand legVecD() %{ 3712 constraint(ALLOC_IN_RC(vectord_reg_legacy)); 3713 match(VecD); 3714 3715 format %{ %} 3716 interface(REG_INTER); 3717 %} 3718 3719 operand vecX() %{ 3720 constraint(ALLOC_IN_RC(vectorx_reg_vlbwdq)); 3721 match(VecX); 3722 3723 format %{ %} 3724 interface(REG_INTER); 3725 %} 3726 3727 operand legVecX() %{ 3728 constraint(ALLOC_IN_RC(vectorx_reg_legacy)); 3729 match(VecX); 3730 3731 format %{ %} 3732 interface(REG_INTER); 3733 %} 3734 3735 operand vecY() %{ 3736 constraint(ALLOC_IN_RC(vectory_reg_vlbwdq)); 3737 match(VecY); 3738 3739 format %{ %} 3740 interface(REG_INTER); 3741 %} 3742 3743 operand legVecY() %{ 3744 constraint(ALLOC_IN_RC(vectory_reg_legacy)); 3745 match(VecY); 3746 3747 format %{ %} 3748 interface(REG_INTER); 3749 %} 3750 3751 //----------Memory Operands---------------------------------------------------- 3752 // Direct Memory Operand 3753 // operand direct(immP addr) 3754 // %{ 3755 // match(addr); 3756 3757 // format %{ "[$addr]" %} 3758 // interface(MEMORY_INTER) %{ 3759 // base(0xFFFFFFFF); 3760 // index(0x4); 3761 // scale(0x0); 3762 // disp($addr); 3763 // %} 3764 // %} 3765 3766 // Indirect Memory Operand 3767 operand indirect(any_RegP reg) 3768 %{ 3769 constraint(ALLOC_IN_RC(ptr_reg)); 3770 match(reg); 3771 3772 format %{ "[$reg]" %} 3773 interface(MEMORY_INTER) %{ 3774 base($reg); 3775 index(0x4); 3776 scale(0x0); 3777 disp(0x0); 3778 %} 3779 %} 3780 3781 // Indirect Memory Plus Short Offset Operand 3782 operand indOffset8(any_RegP reg, immL8 off) 3783 %{ 3784 constraint(ALLOC_IN_RC(ptr_reg)); 3785 match(AddP reg off); 3786 3787 format %{ "[$reg + $off (8-bit)]" %} 3788 interface(MEMORY_INTER) %{ 3789 base($reg); 3790 index(0x4); 3791 scale(0x0); 3792 disp($off); 3793 %} 3794 %} 3795 3796 // Indirect Memory Plus Long Offset Operand 3797 operand indOffset32(any_RegP reg, immL32 off) 3798 %{ 3799 constraint(ALLOC_IN_RC(ptr_reg)); 3800 match(AddP reg off); 3801 3802 format %{ "[$reg + $off (32-bit)]" %} 3803 interface(MEMORY_INTER) %{ 3804 base($reg); 3805 index(0x4); 3806 scale(0x0); 3807 disp($off); 3808 %} 3809 %} 3810 3811 // Indirect Memory Plus Index Register Plus Offset Operand 3812 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3813 %{ 3814 constraint(ALLOC_IN_RC(ptr_reg)); 3815 match(AddP (AddP reg lreg) off); 3816 3817 op_cost(10); 3818 format %{"[$reg + $off + $lreg]" %} 3819 interface(MEMORY_INTER) %{ 3820 base($reg); 3821 index($lreg); 3822 scale(0x0); 3823 disp($off); 3824 %} 3825 %} 3826 3827 // Indirect Memory Plus Index Register Plus Offset Operand 3828 operand indIndex(any_RegP reg, rRegL lreg) 3829 %{ 3830 constraint(ALLOC_IN_RC(ptr_reg)); 3831 match(AddP reg lreg); 3832 3833 op_cost(10); 3834 format %{"[$reg + $lreg]" %} 3835 interface(MEMORY_INTER) %{ 3836 base($reg); 3837 index($lreg); 3838 scale(0x0); 3839 disp(0x0); 3840 %} 3841 %} 3842 3843 // Indirect Memory Times Scale Plus Index Register 3844 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3845 %{ 3846 constraint(ALLOC_IN_RC(ptr_reg)); 3847 match(AddP reg (LShiftL lreg scale)); 3848 3849 op_cost(10); 3850 format %{"[$reg + $lreg << $scale]" %} 3851 interface(MEMORY_INTER) %{ 3852 base($reg); 3853 index($lreg); 3854 scale($scale); 3855 disp(0x0); 3856 %} 3857 %} 3858 3859 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3860 %{ 3861 constraint(ALLOC_IN_RC(ptr_reg)); 3862 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3863 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3864 3865 op_cost(10); 3866 format %{"[$reg + pos $idx << $scale]" %} 3867 interface(MEMORY_INTER) %{ 3868 base($reg); 3869 index($idx); 3870 scale($scale); 3871 disp(0x0); 3872 %} 3873 %} 3874 3875 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3876 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3877 %{ 3878 constraint(ALLOC_IN_RC(ptr_reg)); 3879 match(AddP (AddP reg (LShiftL lreg scale)) off); 3880 3881 op_cost(10); 3882 format %{"[$reg + $off + $lreg << $scale]" %} 3883 interface(MEMORY_INTER) %{ 3884 base($reg); 3885 index($lreg); 3886 scale($scale); 3887 disp($off); 3888 %} 3889 %} 3890 3891 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3892 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3893 %{ 3894 constraint(ALLOC_IN_RC(ptr_reg)); 3895 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3896 match(AddP (AddP reg (ConvI2L idx)) off); 3897 3898 op_cost(10); 3899 format %{"[$reg + $off + $idx]" %} 3900 interface(MEMORY_INTER) %{ 3901 base($reg); 3902 index($idx); 3903 scale(0x0); 3904 disp($off); 3905 %} 3906 %} 3907 3908 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3909 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3910 %{ 3911 constraint(ALLOC_IN_RC(ptr_reg)); 3912 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3913 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3914 3915 op_cost(10); 3916 format %{"[$reg + $off + $idx << $scale]" %} 3917 interface(MEMORY_INTER) %{ 3918 base($reg); 3919 index($idx); 3920 scale($scale); 3921 disp($off); 3922 %} 3923 %} 3924 3925 // Indirect Narrow Oop Plus Offset Operand 3926 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3927 // we can't free r12 even with CompressedOops::base() == NULL. 3928 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3929 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3930 constraint(ALLOC_IN_RC(ptr_reg)); 3931 match(AddP (DecodeN reg) off); 3932 3933 op_cost(10); 3934 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3935 interface(MEMORY_INTER) %{ 3936 base(0xc); // R12 3937 index($reg); 3938 scale(0x3); 3939 disp($off); 3940 %} 3941 %} 3942 3943 // Indirect Memory Operand 3944 operand indirectNarrow(rRegN reg) 3945 %{ 3946 predicate(CompressedOops::shift() == 0); 3947 constraint(ALLOC_IN_RC(ptr_reg)); 3948 match(DecodeN reg); 3949 3950 format %{ "[$reg]" %} 3951 interface(MEMORY_INTER) %{ 3952 base($reg); 3953 index(0x4); 3954 scale(0x0); 3955 disp(0x0); 3956 %} 3957 %} 3958 3959 // Indirect Memory Plus Short Offset Operand 3960 operand indOffset8Narrow(rRegN reg, immL8 off) 3961 %{ 3962 predicate(CompressedOops::shift() == 0); 3963 constraint(ALLOC_IN_RC(ptr_reg)); 3964 match(AddP (DecodeN reg) off); 3965 3966 format %{ "[$reg + $off (8-bit)]" %} 3967 interface(MEMORY_INTER) %{ 3968 base($reg); 3969 index(0x4); 3970 scale(0x0); 3971 disp($off); 3972 %} 3973 %} 3974 3975 // Indirect Memory Plus Long Offset Operand 3976 operand indOffset32Narrow(rRegN reg, immL32 off) 3977 %{ 3978 predicate(CompressedOops::shift() == 0); 3979 constraint(ALLOC_IN_RC(ptr_reg)); 3980 match(AddP (DecodeN reg) off); 3981 3982 format %{ "[$reg + $off (32-bit)]" %} 3983 interface(MEMORY_INTER) %{ 3984 base($reg); 3985 index(0x4); 3986 scale(0x0); 3987 disp($off); 3988 %} 3989 %} 3990 3991 // Indirect Memory Plus Index Register Plus Offset Operand 3992 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3993 %{ 3994 predicate(CompressedOops::shift() == 0); 3995 constraint(ALLOC_IN_RC(ptr_reg)); 3996 match(AddP (AddP (DecodeN reg) lreg) off); 3997 3998 op_cost(10); 3999 format %{"[$reg + $off + $lreg]" %} 4000 interface(MEMORY_INTER) %{ 4001 base($reg); 4002 index($lreg); 4003 scale(0x0); 4004 disp($off); 4005 %} 4006 %} 4007 4008 // Indirect Memory Plus Index Register Plus Offset Operand 4009 operand indIndexNarrow(rRegN reg, rRegL lreg) 4010 %{ 4011 predicate(CompressedOops::shift() == 0); 4012 constraint(ALLOC_IN_RC(ptr_reg)); 4013 match(AddP (DecodeN reg) lreg); 4014 4015 op_cost(10); 4016 format %{"[$reg + $lreg]" %} 4017 interface(MEMORY_INTER) %{ 4018 base($reg); 4019 index($lreg); 4020 scale(0x0); 4021 disp(0x0); 4022 %} 4023 %} 4024 4025 // Indirect Memory Times Scale Plus Index Register 4026 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4027 %{ 4028 predicate(CompressedOops::shift() == 0); 4029 constraint(ALLOC_IN_RC(ptr_reg)); 4030 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4031 4032 op_cost(10); 4033 format %{"[$reg + $lreg << $scale]" %} 4034 interface(MEMORY_INTER) %{ 4035 base($reg); 4036 index($lreg); 4037 scale($scale); 4038 disp(0x0); 4039 %} 4040 %} 4041 4042 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4043 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4044 %{ 4045 predicate(CompressedOops::shift() == 0); 4046 constraint(ALLOC_IN_RC(ptr_reg)); 4047 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4048 4049 op_cost(10); 4050 format %{"[$reg + $off + $lreg << $scale]" %} 4051 interface(MEMORY_INTER) %{ 4052 base($reg); 4053 index($lreg); 4054 scale($scale); 4055 disp($off); 4056 %} 4057 %} 4058 4059 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4060 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4061 %{ 4062 constraint(ALLOC_IN_RC(ptr_reg)); 4063 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4064 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4065 4066 op_cost(10); 4067 format %{"[$reg + $off + $idx]" %} 4068 interface(MEMORY_INTER) %{ 4069 base($reg); 4070 index($idx); 4071 scale(0x0); 4072 disp($off); 4073 %} 4074 %} 4075 4076 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4077 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4078 %{ 4079 constraint(ALLOC_IN_RC(ptr_reg)); 4080 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4081 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4082 4083 op_cost(10); 4084 format %{"[$reg + $off + $idx << $scale]" %} 4085 interface(MEMORY_INTER) %{ 4086 base($reg); 4087 index($idx); 4088 scale($scale); 4089 disp($off); 4090 %} 4091 %} 4092 4093 //----------Special Memory Operands-------------------------------------------- 4094 // Stack Slot Operand - This operand is used for loading and storing temporary 4095 // values on the stack where a match requires a value to 4096 // flow through memory. 4097 operand stackSlotP(sRegP reg) 4098 %{ 4099 constraint(ALLOC_IN_RC(stack_slots)); 4100 // No match rule because this operand is only generated in matching 4101 4102 format %{ "[$reg]" %} 4103 interface(MEMORY_INTER) %{ 4104 base(0x4); // RSP 4105 index(0x4); // No Index 4106 scale(0x0); // No Scale 4107 disp($reg); // Stack Offset 4108 %} 4109 %} 4110 4111 operand stackSlotI(sRegI reg) 4112 %{ 4113 constraint(ALLOC_IN_RC(stack_slots)); 4114 // No match rule because this operand is only generated in matching 4115 4116 format %{ "[$reg]" %} 4117 interface(MEMORY_INTER) %{ 4118 base(0x4); // RSP 4119 index(0x4); // No Index 4120 scale(0x0); // No Scale 4121 disp($reg); // Stack Offset 4122 %} 4123 %} 4124 4125 operand stackSlotF(sRegF reg) 4126 %{ 4127 constraint(ALLOC_IN_RC(stack_slots)); 4128 // No match rule because this operand is only generated in matching 4129 4130 format %{ "[$reg]" %} 4131 interface(MEMORY_INTER) %{ 4132 base(0x4); // RSP 4133 index(0x4); // No Index 4134 scale(0x0); // No Scale 4135 disp($reg); // Stack Offset 4136 %} 4137 %} 4138 4139 operand stackSlotD(sRegD reg) 4140 %{ 4141 constraint(ALLOC_IN_RC(stack_slots)); 4142 // No match rule because this operand is only generated in matching 4143 4144 format %{ "[$reg]" %} 4145 interface(MEMORY_INTER) %{ 4146 base(0x4); // RSP 4147 index(0x4); // No Index 4148 scale(0x0); // No Scale 4149 disp($reg); // Stack Offset 4150 %} 4151 %} 4152 operand stackSlotL(sRegL reg) 4153 %{ 4154 constraint(ALLOC_IN_RC(stack_slots)); 4155 // No match rule because this operand is only generated in matching 4156 4157 format %{ "[$reg]" %} 4158 interface(MEMORY_INTER) %{ 4159 base(0x4); // RSP 4160 index(0x4); // No Index 4161 scale(0x0); // No Scale 4162 disp($reg); // Stack Offset 4163 %} 4164 %} 4165 4166 //----------Conditional Branch Operands---------------------------------------- 4167 // Comparison Op - This is the operation of the comparison, and is limited to 4168 // the following set of codes: 4169 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4170 // 4171 // Other attributes of the comparison, such as unsignedness, are specified 4172 // by the comparison instruction that sets a condition code flags register. 4173 // That result is represented by a flags operand whose subtype is appropriate 4174 // to the unsignedness (etc.) of the comparison. 4175 // 4176 // Later, the instruction which matches both the Comparison Op (a Bool) and 4177 // the flags (produced by the Cmp) specifies the coding of the comparison op 4178 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4179 4180 // Comparision Code 4181 operand cmpOp() 4182 %{ 4183 match(Bool); 4184 4185 format %{ "" %} 4186 interface(COND_INTER) %{ 4187 equal(0x4, "e"); 4188 not_equal(0x5, "ne"); 4189 less(0xC, "l"); 4190 greater_equal(0xD, "ge"); 4191 less_equal(0xE, "le"); 4192 greater(0xF, "g"); 4193 overflow(0x0, "o"); 4194 no_overflow(0x1, "no"); 4195 %} 4196 %} 4197 4198 // Comparison Code, unsigned compare. Used by FP also, with 4199 // C2 (unordered) turned into GT or LT already. The other bits 4200 // C0 and C3 are turned into Carry & Zero flags. 4201 operand cmpOpU() 4202 %{ 4203 match(Bool); 4204 4205 format %{ "" %} 4206 interface(COND_INTER) %{ 4207 equal(0x4, "e"); 4208 not_equal(0x5, "ne"); 4209 less(0x2, "b"); 4210 greater_equal(0x3, "nb"); 4211 less_equal(0x6, "be"); 4212 greater(0x7, "nbe"); 4213 overflow(0x0, "o"); 4214 no_overflow(0x1, "no"); 4215 %} 4216 %} 4217 4218 4219 // Floating comparisons that don't require any fixup for the unordered case 4220 operand cmpOpUCF() %{ 4221 match(Bool); 4222 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4223 n->as_Bool()->_test._test == BoolTest::ge || 4224 n->as_Bool()->_test._test == BoolTest::le || 4225 n->as_Bool()->_test._test == BoolTest::gt); 4226 format %{ "" %} 4227 interface(COND_INTER) %{ 4228 equal(0x4, "e"); 4229 not_equal(0x5, "ne"); 4230 less(0x2, "b"); 4231 greater_equal(0x3, "nb"); 4232 less_equal(0x6, "be"); 4233 greater(0x7, "nbe"); 4234 overflow(0x0, "o"); 4235 no_overflow(0x1, "no"); 4236 %} 4237 %} 4238 4239 4240 // Floating comparisons that can be fixed up with extra conditional jumps 4241 operand cmpOpUCF2() %{ 4242 match(Bool); 4243 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4244 n->as_Bool()->_test._test == BoolTest::eq); 4245 format %{ "" %} 4246 interface(COND_INTER) %{ 4247 equal(0x4, "e"); 4248 not_equal(0x5, "ne"); 4249 less(0x2, "b"); 4250 greater_equal(0x3, "nb"); 4251 less_equal(0x6, "be"); 4252 greater(0x7, "nbe"); 4253 overflow(0x0, "o"); 4254 no_overflow(0x1, "no"); 4255 %} 4256 %} 4257 4258 // Operands for bound floating pointer register arguments 4259 operand rxmm0() %{ 4260 constraint(ALLOC_IN_RC(xmm0_reg)); 4261 match(VecX); 4262 format%{%} 4263 interface(REG_INTER); 4264 %} 4265 operand rxmm1() %{ 4266 constraint(ALLOC_IN_RC(xmm1_reg)); 4267 match(VecX); 4268 format%{%} 4269 interface(REG_INTER); 4270 %} 4271 operand rxmm2() %{ 4272 constraint(ALLOC_IN_RC(xmm2_reg)); 4273 match(VecX); 4274 format%{%} 4275 interface(REG_INTER); 4276 %} 4277 operand rxmm3() %{ 4278 constraint(ALLOC_IN_RC(xmm3_reg)); 4279 match(VecX); 4280 format%{%} 4281 interface(REG_INTER); 4282 %} 4283 operand rxmm4() %{ 4284 constraint(ALLOC_IN_RC(xmm4_reg)); 4285 match(VecX); 4286 format%{%} 4287 interface(REG_INTER); 4288 %} 4289 operand rxmm5() %{ 4290 constraint(ALLOC_IN_RC(xmm5_reg)); 4291 match(VecX); 4292 format%{%} 4293 interface(REG_INTER); 4294 %} 4295 operand rxmm6() %{ 4296 constraint(ALLOC_IN_RC(xmm6_reg)); 4297 match(VecX); 4298 format%{%} 4299 interface(REG_INTER); 4300 %} 4301 operand rxmm7() %{ 4302 constraint(ALLOC_IN_RC(xmm7_reg)); 4303 match(VecX); 4304 format%{%} 4305 interface(REG_INTER); 4306 %} 4307 operand rxmm8() %{ 4308 constraint(ALLOC_IN_RC(xmm8_reg)); 4309 match(VecX); 4310 format%{%} 4311 interface(REG_INTER); 4312 %} 4313 operand rxmm9() %{ 4314 constraint(ALLOC_IN_RC(xmm9_reg)); 4315 match(VecX); 4316 format%{%} 4317 interface(REG_INTER); 4318 %} 4319 operand rxmm10() %{ 4320 constraint(ALLOC_IN_RC(xmm10_reg)); 4321 match(VecX); 4322 format%{%} 4323 interface(REG_INTER); 4324 %} 4325 operand rxmm11() %{ 4326 constraint(ALLOC_IN_RC(xmm11_reg)); 4327 match(VecX); 4328 format%{%} 4329 interface(REG_INTER); 4330 %} 4331 operand rxmm12() %{ 4332 constraint(ALLOC_IN_RC(xmm12_reg)); 4333 match(VecX); 4334 format%{%} 4335 interface(REG_INTER); 4336 %} 4337 operand rxmm13() %{ 4338 constraint(ALLOC_IN_RC(xmm13_reg)); 4339 match(VecX); 4340 format%{%} 4341 interface(REG_INTER); 4342 %} 4343 operand rxmm14() %{ 4344 constraint(ALLOC_IN_RC(xmm14_reg)); 4345 match(VecX); 4346 format%{%} 4347 interface(REG_INTER); 4348 %} 4349 operand rxmm15() %{ 4350 constraint(ALLOC_IN_RC(xmm15_reg)); 4351 match(VecX); 4352 format%{%} 4353 interface(REG_INTER); 4354 %} 4355 operand rxmm16() %{ 4356 constraint(ALLOC_IN_RC(xmm16_reg)); 4357 match(VecX); 4358 format%{%} 4359 interface(REG_INTER); 4360 %} 4361 operand rxmm17() %{ 4362 constraint(ALLOC_IN_RC(xmm17_reg)); 4363 match(VecX); 4364 format%{%} 4365 interface(REG_INTER); 4366 %} 4367 operand rxmm18() %{ 4368 constraint(ALLOC_IN_RC(xmm18_reg)); 4369 match(VecX); 4370 format%{%} 4371 interface(REG_INTER); 4372 %} 4373 operand rxmm19() %{ 4374 constraint(ALLOC_IN_RC(xmm19_reg)); 4375 match(VecX); 4376 format%{%} 4377 interface(REG_INTER); 4378 %} 4379 operand rxmm20() %{ 4380 constraint(ALLOC_IN_RC(xmm20_reg)); 4381 match(VecX); 4382 format%{%} 4383 interface(REG_INTER); 4384 %} 4385 operand rxmm21() %{ 4386 constraint(ALLOC_IN_RC(xmm21_reg)); 4387 match(VecX); 4388 format%{%} 4389 interface(REG_INTER); 4390 %} 4391 operand rxmm22() %{ 4392 constraint(ALLOC_IN_RC(xmm22_reg)); 4393 match(VecX); 4394 format%{%} 4395 interface(REG_INTER); 4396 %} 4397 operand rxmm23() %{ 4398 constraint(ALLOC_IN_RC(xmm23_reg)); 4399 match(VecX); 4400 format%{%} 4401 interface(REG_INTER); 4402 %} 4403 operand rxmm24() %{ 4404 constraint(ALLOC_IN_RC(xmm24_reg)); 4405 match(VecX); 4406 format%{%} 4407 interface(REG_INTER); 4408 %} 4409 operand rxmm25() %{ 4410 constraint(ALLOC_IN_RC(xmm25_reg)); 4411 match(VecX); 4412 format%{%} 4413 interface(REG_INTER); 4414 %} 4415 operand rxmm26() %{ 4416 constraint(ALLOC_IN_RC(xmm26_reg)); 4417 match(VecX); 4418 format%{%} 4419 interface(REG_INTER); 4420 %} 4421 operand rxmm27() %{ 4422 constraint(ALLOC_IN_RC(xmm27_reg)); 4423 match(VecX); 4424 format%{%} 4425 interface(REG_INTER); 4426 %} 4427 operand rxmm28() %{ 4428 constraint(ALLOC_IN_RC(xmm28_reg)); 4429 match(VecX); 4430 format%{%} 4431 interface(REG_INTER); 4432 %} 4433 operand rxmm29() %{ 4434 constraint(ALLOC_IN_RC(xmm29_reg)); 4435 match(VecX); 4436 format%{%} 4437 interface(REG_INTER); 4438 %} 4439 operand rxmm30() %{ 4440 constraint(ALLOC_IN_RC(xmm30_reg)); 4441 match(VecX); 4442 format%{%} 4443 interface(REG_INTER); 4444 %} 4445 operand rxmm31() %{ 4446 constraint(ALLOC_IN_RC(xmm31_reg)); 4447 match(VecX); 4448 format%{%} 4449 interface(REG_INTER); 4450 %} 4451 4452 //----------OPERAND CLASSES---------------------------------------------------- 4453 // Operand Classes are groups of operands that are used as to simplify 4454 // instruction definitions by not requiring the AD writer to specify separate 4455 // instructions for every form of operand when the instruction accepts 4456 // multiple operand types with the same basic encoding and format. The classic 4457 // case of this is memory operands. 4458 4459 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4460 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4461 indCompressedOopOffset, 4462 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4463 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4464 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4465 4466 //----------PIPELINE----------------------------------------------------------- 4467 // Rules which define the behavior of the target architectures pipeline. 4468 pipeline %{ 4469 4470 //----------ATTRIBUTES--------------------------------------------------------- 4471 attributes %{ 4472 variable_size_instructions; // Fixed size instructions 4473 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4474 instruction_unit_size = 1; // An instruction is 1 bytes long 4475 instruction_fetch_unit_size = 16; // The processor fetches one line 4476 instruction_fetch_units = 1; // of 16 bytes 4477 4478 // List of nop instructions 4479 nops( MachNop ); 4480 %} 4481 4482 //----------RESOURCES---------------------------------------------------------- 4483 // Resources are the functional units available to the machine 4484 4485 // Generic P2/P3 pipeline 4486 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4487 // 3 instructions decoded per cycle. 4488 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4489 // 3 ALU op, only ALU0 handles mul instructions. 4490 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4491 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4492 BR, FPU, 4493 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4494 4495 //----------PIPELINE DESCRIPTION----------------------------------------------- 4496 // Pipeline Description specifies the stages in the machine's pipeline 4497 4498 // Generic P2/P3 pipeline 4499 pipe_desc(S0, S1, S2, S3, S4, S5); 4500 4501 //----------PIPELINE CLASSES--------------------------------------------------- 4502 // Pipeline Classes describe the stages in which input and output are 4503 // referenced by the hardware pipeline. 4504 4505 // Naming convention: ialu or fpu 4506 // Then: _reg 4507 // Then: _reg if there is a 2nd register 4508 // Then: _long if it's a pair of instructions implementing a long 4509 // Then: _fat if it requires the big decoder 4510 // Or: _mem if it requires the big decoder and a memory unit. 4511 4512 // Integer ALU reg operation 4513 pipe_class ialu_reg(rRegI dst) 4514 %{ 4515 single_instruction; 4516 dst : S4(write); 4517 dst : S3(read); 4518 DECODE : S0; // any decoder 4519 ALU : S3; // any alu 4520 %} 4521 4522 // Long ALU reg operation 4523 pipe_class ialu_reg_long(rRegL dst) 4524 %{ 4525 instruction_count(2); 4526 dst : S4(write); 4527 dst : S3(read); 4528 DECODE : S0(2); // any 2 decoders 4529 ALU : S3(2); // both alus 4530 %} 4531 4532 // Integer ALU reg operation using big decoder 4533 pipe_class ialu_reg_fat(rRegI dst) 4534 %{ 4535 single_instruction; 4536 dst : S4(write); 4537 dst : S3(read); 4538 D0 : S0; // big decoder only 4539 ALU : S3; // any alu 4540 %} 4541 4542 // Long ALU reg operation using big decoder 4543 pipe_class ialu_reg_long_fat(rRegL dst) 4544 %{ 4545 instruction_count(2); 4546 dst : S4(write); 4547 dst : S3(read); 4548 D0 : S0(2); // big decoder only; twice 4549 ALU : S3(2); // any 2 alus 4550 %} 4551 4552 // Integer ALU reg-reg operation 4553 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4554 %{ 4555 single_instruction; 4556 dst : S4(write); 4557 src : S3(read); 4558 DECODE : S0; // any decoder 4559 ALU : S3; // any alu 4560 %} 4561 4562 // Long ALU reg-reg operation 4563 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4564 %{ 4565 instruction_count(2); 4566 dst : S4(write); 4567 src : S3(read); 4568 DECODE : S0(2); // any 2 decoders 4569 ALU : S3(2); // both alus 4570 %} 4571 4572 // Integer ALU reg-reg operation 4573 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4574 %{ 4575 single_instruction; 4576 dst : S4(write); 4577 src : S3(read); 4578 D0 : S0; // big decoder only 4579 ALU : S3; // any alu 4580 %} 4581 4582 // Long ALU reg-reg operation 4583 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4584 %{ 4585 instruction_count(2); 4586 dst : S4(write); 4587 src : S3(read); 4588 D0 : S0(2); // big decoder only; twice 4589 ALU : S3(2); // both alus 4590 %} 4591 4592 // Integer ALU reg-mem operation 4593 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4594 %{ 4595 single_instruction; 4596 dst : S5(write); 4597 mem : S3(read); 4598 D0 : S0; // big decoder only 4599 ALU : S4; // any alu 4600 MEM : S3; // any mem 4601 %} 4602 4603 // Integer mem operation (prefetch) 4604 pipe_class ialu_mem(memory mem) 4605 %{ 4606 single_instruction; 4607 mem : S3(read); 4608 D0 : S0; // big decoder only 4609 MEM : S3; // any mem 4610 %} 4611 4612 // Integer Store to Memory 4613 pipe_class ialu_mem_reg(memory mem, rRegI src) 4614 %{ 4615 single_instruction; 4616 mem : S3(read); 4617 src : S5(read); 4618 D0 : S0; // big decoder only 4619 ALU : S4; // any alu 4620 MEM : S3; 4621 %} 4622 4623 // // Long Store to Memory 4624 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4625 // %{ 4626 // instruction_count(2); 4627 // mem : S3(read); 4628 // src : S5(read); 4629 // D0 : S0(2); // big decoder only; twice 4630 // ALU : S4(2); // any 2 alus 4631 // MEM : S3(2); // Both mems 4632 // %} 4633 4634 // Integer Store to Memory 4635 pipe_class ialu_mem_imm(memory mem) 4636 %{ 4637 single_instruction; 4638 mem : S3(read); 4639 D0 : S0; // big decoder only 4640 ALU : S4; // any alu 4641 MEM : S3; 4642 %} 4643 4644 // Integer ALU0 reg-reg operation 4645 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4646 %{ 4647 single_instruction; 4648 dst : S4(write); 4649 src : S3(read); 4650 D0 : S0; // Big decoder only 4651 ALU0 : S3; // only alu0 4652 %} 4653 4654 // Integer ALU0 reg-mem operation 4655 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4656 %{ 4657 single_instruction; 4658 dst : S5(write); 4659 mem : S3(read); 4660 D0 : S0; // big decoder only 4661 ALU0 : S4; // ALU0 only 4662 MEM : S3; // any mem 4663 %} 4664 4665 // Integer ALU reg-reg operation 4666 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4667 %{ 4668 single_instruction; 4669 cr : S4(write); 4670 src1 : S3(read); 4671 src2 : S3(read); 4672 DECODE : S0; // any decoder 4673 ALU : S3; // any alu 4674 %} 4675 4676 // Integer ALU reg-imm operation 4677 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4678 %{ 4679 single_instruction; 4680 cr : S4(write); 4681 src1 : S3(read); 4682 DECODE : S0; // any decoder 4683 ALU : S3; // any alu 4684 %} 4685 4686 // Integer ALU reg-mem operation 4687 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4688 %{ 4689 single_instruction; 4690 cr : S4(write); 4691 src1 : S3(read); 4692 src2 : S3(read); 4693 D0 : S0; // big decoder only 4694 ALU : S4; // any alu 4695 MEM : S3; 4696 %} 4697 4698 // Conditional move reg-reg 4699 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4700 %{ 4701 instruction_count(4); 4702 y : S4(read); 4703 q : S3(read); 4704 p : S3(read); 4705 DECODE : S0(4); // any decoder 4706 %} 4707 4708 // Conditional move reg-reg 4709 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4710 %{ 4711 single_instruction; 4712 dst : S4(write); 4713 src : S3(read); 4714 cr : S3(read); 4715 DECODE : S0; // any decoder 4716 %} 4717 4718 // Conditional move reg-mem 4719 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4720 %{ 4721 single_instruction; 4722 dst : S4(write); 4723 src : S3(read); 4724 cr : S3(read); 4725 DECODE : S0; // any decoder 4726 MEM : S3; 4727 %} 4728 4729 // Conditional move reg-reg long 4730 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4731 %{ 4732 single_instruction; 4733 dst : S4(write); 4734 src : S3(read); 4735 cr : S3(read); 4736 DECODE : S0(2); // any 2 decoders 4737 %} 4738 4739 // XXX 4740 // // Conditional move double reg-reg 4741 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4742 // %{ 4743 // single_instruction; 4744 // dst : S4(write); 4745 // src : S3(read); 4746 // cr : S3(read); 4747 // DECODE : S0; // any decoder 4748 // %} 4749 4750 // Float reg-reg operation 4751 pipe_class fpu_reg(regD dst) 4752 %{ 4753 instruction_count(2); 4754 dst : S3(read); 4755 DECODE : S0(2); // any 2 decoders 4756 FPU : S3; 4757 %} 4758 4759 // Float reg-reg operation 4760 pipe_class fpu_reg_reg(regD dst, regD src) 4761 %{ 4762 instruction_count(2); 4763 dst : S4(write); 4764 src : S3(read); 4765 DECODE : S0(2); // any 2 decoders 4766 FPU : S3; 4767 %} 4768 4769 // Float reg-reg operation 4770 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4771 %{ 4772 instruction_count(3); 4773 dst : S4(write); 4774 src1 : S3(read); 4775 src2 : S3(read); 4776 DECODE : S0(3); // any 3 decoders 4777 FPU : S3(2); 4778 %} 4779 4780 // Float reg-reg operation 4781 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4782 %{ 4783 instruction_count(4); 4784 dst : S4(write); 4785 src1 : S3(read); 4786 src2 : S3(read); 4787 src3 : S3(read); 4788 DECODE : S0(4); // any 3 decoders 4789 FPU : S3(2); 4790 %} 4791 4792 // Float reg-reg operation 4793 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4794 %{ 4795 instruction_count(4); 4796 dst : S4(write); 4797 src1 : S3(read); 4798 src2 : S3(read); 4799 src3 : S3(read); 4800 DECODE : S1(3); // any 3 decoders 4801 D0 : S0; // Big decoder only 4802 FPU : S3(2); 4803 MEM : S3; 4804 %} 4805 4806 // Float reg-mem operation 4807 pipe_class fpu_reg_mem(regD dst, memory mem) 4808 %{ 4809 instruction_count(2); 4810 dst : S5(write); 4811 mem : S3(read); 4812 D0 : S0; // big decoder only 4813 DECODE : S1; // any decoder for FPU POP 4814 FPU : S4; 4815 MEM : S3; // any mem 4816 %} 4817 4818 // Float reg-mem operation 4819 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4820 %{ 4821 instruction_count(3); 4822 dst : S5(write); 4823 src1 : S3(read); 4824 mem : S3(read); 4825 D0 : S0; // big decoder only 4826 DECODE : S1(2); // any decoder for FPU POP 4827 FPU : S4; 4828 MEM : S3; // any mem 4829 %} 4830 4831 // Float mem-reg operation 4832 pipe_class fpu_mem_reg(memory mem, regD src) 4833 %{ 4834 instruction_count(2); 4835 src : S5(read); 4836 mem : S3(read); 4837 DECODE : S0; // any decoder for FPU PUSH 4838 D0 : S1; // big decoder only 4839 FPU : S4; 4840 MEM : S3; // any mem 4841 %} 4842 4843 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4844 %{ 4845 instruction_count(3); 4846 src1 : S3(read); 4847 src2 : S3(read); 4848 mem : S3(read); 4849 DECODE : S0(2); // any decoder for FPU PUSH 4850 D0 : S1; // big decoder only 4851 FPU : S4; 4852 MEM : S3; // any mem 4853 %} 4854 4855 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4856 %{ 4857 instruction_count(3); 4858 src1 : S3(read); 4859 src2 : S3(read); 4860 mem : S4(read); 4861 DECODE : S0; // any decoder for FPU PUSH 4862 D0 : S0(2); // big decoder only 4863 FPU : S4; 4864 MEM : S3(2); // any mem 4865 %} 4866 4867 pipe_class fpu_mem_mem(memory dst, memory src1) 4868 %{ 4869 instruction_count(2); 4870 src1 : S3(read); 4871 dst : S4(read); 4872 D0 : S0(2); // big decoder only 4873 MEM : S3(2); // any mem 4874 %} 4875 4876 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4877 %{ 4878 instruction_count(3); 4879 src1 : S3(read); 4880 src2 : S3(read); 4881 dst : S4(read); 4882 D0 : S0(3); // big decoder only 4883 FPU : S4; 4884 MEM : S3(3); // any mem 4885 %} 4886 4887 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4888 %{ 4889 instruction_count(3); 4890 src1 : S4(read); 4891 mem : S4(read); 4892 DECODE : S0; // any decoder for FPU PUSH 4893 D0 : S0(2); // big decoder only 4894 FPU : S4; 4895 MEM : S3(2); // any mem 4896 %} 4897 4898 // Float load constant 4899 pipe_class fpu_reg_con(regD dst) 4900 %{ 4901 instruction_count(2); 4902 dst : S5(write); 4903 D0 : S0; // big decoder only for the load 4904 DECODE : S1; // any decoder for FPU POP 4905 FPU : S4; 4906 MEM : S3; // any mem 4907 %} 4908 4909 // Float load constant 4910 pipe_class fpu_reg_reg_con(regD dst, regD src) 4911 %{ 4912 instruction_count(3); 4913 dst : S5(write); 4914 src : S3(read); 4915 D0 : S0; // big decoder only for the load 4916 DECODE : S1(2); // any decoder for FPU POP 4917 FPU : S4; 4918 MEM : S3; // any mem 4919 %} 4920 4921 // UnConditional branch 4922 pipe_class pipe_jmp(label labl) 4923 %{ 4924 single_instruction; 4925 BR : S3; 4926 %} 4927 4928 // Conditional branch 4929 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4930 %{ 4931 single_instruction; 4932 cr : S1(read); 4933 BR : S3; 4934 %} 4935 4936 // Allocation idiom 4937 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4938 %{ 4939 instruction_count(1); force_serialization; 4940 fixed_latency(6); 4941 heap_ptr : S3(read); 4942 DECODE : S0(3); 4943 D0 : S2; 4944 MEM : S3; 4945 ALU : S3(2); 4946 dst : S5(write); 4947 BR : S5; 4948 %} 4949 4950 // Generic big/slow expanded idiom 4951 pipe_class pipe_slow() 4952 %{ 4953 instruction_count(10); multiple_bundles; force_serialization; 4954 fixed_latency(100); 4955 D0 : S0(2); 4956 MEM : S3(2); 4957 %} 4958 4959 // The real do-nothing guy 4960 pipe_class empty() 4961 %{ 4962 instruction_count(0); 4963 %} 4964 4965 // Define the class for the Nop node 4966 define 4967 %{ 4968 MachNop = empty; 4969 %} 4970 4971 %} 4972 4973 //----------INSTRUCTIONS------------------------------------------------------- 4974 // 4975 // match -- States which machine-independent subtree may be replaced 4976 // by this instruction. 4977 // ins_cost -- The estimated cost of this instruction is used by instruction 4978 // selection to identify a minimum cost tree of machine 4979 // instructions that matches a tree of machine-independent 4980 // instructions. 4981 // format -- A string providing the disassembly for this instruction. 4982 // The value of an instruction's operand may be inserted 4983 // by referring to it with a '$' prefix. 4984 // opcode -- Three instruction opcodes may be provided. These are referred 4985 // to within an encode class as $primary, $secondary, and $tertiary 4986 // rrspectively. The primary opcode is commonly used to 4987 // indicate the type of machine instruction, while secondary 4988 // and tertiary are often used for prefix options or addressing 4989 // modes. 4990 // ins_encode -- A list of encode classes with parameters. The encode class 4991 // name must have been defined in an 'enc_class' specification 4992 // in the encode section of the architecture description. 4993 4994 4995 //----------Load/Store/Move Instructions--------------------------------------- 4996 //----------Load Instructions-------------------------------------------------- 4997 4998 // Load Byte (8 bit signed) 4999 instruct loadB(rRegI dst, memory mem) 5000 %{ 5001 match(Set dst (LoadB mem)); 5002 5003 ins_cost(125); 5004 format %{ "movsbl $dst, $mem\t# byte" %} 5005 5006 ins_encode %{ 5007 __ movsbl($dst$$Register, $mem$$Address); 5008 %} 5009 5010 ins_pipe(ialu_reg_mem); 5011 %} 5012 5013 // Load Byte (8 bit signed) into Long Register 5014 instruct loadB2L(rRegL dst, memory mem) 5015 %{ 5016 match(Set dst (ConvI2L (LoadB mem))); 5017 5018 ins_cost(125); 5019 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5020 5021 ins_encode %{ 5022 __ movsbq($dst$$Register, $mem$$Address); 5023 %} 5024 5025 ins_pipe(ialu_reg_mem); 5026 %} 5027 5028 // Load Unsigned Byte (8 bit UNsigned) 5029 instruct loadUB(rRegI dst, memory mem) 5030 %{ 5031 match(Set dst (LoadUB mem)); 5032 5033 ins_cost(125); 5034 format %{ "movzbl $dst, $mem\t# ubyte" %} 5035 5036 ins_encode %{ 5037 __ movzbl($dst$$Register, $mem$$Address); 5038 %} 5039 5040 ins_pipe(ialu_reg_mem); 5041 %} 5042 5043 // Load Unsigned Byte (8 bit UNsigned) into Long Register 5044 instruct loadUB2L(rRegL dst, memory mem) 5045 %{ 5046 match(Set dst (ConvI2L (LoadUB mem))); 5047 5048 ins_cost(125); 5049 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5050 5051 ins_encode %{ 5052 __ movzbq($dst$$Register, $mem$$Address); 5053 %} 5054 5055 ins_pipe(ialu_reg_mem); 5056 %} 5057 5058 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 5059 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5060 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5061 effect(KILL cr); 5062 5063 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 5064 "andl $dst, right_n_bits($mask, 8)" %} 5065 ins_encode %{ 5066 Register Rdst = $dst$$Register; 5067 __ movzbq(Rdst, $mem$$Address); 5068 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 5069 %} 5070 ins_pipe(ialu_reg_mem); 5071 %} 5072 5073 // Load Short (16 bit signed) 5074 instruct loadS(rRegI dst, memory mem) 5075 %{ 5076 match(Set dst (LoadS mem)); 5077 5078 ins_cost(125); 5079 format %{ "movswl $dst, $mem\t# short" %} 5080 5081 ins_encode %{ 5082 __ movswl($dst$$Register, $mem$$Address); 5083 %} 5084 5085 ins_pipe(ialu_reg_mem); 5086 %} 5087 5088 // Load Short (16 bit signed) to Byte (8 bit signed) 5089 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5090 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5091 5092 ins_cost(125); 5093 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5094 ins_encode %{ 5095 __ movsbl($dst$$Register, $mem$$Address); 5096 %} 5097 ins_pipe(ialu_reg_mem); 5098 %} 5099 5100 // Load Short (16 bit signed) into Long Register 5101 instruct loadS2L(rRegL dst, memory mem) 5102 %{ 5103 match(Set dst (ConvI2L (LoadS mem))); 5104 5105 ins_cost(125); 5106 format %{ "movswq $dst, $mem\t# short -> long" %} 5107 5108 ins_encode %{ 5109 __ movswq($dst$$Register, $mem$$Address); 5110 %} 5111 5112 ins_pipe(ialu_reg_mem); 5113 %} 5114 5115 // Load Unsigned Short/Char (16 bit UNsigned) 5116 instruct loadUS(rRegI dst, memory mem) 5117 %{ 5118 match(Set dst (LoadUS mem)); 5119 5120 ins_cost(125); 5121 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5122 5123 ins_encode %{ 5124 __ movzwl($dst$$Register, $mem$$Address); 5125 %} 5126 5127 ins_pipe(ialu_reg_mem); 5128 %} 5129 5130 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5131 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5132 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5133 5134 ins_cost(125); 5135 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5136 ins_encode %{ 5137 __ movsbl($dst$$Register, $mem$$Address); 5138 %} 5139 ins_pipe(ialu_reg_mem); 5140 %} 5141 5142 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5143 instruct loadUS2L(rRegL dst, memory mem) 5144 %{ 5145 match(Set dst (ConvI2L (LoadUS mem))); 5146 5147 ins_cost(125); 5148 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5149 5150 ins_encode %{ 5151 __ movzwq($dst$$Register, $mem$$Address); 5152 %} 5153 5154 ins_pipe(ialu_reg_mem); 5155 %} 5156 5157 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5158 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5159 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5160 5161 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5162 ins_encode %{ 5163 __ movzbq($dst$$Register, $mem$$Address); 5164 %} 5165 ins_pipe(ialu_reg_mem); 5166 %} 5167 5168 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5169 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5170 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5171 effect(KILL cr); 5172 5173 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5174 "andl $dst, right_n_bits($mask, 16)" %} 5175 ins_encode %{ 5176 Register Rdst = $dst$$Register; 5177 __ movzwq(Rdst, $mem$$Address); 5178 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5179 %} 5180 ins_pipe(ialu_reg_mem); 5181 %} 5182 5183 // Load Integer 5184 instruct loadI(rRegI dst, memory mem) 5185 %{ 5186 match(Set dst (LoadI mem)); 5187 5188 ins_cost(125); 5189 format %{ "movl $dst, $mem\t# int" %} 5190 5191 ins_encode %{ 5192 __ movl($dst$$Register, $mem$$Address); 5193 %} 5194 5195 ins_pipe(ialu_reg_mem); 5196 %} 5197 5198 // Load Integer (32 bit signed) to Byte (8 bit signed) 5199 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5200 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5201 5202 ins_cost(125); 5203 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5204 ins_encode %{ 5205 __ movsbl($dst$$Register, $mem$$Address); 5206 %} 5207 ins_pipe(ialu_reg_mem); 5208 %} 5209 5210 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5211 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5212 match(Set dst (AndI (LoadI mem) mask)); 5213 5214 ins_cost(125); 5215 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5216 ins_encode %{ 5217 __ movzbl($dst$$Register, $mem$$Address); 5218 %} 5219 ins_pipe(ialu_reg_mem); 5220 %} 5221 5222 // Load Integer (32 bit signed) to Short (16 bit signed) 5223 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5224 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5225 5226 ins_cost(125); 5227 format %{ "movswl $dst, $mem\t# int -> short" %} 5228 ins_encode %{ 5229 __ movswl($dst$$Register, $mem$$Address); 5230 %} 5231 ins_pipe(ialu_reg_mem); 5232 %} 5233 5234 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5235 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5236 match(Set dst (AndI (LoadI mem) mask)); 5237 5238 ins_cost(125); 5239 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5240 ins_encode %{ 5241 __ movzwl($dst$$Register, $mem$$Address); 5242 %} 5243 ins_pipe(ialu_reg_mem); 5244 %} 5245 5246 // Load Integer into Long Register 5247 instruct loadI2L(rRegL dst, memory mem) 5248 %{ 5249 match(Set dst (ConvI2L (LoadI mem))); 5250 5251 ins_cost(125); 5252 format %{ "movslq $dst, $mem\t# int -> long" %} 5253 5254 ins_encode %{ 5255 __ movslq($dst$$Register, $mem$$Address); 5256 %} 5257 5258 ins_pipe(ialu_reg_mem); 5259 %} 5260 5261 // Load Integer with mask 0xFF into Long Register 5262 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5263 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5264 5265 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5266 ins_encode %{ 5267 __ movzbq($dst$$Register, $mem$$Address); 5268 %} 5269 ins_pipe(ialu_reg_mem); 5270 %} 5271 5272 // Load Integer with mask 0xFFFF into Long Register 5273 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5274 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5275 5276 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5277 ins_encode %{ 5278 __ movzwq($dst$$Register, $mem$$Address); 5279 %} 5280 ins_pipe(ialu_reg_mem); 5281 %} 5282 5283 // Load Integer with a 31-bit mask into Long Register 5284 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5285 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5286 effect(KILL cr); 5287 5288 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5289 "andl $dst, $mask" %} 5290 ins_encode %{ 5291 Register Rdst = $dst$$Register; 5292 __ movl(Rdst, $mem$$Address); 5293 __ andl(Rdst, $mask$$constant); 5294 %} 5295 ins_pipe(ialu_reg_mem); 5296 %} 5297 5298 // Load Unsigned Integer into Long Register 5299 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5300 %{ 5301 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5302 5303 ins_cost(125); 5304 format %{ "movl $dst, $mem\t# uint -> long" %} 5305 5306 ins_encode %{ 5307 __ movl($dst$$Register, $mem$$Address); 5308 %} 5309 5310 ins_pipe(ialu_reg_mem); 5311 %} 5312 5313 // Load Long 5314 instruct loadL(rRegL dst, memory mem) 5315 %{ 5316 match(Set dst (LoadL mem)); 5317 5318 ins_cost(125); 5319 format %{ "movq $dst, $mem\t# long" %} 5320 5321 ins_encode %{ 5322 __ movq($dst$$Register, $mem$$Address); 5323 %} 5324 5325 ins_pipe(ialu_reg_mem); // XXX 5326 %} 5327 5328 // Load Range 5329 instruct loadRange(rRegI dst, memory mem) 5330 %{ 5331 match(Set dst (LoadRange mem)); 5332 5333 ins_cost(125); // XXX 5334 format %{ "movl $dst, $mem\t# range" %} 5335 opcode(0x8B); 5336 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5337 ins_pipe(ialu_reg_mem); 5338 %} 5339 5340 // Load Pointer 5341 instruct loadP(rRegP dst, memory mem) 5342 %{ 5343 match(Set dst (LoadP mem)); 5344 5345 ins_cost(125); // XXX 5346 format %{ "movq $dst, $mem\t# ptr" %} 5347 opcode(0x8B); 5348 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5349 ins_pipe(ialu_reg_mem); // XXX 5350 %} 5351 5352 // Load Compressed Pointer 5353 instruct loadN(rRegN dst, memory mem) 5354 %{ 5355 match(Set dst (LoadN mem)); 5356 5357 ins_cost(125); // XXX 5358 format %{ "movl $dst, $mem\t# compressed ptr" %} 5359 ins_encode %{ 5360 __ movl($dst$$Register, $mem$$Address); 5361 %} 5362 ins_pipe(ialu_reg_mem); // XXX 5363 %} 5364 5365 5366 // Load Klass Pointer 5367 instruct loadKlass(rRegP dst, memory mem) 5368 %{ 5369 match(Set dst (LoadKlass mem)); 5370 5371 ins_cost(125); // XXX 5372 format %{ "movq $dst, $mem\t# class\n\t" 5373 "shlq $dst, oopDesc::storage_props_nof_bits\n\t" 5374 "shrq $dst, oopDesc::storage_props_nof_bits" %} 5375 ins_encode %{ 5376 __ movptr($dst$$Register, $mem$$Address); 5377 __ shlq($dst$$Register, oopDesc::storage_props_nof_bits); 5378 __ shrq($dst$$Register, oopDesc::storage_props_nof_bits); 5379 %} 5380 ins_pipe(ialu_reg_mem); // XXX 5381 %} 5382 5383 // Load narrow Klass Pointer 5384 instruct loadNKlass(rRegN dst, memory mem) 5385 %{ 5386 match(Set dst (LoadNKlass mem)); 5387 5388 ins_cost(125); // XXX 5389 format %{ "movl $dst, $mem\t# compressed klass ptr\n\t" 5390 "andl $dst, oopDesc::compressed_klass_mask()" %} 5391 ins_encode %{ 5392 __ movl($dst$$Register, $mem$$Address); 5393 __ andl($dst$$Register, oopDesc::compressed_klass_mask()); 5394 %} 5395 ins_pipe(ialu_reg_mem); // XXX 5396 %} 5397 5398 // Load Float 5399 instruct loadF(regF dst, memory mem) 5400 %{ 5401 match(Set dst (LoadF mem)); 5402 5403 ins_cost(145); // XXX 5404 format %{ "movss $dst, $mem\t# float" %} 5405 ins_encode %{ 5406 __ movflt($dst$$XMMRegister, $mem$$Address); 5407 %} 5408 ins_pipe(pipe_slow); // XXX 5409 %} 5410 5411 // Load Float 5412 instruct MoveF2VL(vlRegF dst, regF src) %{ 5413 match(Set dst src); 5414 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5415 ins_encode %{ 5416 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5417 %} 5418 ins_pipe( fpu_reg_reg ); 5419 %} 5420 5421 // Load Float 5422 instruct MoveF2LEG(legRegF dst, regF src) %{ 5423 match(Set dst src); 5424 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5425 ins_encode %{ 5426 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5427 %} 5428 ins_pipe( fpu_reg_reg ); 5429 %} 5430 5431 // Load Float 5432 instruct MoveVL2F(regF dst, vlRegF src) %{ 5433 match(Set dst src); 5434 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5435 ins_encode %{ 5436 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5437 %} 5438 ins_pipe( fpu_reg_reg ); 5439 %} 5440 5441 // Load Float 5442 instruct MoveLEG2F(regF dst, legRegF src) %{ 5443 match(Set dst src); 5444 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5445 ins_encode %{ 5446 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5447 %} 5448 ins_pipe( fpu_reg_reg ); 5449 %} 5450 5451 // Load Double 5452 instruct loadD_partial(regD dst, memory mem) 5453 %{ 5454 predicate(!UseXmmLoadAndClearUpper); 5455 match(Set dst (LoadD mem)); 5456 5457 ins_cost(145); // XXX 5458 format %{ "movlpd $dst, $mem\t# double" %} 5459 ins_encode %{ 5460 __ movdbl($dst$$XMMRegister, $mem$$Address); 5461 %} 5462 ins_pipe(pipe_slow); // XXX 5463 %} 5464 5465 instruct loadD(regD dst, memory mem) 5466 %{ 5467 predicate(UseXmmLoadAndClearUpper); 5468 match(Set dst (LoadD mem)); 5469 5470 ins_cost(145); // XXX 5471 format %{ "movsd $dst, $mem\t# double" %} 5472 ins_encode %{ 5473 __ movdbl($dst$$XMMRegister, $mem$$Address); 5474 %} 5475 ins_pipe(pipe_slow); // XXX 5476 %} 5477 5478 // Load Double 5479 instruct MoveD2VL(vlRegD dst, regD src) %{ 5480 match(Set dst src); 5481 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5482 ins_encode %{ 5483 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5484 %} 5485 ins_pipe( fpu_reg_reg ); 5486 %} 5487 5488 // Load Double 5489 instruct MoveD2LEG(legRegD dst, regD src) %{ 5490 match(Set dst src); 5491 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5492 ins_encode %{ 5493 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5494 %} 5495 ins_pipe( fpu_reg_reg ); 5496 %} 5497 5498 // Load Double 5499 instruct MoveVL2D(regD dst, vlRegD src) %{ 5500 match(Set dst src); 5501 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5502 ins_encode %{ 5503 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5504 %} 5505 ins_pipe( fpu_reg_reg ); 5506 %} 5507 5508 // Load Double 5509 instruct MoveLEG2D(regD dst, legRegD src) %{ 5510 match(Set dst src); 5511 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5512 ins_encode %{ 5513 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5514 %} 5515 ins_pipe( fpu_reg_reg ); 5516 %} 5517 5518 // Following pseudo code describes the algorithm for max[FD]: 5519 // Min algorithm is on similar lines 5520 // btmp = (b < +0.0) ? a : b 5521 // atmp = (b < +0.0) ? b : a 5522 // Tmp = Max_Float(atmp , btmp) 5523 // Res = (atmp == NaN) ? atmp : Tmp 5524 5525 // max = java.lang.Math.max(float a, float b) 5526 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5527 predicate(UseAVX > 0 && !n->is_reduction()); 5528 match(Set dst (MaxF a b)); 5529 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5530 format %{ 5531 "blendvps $btmp,$b,$a,$b \n\t" 5532 "blendvps $atmp,$a,$b,$b \n\t" 5533 "vmaxss $tmp,$atmp,$btmp \n\t" 5534 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5535 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5536 %} 5537 ins_encode %{ 5538 int vector_len = Assembler::AVX_128bit; 5539 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5540 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5541 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5542 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5543 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5544 %} 5545 ins_pipe( pipe_slow ); 5546 %} 5547 5548 instruct maxF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{ 5549 predicate(UseAVX > 0 && n->is_reduction()); 5550 match(Set dst (MaxF a b)); 5551 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5552 5553 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 5554 ins_encode %{ 5555 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5556 false /*min*/, true /*single*/); 5557 %} 5558 ins_pipe( pipe_slow ); 5559 %} 5560 5561 // max = java.lang.Math.max(double a, double b) 5562 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5563 predicate(UseAVX > 0 && !n->is_reduction()); 5564 match(Set dst (MaxD a b)); 5565 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 5566 format %{ 5567 "blendvpd $btmp,$b,$a,$b \n\t" 5568 "blendvpd $atmp,$a,$b,$b \n\t" 5569 "vmaxsd $tmp,$atmp,$btmp \n\t" 5570 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5571 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5572 %} 5573 ins_encode %{ 5574 int vector_len = Assembler::AVX_128bit; 5575 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5576 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5577 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5578 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5579 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5580 %} 5581 ins_pipe( pipe_slow ); 5582 %} 5583 5584 instruct maxD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{ 5585 predicate(UseAVX > 0 && n->is_reduction()); 5586 match(Set dst (MaxD a b)); 5587 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5588 5589 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 5590 ins_encode %{ 5591 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5592 false /*min*/, false /*single*/); 5593 %} 5594 ins_pipe( pipe_slow ); 5595 %} 5596 5597 // min = java.lang.Math.min(float a, float b) 5598 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5599 predicate(UseAVX > 0 && !n->is_reduction()); 5600 match(Set dst (MinF a b)); 5601 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5602 format %{ 5603 "blendvps $atmp,$a,$b,$a \n\t" 5604 "blendvps $btmp,$b,$a,$a \n\t" 5605 "vminss $tmp,$atmp,$btmp \n\t" 5606 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5607 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5608 %} 5609 ins_encode %{ 5610 int vector_len = Assembler::AVX_128bit; 5611 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5612 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5613 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5614 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5615 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5616 %} 5617 ins_pipe( pipe_slow ); 5618 %} 5619 5620 instruct minF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{ 5621 predicate(UseAVX > 0 && n->is_reduction()); 5622 match(Set dst (MinF a b)); 5623 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5624 5625 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 5626 ins_encode %{ 5627 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5628 true /*min*/, true /*single*/); 5629 %} 5630 ins_pipe( pipe_slow ); 5631 %} 5632 5633 // min = java.lang.Math.min(double a, double b) 5634 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5635 predicate(UseAVX > 0 && !n->is_reduction()); 5636 match(Set dst (MinD a b)); 5637 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5638 format %{ 5639 "blendvpd $atmp,$a,$b,$a \n\t" 5640 "blendvpd $btmp,$b,$a,$a \n\t" 5641 "vminsd $tmp,$atmp,$btmp \n\t" 5642 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5643 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5644 %} 5645 ins_encode %{ 5646 int vector_len = Assembler::AVX_128bit; 5647 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5648 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5649 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5650 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5651 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5652 %} 5653 ins_pipe( pipe_slow ); 5654 %} 5655 5656 instruct minD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{ 5657 predicate(UseAVX > 0 && n->is_reduction()); 5658 match(Set dst (MinD a b)); 5659 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5660 5661 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 5662 ins_encode %{ 5663 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5664 true /*min*/, false /*single*/); 5665 %} 5666 ins_pipe( pipe_slow ); 5667 %} 5668 5669 // Load Effective Address 5670 instruct leaP8(rRegP dst, indOffset8 mem) 5671 %{ 5672 match(Set dst mem); 5673 5674 ins_cost(110); // XXX 5675 format %{ "leaq $dst, $mem\t# ptr 8" %} 5676 opcode(0x8D); 5677 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5678 ins_pipe(ialu_reg_reg_fat); 5679 %} 5680 5681 instruct leaP32(rRegP dst, indOffset32 mem) 5682 %{ 5683 match(Set dst mem); 5684 5685 ins_cost(110); 5686 format %{ "leaq $dst, $mem\t# ptr 32" %} 5687 opcode(0x8D); 5688 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5689 ins_pipe(ialu_reg_reg_fat); 5690 %} 5691 5692 // instruct leaPIdx(rRegP dst, indIndex mem) 5693 // %{ 5694 // match(Set dst mem); 5695 5696 // ins_cost(110); 5697 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5698 // opcode(0x8D); 5699 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5700 // ins_pipe(ialu_reg_reg_fat); 5701 // %} 5702 5703 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5704 %{ 5705 match(Set dst mem); 5706 5707 ins_cost(110); 5708 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5709 opcode(0x8D); 5710 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5711 ins_pipe(ialu_reg_reg_fat); 5712 %} 5713 5714 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5715 %{ 5716 match(Set dst mem); 5717 5718 ins_cost(110); 5719 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5720 opcode(0x8D); 5721 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5722 ins_pipe(ialu_reg_reg_fat); 5723 %} 5724 5725 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5726 %{ 5727 match(Set dst mem); 5728 5729 ins_cost(110); 5730 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5731 opcode(0x8D); 5732 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5733 ins_pipe(ialu_reg_reg_fat); 5734 %} 5735 5736 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5737 %{ 5738 match(Set dst mem); 5739 5740 ins_cost(110); 5741 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5742 opcode(0x8D); 5743 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5744 ins_pipe(ialu_reg_reg_fat); 5745 %} 5746 5747 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5748 %{ 5749 match(Set dst mem); 5750 5751 ins_cost(110); 5752 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5753 opcode(0x8D); 5754 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5755 ins_pipe(ialu_reg_reg_fat); 5756 %} 5757 5758 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5759 %{ 5760 match(Set dst mem); 5761 5762 ins_cost(110); 5763 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5764 opcode(0x8D); 5765 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5766 ins_pipe(ialu_reg_reg_fat); 5767 %} 5768 5769 // Load Effective Address which uses Narrow (32-bits) oop 5770 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5771 %{ 5772 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 5773 match(Set dst mem); 5774 5775 ins_cost(110); 5776 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5777 opcode(0x8D); 5778 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5779 ins_pipe(ialu_reg_reg_fat); 5780 %} 5781 5782 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5783 %{ 5784 predicate(CompressedOops::shift() == 0); 5785 match(Set dst mem); 5786 5787 ins_cost(110); // XXX 5788 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5789 opcode(0x8D); 5790 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5791 ins_pipe(ialu_reg_reg_fat); 5792 %} 5793 5794 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5795 %{ 5796 predicate(CompressedOops::shift() == 0); 5797 match(Set dst mem); 5798 5799 ins_cost(110); 5800 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5801 opcode(0x8D); 5802 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5803 ins_pipe(ialu_reg_reg_fat); 5804 %} 5805 5806 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5807 %{ 5808 predicate(CompressedOops::shift() == 0); 5809 match(Set dst mem); 5810 5811 ins_cost(110); 5812 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5813 opcode(0x8D); 5814 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5815 ins_pipe(ialu_reg_reg_fat); 5816 %} 5817 5818 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5819 %{ 5820 predicate(CompressedOops::shift() == 0); 5821 match(Set dst mem); 5822 5823 ins_cost(110); 5824 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5825 opcode(0x8D); 5826 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5827 ins_pipe(ialu_reg_reg_fat); 5828 %} 5829 5830 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5831 %{ 5832 predicate(CompressedOops::shift() == 0); 5833 match(Set dst mem); 5834 5835 ins_cost(110); 5836 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5837 opcode(0x8D); 5838 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5839 ins_pipe(ialu_reg_reg_fat); 5840 %} 5841 5842 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5843 %{ 5844 predicate(CompressedOops::shift() == 0); 5845 match(Set dst mem); 5846 5847 ins_cost(110); 5848 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5849 opcode(0x8D); 5850 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5851 ins_pipe(ialu_reg_reg_fat); 5852 %} 5853 5854 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5855 %{ 5856 predicate(CompressedOops::shift() == 0); 5857 match(Set dst mem); 5858 5859 ins_cost(110); 5860 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5861 opcode(0x8D); 5862 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5863 ins_pipe(ialu_reg_reg_fat); 5864 %} 5865 5866 instruct loadConI(rRegI dst, immI src) 5867 %{ 5868 match(Set dst src); 5869 5870 format %{ "movl $dst, $src\t# int" %} 5871 ins_encode(load_immI(dst, src)); 5872 ins_pipe(ialu_reg_fat); // XXX 5873 %} 5874 5875 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5876 %{ 5877 match(Set dst src); 5878 effect(KILL cr); 5879 5880 ins_cost(50); 5881 format %{ "xorl $dst, $dst\t# int" %} 5882 opcode(0x33); /* + rd */ 5883 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5884 ins_pipe(ialu_reg); 5885 %} 5886 5887 instruct loadConL(rRegL dst, immL src) 5888 %{ 5889 match(Set dst src); 5890 5891 ins_cost(150); 5892 format %{ "movq $dst, $src\t# long" %} 5893 ins_encode(load_immL(dst, src)); 5894 ins_pipe(ialu_reg); 5895 %} 5896 5897 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5898 %{ 5899 match(Set dst src); 5900 effect(KILL cr); 5901 5902 ins_cost(50); 5903 format %{ "xorl $dst, $dst\t# long" %} 5904 opcode(0x33); /* + rd */ 5905 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5906 ins_pipe(ialu_reg); // XXX 5907 %} 5908 5909 instruct loadConUL32(rRegL dst, immUL32 src) 5910 %{ 5911 match(Set dst src); 5912 5913 ins_cost(60); 5914 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5915 ins_encode(load_immUL32(dst, src)); 5916 ins_pipe(ialu_reg); 5917 %} 5918 5919 instruct loadConL32(rRegL dst, immL32 src) 5920 %{ 5921 match(Set dst src); 5922 5923 ins_cost(70); 5924 format %{ "movq $dst, $src\t# long (32-bit)" %} 5925 ins_encode(load_immL32(dst, src)); 5926 ins_pipe(ialu_reg); 5927 %} 5928 5929 instruct loadConP(rRegP dst, immP con) %{ 5930 match(Set dst con); 5931 5932 format %{ "movq $dst, $con\t# ptr" %} 5933 ins_encode(load_immP(dst, con)); 5934 ins_pipe(ialu_reg_fat); // XXX 5935 %} 5936 5937 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5938 %{ 5939 match(Set dst src); 5940 effect(KILL cr); 5941 5942 ins_cost(50); 5943 format %{ "xorl $dst, $dst\t# ptr" %} 5944 opcode(0x33); /* + rd */ 5945 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5946 ins_pipe(ialu_reg); 5947 %} 5948 5949 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5950 %{ 5951 match(Set dst src); 5952 effect(KILL cr); 5953 5954 ins_cost(60); 5955 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5956 ins_encode(load_immP31(dst, src)); 5957 ins_pipe(ialu_reg); 5958 %} 5959 5960 instruct loadConF(regF dst, immF con) %{ 5961 match(Set dst con); 5962 ins_cost(125); 5963 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5964 ins_encode %{ 5965 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5966 %} 5967 ins_pipe(pipe_slow); 5968 %} 5969 5970 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5971 match(Set dst src); 5972 effect(KILL cr); 5973 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5974 ins_encode %{ 5975 __ xorq($dst$$Register, $dst$$Register); 5976 %} 5977 ins_pipe(ialu_reg); 5978 %} 5979 5980 instruct loadConN(rRegN dst, immN src) %{ 5981 match(Set dst src); 5982 5983 ins_cost(125); 5984 format %{ "movl $dst, $src\t# compressed ptr" %} 5985 ins_encode %{ 5986 address con = (address)$src$$constant; 5987 if (con == NULL) { 5988 ShouldNotReachHere(); 5989 } else { 5990 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5991 } 5992 %} 5993 ins_pipe(ialu_reg_fat); // XXX 5994 %} 5995 5996 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5997 match(Set dst src); 5998 5999 ins_cost(125); 6000 format %{ "movl $dst, $src\t# compressed klass ptr" %} 6001 ins_encode %{ 6002 address con = (address)$src$$constant; 6003 if (con == NULL) { 6004 ShouldNotReachHere(); 6005 } else { 6006 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 6007 } 6008 %} 6009 ins_pipe(ialu_reg_fat); // XXX 6010 %} 6011 6012 instruct loadConF0(regF dst, immF0 src) 6013 %{ 6014 match(Set dst src); 6015 ins_cost(100); 6016 6017 format %{ "xorps $dst, $dst\t# float 0.0" %} 6018 ins_encode %{ 6019 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 6020 %} 6021 ins_pipe(pipe_slow); 6022 %} 6023 6024 // Use the same format since predicate() can not be used here. 6025 instruct loadConD(regD dst, immD con) %{ 6026 match(Set dst con); 6027 ins_cost(125); 6028 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 6029 ins_encode %{ 6030 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 6031 %} 6032 ins_pipe(pipe_slow); 6033 %} 6034 6035 instruct loadConD0(regD dst, immD0 src) 6036 %{ 6037 match(Set dst src); 6038 ins_cost(100); 6039 6040 format %{ "xorpd $dst, $dst\t# double 0.0" %} 6041 ins_encode %{ 6042 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 6043 %} 6044 ins_pipe(pipe_slow); 6045 %} 6046 6047 instruct loadSSI(rRegI dst, stackSlotI src) 6048 %{ 6049 match(Set dst src); 6050 6051 ins_cost(125); 6052 format %{ "movl $dst, $src\t# int stk" %} 6053 opcode(0x8B); 6054 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6055 ins_pipe(ialu_reg_mem); 6056 %} 6057 6058 instruct loadSSL(rRegL dst, stackSlotL src) 6059 %{ 6060 match(Set dst src); 6061 6062 ins_cost(125); 6063 format %{ "movq $dst, $src\t# long stk" %} 6064 opcode(0x8B); 6065 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6066 ins_pipe(ialu_reg_mem); 6067 %} 6068 6069 instruct loadSSP(rRegP dst, stackSlotP src) 6070 %{ 6071 match(Set dst src); 6072 6073 ins_cost(125); 6074 format %{ "movq $dst, $src\t# ptr stk" %} 6075 opcode(0x8B); 6076 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6077 ins_pipe(ialu_reg_mem); 6078 %} 6079 6080 instruct loadSSF(regF dst, stackSlotF src) 6081 %{ 6082 match(Set dst src); 6083 6084 ins_cost(125); 6085 format %{ "movss $dst, $src\t# float stk" %} 6086 ins_encode %{ 6087 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 6088 %} 6089 ins_pipe(pipe_slow); // XXX 6090 %} 6091 6092 // Use the same format since predicate() can not be used here. 6093 instruct loadSSD(regD dst, stackSlotD src) 6094 %{ 6095 match(Set dst src); 6096 6097 ins_cost(125); 6098 format %{ "movsd $dst, $src\t# double stk" %} 6099 ins_encode %{ 6100 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 6101 %} 6102 ins_pipe(pipe_slow); // XXX 6103 %} 6104 6105 // Prefetch instructions for allocation. 6106 // Must be safe to execute with invalid address (cannot fault). 6107 6108 instruct prefetchAlloc( memory mem ) %{ 6109 predicate(AllocatePrefetchInstr==3); 6110 match(PrefetchAllocation mem); 6111 ins_cost(125); 6112 6113 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 6114 ins_encode %{ 6115 __ prefetchw($mem$$Address); 6116 %} 6117 ins_pipe(ialu_mem); 6118 %} 6119 6120 instruct prefetchAllocNTA( memory mem ) %{ 6121 predicate(AllocatePrefetchInstr==0); 6122 match(PrefetchAllocation mem); 6123 ins_cost(125); 6124 6125 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 6126 ins_encode %{ 6127 __ prefetchnta($mem$$Address); 6128 %} 6129 ins_pipe(ialu_mem); 6130 %} 6131 6132 instruct prefetchAllocT0( memory mem ) %{ 6133 predicate(AllocatePrefetchInstr==1); 6134 match(PrefetchAllocation mem); 6135 ins_cost(125); 6136 6137 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 6138 ins_encode %{ 6139 __ prefetcht0($mem$$Address); 6140 %} 6141 ins_pipe(ialu_mem); 6142 %} 6143 6144 instruct prefetchAllocT2( memory mem ) %{ 6145 predicate(AllocatePrefetchInstr==2); 6146 match(PrefetchAllocation mem); 6147 ins_cost(125); 6148 6149 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 6150 ins_encode %{ 6151 __ prefetcht2($mem$$Address); 6152 %} 6153 ins_pipe(ialu_mem); 6154 %} 6155 6156 //----------Store Instructions------------------------------------------------- 6157 6158 // Store Byte 6159 instruct storeB(memory mem, rRegI src) 6160 %{ 6161 match(Set mem (StoreB mem src)); 6162 6163 ins_cost(125); // XXX 6164 format %{ "movb $mem, $src\t# byte" %} 6165 opcode(0x88); 6166 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6167 ins_pipe(ialu_mem_reg); 6168 %} 6169 6170 // Store Char/Short 6171 instruct storeC(memory mem, rRegI src) 6172 %{ 6173 match(Set mem (StoreC mem src)); 6174 6175 ins_cost(125); // XXX 6176 format %{ "movw $mem, $src\t# char/short" %} 6177 opcode(0x89); 6178 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6179 ins_pipe(ialu_mem_reg); 6180 %} 6181 6182 // Store Integer 6183 instruct storeI(memory mem, rRegI src) 6184 %{ 6185 match(Set mem (StoreI mem src)); 6186 6187 ins_cost(125); // XXX 6188 format %{ "movl $mem, $src\t# int" %} 6189 opcode(0x89); 6190 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6191 ins_pipe(ialu_mem_reg); 6192 %} 6193 6194 // Store Long 6195 instruct storeL(memory mem, rRegL src) 6196 %{ 6197 match(Set mem (StoreL mem src)); 6198 6199 ins_cost(125); // XXX 6200 format %{ "movq $mem, $src\t# long" %} 6201 opcode(0x89); 6202 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6203 ins_pipe(ialu_mem_reg); // XXX 6204 %} 6205 6206 // Store Pointer 6207 instruct storeP(memory mem, any_RegP src) 6208 %{ 6209 match(Set mem (StoreP mem src)); 6210 6211 ins_cost(125); // XXX 6212 format %{ "movq $mem, $src\t# ptr" %} 6213 opcode(0x89); 6214 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6215 ins_pipe(ialu_mem_reg); 6216 %} 6217 6218 instruct storeImmP0(memory mem, immP0 zero) 6219 %{ 6220 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6221 match(Set mem (StoreP mem zero)); 6222 6223 ins_cost(125); // XXX 6224 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6225 ins_encode %{ 6226 __ movq($mem$$Address, r12); 6227 %} 6228 ins_pipe(ialu_mem_reg); 6229 %} 6230 6231 // Store NULL Pointer, mark word, or other simple pointer constant. 6232 instruct storeImmP(memory mem, immP31 src) 6233 %{ 6234 match(Set mem (StoreP mem src)); 6235 6236 ins_cost(150); // XXX 6237 format %{ "movq $mem, $src\t# ptr" %} 6238 opcode(0xC7); /* C7 /0 */ 6239 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6240 ins_pipe(ialu_mem_imm); 6241 %} 6242 6243 // Store Compressed Pointer 6244 instruct storeN(memory mem, rRegN src) 6245 %{ 6246 match(Set mem (StoreN mem src)); 6247 6248 ins_cost(125); // XXX 6249 format %{ "movl $mem, $src\t# compressed ptr" %} 6250 ins_encode %{ 6251 __ movl($mem$$Address, $src$$Register); 6252 %} 6253 ins_pipe(ialu_mem_reg); 6254 %} 6255 6256 instruct storeNKlass(memory mem, rRegN src) 6257 %{ 6258 match(Set mem (StoreNKlass mem src)); 6259 6260 ins_cost(125); // XXX 6261 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6262 ins_encode %{ 6263 __ movl($mem$$Address, $src$$Register); 6264 %} 6265 ins_pipe(ialu_mem_reg); 6266 %} 6267 6268 instruct storeImmN0(memory mem, immN0 zero) 6269 %{ 6270 predicate(CompressedOops::base() == NULL && CompressedKlassPointers::base() == NULL); 6271 match(Set mem (StoreN mem zero)); 6272 6273 ins_cost(125); // XXX 6274 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6275 ins_encode %{ 6276 __ movl($mem$$Address, r12); 6277 %} 6278 ins_pipe(ialu_mem_reg); 6279 %} 6280 6281 instruct storeImmN(memory mem, immN src) 6282 %{ 6283 match(Set mem (StoreN mem src)); 6284 6285 ins_cost(150); // XXX 6286 format %{ "movl $mem, $src\t# compressed ptr" %} 6287 ins_encode %{ 6288 address con = (address)$src$$constant; 6289 if (con == NULL) { 6290 __ movl($mem$$Address, (int32_t)0); 6291 } else { 6292 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6293 } 6294 %} 6295 ins_pipe(ialu_mem_imm); 6296 %} 6297 6298 instruct storeImmNKlass(memory mem, immNKlass src) 6299 %{ 6300 match(Set mem (StoreNKlass mem src)); 6301 6302 ins_cost(150); // XXX 6303 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6304 ins_encode %{ 6305 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6306 %} 6307 ins_pipe(ialu_mem_imm); 6308 %} 6309 6310 // Store Integer Immediate 6311 instruct storeImmI0(memory mem, immI0 zero) 6312 %{ 6313 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6314 match(Set mem (StoreI mem zero)); 6315 6316 ins_cost(125); // XXX 6317 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6318 ins_encode %{ 6319 __ movl($mem$$Address, r12); 6320 %} 6321 ins_pipe(ialu_mem_reg); 6322 %} 6323 6324 instruct storeImmI(memory mem, immI src) 6325 %{ 6326 match(Set mem (StoreI mem src)); 6327 6328 ins_cost(150); 6329 format %{ "movl $mem, $src\t# int" %} 6330 opcode(0xC7); /* C7 /0 */ 6331 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6332 ins_pipe(ialu_mem_imm); 6333 %} 6334 6335 // Store Long Immediate 6336 instruct storeImmL0(memory mem, immL0 zero) 6337 %{ 6338 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6339 match(Set mem (StoreL mem zero)); 6340 6341 ins_cost(125); // XXX 6342 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6343 ins_encode %{ 6344 __ movq($mem$$Address, r12); 6345 %} 6346 ins_pipe(ialu_mem_reg); 6347 %} 6348 6349 instruct storeImmL(memory mem, immL32 src) 6350 %{ 6351 match(Set mem (StoreL mem src)); 6352 6353 ins_cost(150); 6354 format %{ "movq $mem, $src\t# long" %} 6355 opcode(0xC7); /* C7 /0 */ 6356 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6357 ins_pipe(ialu_mem_imm); 6358 %} 6359 6360 // Store Short/Char Immediate 6361 instruct storeImmC0(memory mem, immI0 zero) 6362 %{ 6363 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6364 match(Set mem (StoreC mem zero)); 6365 6366 ins_cost(125); // XXX 6367 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6368 ins_encode %{ 6369 __ movw($mem$$Address, r12); 6370 %} 6371 ins_pipe(ialu_mem_reg); 6372 %} 6373 6374 instruct storeImmI16(memory mem, immI16 src) 6375 %{ 6376 predicate(UseStoreImmI16); 6377 match(Set mem (StoreC mem src)); 6378 6379 ins_cost(150); 6380 format %{ "movw $mem, $src\t# short/char" %} 6381 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6382 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6383 ins_pipe(ialu_mem_imm); 6384 %} 6385 6386 // Store Byte Immediate 6387 instruct storeImmB0(memory mem, immI0 zero) 6388 %{ 6389 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6390 match(Set mem (StoreB mem zero)); 6391 6392 ins_cost(125); // XXX 6393 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6394 ins_encode %{ 6395 __ movb($mem$$Address, r12); 6396 %} 6397 ins_pipe(ialu_mem_reg); 6398 %} 6399 6400 instruct storeImmB(memory mem, immI8 src) 6401 %{ 6402 match(Set mem (StoreB mem src)); 6403 6404 ins_cost(150); // XXX 6405 format %{ "movb $mem, $src\t# byte" %} 6406 opcode(0xC6); /* C6 /0 */ 6407 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6408 ins_pipe(ialu_mem_imm); 6409 %} 6410 6411 // Store CMS card-mark Immediate 6412 instruct storeImmCM0_reg(memory mem, immI0 zero) 6413 %{ 6414 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6415 match(Set mem (StoreCM mem zero)); 6416 6417 ins_cost(125); // XXX 6418 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6419 ins_encode %{ 6420 __ movb($mem$$Address, r12); 6421 %} 6422 ins_pipe(ialu_mem_reg); 6423 %} 6424 6425 instruct storeImmCM0(memory mem, immI0 src) 6426 %{ 6427 match(Set mem (StoreCM mem src)); 6428 6429 ins_cost(150); // XXX 6430 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6431 opcode(0xC6); /* C6 /0 */ 6432 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6433 ins_pipe(ialu_mem_imm); 6434 %} 6435 6436 // Store Float 6437 instruct storeF(memory mem, regF src) 6438 %{ 6439 match(Set mem (StoreF mem src)); 6440 6441 ins_cost(95); // XXX 6442 format %{ "movss $mem, $src\t# float" %} 6443 ins_encode %{ 6444 __ movflt($mem$$Address, $src$$XMMRegister); 6445 %} 6446 ins_pipe(pipe_slow); // XXX 6447 %} 6448 6449 // Store immediate Float value (it is faster than store from XMM register) 6450 instruct storeF0(memory mem, immF0 zero) 6451 %{ 6452 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6453 match(Set mem (StoreF mem zero)); 6454 6455 ins_cost(25); // XXX 6456 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6457 ins_encode %{ 6458 __ movl($mem$$Address, r12); 6459 %} 6460 ins_pipe(ialu_mem_reg); 6461 %} 6462 6463 instruct storeF_imm(memory mem, immF src) 6464 %{ 6465 match(Set mem (StoreF mem src)); 6466 6467 ins_cost(50); 6468 format %{ "movl $mem, $src\t# float" %} 6469 opcode(0xC7); /* C7 /0 */ 6470 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6471 ins_pipe(ialu_mem_imm); 6472 %} 6473 6474 // Store Double 6475 instruct storeD(memory mem, regD src) 6476 %{ 6477 match(Set mem (StoreD mem src)); 6478 6479 ins_cost(95); // XXX 6480 format %{ "movsd $mem, $src\t# double" %} 6481 ins_encode %{ 6482 __ movdbl($mem$$Address, $src$$XMMRegister); 6483 %} 6484 ins_pipe(pipe_slow); // XXX 6485 %} 6486 6487 // Store immediate double 0.0 (it is faster than store from XMM register) 6488 instruct storeD0_imm(memory mem, immD0 src) 6489 %{ 6490 predicate(!UseCompressedOops || (CompressedOops::base() != NULL)); 6491 match(Set mem (StoreD mem src)); 6492 6493 ins_cost(50); 6494 format %{ "movq $mem, $src\t# double 0." %} 6495 opcode(0xC7); /* C7 /0 */ 6496 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6497 ins_pipe(ialu_mem_imm); 6498 %} 6499 6500 instruct storeD0(memory mem, immD0 zero) 6501 %{ 6502 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6503 match(Set mem (StoreD mem zero)); 6504 6505 ins_cost(25); // XXX 6506 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6507 ins_encode %{ 6508 __ movq($mem$$Address, r12); 6509 %} 6510 ins_pipe(ialu_mem_reg); 6511 %} 6512 6513 instruct storeSSI(stackSlotI dst, rRegI src) 6514 %{ 6515 match(Set dst src); 6516 6517 ins_cost(100); 6518 format %{ "movl $dst, $src\t# int stk" %} 6519 opcode(0x89); 6520 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6521 ins_pipe( ialu_mem_reg ); 6522 %} 6523 6524 instruct storeSSL(stackSlotL dst, rRegL src) 6525 %{ 6526 match(Set dst src); 6527 6528 ins_cost(100); 6529 format %{ "movq $dst, $src\t# long stk" %} 6530 opcode(0x89); 6531 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6532 ins_pipe(ialu_mem_reg); 6533 %} 6534 6535 instruct storeSSP(stackSlotP dst, rRegP src) 6536 %{ 6537 match(Set dst src); 6538 6539 ins_cost(100); 6540 format %{ "movq $dst, $src\t# ptr stk" %} 6541 opcode(0x89); 6542 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6543 ins_pipe(ialu_mem_reg); 6544 %} 6545 6546 instruct storeSSF(stackSlotF dst, regF src) 6547 %{ 6548 match(Set dst src); 6549 6550 ins_cost(95); // XXX 6551 format %{ "movss $dst, $src\t# float stk" %} 6552 ins_encode %{ 6553 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6554 %} 6555 ins_pipe(pipe_slow); // XXX 6556 %} 6557 6558 instruct storeSSD(stackSlotD dst, regD src) 6559 %{ 6560 match(Set dst src); 6561 6562 ins_cost(95); // XXX 6563 format %{ "movsd $dst, $src\t# double stk" %} 6564 ins_encode %{ 6565 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6566 %} 6567 ins_pipe(pipe_slow); // XXX 6568 %} 6569 6570 //----------BSWAP Instructions------------------------------------------------- 6571 instruct bytes_reverse_int(rRegI dst) %{ 6572 match(Set dst (ReverseBytesI dst)); 6573 6574 format %{ "bswapl $dst" %} 6575 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6576 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6577 ins_pipe( ialu_reg ); 6578 %} 6579 6580 instruct bytes_reverse_long(rRegL dst) %{ 6581 match(Set dst (ReverseBytesL dst)); 6582 6583 format %{ "bswapq $dst" %} 6584 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6585 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6586 ins_pipe( ialu_reg); 6587 %} 6588 6589 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6590 match(Set dst (ReverseBytesUS dst)); 6591 effect(KILL cr); 6592 6593 format %{ "bswapl $dst\n\t" 6594 "shrl $dst,16\n\t" %} 6595 ins_encode %{ 6596 __ bswapl($dst$$Register); 6597 __ shrl($dst$$Register, 16); 6598 %} 6599 ins_pipe( ialu_reg ); 6600 %} 6601 6602 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6603 match(Set dst (ReverseBytesS dst)); 6604 effect(KILL cr); 6605 6606 format %{ "bswapl $dst\n\t" 6607 "sar $dst,16\n\t" %} 6608 ins_encode %{ 6609 __ bswapl($dst$$Register); 6610 __ sarl($dst$$Register, 16); 6611 %} 6612 ins_pipe( ialu_reg ); 6613 %} 6614 6615 //---------- Zeros Count Instructions ------------------------------------------ 6616 6617 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6618 predicate(UseCountLeadingZerosInstruction); 6619 match(Set dst (CountLeadingZerosI src)); 6620 effect(KILL cr); 6621 6622 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6623 ins_encode %{ 6624 __ lzcntl($dst$$Register, $src$$Register); 6625 %} 6626 ins_pipe(ialu_reg); 6627 %} 6628 6629 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6630 predicate(!UseCountLeadingZerosInstruction); 6631 match(Set dst (CountLeadingZerosI src)); 6632 effect(KILL cr); 6633 6634 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6635 "jnz skip\n\t" 6636 "movl $dst, -1\n" 6637 "skip:\n\t" 6638 "negl $dst\n\t" 6639 "addl $dst, 31" %} 6640 ins_encode %{ 6641 Register Rdst = $dst$$Register; 6642 Register Rsrc = $src$$Register; 6643 Label skip; 6644 __ bsrl(Rdst, Rsrc); 6645 __ jccb(Assembler::notZero, skip); 6646 __ movl(Rdst, -1); 6647 __ bind(skip); 6648 __ negl(Rdst); 6649 __ addl(Rdst, BitsPerInt - 1); 6650 %} 6651 ins_pipe(ialu_reg); 6652 %} 6653 6654 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6655 predicate(UseCountLeadingZerosInstruction); 6656 match(Set dst (CountLeadingZerosL src)); 6657 effect(KILL cr); 6658 6659 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6660 ins_encode %{ 6661 __ lzcntq($dst$$Register, $src$$Register); 6662 %} 6663 ins_pipe(ialu_reg); 6664 %} 6665 6666 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6667 predicate(!UseCountLeadingZerosInstruction); 6668 match(Set dst (CountLeadingZerosL src)); 6669 effect(KILL cr); 6670 6671 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6672 "jnz skip\n\t" 6673 "movl $dst, -1\n" 6674 "skip:\n\t" 6675 "negl $dst\n\t" 6676 "addl $dst, 63" %} 6677 ins_encode %{ 6678 Register Rdst = $dst$$Register; 6679 Register Rsrc = $src$$Register; 6680 Label skip; 6681 __ bsrq(Rdst, Rsrc); 6682 __ jccb(Assembler::notZero, skip); 6683 __ movl(Rdst, -1); 6684 __ bind(skip); 6685 __ negl(Rdst); 6686 __ addl(Rdst, BitsPerLong - 1); 6687 %} 6688 ins_pipe(ialu_reg); 6689 %} 6690 6691 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6692 predicate(UseCountTrailingZerosInstruction); 6693 match(Set dst (CountTrailingZerosI src)); 6694 effect(KILL cr); 6695 6696 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6697 ins_encode %{ 6698 __ tzcntl($dst$$Register, $src$$Register); 6699 %} 6700 ins_pipe(ialu_reg); 6701 %} 6702 6703 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6704 predicate(!UseCountTrailingZerosInstruction); 6705 match(Set dst (CountTrailingZerosI src)); 6706 effect(KILL cr); 6707 6708 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6709 "jnz done\n\t" 6710 "movl $dst, 32\n" 6711 "done:" %} 6712 ins_encode %{ 6713 Register Rdst = $dst$$Register; 6714 Label done; 6715 __ bsfl(Rdst, $src$$Register); 6716 __ jccb(Assembler::notZero, done); 6717 __ movl(Rdst, BitsPerInt); 6718 __ bind(done); 6719 %} 6720 ins_pipe(ialu_reg); 6721 %} 6722 6723 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6724 predicate(UseCountTrailingZerosInstruction); 6725 match(Set dst (CountTrailingZerosL src)); 6726 effect(KILL cr); 6727 6728 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6729 ins_encode %{ 6730 __ tzcntq($dst$$Register, $src$$Register); 6731 %} 6732 ins_pipe(ialu_reg); 6733 %} 6734 6735 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6736 predicate(!UseCountTrailingZerosInstruction); 6737 match(Set dst (CountTrailingZerosL src)); 6738 effect(KILL cr); 6739 6740 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6741 "jnz done\n\t" 6742 "movl $dst, 64\n" 6743 "done:" %} 6744 ins_encode %{ 6745 Register Rdst = $dst$$Register; 6746 Label done; 6747 __ bsfq(Rdst, $src$$Register); 6748 __ jccb(Assembler::notZero, done); 6749 __ movl(Rdst, BitsPerLong); 6750 __ bind(done); 6751 %} 6752 ins_pipe(ialu_reg); 6753 %} 6754 6755 6756 //---------- Population Count Instructions ------------------------------------- 6757 6758 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6759 predicate(UsePopCountInstruction); 6760 match(Set dst (PopCountI src)); 6761 effect(KILL cr); 6762 6763 format %{ "popcnt $dst, $src" %} 6764 ins_encode %{ 6765 __ popcntl($dst$$Register, $src$$Register); 6766 %} 6767 ins_pipe(ialu_reg); 6768 %} 6769 6770 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6771 predicate(UsePopCountInstruction); 6772 match(Set dst (PopCountI (LoadI mem))); 6773 effect(KILL cr); 6774 6775 format %{ "popcnt $dst, $mem" %} 6776 ins_encode %{ 6777 __ popcntl($dst$$Register, $mem$$Address); 6778 %} 6779 ins_pipe(ialu_reg); 6780 %} 6781 6782 // Note: Long.bitCount(long) returns an int. 6783 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6784 predicate(UsePopCountInstruction); 6785 match(Set dst (PopCountL src)); 6786 effect(KILL cr); 6787 6788 format %{ "popcnt $dst, $src" %} 6789 ins_encode %{ 6790 __ popcntq($dst$$Register, $src$$Register); 6791 %} 6792 ins_pipe(ialu_reg); 6793 %} 6794 6795 // Note: Long.bitCount(long) returns an int. 6796 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6797 predicate(UsePopCountInstruction); 6798 match(Set dst (PopCountL (LoadL mem))); 6799 effect(KILL cr); 6800 6801 format %{ "popcnt $dst, $mem" %} 6802 ins_encode %{ 6803 __ popcntq($dst$$Register, $mem$$Address); 6804 %} 6805 ins_pipe(ialu_reg); 6806 %} 6807 6808 6809 //----------MemBar Instructions----------------------------------------------- 6810 // Memory barrier flavors 6811 6812 instruct membar_acquire() 6813 %{ 6814 match(MemBarAcquire); 6815 match(LoadFence); 6816 ins_cost(0); 6817 6818 size(0); 6819 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6820 ins_encode(); 6821 ins_pipe(empty); 6822 %} 6823 6824 instruct membar_acquire_lock() 6825 %{ 6826 match(MemBarAcquireLock); 6827 ins_cost(0); 6828 6829 size(0); 6830 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6831 ins_encode(); 6832 ins_pipe(empty); 6833 %} 6834 6835 instruct membar_release() 6836 %{ 6837 match(MemBarRelease); 6838 match(StoreFence); 6839 ins_cost(0); 6840 6841 size(0); 6842 format %{ "MEMBAR-release ! (empty encoding)" %} 6843 ins_encode(); 6844 ins_pipe(empty); 6845 %} 6846 6847 instruct membar_release_lock() 6848 %{ 6849 match(MemBarReleaseLock); 6850 ins_cost(0); 6851 6852 size(0); 6853 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6854 ins_encode(); 6855 ins_pipe(empty); 6856 %} 6857 6858 instruct membar_volatile(rFlagsReg cr) %{ 6859 match(MemBarVolatile); 6860 effect(KILL cr); 6861 ins_cost(400); 6862 6863 format %{ 6864 $$template 6865 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6866 %} 6867 ins_encode %{ 6868 __ membar(Assembler::StoreLoad); 6869 %} 6870 ins_pipe(pipe_slow); 6871 %} 6872 6873 instruct unnecessary_membar_volatile() 6874 %{ 6875 match(MemBarVolatile); 6876 predicate(Matcher::post_store_load_barrier(n)); 6877 ins_cost(0); 6878 6879 size(0); 6880 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6881 ins_encode(); 6882 ins_pipe(empty); 6883 %} 6884 6885 instruct membar_storestore() %{ 6886 match(MemBarStoreStore); 6887 ins_cost(0); 6888 6889 size(0); 6890 format %{ "MEMBAR-storestore (empty encoding)" %} 6891 ins_encode( ); 6892 ins_pipe(empty); 6893 %} 6894 6895 //----------Move Instructions-------------------------------------------------- 6896 6897 instruct castX2P(rRegP dst, rRegL src) 6898 %{ 6899 match(Set dst (CastX2P src)); 6900 6901 format %{ "movq $dst, $src\t# long->ptr" %} 6902 ins_encode %{ 6903 if ($dst$$reg != $src$$reg) { 6904 __ movptr($dst$$Register, $src$$Register); 6905 } 6906 %} 6907 ins_pipe(ialu_reg_reg); // XXX 6908 %} 6909 6910 instruct castN2X(rRegL dst, rRegN src) 6911 %{ 6912 match(Set dst (CastP2X src)); 6913 6914 format %{ "movq $dst, $src\t# ptr -> long" %} 6915 ins_encode %{ 6916 if ($dst$$reg != $src$$reg) { 6917 __ movptr($dst$$Register, $src$$Register); 6918 } 6919 %} 6920 ins_pipe(ialu_reg_reg); // XXX 6921 %} 6922 6923 instruct castP2X(rRegL dst, rRegP src) 6924 %{ 6925 match(Set dst (CastP2X src)); 6926 6927 format %{ "movq $dst, $src\t# ptr -> long" %} 6928 ins_encode %{ 6929 if ($dst$$reg != $src$$reg) { 6930 __ movptr($dst$$Register, $src$$Register); 6931 } 6932 %} 6933 ins_pipe(ialu_reg_reg); // XXX 6934 %} 6935 6936 // Convert oop into int for vectors alignment masking 6937 instruct convP2I(rRegI dst, rRegP src) 6938 %{ 6939 match(Set dst (ConvL2I (CastP2X src))); 6940 6941 format %{ "movl $dst, $src\t# ptr -> int" %} 6942 ins_encode %{ 6943 __ movl($dst$$Register, $src$$Register); 6944 %} 6945 ins_pipe(ialu_reg_reg); // XXX 6946 %} 6947 6948 // Convert compressed oop into int for vectors alignment masking 6949 // in case of 32bit oops (heap < 4Gb). 6950 instruct convN2I(rRegI dst, rRegN src) 6951 %{ 6952 predicate(CompressedOops::shift() == 0); 6953 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6954 6955 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6956 ins_encode %{ 6957 __ movl($dst$$Register, $src$$Register); 6958 %} 6959 ins_pipe(ialu_reg_reg); // XXX 6960 %} 6961 6962 // Convert oop pointer into compressed form 6963 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6964 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6965 match(Set dst (EncodeP src)); 6966 effect(KILL cr); 6967 format %{ "encode_heap_oop $dst,$src" %} 6968 ins_encode %{ 6969 Register s = $src$$Register; 6970 Register d = $dst$$Register; 6971 if (s != d) { 6972 __ movq(d, s); 6973 } 6974 __ encode_heap_oop(d); 6975 %} 6976 ins_pipe(ialu_reg_long); 6977 %} 6978 6979 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6980 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6981 match(Set dst (EncodeP src)); 6982 effect(KILL cr); 6983 format %{ "encode_heap_oop_not_null $dst,$src" %} 6984 ins_encode %{ 6985 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6986 %} 6987 ins_pipe(ialu_reg_long); 6988 %} 6989 6990 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6991 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6992 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6993 match(Set dst (DecodeN src)); 6994 effect(KILL cr); 6995 format %{ "decode_heap_oop $dst,$src" %} 6996 ins_encode %{ 6997 Register s = $src$$Register; 6998 Register d = $dst$$Register; 6999 if (s != d) { 7000 __ movq(d, s); 7001 } 7002 __ decode_heap_oop(d); 7003 %} 7004 ins_pipe(ialu_reg_long); 7005 %} 7006 7007 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7008 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7009 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7010 match(Set dst (DecodeN src)); 7011 effect(KILL cr); 7012 format %{ "decode_heap_oop_not_null $dst,$src" %} 7013 ins_encode %{ 7014 Register s = $src$$Register; 7015 Register d = $dst$$Register; 7016 if (s != d) { 7017 __ decode_heap_oop_not_null(d, s); 7018 } else { 7019 __ decode_heap_oop_not_null(d); 7020 } 7021 %} 7022 ins_pipe(ialu_reg_long); 7023 %} 7024 7025 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7026 match(Set dst (EncodePKlass src)); 7027 effect(KILL cr); 7028 format %{ "encode_klass_not_null $dst,$src" %} 7029 ins_encode %{ 7030 __ encode_klass_not_null($dst$$Register, $src$$Register); 7031 %} 7032 ins_pipe(ialu_reg_long); 7033 %} 7034 7035 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7036 match(Set dst (DecodeNKlass src)); 7037 effect(KILL cr); 7038 format %{ "decode_klass_not_null $dst,$src" %} 7039 ins_encode %{ 7040 Register s = $src$$Register; 7041 Register d = $dst$$Register; 7042 if (s != d) { 7043 __ decode_klass_not_null(d, s); 7044 } else { 7045 __ decode_klass_not_null(d); 7046 } 7047 %} 7048 ins_pipe(ialu_reg_long); 7049 %} 7050 7051 7052 //----------Conditional Move--------------------------------------------------- 7053 // Jump 7054 // dummy instruction for generating temp registers 7055 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7056 match(Jump (LShiftL switch_val shift)); 7057 ins_cost(350); 7058 predicate(false); 7059 effect(TEMP dest); 7060 7061 format %{ "leaq $dest, [$constantaddress]\n\t" 7062 "jmp [$dest + $switch_val << $shift]\n\t" %} 7063 ins_encode %{ 7064 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7065 // to do that and the compiler is using that register as one it can allocate. 7066 // So we build it all by hand. 7067 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 7068 // ArrayAddress dispatch(table, index); 7069 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 7070 __ lea($dest$$Register, $constantaddress); 7071 __ jmp(dispatch); 7072 %} 7073 ins_pipe(pipe_jmp); 7074 %} 7075 7076 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7077 match(Jump (AddL (LShiftL switch_val shift) offset)); 7078 ins_cost(350); 7079 effect(TEMP dest); 7080 7081 format %{ "leaq $dest, [$constantaddress]\n\t" 7082 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7083 ins_encode %{ 7084 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7085 // to do that and the compiler is using that register as one it can allocate. 7086 // So we build it all by hand. 7087 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7088 // ArrayAddress dispatch(table, index); 7089 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7090 __ lea($dest$$Register, $constantaddress); 7091 __ jmp(dispatch); 7092 %} 7093 ins_pipe(pipe_jmp); 7094 %} 7095 7096 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7097 match(Jump switch_val); 7098 ins_cost(350); 7099 effect(TEMP dest); 7100 7101 format %{ "leaq $dest, [$constantaddress]\n\t" 7102 "jmp [$dest + $switch_val]\n\t" %} 7103 ins_encode %{ 7104 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7105 // to do that and the compiler is using that register as one it can allocate. 7106 // So we build it all by hand. 7107 // Address index(noreg, switch_reg, Address::times_1); 7108 // ArrayAddress dispatch(table, index); 7109 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 7110 __ lea($dest$$Register, $constantaddress); 7111 __ jmp(dispatch); 7112 %} 7113 ins_pipe(pipe_jmp); 7114 %} 7115 7116 // Conditional move 7117 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 7118 %{ 7119 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7120 7121 ins_cost(200); // XXX 7122 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7123 opcode(0x0F, 0x40); 7124 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7125 ins_pipe(pipe_cmov_reg); 7126 %} 7127 7128 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 7129 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7130 7131 ins_cost(200); // XXX 7132 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7133 opcode(0x0F, 0x40); 7134 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7135 ins_pipe(pipe_cmov_reg); 7136 %} 7137 7138 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 7139 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7140 ins_cost(200); 7141 expand %{ 7142 cmovI_regU(cop, cr, dst, src); 7143 %} 7144 %} 7145 7146 // Conditional move 7147 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7148 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7149 7150 ins_cost(250); // XXX 7151 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7152 opcode(0x0F, 0x40); 7153 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7154 ins_pipe(pipe_cmov_mem); 7155 %} 7156 7157 // Conditional move 7158 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7159 %{ 7160 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7161 7162 ins_cost(250); // XXX 7163 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7164 opcode(0x0F, 0x40); 7165 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7166 ins_pipe(pipe_cmov_mem); 7167 %} 7168 7169 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7170 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7171 ins_cost(250); 7172 expand %{ 7173 cmovI_memU(cop, cr, dst, src); 7174 %} 7175 %} 7176 7177 // Conditional move 7178 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7179 %{ 7180 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7181 7182 ins_cost(200); // XXX 7183 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7184 opcode(0x0F, 0x40); 7185 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7186 ins_pipe(pipe_cmov_reg); 7187 %} 7188 7189 // Conditional move 7190 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7191 %{ 7192 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7193 7194 ins_cost(200); // XXX 7195 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7196 opcode(0x0F, 0x40); 7197 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7198 ins_pipe(pipe_cmov_reg); 7199 %} 7200 7201 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7202 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7203 ins_cost(200); 7204 expand %{ 7205 cmovN_regU(cop, cr, dst, src); 7206 %} 7207 %} 7208 7209 // Conditional move 7210 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7211 %{ 7212 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7213 7214 ins_cost(200); // XXX 7215 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7216 opcode(0x0F, 0x40); 7217 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7218 ins_pipe(pipe_cmov_reg); // XXX 7219 %} 7220 7221 // Conditional move 7222 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7223 %{ 7224 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7225 7226 ins_cost(200); // XXX 7227 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7228 opcode(0x0F, 0x40); 7229 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7230 ins_pipe(pipe_cmov_reg); // XXX 7231 %} 7232 7233 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7234 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7235 ins_cost(200); 7236 expand %{ 7237 cmovP_regU(cop, cr, dst, src); 7238 %} 7239 %} 7240 7241 // DISABLED: Requires the ADLC to emit a bottom_type call that 7242 // correctly meets the two pointer arguments; one is an incoming 7243 // register but the other is a memory operand. ALSO appears to 7244 // be buggy with implicit null checks. 7245 // 7246 //// Conditional move 7247 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7248 //%{ 7249 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7250 // ins_cost(250); 7251 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7252 // opcode(0x0F,0x40); 7253 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7254 // ins_pipe( pipe_cmov_mem ); 7255 //%} 7256 // 7257 //// Conditional move 7258 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7259 //%{ 7260 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7261 // ins_cost(250); 7262 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7263 // opcode(0x0F,0x40); 7264 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7265 // ins_pipe( pipe_cmov_mem ); 7266 //%} 7267 7268 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7269 %{ 7270 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7271 7272 ins_cost(200); // XXX 7273 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7274 opcode(0x0F, 0x40); 7275 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7276 ins_pipe(pipe_cmov_reg); // XXX 7277 %} 7278 7279 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7280 %{ 7281 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7282 7283 ins_cost(200); // XXX 7284 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7285 opcode(0x0F, 0x40); 7286 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7287 ins_pipe(pipe_cmov_mem); // XXX 7288 %} 7289 7290 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7291 %{ 7292 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7293 7294 ins_cost(200); // XXX 7295 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7296 opcode(0x0F, 0x40); 7297 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7298 ins_pipe(pipe_cmov_reg); // XXX 7299 %} 7300 7301 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7302 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7303 ins_cost(200); 7304 expand %{ 7305 cmovL_regU(cop, cr, dst, src); 7306 %} 7307 %} 7308 7309 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7310 %{ 7311 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7312 7313 ins_cost(200); // XXX 7314 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7315 opcode(0x0F, 0x40); 7316 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7317 ins_pipe(pipe_cmov_mem); // XXX 7318 %} 7319 7320 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7321 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7322 ins_cost(200); 7323 expand %{ 7324 cmovL_memU(cop, cr, dst, src); 7325 %} 7326 %} 7327 7328 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7329 %{ 7330 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7331 7332 ins_cost(200); // XXX 7333 format %{ "jn$cop skip\t# signed cmove float\n\t" 7334 "movss $dst, $src\n" 7335 "skip:" %} 7336 ins_encode %{ 7337 Label Lskip; 7338 // Invert sense of branch from sense of CMOV 7339 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7340 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7341 __ bind(Lskip); 7342 %} 7343 ins_pipe(pipe_slow); 7344 %} 7345 7346 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7347 // %{ 7348 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7349 7350 // ins_cost(200); // XXX 7351 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7352 // "movss $dst, $src\n" 7353 // "skip:" %} 7354 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7355 // ins_pipe(pipe_slow); 7356 // %} 7357 7358 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7359 %{ 7360 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7361 7362 ins_cost(200); // XXX 7363 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7364 "movss $dst, $src\n" 7365 "skip:" %} 7366 ins_encode %{ 7367 Label Lskip; 7368 // Invert sense of branch from sense of CMOV 7369 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7370 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7371 __ bind(Lskip); 7372 %} 7373 ins_pipe(pipe_slow); 7374 %} 7375 7376 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7377 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7378 ins_cost(200); 7379 expand %{ 7380 cmovF_regU(cop, cr, dst, src); 7381 %} 7382 %} 7383 7384 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7385 %{ 7386 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7387 7388 ins_cost(200); // XXX 7389 format %{ "jn$cop skip\t# signed cmove double\n\t" 7390 "movsd $dst, $src\n" 7391 "skip:" %} 7392 ins_encode %{ 7393 Label Lskip; 7394 // Invert sense of branch from sense of CMOV 7395 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7396 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7397 __ bind(Lskip); 7398 %} 7399 ins_pipe(pipe_slow); 7400 %} 7401 7402 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7403 %{ 7404 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7405 7406 ins_cost(200); // XXX 7407 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7408 "movsd $dst, $src\n" 7409 "skip:" %} 7410 ins_encode %{ 7411 Label Lskip; 7412 // Invert sense of branch from sense of CMOV 7413 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7414 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7415 __ bind(Lskip); 7416 %} 7417 ins_pipe(pipe_slow); 7418 %} 7419 7420 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7421 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7422 ins_cost(200); 7423 expand %{ 7424 cmovD_regU(cop, cr, dst, src); 7425 %} 7426 %} 7427 7428 //----------Arithmetic Instructions-------------------------------------------- 7429 //----------Addition Instructions---------------------------------------------- 7430 7431 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7432 %{ 7433 match(Set dst (AddI dst src)); 7434 effect(KILL cr); 7435 7436 format %{ "addl $dst, $src\t# int" %} 7437 opcode(0x03); 7438 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7439 ins_pipe(ialu_reg_reg); 7440 %} 7441 7442 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7443 %{ 7444 match(Set dst (AddI dst src)); 7445 effect(KILL cr); 7446 7447 format %{ "addl $dst, $src\t# int" %} 7448 opcode(0x81, 0x00); /* /0 id */ 7449 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7450 ins_pipe( ialu_reg ); 7451 %} 7452 7453 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7454 %{ 7455 match(Set dst (AddI dst (LoadI src))); 7456 effect(KILL cr); 7457 7458 ins_cost(125); // XXX 7459 format %{ "addl $dst, $src\t# int" %} 7460 opcode(0x03); 7461 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7462 ins_pipe(ialu_reg_mem); 7463 %} 7464 7465 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7466 %{ 7467 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7468 effect(KILL cr); 7469 7470 ins_cost(150); // XXX 7471 format %{ "addl $dst, $src\t# int" %} 7472 opcode(0x01); /* Opcode 01 /r */ 7473 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7474 ins_pipe(ialu_mem_reg); 7475 %} 7476 7477 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7478 %{ 7479 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7480 effect(KILL cr); 7481 7482 ins_cost(125); // XXX 7483 format %{ "addl $dst, $src\t# int" %} 7484 opcode(0x81); /* Opcode 81 /0 id */ 7485 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7486 ins_pipe(ialu_mem_imm); 7487 %} 7488 7489 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7490 %{ 7491 predicate(UseIncDec); 7492 match(Set dst (AddI dst src)); 7493 effect(KILL cr); 7494 7495 format %{ "incl $dst\t# int" %} 7496 opcode(0xFF, 0x00); // FF /0 7497 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7498 ins_pipe(ialu_reg); 7499 %} 7500 7501 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7502 %{ 7503 predicate(UseIncDec); 7504 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7505 effect(KILL cr); 7506 7507 ins_cost(125); // XXX 7508 format %{ "incl $dst\t# int" %} 7509 opcode(0xFF); /* Opcode FF /0 */ 7510 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7511 ins_pipe(ialu_mem_imm); 7512 %} 7513 7514 // XXX why does that use AddI 7515 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7516 %{ 7517 predicate(UseIncDec); 7518 match(Set dst (AddI dst src)); 7519 effect(KILL cr); 7520 7521 format %{ "decl $dst\t# int" %} 7522 opcode(0xFF, 0x01); // FF /1 7523 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7524 ins_pipe(ialu_reg); 7525 %} 7526 7527 // XXX why does that use AddI 7528 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7529 %{ 7530 predicate(UseIncDec); 7531 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7532 effect(KILL cr); 7533 7534 ins_cost(125); // XXX 7535 format %{ "decl $dst\t# int" %} 7536 opcode(0xFF); /* Opcode FF /1 */ 7537 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7538 ins_pipe(ialu_mem_imm); 7539 %} 7540 7541 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7542 %{ 7543 match(Set dst (AddI src0 src1)); 7544 7545 ins_cost(110); 7546 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7547 opcode(0x8D); /* 0x8D /r */ 7548 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7549 ins_pipe(ialu_reg_reg); 7550 %} 7551 7552 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7553 %{ 7554 match(Set dst (AddL dst src)); 7555 effect(KILL cr); 7556 7557 format %{ "addq $dst, $src\t# long" %} 7558 opcode(0x03); 7559 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7560 ins_pipe(ialu_reg_reg); 7561 %} 7562 7563 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7564 %{ 7565 match(Set dst (AddL dst src)); 7566 effect(KILL cr); 7567 7568 format %{ "addq $dst, $src\t# long" %} 7569 opcode(0x81, 0x00); /* /0 id */ 7570 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7571 ins_pipe( ialu_reg ); 7572 %} 7573 7574 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7575 %{ 7576 match(Set dst (AddL dst (LoadL src))); 7577 effect(KILL cr); 7578 7579 ins_cost(125); // XXX 7580 format %{ "addq $dst, $src\t# long" %} 7581 opcode(0x03); 7582 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7583 ins_pipe(ialu_reg_mem); 7584 %} 7585 7586 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7587 %{ 7588 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7589 effect(KILL cr); 7590 7591 ins_cost(150); // XXX 7592 format %{ "addq $dst, $src\t# long" %} 7593 opcode(0x01); /* Opcode 01 /r */ 7594 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7595 ins_pipe(ialu_mem_reg); 7596 %} 7597 7598 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7599 %{ 7600 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7601 effect(KILL cr); 7602 7603 ins_cost(125); // XXX 7604 format %{ "addq $dst, $src\t# long" %} 7605 opcode(0x81); /* Opcode 81 /0 id */ 7606 ins_encode(REX_mem_wide(dst), 7607 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7608 ins_pipe(ialu_mem_imm); 7609 %} 7610 7611 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7612 %{ 7613 predicate(UseIncDec); 7614 match(Set dst (AddL dst src)); 7615 effect(KILL cr); 7616 7617 format %{ "incq $dst\t# long" %} 7618 opcode(0xFF, 0x00); // FF /0 7619 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7620 ins_pipe(ialu_reg); 7621 %} 7622 7623 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7624 %{ 7625 predicate(UseIncDec); 7626 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7627 effect(KILL cr); 7628 7629 ins_cost(125); // XXX 7630 format %{ "incq $dst\t# long" %} 7631 opcode(0xFF); /* Opcode FF /0 */ 7632 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7633 ins_pipe(ialu_mem_imm); 7634 %} 7635 7636 // XXX why does that use AddL 7637 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7638 %{ 7639 predicate(UseIncDec); 7640 match(Set dst (AddL dst src)); 7641 effect(KILL cr); 7642 7643 format %{ "decq $dst\t# long" %} 7644 opcode(0xFF, 0x01); // FF /1 7645 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7646 ins_pipe(ialu_reg); 7647 %} 7648 7649 // XXX why does that use AddL 7650 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7651 %{ 7652 predicate(UseIncDec); 7653 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7654 effect(KILL cr); 7655 7656 ins_cost(125); // XXX 7657 format %{ "decq $dst\t# long" %} 7658 opcode(0xFF); /* Opcode FF /1 */ 7659 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7660 ins_pipe(ialu_mem_imm); 7661 %} 7662 7663 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7664 %{ 7665 match(Set dst (AddL src0 src1)); 7666 7667 ins_cost(110); 7668 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7669 opcode(0x8D); /* 0x8D /r */ 7670 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7671 ins_pipe(ialu_reg_reg); 7672 %} 7673 7674 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7675 %{ 7676 match(Set dst (AddP dst src)); 7677 effect(KILL cr); 7678 7679 format %{ "addq $dst, $src\t# ptr" %} 7680 opcode(0x03); 7681 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7682 ins_pipe(ialu_reg_reg); 7683 %} 7684 7685 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7686 %{ 7687 match(Set dst (AddP dst src)); 7688 effect(KILL cr); 7689 7690 format %{ "addq $dst, $src\t# ptr" %} 7691 opcode(0x81, 0x00); /* /0 id */ 7692 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7693 ins_pipe( ialu_reg ); 7694 %} 7695 7696 // XXX addP mem ops ???? 7697 7698 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7699 %{ 7700 match(Set dst (AddP src0 src1)); 7701 7702 ins_cost(110); 7703 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7704 opcode(0x8D); /* 0x8D /r */ 7705 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7706 ins_pipe(ialu_reg_reg); 7707 %} 7708 7709 instruct checkCastPP(rRegP dst) 7710 %{ 7711 match(Set dst (CheckCastPP dst)); 7712 7713 size(0); 7714 format %{ "# checkcastPP of $dst" %} 7715 ins_encode(/* empty encoding */); 7716 ins_pipe(empty); 7717 %} 7718 7719 instruct castPP(rRegP dst) 7720 %{ 7721 match(Set dst (CastPP dst)); 7722 7723 size(0); 7724 format %{ "# castPP of $dst" %} 7725 ins_encode(/* empty encoding */); 7726 ins_pipe(empty); 7727 %} 7728 7729 instruct castII(rRegI dst) 7730 %{ 7731 match(Set dst (CastII dst)); 7732 7733 size(0); 7734 format %{ "# castII of $dst" %} 7735 ins_encode(/* empty encoding */); 7736 ins_cost(0); 7737 ins_pipe(empty); 7738 %} 7739 7740 // LoadP-locked same as a regular LoadP when used with compare-swap 7741 instruct loadPLocked(rRegP dst, memory mem) 7742 %{ 7743 match(Set dst (LoadPLocked mem)); 7744 7745 ins_cost(125); // XXX 7746 format %{ "movq $dst, $mem\t# ptr locked" %} 7747 opcode(0x8B); 7748 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7749 ins_pipe(ialu_reg_mem); // XXX 7750 %} 7751 7752 // Conditional-store of the updated heap-top. 7753 // Used during allocation of the shared heap. 7754 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7755 7756 instruct storePConditional(memory heap_top_ptr, 7757 rax_RegP oldval, rRegP newval, 7758 rFlagsReg cr) 7759 %{ 7760 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7761 7762 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7763 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7764 opcode(0x0F, 0xB1); 7765 ins_encode(lock_prefix, 7766 REX_reg_mem_wide(newval, heap_top_ptr), 7767 OpcP, OpcS, 7768 reg_mem(newval, heap_top_ptr)); 7769 ins_pipe(pipe_cmpxchg); 7770 %} 7771 7772 // Conditional-store of an int value. 7773 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7774 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7775 %{ 7776 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7777 effect(KILL oldval); 7778 7779 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7780 opcode(0x0F, 0xB1); 7781 ins_encode(lock_prefix, 7782 REX_reg_mem(newval, mem), 7783 OpcP, OpcS, 7784 reg_mem(newval, mem)); 7785 ins_pipe(pipe_cmpxchg); 7786 %} 7787 7788 // Conditional-store of a long value. 7789 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7790 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7791 %{ 7792 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7793 effect(KILL oldval); 7794 7795 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7796 opcode(0x0F, 0xB1); 7797 ins_encode(lock_prefix, 7798 REX_reg_mem_wide(newval, mem), 7799 OpcP, OpcS, 7800 reg_mem(newval, mem)); 7801 ins_pipe(pipe_cmpxchg); 7802 %} 7803 7804 7805 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7806 instruct compareAndSwapP(rRegI res, 7807 memory mem_ptr, 7808 rax_RegP oldval, rRegP newval, 7809 rFlagsReg cr) 7810 %{ 7811 predicate(VM_Version::supports_cx8()); 7812 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7813 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7814 effect(KILL cr, KILL oldval); 7815 7816 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7817 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7818 "sete $res\n\t" 7819 "movzbl $res, $res" %} 7820 opcode(0x0F, 0xB1); 7821 ins_encode(lock_prefix, 7822 REX_reg_mem_wide(newval, mem_ptr), 7823 OpcP, OpcS, 7824 reg_mem(newval, mem_ptr), 7825 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7826 REX_reg_breg(res, res), // movzbl 7827 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7828 ins_pipe( pipe_cmpxchg ); 7829 %} 7830 7831 instruct compareAndSwapL(rRegI res, 7832 memory mem_ptr, 7833 rax_RegL oldval, rRegL newval, 7834 rFlagsReg cr) 7835 %{ 7836 predicate(VM_Version::supports_cx8()); 7837 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7838 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7839 effect(KILL cr, KILL oldval); 7840 7841 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7842 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7843 "sete $res\n\t" 7844 "movzbl $res, $res" %} 7845 opcode(0x0F, 0xB1); 7846 ins_encode(lock_prefix, 7847 REX_reg_mem_wide(newval, mem_ptr), 7848 OpcP, OpcS, 7849 reg_mem(newval, mem_ptr), 7850 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7851 REX_reg_breg(res, res), // movzbl 7852 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7853 ins_pipe( pipe_cmpxchg ); 7854 %} 7855 7856 instruct compareAndSwapI(rRegI res, 7857 memory mem_ptr, 7858 rax_RegI oldval, rRegI newval, 7859 rFlagsReg cr) 7860 %{ 7861 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7862 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7863 effect(KILL cr, KILL oldval); 7864 7865 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7866 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7867 "sete $res\n\t" 7868 "movzbl $res, $res" %} 7869 opcode(0x0F, 0xB1); 7870 ins_encode(lock_prefix, 7871 REX_reg_mem(newval, mem_ptr), 7872 OpcP, OpcS, 7873 reg_mem(newval, mem_ptr), 7874 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7875 REX_reg_breg(res, res), // movzbl 7876 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7877 ins_pipe( pipe_cmpxchg ); 7878 %} 7879 7880 instruct compareAndSwapB(rRegI res, 7881 memory mem_ptr, 7882 rax_RegI oldval, rRegI newval, 7883 rFlagsReg cr) 7884 %{ 7885 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7886 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7887 effect(KILL cr, KILL oldval); 7888 7889 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7890 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7891 "sete $res\n\t" 7892 "movzbl $res, $res" %} 7893 opcode(0x0F, 0xB0); 7894 ins_encode(lock_prefix, 7895 REX_breg_mem(newval, mem_ptr), 7896 OpcP, OpcS, 7897 reg_mem(newval, mem_ptr), 7898 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7899 REX_reg_breg(res, res), // movzbl 7900 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7901 ins_pipe( pipe_cmpxchg ); 7902 %} 7903 7904 instruct compareAndSwapS(rRegI res, 7905 memory mem_ptr, 7906 rax_RegI oldval, rRegI newval, 7907 rFlagsReg cr) 7908 %{ 7909 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7910 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7911 effect(KILL cr, KILL oldval); 7912 7913 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7914 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7915 "sete $res\n\t" 7916 "movzbl $res, $res" %} 7917 opcode(0x0F, 0xB1); 7918 ins_encode(lock_prefix, 7919 SizePrefix, 7920 REX_reg_mem(newval, mem_ptr), 7921 OpcP, OpcS, 7922 reg_mem(newval, mem_ptr), 7923 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7924 REX_reg_breg(res, res), // movzbl 7925 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7926 ins_pipe( pipe_cmpxchg ); 7927 %} 7928 7929 instruct compareAndSwapN(rRegI res, 7930 memory mem_ptr, 7931 rax_RegN oldval, rRegN newval, 7932 rFlagsReg cr) %{ 7933 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7934 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7935 effect(KILL cr, KILL oldval); 7936 7937 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7938 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7939 "sete $res\n\t" 7940 "movzbl $res, $res" %} 7941 opcode(0x0F, 0xB1); 7942 ins_encode(lock_prefix, 7943 REX_reg_mem(newval, mem_ptr), 7944 OpcP, OpcS, 7945 reg_mem(newval, mem_ptr), 7946 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7947 REX_reg_breg(res, res), // movzbl 7948 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7949 ins_pipe( pipe_cmpxchg ); 7950 %} 7951 7952 instruct compareAndExchangeB( 7953 memory mem_ptr, 7954 rax_RegI oldval, rRegI newval, 7955 rFlagsReg cr) 7956 %{ 7957 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7958 effect(KILL cr); 7959 7960 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7961 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7962 opcode(0x0F, 0xB0); 7963 ins_encode(lock_prefix, 7964 REX_breg_mem(newval, mem_ptr), 7965 OpcP, OpcS, 7966 reg_mem(newval, mem_ptr) // lock cmpxchg 7967 ); 7968 ins_pipe( pipe_cmpxchg ); 7969 %} 7970 7971 instruct compareAndExchangeS( 7972 memory mem_ptr, 7973 rax_RegI oldval, rRegI newval, 7974 rFlagsReg cr) 7975 %{ 7976 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7977 effect(KILL cr); 7978 7979 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7980 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7981 opcode(0x0F, 0xB1); 7982 ins_encode(lock_prefix, 7983 SizePrefix, 7984 REX_reg_mem(newval, mem_ptr), 7985 OpcP, OpcS, 7986 reg_mem(newval, mem_ptr) // lock cmpxchg 7987 ); 7988 ins_pipe( pipe_cmpxchg ); 7989 %} 7990 7991 instruct compareAndExchangeI( 7992 memory mem_ptr, 7993 rax_RegI oldval, rRegI newval, 7994 rFlagsReg cr) 7995 %{ 7996 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7997 effect(KILL cr); 7998 7999 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8000 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8001 opcode(0x0F, 0xB1); 8002 ins_encode(lock_prefix, 8003 REX_reg_mem(newval, mem_ptr), 8004 OpcP, OpcS, 8005 reg_mem(newval, mem_ptr) // lock cmpxchg 8006 ); 8007 ins_pipe( pipe_cmpxchg ); 8008 %} 8009 8010 instruct compareAndExchangeL( 8011 memory mem_ptr, 8012 rax_RegL oldval, rRegL newval, 8013 rFlagsReg cr) 8014 %{ 8015 predicate(VM_Version::supports_cx8()); 8016 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 8017 effect(KILL cr); 8018 8019 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8020 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8021 opcode(0x0F, 0xB1); 8022 ins_encode(lock_prefix, 8023 REX_reg_mem_wide(newval, mem_ptr), 8024 OpcP, OpcS, 8025 reg_mem(newval, mem_ptr) // lock cmpxchg 8026 ); 8027 ins_pipe( pipe_cmpxchg ); 8028 %} 8029 8030 instruct compareAndExchangeN( 8031 memory mem_ptr, 8032 rax_RegN oldval, rRegN newval, 8033 rFlagsReg cr) %{ 8034 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 8035 effect(KILL cr); 8036 8037 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8038 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8039 opcode(0x0F, 0xB1); 8040 ins_encode(lock_prefix, 8041 REX_reg_mem(newval, mem_ptr), 8042 OpcP, OpcS, 8043 reg_mem(newval, mem_ptr) // lock cmpxchg 8044 ); 8045 ins_pipe( pipe_cmpxchg ); 8046 %} 8047 8048 instruct compareAndExchangeP( 8049 memory mem_ptr, 8050 rax_RegP oldval, rRegP newval, 8051 rFlagsReg cr) 8052 %{ 8053 predicate(VM_Version::supports_cx8()); 8054 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 8055 effect(KILL cr); 8056 8057 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8058 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8059 opcode(0x0F, 0xB1); 8060 ins_encode(lock_prefix, 8061 REX_reg_mem_wide(newval, mem_ptr), 8062 OpcP, OpcS, 8063 reg_mem(newval, mem_ptr) // lock cmpxchg 8064 ); 8065 ins_pipe( pipe_cmpxchg ); 8066 %} 8067 8068 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8069 predicate(n->as_LoadStore()->result_not_used()); 8070 match(Set dummy (GetAndAddB mem add)); 8071 effect(KILL cr); 8072 format %{ "ADDB [$mem],$add" %} 8073 ins_encode %{ 8074 __ lock(); 8075 __ addb($mem$$Address, $add$$constant); 8076 %} 8077 ins_pipe( pipe_cmpxchg ); 8078 %} 8079 8080 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 8081 match(Set newval (GetAndAddB mem newval)); 8082 effect(KILL cr); 8083 format %{ "XADDB [$mem],$newval" %} 8084 ins_encode %{ 8085 __ lock(); 8086 __ xaddb($mem$$Address, $newval$$Register); 8087 %} 8088 ins_pipe( pipe_cmpxchg ); 8089 %} 8090 8091 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8092 predicate(n->as_LoadStore()->result_not_used()); 8093 match(Set dummy (GetAndAddS mem add)); 8094 effect(KILL cr); 8095 format %{ "ADDW [$mem],$add" %} 8096 ins_encode %{ 8097 __ lock(); 8098 __ addw($mem$$Address, $add$$constant); 8099 %} 8100 ins_pipe( pipe_cmpxchg ); 8101 %} 8102 8103 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 8104 match(Set newval (GetAndAddS mem newval)); 8105 effect(KILL cr); 8106 format %{ "XADDW [$mem],$newval" %} 8107 ins_encode %{ 8108 __ lock(); 8109 __ xaddw($mem$$Address, $newval$$Register); 8110 %} 8111 ins_pipe( pipe_cmpxchg ); 8112 %} 8113 8114 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8115 predicate(n->as_LoadStore()->result_not_used()); 8116 match(Set dummy (GetAndAddI mem add)); 8117 effect(KILL cr); 8118 format %{ "ADDL [$mem],$add" %} 8119 ins_encode %{ 8120 __ lock(); 8121 __ addl($mem$$Address, $add$$constant); 8122 %} 8123 ins_pipe( pipe_cmpxchg ); 8124 %} 8125 8126 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 8127 match(Set newval (GetAndAddI mem newval)); 8128 effect(KILL cr); 8129 format %{ "XADDL [$mem],$newval" %} 8130 ins_encode %{ 8131 __ lock(); 8132 __ xaddl($mem$$Address, $newval$$Register); 8133 %} 8134 ins_pipe( pipe_cmpxchg ); 8135 %} 8136 8137 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8138 predicate(n->as_LoadStore()->result_not_used()); 8139 match(Set dummy (GetAndAddL mem add)); 8140 effect(KILL cr); 8141 format %{ "ADDQ [$mem],$add" %} 8142 ins_encode %{ 8143 __ lock(); 8144 __ addq($mem$$Address, $add$$constant); 8145 %} 8146 ins_pipe( pipe_cmpxchg ); 8147 %} 8148 8149 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 8150 match(Set newval (GetAndAddL mem newval)); 8151 effect(KILL cr); 8152 format %{ "XADDQ [$mem],$newval" %} 8153 ins_encode %{ 8154 __ lock(); 8155 __ xaddq($mem$$Address, $newval$$Register); 8156 %} 8157 ins_pipe( pipe_cmpxchg ); 8158 %} 8159 8160 instruct xchgB( memory mem, rRegI newval) %{ 8161 match(Set newval (GetAndSetB mem newval)); 8162 format %{ "XCHGB $newval,[$mem]" %} 8163 ins_encode %{ 8164 __ xchgb($newval$$Register, $mem$$Address); 8165 %} 8166 ins_pipe( pipe_cmpxchg ); 8167 %} 8168 8169 instruct xchgS( memory mem, rRegI newval) %{ 8170 match(Set newval (GetAndSetS mem newval)); 8171 format %{ "XCHGW $newval,[$mem]" %} 8172 ins_encode %{ 8173 __ xchgw($newval$$Register, $mem$$Address); 8174 %} 8175 ins_pipe( pipe_cmpxchg ); 8176 %} 8177 8178 instruct xchgI( memory mem, rRegI newval) %{ 8179 match(Set newval (GetAndSetI mem newval)); 8180 format %{ "XCHGL $newval,[$mem]" %} 8181 ins_encode %{ 8182 __ xchgl($newval$$Register, $mem$$Address); 8183 %} 8184 ins_pipe( pipe_cmpxchg ); 8185 %} 8186 8187 instruct xchgL( memory mem, rRegL newval) %{ 8188 match(Set newval (GetAndSetL mem newval)); 8189 format %{ "XCHGL $newval,[$mem]" %} 8190 ins_encode %{ 8191 __ xchgq($newval$$Register, $mem$$Address); 8192 %} 8193 ins_pipe( pipe_cmpxchg ); 8194 %} 8195 8196 instruct xchgP( memory mem, rRegP newval) %{ 8197 match(Set newval (GetAndSetP mem newval)); 8198 format %{ "XCHGQ $newval,[$mem]" %} 8199 ins_encode %{ 8200 __ xchgq($newval$$Register, $mem$$Address); 8201 %} 8202 ins_pipe( pipe_cmpxchg ); 8203 %} 8204 8205 instruct xchgN( memory mem, rRegN newval) %{ 8206 match(Set newval (GetAndSetN mem newval)); 8207 format %{ "XCHGL $newval,$mem]" %} 8208 ins_encode %{ 8209 __ xchgl($newval$$Register, $mem$$Address); 8210 %} 8211 ins_pipe( pipe_cmpxchg ); 8212 %} 8213 8214 //----------Abs Instructions------------------------------------------- 8215 8216 // Integer Absolute Instructions 8217 instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr) 8218 %{ 8219 match(Set dst (AbsI src)); 8220 effect(TEMP dst, TEMP tmp, KILL cr); 8221 format %{ "movl $tmp, $src\n\t" 8222 "sarl $tmp, 31\n\t" 8223 "movl $dst, $src\n\t" 8224 "xorl $dst, $tmp\n\t" 8225 "subl $dst, $tmp\n" 8226 %} 8227 ins_encode %{ 8228 __ movl($tmp$$Register, $src$$Register); 8229 __ sarl($tmp$$Register, 31); 8230 __ movl($dst$$Register, $src$$Register); 8231 __ xorl($dst$$Register, $tmp$$Register); 8232 __ subl($dst$$Register, $tmp$$Register); 8233 %} 8234 8235 ins_pipe(ialu_reg_reg); 8236 %} 8237 8238 // Long Absolute Instructions 8239 instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr) 8240 %{ 8241 match(Set dst (AbsL src)); 8242 effect(TEMP dst, TEMP tmp, KILL cr); 8243 format %{ "movq $tmp, $src\n\t" 8244 "sarq $tmp, 63\n\t" 8245 "movq $dst, $src\n\t" 8246 "xorq $dst, $tmp\n\t" 8247 "subq $dst, $tmp\n" 8248 %} 8249 ins_encode %{ 8250 __ movq($tmp$$Register, $src$$Register); 8251 __ sarq($tmp$$Register, 63); 8252 __ movq($dst$$Register, $src$$Register); 8253 __ xorq($dst$$Register, $tmp$$Register); 8254 __ subq($dst$$Register, $tmp$$Register); 8255 %} 8256 8257 ins_pipe(ialu_reg_reg); 8258 %} 8259 8260 //----------Subtraction Instructions------------------------------------------- 8261 8262 // Integer Subtraction Instructions 8263 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8264 %{ 8265 match(Set dst (SubI dst src)); 8266 effect(KILL cr); 8267 8268 format %{ "subl $dst, $src\t# int" %} 8269 opcode(0x2B); 8270 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8271 ins_pipe(ialu_reg_reg); 8272 %} 8273 8274 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8275 %{ 8276 match(Set dst (SubI dst src)); 8277 effect(KILL cr); 8278 8279 format %{ "subl $dst, $src\t# int" %} 8280 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8281 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8282 ins_pipe(ialu_reg); 8283 %} 8284 8285 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8286 %{ 8287 match(Set dst (SubI dst (LoadI src))); 8288 effect(KILL cr); 8289 8290 ins_cost(125); 8291 format %{ "subl $dst, $src\t# int" %} 8292 opcode(0x2B); 8293 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8294 ins_pipe(ialu_reg_mem); 8295 %} 8296 8297 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8298 %{ 8299 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8300 effect(KILL cr); 8301 8302 ins_cost(150); 8303 format %{ "subl $dst, $src\t# int" %} 8304 opcode(0x29); /* Opcode 29 /r */ 8305 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8306 ins_pipe(ialu_mem_reg); 8307 %} 8308 8309 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8310 %{ 8311 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8312 effect(KILL cr); 8313 8314 ins_cost(125); // XXX 8315 format %{ "subl $dst, $src\t# int" %} 8316 opcode(0x81); /* Opcode 81 /5 id */ 8317 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8318 ins_pipe(ialu_mem_imm); 8319 %} 8320 8321 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8322 %{ 8323 match(Set dst (SubL dst src)); 8324 effect(KILL cr); 8325 8326 format %{ "subq $dst, $src\t# long" %} 8327 opcode(0x2B); 8328 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8329 ins_pipe(ialu_reg_reg); 8330 %} 8331 8332 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8333 %{ 8334 match(Set dst (SubL dst src)); 8335 effect(KILL cr); 8336 8337 format %{ "subq $dst, $src\t# long" %} 8338 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8339 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8340 ins_pipe(ialu_reg); 8341 %} 8342 8343 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8344 %{ 8345 match(Set dst (SubL dst (LoadL src))); 8346 effect(KILL cr); 8347 8348 ins_cost(125); 8349 format %{ "subq $dst, $src\t# long" %} 8350 opcode(0x2B); 8351 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8352 ins_pipe(ialu_reg_mem); 8353 %} 8354 8355 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8356 %{ 8357 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8358 effect(KILL cr); 8359 8360 ins_cost(150); 8361 format %{ "subq $dst, $src\t# long" %} 8362 opcode(0x29); /* Opcode 29 /r */ 8363 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8364 ins_pipe(ialu_mem_reg); 8365 %} 8366 8367 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8368 %{ 8369 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8370 effect(KILL cr); 8371 8372 ins_cost(125); // XXX 8373 format %{ "subq $dst, $src\t# long" %} 8374 opcode(0x81); /* Opcode 81 /5 id */ 8375 ins_encode(REX_mem_wide(dst), 8376 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8377 ins_pipe(ialu_mem_imm); 8378 %} 8379 8380 // Subtract from a pointer 8381 // XXX hmpf??? 8382 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8383 %{ 8384 match(Set dst (AddP dst (SubI zero src))); 8385 effect(KILL cr); 8386 8387 format %{ "subq $dst, $src\t# ptr - int" %} 8388 opcode(0x2B); 8389 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8390 ins_pipe(ialu_reg_reg); 8391 %} 8392 8393 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8394 %{ 8395 match(Set dst (SubI zero dst)); 8396 effect(KILL cr); 8397 8398 format %{ "negl $dst\t# int" %} 8399 opcode(0xF7, 0x03); // Opcode F7 /3 8400 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8401 ins_pipe(ialu_reg); 8402 %} 8403 8404 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8405 %{ 8406 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8407 effect(KILL cr); 8408 8409 format %{ "negl $dst\t# int" %} 8410 opcode(0xF7, 0x03); // Opcode F7 /3 8411 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8412 ins_pipe(ialu_reg); 8413 %} 8414 8415 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8416 %{ 8417 match(Set dst (SubL zero dst)); 8418 effect(KILL cr); 8419 8420 format %{ "negq $dst\t# long" %} 8421 opcode(0xF7, 0x03); // Opcode F7 /3 8422 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8423 ins_pipe(ialu_reg); 8424 %} 8425 8426 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8427 %{ 8428 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8429 effect(KILL cr); 8430 8431 format %{ "negq $dst\t# long" %} 8432 opcode(0xF7, 0x03); // Opcode F7 /3 8433 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8434 ins_pipe(ialu_reg); 8435 %} 8436 8437 //----------Multiplication/Division Instructions------------------------------- 8438 // Integer Multiplication Instructions 8439 // Multiply Register 8440 8441 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8442 %{ 8443 match(Set dst (MulI dst src)); 8444 effect(KILL cr); 8445 8446 ins_cost(300); 8447 format %{ "imull $dst, $src\t# int" %} 8448 opcode(0x0F, 0xAF); 8449 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8450 ins_pipe(ialu_reg_reg_alu0); 8451 %} 8452 8453 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8454 %{ 8455 match(Set dst (MulI src imm)); 8456 effect(KILL cr); 8457 8458 ins_cost(300); 8459 format %{ "imull $dst, $src, $imm\t# int" %} 8460 opcode(0x69); /* 69 /r id */ 8461 ins_encode(REX_reg_reg(dst, src), 8462 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8463 ins_pipe(ialu_reg_reg_alu0); 8464 %} 8465 8466 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8467 %{ 8468 match(Set dst (MulI dst (LoadI src))); 8469 effect(KILL cr); 8470 8471 ins_cost(350); 8472 format %{ "imull $dst, $src\t# int" %} 8473 opcode(0x0F, 0xAF); 8474 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8475 ins_pipe(ialu_reg_mem_alu0); 8476 %} 8477 8478 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8479 %{ 8480 match(Set dst (MulI (LoadI src) imm)); 8481 effect(KILL cr); 8482 8483 ins_cost(300); 8484 format %{ "imull $dst, $src, $imm\t# int" %} 8485 opcode(0x69); /* 69 /r id */ 8486 ins_encode(REX_reg_mem(dst, src), 8487 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8488 ins_pipe(ialu_reg_mem_alu0); 8489 %} 8490 8491 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8492 %{ 8493 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8494 effect(KILL cr, KILL src2); 8495 8496 expand %{ mulI_rReg(dst, src1, cr); 8497 mulI_rReg(src2, src3, cr); 8498 addI_rReg(dst, src2, cr); %} 8499 %} 8500 8501 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8502 %{ 8503 match(Set dst (MulL dst src)); 8504 effect(KILL cr); 8505 8506 ins_cost(300); 8507 format %{ "imulq $dst, $src\t# long" %} 8508 opcode(0x0F, 0xAF); 8509 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8510 ins_pipe(ialu_reg_reg_alu0); 8511 %} 8512 8513 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8514 %{ 8515 match(Set dst (MulL src imm)); 8516 effect(KILL cr); 8517 8518 ins_cost(300); 8519 format %{ "imulq $dst, $src, $imm\t# long" %} 8520 opcode(0x69); /* 69 /r id */ 8521 ins_encode(REX_reg_reg_wide(dst, src), 8522 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8523 ins_pipe(ialu_reg_reg_alu0); 8524 %} 8525 8526 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8527 %{ 8528 match(Set dst (MulL dst (LoadL src))); 8529 effect(KILL cr); 8530 8531 ins_cost(350); 8532 format %{ "imulq $dst, $src\t# long" %} 8533 opcode(0x0F, 0xAF); 8534 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8535 ins_pipe(ialu_reg_mem_alu0); 8536 %} 8537 8538 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8539 %{ 8540 match(Set dst (MulL (LoadL src) imm)); 8541 effect(KILL cr); 8542 8543 ins_cost(300); 8544 format %{ "imulq $dst, $src, $imm\t# long" %} 8545 opcode(0x69); /* 69 /r id */ 8546 ins_encode(REX_reg_mem_wide(dst, src), 8547 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8548 ins_pipe(ialu_reg_mem_alu0); 8549 %} 8550 8551 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8552 %{ 8553 match(Set dst (MulHiL src rax)); 8554 effect(USE_KILL rax, KILL cr); 8555 8556 ins_cost(300); 8557 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8558 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8559 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8560 ins_pipe(ialu_reg_reg_alu0); 8561 %} 8562 8563 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8564 rFlagsReg cr) 8565 %{ 8566 match(Set rax (DivI rax div)); 8567 effect(KILL rdx, KILL cr); 8568 8569 ins_cost(30*100+10*100); // XXX 8570 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8571 "jne,s normal\n\t" 8572 "xorl rdx, rdx\n\t" 8573 "cmpl $div, -1\n\t" 8574 "je,s done\n" 8575 "normal: cdql\n\t" 8576 "idivl $div\n" 8577 "done:" %} 8578 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8579 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8580 ins_pipe(ialu_reg_reg_alu0); 8581 %} 8582 8583 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8584 rFlagsReg cr) 8585 %{ 8586 match(Set rax (DivL rax div)); 8587 effect(KILL rdx, KILL cr); 8588 8589 ins_cost(30*100+10*100); // XXX 8590 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8591 "cmpq rax, rdx\n\t" 8592 "jne,s normal\n\t" 8593 "xorl rdx, rdx\n\t" 8594 "cmpq $div, -1\n\t" 8595 "je,s done\n" 8596 "normal: cdqq\n\t" 8597 "idivq $div\n" 8598 "done:" %} 8599 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8600 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8601 ins_pipe(ialu_reg_reg_alu0); 8602 %} 8603 8604 // Integer DIVMOD with Register, both quotient and mod results 8605 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8606 rFlagsReg cr) 8607 %{ 8608 match(DivModI rax div); 8609 effect(KILL cr); 8610 8611 ins_cost(30*100+10*100); // XXX 8612 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8613 "jne,s normal\n\t" 8614 "xorl rdx, rdx\n\t" 8615 "cmpl $div, -1\n\t" 8616 "je,s done\n" 8617 "normal: cdql\n\t" 8618 "idivl $div\n" 8619 "done:" %} 8620 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8621 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8622 ins_pipe(pipe_slow); 8623 %} 8624 8625 // Long DIVMOD with Register, both quotient and mod results 8626 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8627 rFlagsReg cr) 8628 %{ 8629 match(DivModL rax div); 8630 effect(KILL cr); 8631 8632 ins_cost(30*100+10*100); // XXX 8633 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8634 "cmpq rax, rdx\n\t" 8635 "jne,s normal\n\t" 8636 "xorl rdx, rdx\n\t" 8637 "cmpq $div, -1\n\t" 8638 "je,s done\n" 8639 "normal: cdqq\n\t" 8640 "idivq $div\n" 8641 "done:" %} 8642 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8643 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8644 ins_pipe(pipe_slow); 8645 %} 8646 8647 //----------- DivL-By-Constant-Expansions-------------------------------------- 8648 // DivI cases are handled by the compiler 8649 8650 // Magic constant, reciprocal of 10 8651 instruct loadConL_0x6666666666666667(rRegL dst) 8652 %{ 8653 effect(DEF dst); 8654 8655 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8656 ins_encode(load_immL(dst, 0x6666666666666667)); 8657 ins_pipe(ialu_reg); 8658 %} 8659 8660 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8661 %{ 8662 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8663 8664 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8665 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8666 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8667 ins_pipe(ialu_reg_reg_alu0); 8668 %} 8669 8670 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8671 %{ 8672 effect(USE_DEF dst, KILL cr); 8673 8674 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8675 opcode(0xC1, 0x7); /* C1 /7 ib */ 8676 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8677 ins_pipe(ialu_reg); 8678 %} 8679 8680 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8681 %{ 8682 effect(USE_DEF dst, KILL cr); 8683 8684 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8685 opcode(0xC1, 0x7); /* C1 /7 ib */ 8686 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8687 ins_pipe(ialu_reg); 8688 %} 8689 8690 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8691 %{ 8692 match(Set dst (DivL src div)); 8693 8694 ins_cost((5+8)*100); 8695 expand %{ 8696 rax_RegL rax; // Killed temp 8697 rFlagsReg cr; // Killed 8698 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8699 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8700 sarL_rReg_63(src, cr); // sarq src, 63 8701 sarL_rReg_2(dst, cr); // sarq rdx, 2 8702 subL_rReg(dst, src, cr); // subl rdx, src 8703 %} 8704 %} 8705 8706 //----------------------------------------------------------------------------- 8707 8708 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8709 rFlagsReg cr) 8710 %{ 8711 match(Set rdx (ModI rax div)); 8712 effect(KILL rax, KILL cr); 8713 8714 ins_cost(300); // XXX 8715 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8716 "jne,s normal\n\t" 8717 "xorl rdx, rdx\n\t" 8718 "cmpl $div, -1\n\t" 8719 "je,s done\n" 8720 "normal: cdql\n\t" 8721 "idivl $div\n" 8722 "done:" %} 8723 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8724 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8725 ins_pipe(ialu_reg_reg_alu0); 8726 %} 8727 8728 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8729 rFlagsReg cr) 8730 %{ 8731 match(Set rdx (ModL rax div)); 8732 effect(KILL rax, KILL cr); 8733 8734 ins_cost(300); // XXX 8735 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8736 "cmpq rax, rdx\n\t" 8737 "jne,s normal\n\t" 8738 "xorl rdx, rdx\n\t" 8739 "cmpq $div, -1\n\t" 8740 "je,s done\n" 8741 "normal: cdqq\n\t" 8742 "idivq $div\n" 8743 "done:" %} 8744 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8745 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8746 ins_pipe(ialu_reg_reg_alu0); 8747 %} 8748 8749 // Integer Shift Instructions 8750 // Shift Left by one 8751 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8752 %{ 8753 match(Set dst (LShiftI dst shift)); 8754 effect(KILL cr); 8755 8756 format %{ "sall $dst, $shift" %} 8757 opcode(0xD1, 0x4); /* D1 /4 */ 8758 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8759 ins_pipe(ialu_reg); 8760 %} 8761 8762 // Shift Left by one 8763 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8764 %{ 8765 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8766 effect(KILL cr); 8767 8768 format %{ "sall $dst, $shift\t" %} 8769 opcode(0xD1, 0x4); /* D1 /4 */ 8770 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8771 ins_pipe(ialu_mem_imm); 8772 %} 8773 8774 // Shift Left by 8-bit immediate 8775 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8776 %{ 8777 match(Set dst (LShiftI dst shift)); 8778 effect(KILL cr); 8779 8780 format %{ "sall $dst, $shift" %} 8781 opcode(0xC1, 0x4); /* C1 /4 ib */ 8782 ins_encode(reg_opc_imm(dst, shift)); 8783 ins_pipe(ialu_reg); 8784 %} 8785 8786 // Shift Left by 8-bit immediate 8787 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8788 %{ 8789 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8790 effect(KILL cr); 8791 8792 format %{ "sall $dst, $shift" %} 8793 opcode(0xC1, 0x4); /* C1 /4 ib */ 8794 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8795 ins_pipe(ialu_mem_imm); 8796 %} 8797 8798 // Shift Left by variable 8799 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8800 %{ 8801 match(Set dst (LShiftI dst shift)); 8802 effect(KILL cr); 8803 8804 format %{ "sall $dst, $shift" %} 8805 opcode(0xD3, 0x4); /* D3 /4 */ 8806 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8807 ins_pipe(ialu_reg_reg); 8808 %} 8809 8810 // Shift Left by variable 8811 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8812 %{ 8813 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8814 effect(KILL cr); 8815 8816 format %{ "sall $dst, $shift" %} 8817 opcode(0xD3, 0x4); /* D3 /4 */ 8818 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8819 ins_pipe(ialu_mem_reg); 8820 %} 8821 8822 // Arithmetic shift right by one 8823 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8824 %{ 8825 match(Set dst (RShiftI dst shift)); 8826 effect(KILL cr); 8827 8828 format %{ "sarl $dst, $shift" %} 8829 opcode(0xD1, 0x7); /* D1 /7 */ 8830 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8831 ins_pipe(ialu_reg); 8832 %} 8833 8834 // Arithmetic shift right by one 8835 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8836 %{ 8837 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8838 effect(KILL cr); 8839 8840 format %{ "sarl $dst, $shift" %} 8841 opcode(0xD1, 0x7); /* D1 /7 */ 8842 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8843 ins_pipe(ialu_mem_imm); 8844 %} 8845 8846 // Arithmetic Shift Right by 8-bit immediate 8847 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8848 %{ 8849 match(Set dst (RShiftI dst shift)); 8850 effect(KILL cr); 8851 8852 format %{ "sarl $dst, $shift" %} 8853 opcode(0xC1, 0x7); /* C1 /7 ib */ 8854 ins_encode(reg_opc_imm(dst, shift)); 8855 ins_pipe(ialu_mem_imm); 8856 %} 8857 8858 // Arithmetic Shift Right by 8-bit immediate 8859 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8860 %{ 8861 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8862 effect(KILL cr); 8863 8864 format %{ "sarl $dst, $shift" %} 8865 opcode(0xC1, 0x7); /* C1 /7 ib */ 8866 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8867 ins_pipe(ialu_mem_imm); 8868 %} 8869 8870 // Arithmetic Shift Right by variable 8871 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8872 %{ 8873 match(Set dst (RShiftI dst shift)); 8874 effect(KILL cr); 8875 8876 format %{ "sarl $dst, $shift" %} 8877 opcode(0xD3, 0x7); /* D3 /7 */ 8878 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8879 ins_pipe(ialu_reg_reg); 8880 %} 8881 8882 // Arithmetic Shift Right by variable 8883 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8884 %{ 8885 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8886 effect(KILL cr); 8887 8888 format %{ "sarl $dst, $shift" %} 8889 opcode(0xD3, 0x7); /* D3 /7 */ 8890 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8891 ins_pipe(ialu_mem_reg); 8892 %} 8893 8894 // Logical shift right by one 8895 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8896 %{ 8897 match(Set dst (URShiftI dst shift)); 8898 effect(KILL cr); 8899 8900 format %{ "shrl $dst, $shift" %} 8901 opcode(0xD1, 0x5); /* D1 /5 */ 8902 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8903 ins_pipe(ialu_reg); 8904 %} 8905 8906 // Logical shift right by one 8907 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8908 %{ 8909 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8910 effect(KILL cr); 8911 8912 format %{ "shrl $dst, $shift" %} 8913 opcode(0xD1, 0x5); /* D1 /5 */ 8914 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8915 ins_pipe(ialu_mem_imm); 8916 %} 8917 8918 // Logical Shift Right by 8-bit immediate 8919 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8920 %{ 8921 match(Set dst (URShiftI dst shift)); 8922 effect(KILL cr); 8923 8924 format %{ "shrl $dst, $shift" %} 8925 opcode(0xC1, 0x5); /* C1 /5 ib */ 8926 ins_encode(reg_opc_imm(dst, shift)); 8927 ins_pipe(ialu_reg); 8928 %} 8929 8930 // Logical Shift Right by 8-bit immediate 8931 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8932 %{ 8933 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8934 effect(KILL cr); 8935 8936 format %{ "shrl $dst, $shift" %} 8937 opcode(0xC1, 0x5); /* C1 /5 ib */ 8938 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8939 ins_pipe(ialu_mem_imm); 8940 %} 8941 8942 // Logical Shift Right by variable 8943 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8944 %{ 8945 match(Set dst (URShiftI dst shift)); 8946 effect(KILL cr); 8947 8948 format %{ "shrl $dst, $shift" %} 8949 opcode(0xD3, 0x5); /* D3 /5 */ 8950 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8951 ins_pipe(ialu_reg_reg); 8952 %} 8953 8954 // Logical Shift Right by variable 8955 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8956 %{ 8957 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8958 effect(KILL cr); 8959 8960 format %{ "shrl $dst, $shift" %} 8961 opcode(0xD3, 0x5); /* D3 /5 */ 8962 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8963 ins_pipe(ialu_mem_reg); 8964 %} 8965 8966 // Long Shift Instructions 8967 // Shift Left by one 8968 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8969 %{ 8970 match(Set dst (LShiftL dst shift)); 8971 effect(KILL cr); 8972 8973 format %{ "salq $dst, $shift" %} 8974 opcode(0xD1, 0x4); /* D1 /4 */ 8975 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8976 ins_pipe(ialu_reg); 8977 %} 8978 8979 // Shift Left by one 8980 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8981 %{ 8982 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8983 effect(KILL cr); 8984 8985 format %{ "salq $dst, $shift" %} 8986 opcode(0xD1, 0x4); /* D1 /4 */ 8987 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8988 ins_pipe(ialu_mem_imm); 8989 %} 8990 8991 // Shift Left by 8-bit immediate 8992 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8993 %{ 8994 match(Set dst (LShiftL dst shift)); 8995 effect(KILL cr); 8996 8997 format %{ "salq $dst, $shift" %} 8998 opcode(0xC1, 0x4); /* C1 /4 ib */ 8999 ins_encode(reg_opc_imm_wide(dst, shift)); 9000 ins_pipe(ialu_reg); 9001 %} 9002 9003 // Shift Left by 8-bit immediate 9004 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9005 %{ 9006 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9007 effect(KILL cr); 9008 9009 format %{ "salq $dst, $shift" %} 9010 opcode(0xC1, 0x4); /* C1 /4 ib */ 9011 ins_encode(REX_mem_wide(dst), OpcP, 9012 RM_opc_mem(secondary, dst), Con8or32(shift)); 9013 ins_pipe(ialu_mem_imm); 9014 %} 9015 9016 // Shift Left by variable 9017 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9018 %{ 9019 match(Set dst (LShiftL dst shift)); 9020 effect(KILL cr); 9021 9022 format %{ "salq $dst, $shift" %} 9023 opcode(0xD3, 0x4); /* D3 /4 */ 9024 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9025 ins_pipe(ialu_reg_reg); 9026 %} 9027 9028 // Shift Left by variable 9029 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9030 %{ 9031 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9032 effect(KILL cr); 9033 9034 format %{ "salq $dst, $shift" %} 9035 opcode(0xD3, 0x4); /* D3 /4 */ 9036 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9037 ins_pipe(ialu_mem_reg); 9038 %} 9039 9040 // Arithmetic shift right by one 9041 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9042 %{ 9043 match(Set dst (RShiftL dst shift)); 9044 effect(KILL cr); 9045 9046 format %{ "sarq $dst, $shift" %} 9047 opcode(0xD1, 0x7); /* D1 /7 */ 9048 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9049 ins_pipe(ialu_reg); 9050 %} 9051 9052 // Arithmetic shift right by one 9053 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9054 %{ 9055 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9056 effect(KILL cr); 9057 9058 format %{ "sarq $dst, $shift" %} 9059 opcode(0xD1, 0x7); /* D1 /7 */ 9060 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9061 ins_pipe(ialu_mem_imm); 9062 %} 9063 9064 // Arithmetic Shift Right by 8-bit immediate 9065 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9066 %{ 9067 match(Set dst (RShiftL dst shift)); 9068 effect(KILL cr); 9069 9070 format %{ "sarq $dst, $shift" %} 9071 opcode(0xC1, 0x7); /* C1 /7 ib */ 9072 ins_encode(reg_opc_imm_wide(dst, shift)); 9073 ins_pipe(ialu_mem_imm); 9074 %} 9075 9076 // Arithmetic Shift Right by 8-bit immediate 9077 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9078 %{ 9079 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9080 effect(KILL cr); 9081 9082 format %{ "sarq $dst, $shift" %} 9083 opcode(0xC1, 0x7); /* C1 /7 ib */ 9084 ins_encode(REX_mem_wide(dst), OpcP, 9085 RM_opc_mem(secondary, dst), Con8or32(shift)); 9086 ins_pipe(ialu_mem_imm); 9087 %} 9088 9089 // Arithmetic Shift Right by variable 9090 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9091 %{ 9092 match(Set dst (RShiftL dst shift)); 9093 effect(KILL cr); 9094 9095 format %{ "sarq $dst, $shift" %} 9096 opcode(0xD3, 0x7); /* D3 /7 */ 9097 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9098 ins_pipe(ialu_reg_reg); 9099 %} 9100 9101 // Arithmetic Shift Right by variable 9102 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9103 %{ 9104 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9105 effect(KILL cr); 9106 9107 format %{ "sarq $dst, $shift" %} 9108 opcode(0xD3, 0x7); /* D3 /7 */ 9109 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9110 ins_pipe(ialu_mem_reg); 9111 %} 9112 9113 // Logical shift right by one 9114 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9115 %{ 9116 match(Set dst (URShiftL dst shift)); 9117 effect(KILL cr); 9118 9119 format %{ "shrq $dst, $shift" %} 9120 opcode(0xD1, 0x5); /* D1 /5 */ 9121 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 9122 ins_pipe(ialu_reg); 9123 %} 9124 9125 // Logical shift right by one 9126 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9127 %{ 9128 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9129 effect(KILL cr); 9130 9131 format %{ "shrq $dst, $shift" %} 9132 opcode(0xD1, 0x5); /* D1 /5 */ 9133 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9134 ins_pipe(ialu_mem_imm); 9135 %} 9136 9137 // Logical Shift Right by 8-bit immediate 9138 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9139 %{ 9140 match(Set dst (URShiftL dst shift)); 9141 effect(KILL cr); 9142 9143 format %{ "shrq $dst, $shift" %} 9144 opcode(0xC1, 0x5); /* C1 /5 ib */ 9145 ins_encode(reg_opc_imm_wide(dst, shift)); 9146 ins_pipe(ialu_reg); 9147 %} 9148 9149 9150 // Logical Shift Right by 8-bit immediate 9151 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9152 %{ 9153 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9154 effect(KILL cr); 9155 9156 format %{ "shrq $dst, $shift" %} 9157 opcode(0xC1, 0x5); /* C1 /5 ib */ 9158 ins_encode(REX_mem_wide(dst), OpcP, 9159 RM_opc_mem(secondary, dst), Con8or32(shift)); 9160 ins_pipe(ialu_mem_imm); 9161 %} 9162 9163 // Logical Shift Right by variable 9164 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9165 %{ 9166 match(Set dst (URShiftL dst shift)); 9167 effect(KILL cr); 9168 9169 format %{ "shrq $dst, $shift" %} 9170 opcode(0xD3, 0x5); /* D3 /5 */ 9171 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9172 ins_pipe(ialu_reg_reg); 9173 %} 9174 9175 // Logical Shift Right by variable 9176 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9177 %{ 9178 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9179 effect(KILL cr); 9180 9181 format %{ "shrq $dst, $shift" %} 9182 opcode(0xD3, 0x5); /* D3 /5 */ 9183 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9184 ins_pipe(ialu_mem_reg); 9185 %} 9186 9187 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9188 // This idiom is used by the compiler for the i2b bytecode. 9189 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9190 %{ 9191 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9192 9193 format %{ "movsbl $dst, $src\t# i2b" %} 9194 opcode(0x0F, 0xBE); 9195 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9196 ins_pipe(ialu_reg_reg); 9197 %} 9198 9199 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9200 // This idiom is used by the compiler the i2s bytecode. 9201 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9202 %{ 9203 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9204 9205 format %{ "movswl $dst, $src\t# i2s" %} 9206 opcode(0x0F, 0xBF); 9207 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9208 ins_pipe(ialu_reg_reg); 9209 %} 9210 9211 // ROL/ROR instructions 9212 9213 // ROL expand 9214 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9215 effect(KILL cr, USE_DEF dst); 9216 9217 format %{ "roll $dst" %} 9218 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9219 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9220 ins_pipe(ialu_reg); 9221 %} 9222 9223 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9224 effect(USE_DEF dst, USE shift, KILL cr); 9225 9226 format %{ "roll $dst, $shift" %} 9227 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9228 ins_encode( reg_opc_imm(dst, shift) ); 9229 ins_pipe(ialu_reg); 9230 %} 9231 9232 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9233 %{ 9234 effect(USE_DEF dst, USE shift, KILL cr); 9235 9236 format %{ "roll $dst, $shift" %} 9237 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9238 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9239 ins_pipe(ialu_reg_reg); 9240 %} 9241 // end of ROL expand 9242 9243 // Rotate Left by one 9244 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9245 %{ 9246 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9247 9248 expand %{ 9249 rolI_rReg_imm1(dst, cr); 9250 %} 9251 %} 9252 9253 // Rotate Left by 8-bit immediate 9254 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9255 %{ 9256 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9257 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9258 9259 expand %{ 9260 rolI_rReg_imm8(dst, lshift, cr); 9261 %} 9262 %} 9263 9264 // Rotate Left by variable 9265 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9266 %{ 9267 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9268 9269 expand %{ 9270 rolI_rReg_CL(dst, shift, cr); 9271 %} 9272 %} 9273 9274 // Rotate Left by variable 9275 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9276 %{ 9277 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9278 9279 expand %{ 9280 rolI_rReg_CL(dst, shift, cr); 9281 %} 9282 %} 9283 9284 // ROR expand 9285 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9286 %{ 9287 effect(USE_DEF dst, KILL cr); 9288 9289 format %{ "rorl $dst" %} 9290 opcode(0xD1, 0x1); /* D1 /1 */ 9291 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9292 ins_pipe(ialu_reg); 9293 %} 9294 9295 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9296 %{ 9297 effect(USE_DEF dst, USE shift, KILL cr); 9298 9299 format %{ "rorl $dst, $shift" %} 9300 opcode(0xC1, 0x1); /* C1 /1 ib */ 9301 ins_encode(reg_opc_imm(dst, shift)); 9302 ins_pipe(ialu_reg); 9303 %} 9304 9305 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9306 %{ 9307 effect(USE_DEF dst, USE shift, KILL cr); 9308 9309 format %{ "rorl $dst, $shift" %} 9310 opcode(0xD3, 0x1); /* D3 /1 */ 9311 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9312 ins_pipe(ialu_reg_reg); 9313 %} 9314 // end of ROR expand 9315 9316 // Rotate Right by one 9317 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9318 %{ 9319 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9320 9321 expand %{ 9322 rorI_rReg_imm1(dst, cr); 9323 %} 9324 %} 9325 9326 // Rotate Right by 8-bit immediate 9327 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9328 %{ 9329 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9330 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9331 9332 expand %{ 9333 rorI_rReg_imm8(dst, rshift, cr); 9334 %} 9335 %} 9336 9337 // Rotate Right by variable 9338 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9339 %{ 9340 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9341 9342 expand %{ 9343 rorI_rReg_CL(dst, shift, cr); 9344 %} 9345 %} 9346 9347 // Rotate Right by variable 9348 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9349 %{ 9350 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9351 9352 expand %{ 9353 rorI_rReg_CL(dst, shift, cr); 9354 %} 9355 %} 9356 9357 // for long rotate 9358 // ROL expand 9359 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9360 effect(USE_DEF dst, KILL cr); 9361 9362 format %{ "rolq $dst" %} 9363 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9364 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9365 ins_pipe(ialu_reg); 9366 %} 9367 9368 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9369 effect(USE_DEF dst, USE shift, KILL cr); 9370 9371 format %{ "rolq $dst, $shift" %} 9372 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9373 ins_encode( reg_opc_imm_wide(dst, shift) ); 9374 ins_pipe(ialu_reg); 9375 %} 9376 9377 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9378 %{ 9379 effect(USE_DEF dst, USE shift, KILL cr); 9380 9381 format %{ "rolq $dst, $shift" %} 9382 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9383 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9384 ins_pipe(ialu_reg_reg); 9385 %} 9386 // end of ROL expand 9387 9388 // Rotate Left by one 9389 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9390 %{ 9391 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9392 9393 expand %{ 9394 rolL_rReg_imm1(dst, cr); 9395 %} 9396 %} 9397 9398 // Rotate Left by 8-bit immediate 9399 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9400 %{ 9401 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9402 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9403 9404 expand %{ 9405 rolL_rReg_imm8(dst, lshift, cr); 9406 %} 9407 %} 9408 9409 // Rotate Left by variable 9410 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9411 %{ 9412 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9413 9414 expand %{ 9415 rolL_rReg_CL(dst, shift, cr); 9416 %} 9417 %} 9418 9419 // Rotate Left by variable 9420 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9421 %{ 9422 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9423 9424 expand %{ 9425 rolL_rReg_CL(dst, shift, cr); 9426 %} 9427 %} 9428 9429 // ROR expand 9430 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9431 %{ 9432 effect(USE_DEF dst, KILL cr); 9433 9434 format %{ "rorq $dst" %} 9435 opcode(0xD1, 0x1); /* D1 /1 */ 9436 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9437 ins_pipe(ialu_reg); 9438 %} 9439 9440 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9441 %{ 9442 effect(USE_DEF dst, USE shift, KILL cr); 9443 9444 format %{ "rorq $dst, $shift" %} 9445 opcode(0xC1, 0x1); /* C1 /1 ib */ 9446 ins_encode(reg_opc_imm_wide(dst, shift)); 9447 ins_pipe(ialu_reg); 9448 %} 9449 9450 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9451 %{ 9452 effect(USE_DEF dst, USE shift, KILL cr); 9453 9454 format %{ "rorq $dst, $shift" %} 9455 opcode(0xD3, 0x1); /* D3 /1 */ 9456 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9457 ins_pipe(ialu_reg_reg); 9458 %} 9459 // end of ROR expand 9460 9461 // Rotate Right by one 9462 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9463 %{ 9464 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9465 9466 expand %{ 9467 rorL_rReg_imm1(dst, cr); 9468 %} 9469 %} 9470 9471 // Rotate Right by 8-bit immediate 9472 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9473 %{ 9474 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9475 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9476 9477 expand %{ 9478 rorL_rReg_imm8(dst, rshift, cr); 9479 %} 9480 %} 9481 9482 // Rotate Right by variable 9483 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9484 %{ 9485 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9486 9487 expand %{ 9488 rorL_rReg_CL(dst, shift, cr); 9489 %} 9490 %} 9491 9492 // Rotate Right by variable 9493 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9494 %{ 9495 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9496 9497 expand %{ 9498 rorL_rReg_CL(dst, shift, cr); 9499 %} 9500 %} 9501 9502 // Logical Instructions 9503 9504 // Integer Logical Instructions 9505 9506 // And Instructions 9507 // And Register with Register 9508 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9509 %{ 9510 match(Set dst (AndI dst src)); 9511 effect(KILL cr); 9512 9513 format %{ "andl $dst, $src\t# int" %} 9514 opcode(0x23); 9515 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9516 ins_pipe(ialu_reg_reg); 9517 %} 9518 9519 // And Register with Immediate 255 9520 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9521 %{ 9522 match(Set dst (AndI dst src)); 9523 9524 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9525 opcode(0x0F, 0xB6); 9526 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9527 ins_pipe(ialu_reg); 9528 %} 9529 9530 // And Register with Immediate 255 and promote to long 9531 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9532 %{ 9533 match(Set dst (ConvI2L (AndI src mask))); 9534 9535 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9536 opcode(0x0F, 0xB6); 9537 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9538 ins_pipe(ialu_reg); 9539 %} 9540 9541 // And Register with Immediate 65535 9542 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9543 %{ 9544 match(Set dst (AndI dst src)); 9545 9546 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9547 opcode(0x0F, 0xB7); 9548 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9549 ins_pipe(ialu_reg); 9550 %} 9551 9552 // And Register with Immediate 65535 and promote to long 9553 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9554 %{ 9555 match(Set dst (ConvI2L (AndI src mask))); 9556 9557 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9558 opcode(0x0F, 0xB7); 9559 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9560 ins_pipe(ialu_reg); 9561 %} 9562 9563 // And Register with Immediate 9564 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9565 %{ 9566 match(Set dst (AndI dst src)); 9567 effect(KILL cr); 9568 9569 format %{ "andl $dst, $src\t# int" %} 9570 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9571 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9572 ins_pipe(ialu_reg); 9573 %} 9574 9575 // And Register with Memory 9576 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9577 %{ 9578 match(Set dst (AndI dst (LoadI src))); 9579 effect(KILL cr); 9580 9581 ins_cost(125); 9582 format %{ "andl $dst, $src\t# int" %} 9583 opcode(0x23); 9584 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9585 ins_pipe(ialu_reg_mem); 9586 %} 9587 9588 // And Memory with Register 9589 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9590 %{ 9591 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9592 effect(KILL cr); 9593 9594 ins_cost(150); 9595 format %{ "andb $dst, $src\t# byte" %} 9596 opcode(0x20); 9597 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9598 ins_pipe(ialu_mem_reg); 9599 %} 9600 9601 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9602 %{ 9603 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9604 effect(KILL cr); 9605 9606 ins_cost(150); 9607 format %{ "andl $dst, $src\t# int" %} 9608 opcode(0x21); /* Opcode 21 /r */ 9609 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9610 ins_pipe(ialu_mem_reg); 9611 %} 9612 9613 // And Memory with Immediate 9614 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9615 %{ 9616 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9617 effect(KILL cr); 9618 9619 ins_cost(125); 9620 format %{ "andl $dst, $src\t# int" %} 9621 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9622 ins_encode(REX_mem(dst), OpcSE(src), 9623 RM_opc_mem(secondary, dst), Con8or32(src)); 9624 ins_pipe(ialu_mem_imm); 9625 %} 9626 9627 // BMI1 instructions 9628 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9629 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9630 predicate(UseBMI1Instructions); 9631 effect(KILL cr); 9632 9633 ins_cost(125); 9634 format %{ "andnl $dst, $src1, $src2" %} 9635 9636 ins_encode %{ 9637 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9638 %} 9639 ins_pipe(ialu_reg_mem); 9640 %} 9641 9642 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9643 match(Set dst (AndI (XorI src1 minus_1) src2)); 9644 predicate(UseBMI1Instructions); 9645 effect(KILL cr); 9646 9647 format %{ "andnl $dst, $src1, $src2" %} 9648 9649 ins_encode %{ 9650 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9651 %} 9652 ins_pipe(ialu_reg); 9653 %} 9654 9655 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9656 match(Set dst (AndI (SubI imm_zero src) src)); 9657 predicate(UseBMI1Instructions); 9658 effect(KILL cr); 9659 9660 format %{ "blsil $dst, $src" %} 9661 9662 ins_encode %{ 9663 __ blsil($dst$$Register, $src$$Register); 9664 %} 9665 ins_pipe(ialu_reg); 9666 %} 9667 9668 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9669 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9670 predicate(UseBMI1Instructions); 9671 effect(KILL cr); 9672 9673 ins_cost(125); 9674 format %{ "blsil $dst, $src" %} 9675 9676 ins_encode %{ 9677 __ blsil($dst$$Register, $src$$Address); 9678 %} 9679 ins_pipe(ialu_reg_mem); 9680 %} 9681 9682 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9683 %{ 9684 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9685 predicate(UseBMI1Instructions); 9686 effect(KILL cr); 9687 9688 ins_cost(125); 9689 format %{ "blsmskl $dst, $src" %} 9690 9691 ins_encode %{ 9692 __ blsmskl($dst$$Register, $src$$Address); 9693 %} 9694 ins_pipe(ialu_reg_mem); 9695 %} 9696 9697 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9698 %{ 9699 match(Set dst (XorI (AddI src minus_1) src)); 9700 predicate(UseBMI1Instructions); 9701 effect(KILL cr); 9702 9703 format %{ "blsmskl $dst, $src" %} 9704 9705 ins_encode %{ 9706 __ blsmskl($dst$$Register, $src$$Register); 9707 %} 9708 9709 ins_pipe(ialu_reg); 9710 %} 9711 9712 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9713 %{ 9714 match(Set dst (AndI (AddI src minus_1) src) ); 9715 predicate(UseBMI1Instructions); 9716 effect(KILL cr); 9717 9718 format %{ "blsrl $dst, $src" %} 9719 9720 ins_encode %{ 9721 __ blsrl($dst$$Register, $src$$Register); 9722 %} 9723 9724 ins_pipe(ialu_reg_mem); 9725 %} 9726 9727 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9728 %{ 9729 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9730 predicate(UseBMI1Instructions); 9731 effect(KILL cr); 9732 9733 ins_cost(125); 9734 format %{ "blsrl $dst, $src" %} 9735 9736 ins_encode %{ 9737 __ blsrl($dst$$Register, $src$$Address); 9738 %} 9739 9740 ins_pipe(ialu_reg); 9741 %} 9742 9743 // Or Instructions 9744 // Or Register with Register 9745 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9746 %{ 9747 match(Set dst (OrI dst src)); 9748 effect(KILL cr); 9749 9750 format %{ "orl $dst, $src\t# int" %} 9751 opcode(0x0B); 9752 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9753 ins_pipe(ialu_reg_reg); 9754 %} 9755 9756 // Or Register with Immediate 9757 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9758 %{ 9759 match(Set dst (OrI dst src)); 9760 effect(KILL cr); 9761 9762 format %{ "orl $dst, $src\t# int" %} 9763 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9764 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9765 ins_pipe(ialu_reg); 9766 %} 9767 9768 // Or Register with Memory 9769 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9770 %{ 9771 match(Set dst (OrI dst (LoadI src))); 9772 effect(KILL cr); 9773 9774 ins_cost(125); 9775 format %{ "orl $dst, $src\t# int" %} 9776 opcode(0x0B); 9777 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9778 ins_pipe(ialu_reg_mem); 9779 %} 9780 9781 // Or Memory with Register 9782 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9783 %{ 9784 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9785 effect(KILL cr); 9786 9787 ins_cost(150); 9788 format %{ "orb $dst, $src\t# byte" %} 9789 opcode(0x08); 9790 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9791 ins_pipe(ialu_mem_reg); 9792 %} 9793 9794 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9795 %{ 9796 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9797 effect(KILL cr); 9798 9799 ins_cost(150); 9800 format %{ "orl $dst, $src\t# int" %} 9801 opcode(0x09); /* Opcode 09 /r */ 9802 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9803 ins_pipe(ialu_mem_reg); 9804 %} 9805 9806 // Or Memory with Immediate 9807 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9808 %{ 9809 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9810 effect(KILL cr); 9811 9812 ins_cost(125); 9813 format %{ "orl $dst, $src\t# int" %} 9814 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9815 ins_encode(REX_mem(dst), OpcSE(src), 9816 RM_opc_mem(secondary, dst), Con8or32(src)); 9817 ins_pipe(ialu_mem_imm); 9818 %} 9819 9820 // Xor Instructions 9821 // Xor Register with Register 9822 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9823 %{ 9824 match(Set dst (XorI dst src)); 9825 effect(KILL cr); 9826 9827 format %{ "xorl $dst, $src\t# int" %} 9828 opcode(0x33); 9829 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9830 ins_pipe(ialu_reg_reg); 9831 %} 9832 9833 // Xor Register with Immediate -1 9834 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9835 match(Set dst (XorI dst imm)); 9836 9837 format %{ "not $dst" %} 9838 ins_encode %{ 9839 __ notl($dst$$Register); 9840 %} 9841 ins_pipe(ialu_reg); 9842 %} 9843 9844 // Xor Register with Immediate 9845 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9846 %{ 9847 match(Set dst (XorI dst src)); 9848 effect(KILL cr); 9849 9850 format %{ "xorl $dst, $src\t# int" %} 9851 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9852 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9853 ins_pipe(ialu_reg); 9854 %} 9855 9856 // Xor Register with Memory 9857 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9858 %{ 9859 match(Set dst (XorI dst (LoadI src))); 9860 effect(KILL cr); 9861 9862 ins_cost(125); 9863 format %{ "xorl $dst, $src\t# int" %} 9864 opcode(0x33); 9865 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9866 ins_pipe(ialu_reg_mem); 9867 %} 9868 9869 // Xor Memory with Register 9870 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9871 %{ 9872 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9873 effect(KILL cr); 9874 9875 ins_cost(150); 9876 format %{ "xorb $dst, $src\t# byte" %} 9877 opcode(0x30); 9878 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9879 ins_pipe(ialu_mem_reg); 9880 %} 9881 9882 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9883 %{ 9884 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9885 effect(KILL cr); 9886 9887 ins_cost(150); 9888 format %{ "xorl $dst, $src\t# int" %} 9889 opcode(0x31); /* Opcode 31 /r */ 9890 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9891 ins_pipe(ialu_mem_reg); 9892 %} 9893 9894 // Xor Memory with Immediate 9895 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9896 %{ 9897 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9898 effect(KILL cr); 9899 9900 ins_cost(125); 9901 format %{ "xorl $dst, $src\t# int" %} 9902 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9903 ins_encode(REX_mem(dst), OpcSE(src), 9904 RM_opc_mem(secondary, dst), Con8or32(src)); 9905 ins_pipe(ialu_mem_imm); 9906 %} 9907 9908 9909 // Long Logical Instructions 9910 9911 // And Instructions 9912 // And Register with Register 9913 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9914 %{ 9915 match(Set dst (AndL dst src)); 9916 effect(KILL cr); 9917 9918 format %{ "andq $dst, $src\t# long" %} 9919 opcode(0x23); 9920 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9921 ins_pipe(ialu_reg_reg); 9922 %} 9923 9924 // And Register with Immediate 255 9925 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9926 %{ 9927 match(Set dst (AndL dst src)); 9928 9929 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9930 opcode(0x0F, 0xB6); 9931 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9932 ins_pipe(ialu_reg); 9933 %} 9934 9935 // And Register with Immediate 65535 9936 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9937 %{ 9938 match(Set dst (AndL dst src)); 9939 9940 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9941 opcode(0x0F, 0xB7); 9942 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9943 ins_pipe(ialu_reg); 9944 %} 9945 9946 // And Register with Immediate 9947 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9948 %{ 9949 match(Set dst (AndL dst src)); 9950 effect(KILL cr); 9951 9952 format %{ "andq $dst, $src\t# long" %} 9953 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9954 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9955 ins_pipe(ialu_reg); 9956 %} 9957 9958 // And Register with Memory 9959 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9960 %{ 9961 match(Set dst (AndL dst (LoadL src))); 9962 effect(KILL cr); 9963 9964 ins_cost(125); 9965 format %{ "andq $dst, $src\t# long" %} 9966 opcode(0x23); 9967 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9968 ins_pipe(ialu_reg_mem); 9969 %} 9970 9971 // And Memory with Register 9972 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9973 %{ 9974 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9975 effect(KILL cr); 9976 9977 ins_cost(150); 9978 format %{ "andq $dst, $src\t# long" %} 9979 opcode(0x21); /* Opcode 21 /r */ 9980 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9981 ins_pipe(ialu_mem_reg); 9982 %} 9983 9984 // And Memory with Immediate 9985 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9986 %{ 9987 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9988 effect(KILL cr); 9989 9990 ins_cost(125); 9991 format %{ "andq $dst, $src\t# long" %} 9992 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9993 ins_encode(REX_mem_wide(dst), OpcSE(src), 9994 RM_opc_mem(secondary, dst), Con8or32(src)); 9995 ins_pipe(ialu_mem_imm); 9996 %} 9997 9998 // BMI1 instructions 9999 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10000 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10001 predicate(UseBMI1Instructions); 10002 effect(KILL cr); 10003 10004 ins_cost(125); 10005 format %{ "andnq $dst, $src1, $src2" %} 10006 10007 ins_encode %{ 10008 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10009 %} 10010 ins_pipe(ialu_reg_mem); 10011 %} 10012 10013 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10014 match(Set dst (AndL (XorL src1 minus_1) src2)); 10015 predicate(UseBMI1Instructions); 10016 effect(KILL cr); 10017 10018 format %{ "andnq $dst, $src1, $src2" %} 10019 10020 ins_encode %{ 10021 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10022 %} 10023 ins_pipe(ialu_reg_mem); 10024 %} 10025 10026 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10027 match(Set dst (AndL (SubL imm_zero src) src)); 10028 predicate(UseBMI1Instructions); 10029 effect(KILL cr); 10030 10031 format %{ "blsiq $dst, $src" %} 10032 10033 ins_encode %{ 10034 __ blsiq($dst$$Register, $src$$Register); 10035 %} 10036 ins_pipe(ialu_reg); 10037 %} 10038 10039 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10040 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10041 predicate(UseBMI1Instructions); 10042 effect(KILL cr); 10043 10044 ins_cost(125); 10045 format %{ "blsiq $dst, $src" %} 10046 10047 ins_encode %{ 10048 __ blsiq($dst$$Register, $src$$Address); 10049 %} 10050 ins_pipe(ialu_reg_mem); 10051 %} 10052 10053 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10054 %{ 10055 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 10056 predicate(UseBMI1Instructions); 10057 effect(KILL cr); 10058 10059 ins_cost(125); 10060 format %{ "blsmskq $dst, $src" %} 10061 10062 ins_encode %{ 10063 __ blsmskq($dst$$Register, $src$$Address); 10064 %} 10065 ins_pipe(ialu_reg_mem); 10066 %} 10067 10068 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10069 %{ 10070 match(Set dst (XorL (AddL src minus_1) src)); 10071 predicate(UseBMI1Instructions); 10072 effect(KILL cr); 10073 10074 format %{ "blsmskq $dst, $src" %} 10075 10076 ins_encode %{ 10077 __ blsmskq($dst$$Register, $src$$Register); 10078 %} 10079 10080 ins_pipe(ialu_reg); 10081 %} 10082 10083 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10084 %{ 10085 match(Set dst (AndL (AddL src minus_1) src) ); 10086 predicate(UseBMI1Instructions); 10087 effect(KILL cr); 10088 10089 format %{ "blsrq $dst, $src" %} 10090 10091 ins_encode %{ 10092 __ blsrq($dst$$Register, $src$$Register); 10093 %} 10094 10095 ins_pipe(ialu_reg); 10096 %} 10097 10098 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10099 %{ 10100 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 10101 predicate(UseBMI1Instructions); 10102 effect(KILL cr); 10103 10104 ins_cost(125); 10105 format %{ "blsrq $dst, $src" %} 10106 10107 ins_encode %{ 10108 __ blsrq($dst$$Register, $src$$Address); 10109 %} 10110 10111 ins_pipe(ialu_reg); 10112 %} 10113 10114 // Or Instructions 10115 // Or Register with Register 10116 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10117 %{ 10118 match(Set dst (OrL dst src)); 10119 effect(KILL cr); 10120 10121 format %{ "orq $dst, $src\t# long" %} 10122 opcode(0x0B); 10123 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10124 ins_pipe(ialu_reg_reg); 10125 %} 10126 10127 // Use any_RegP to match R15 (TLS register) without spilling. 10128 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 10129 match(Set dst (OrL dst (CastP2X src))); 10130 effect(KILL cr); 10131 10132 format %{ "orq $dst, $src\t# long" %} 10133 opcode(0x0B); 10134 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10135 ins_pipe(ialu_reg_reg); 10136 %} 10137 10138 10139 // Or Register with Immediate 10140 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10141 %{ 10142 match(Set dst (OrL dst src)); 10143 effect(KILL cr); 10144 10145 format %{ "orq $dst, $src\t# long" %} 10146 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 10147 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10148 ins_pipe(ialu_reg); 10149 %} 10150 10151 // Or Register with Memory 10152 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10153 %{ 10154 match(Set dst (OrL dst (LoadL src))); 10155 effect(KILL cr); 10156 10157 ins_cost(125); 10158 format %{ "orq $dst, $src\t# long" %} 10159 opcode(0x0B); 10160 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10161 ins_pipe(ialu_reg_mem); 10162 %} 10163 10164 // Or Memory with Register 10165 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10166 %{ 10167 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10168 effect(KILL cr); 10169 10170 ins_cost(150); 10171 format %{ "orq $dst, $src\t# long" %} 10172 opcode(0x09); /* Opcode 09 /r */ 10173 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10174 ins_pipe(ialu_mem_reg); 10175 %} 10176 10177 // Or Memory with Immediate 10178 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10179 %{ 10180 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10181 effect(KILL cr); 10182 10183 ins_cost(125); 10184 format %{ "orq $dst, $src\t# long" %} 10185 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 10186 ins_encode(REX_mem_wide(dst), OpcSE(src), 10187 RM_opc_mem(secondary, dst), Con8or32(src)); 10188 ins_pipe(ialu_mem_imm); 10189 %} 10190 10191 // Xor Instructions 10192 // Xor Register with Register 10193 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10194 %{ 10195 match(Set dst (XorL dst src)); 10196 effect(KILL cr); 10197 10198 format %{ "xorq $dst, $src\t# long" %} 10199 opcode(0x33); 10200 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10201 ins_pipe(ialu_reg_reg); 10202 %} 10203 10204 // Xor Register with Immediate -1 10205 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10206 match(Set dst (XorL dst imm)); 10207 10208 format %{ "notq $dst" %} 10209 ins_encode %{ 10210 __ notq($dst$$Register); 10211 %} 10212 ins_pipe(ialu_reg); 10213 %} 10214 10215 // Xor Register with Immediate 10216 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10217 %{ 10218 match(Set dst (XorL dst src)); 10219 effect(KILL cr); 10220 10221 format %{ "xorq $dst, $src\t# long" %} 10222 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10223 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10224 ins_pipe(ialu_reg); 10225 %} 10226 10227 // Xor Register with Memory 10228 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10229 %{ 10230 match(Set dst (XorL dst (LoadL src))); 10231 effect(KILL cr); 10232 10233 ins_cost(125); 10234 format %{ "xorq $dst, $src\t# long" %} 10235 opcode(0x33); 10236 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10237 ins_pipe(ialu_reg_mem); 10238 %} 10239 10240 // Xor Memory with Register 10241 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10242 %{ 10243 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10244 effect(KILL cr); 10245 10246 ins_cost(150); 10247 format %{ "xorq $dst, $src\t# long" %} 10248 opcode(0x31); /* Opcode 31 /r */ 10249 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10250 ins_pipe(ialu_mem_reg); 10251 %} 10252 10253 // Xor Memory with Immediate 10254 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10255 %{ 10256 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10257 effect(KILL cr); 10258 10259 ins_cost(125); 10260 format %{ "xorq $dst, $src\t# long" %} 10261 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10262 ins_encode(REX_mem_wide(dst), OpcSE(src), 10263 RM_opc_mem(secondary, dst), Con8or32(src)); 10264 ins_pipe(ialu_mem_imm); 10265 %} 10266 10267 // Convert Int to Boolean 10268 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10269 %{ 10270 match(Set dst (Conv2B src)); 10271 effect(KILL cr); 10272 10273 format %{ "testl $src, $src\t# ci2b\n\t" 10274 "setnz $dst\n\t" 10275 "movzbl $dst, $dst" %} 10276 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10277 setNZ_reg(dst), 10278 REX_reg_breg(dst, dst), // movzbl 10279 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10280 ins_pipe(pipe_slow); // XXX 10281 %} 10282 10283 // Convert Pointer to Boolean 10284 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10285 %{ 10286 match(Set dst (Conv2B src)); 10287 effect(KILL cr); 10288 10289 format %{ "testq $src, $src\t# cp2b\n\t" 10290 "setnz $dst\n\t" 10291 "movzbl $dst, $dst" %} 10292 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10293 setNZ_reg(dst), 10294 REX_reg_breg(dst, dst), // movzbl 10295 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10296 ins_pipe(pipe_slow); // XXX 10297 %} 10298 10299 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10300 %{ 10301 match(Set dst (CmpLTMask p q)); 10302 effect(KILL cr); 10303 10304 ins_cost(400); 10305 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10306 "setlt $dst\n\t" 10307 "movzbl $dst, $dst\n\t" 10308 "negl $dst" %} 10309 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10310 setLT_reg(dst), 10311 REX_reg_breg(dst, dst), // movzbl 10312 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10313 neg_reg(dst)); 10314 ins_pipe(pipe_slow); 10315 %} 10316 10317 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10318 %{ 10319 match(Set dst (CmpLTMask dst zero)); 10320 effect(KILL cr); 10321 10322 ins_cost(100); 10323 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10324 ins_encode %{ 10325 __ sarl($dst$$Register, 31); 10326 %} 10327 ins_pipe(ialu_reg); 10328 %} 10329 10330 /* Better to save a register than avoid a branch */ 10331 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10332 %{ 10333 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10334 effect(KILL cr); 10335 ins_cost(300); 10336 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10337 "jge done\n\t" 10338 "addl $p,$y\n" 10339 "done: " %} 10340 ins_encode %{ 10341 Register Rp = $p$$Register; 10342 Register Rq = $q$$Register; 10343 Register Ry = $y$$Register; 10344 Label done; 10345 __ subl(Rp, Rq); 10346 __ jccb(Assembler::greaterEqual, done); 10347 __ addl(Rp, Ry); 10348 __ bind(done); 10349 %} 10350 ins_pipe(pipe_cmplt); 10351 %} 10352 10353 /* Better to save a register than avoid a branch */ 10354 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10355 %{ 10356 match(Set y (AndI (CmpLTMask p q) y)); 10357 effect(KILL cr); 10358 10359 ins_cost(300); 10360 10361 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10362 "jlt done\n\t" 10363 "xorl $y, $y\n" 10364 "done: " %} 10365 ins_encode %{ 10366 Register Rp = $p$$Register; 10367 Register Rq = $q$$Register; 10368 Register Ry = $y$$Register; 10369 Label done; 10370 __ cmpl(Rp, Rq); 10371 __ jccb(Assembler::less, done); 10372 __ xorl(Ry, Ry); 10373 __ bind(done); 10374 %} 10375 ins_pipe(pipe_cmplt); 10376 %} 10377 10378 10379 //---------- FP Instructions------------------------------------------------ 10380 10381 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10382 %{ 10383 match(Set cr (CmpF src1 src2)); 10384 10385 ins_cost(145); 10386 format %{ "ucomiss $src1, $src2\n\t" 10387 "jnp,s exit\n\t" 10388 "pushfq\t# saw NaN, set CF\n\t" 10389 "andq [rsp], #0xffffff2b\n\t" 10390 "popfq\n" 10391 "exit:" %} 10392 ins_encode %{ 10393 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10394 emit_cmpfp_fixup(_masm); 10395 %} 10396 ins_pipe(pipe_slow); 10397 %} 10398 10399 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10400 match(Set cr (CmpF src1 src2)); 10401 10402 ins_cost(100); 10403 format %{ "ucomiss $src1, $src2" %} 10404 ins_encode %{ 10405 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10406 %} 10407 ins_pipe(pipe_slow); 10408 %} 10409 10410 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10411 %{ 10412 match(Set cr (CmpF src1 (LoadF src2))); 10413 10414 ins_cost(145); 10415 format %{ "ucomiss $src1, $src2\n\t" 10416 "jnp,s exit\n\t" 10417 "pushfq\t# saw NaN, set CF\n\t" 10418 "andq [rsp], #0xffffff2b\n\t" 10419 "popfq\n" 10420 "exit:" %} 10421 ins_encode %{ 10422 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10423 emit_cmpfp_fixup(_masm); 10424 %} 10425 ins_pipe(pipe_slow); 10426 %} 10427 10428 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10429 match(Set cr (CmpF src1 (LoadF src2))); 10430 10431 ins_cost(100); 10432 format %{ "ucomiss $src1, $src2" %} 10433 ins_encode %{ 10434 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10435 %} 10436 ins_pipe(pipe_slow); 10437 %} 10438 10439 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10440 match(Set cr (CmpF src con)); 10441 10442 ins_cost(145); 10443 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10444 "jnp,s exit\n\t" 10445 "pushfq\t# saw NaN, set CF\n\t" 10446 "andq [rsp], #0xffffff2b\n\t" 10447 "popfq\n" 10448 "exit:" %} 10449 ins_encode %{ 10450 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10451 emit_cmpfp_fixup(_masm); 10452 %} 10453 ins_pipe(pipe_slow); 10454 %} 10455 10456 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10457 match(Set cr (CmpF src con)); 10458 ins_cost(100); 10459 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10460 ins_encode %{ 10461 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10462 %} 10463 ins_pipe(pipe_slow); 10464 %} 10465 10466 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10467 %{ 10468 match(Set cr (CmpD src1 src2)); 10469 10470 ins_cost(145); 10471 format %{ "ucomisd $src1, $src2\n\t" 10472 "jnp,s exit\n\t" 10473 "pushfq\t# saw NaN, set CF\n\t" 10474 "andq [rsp], #0xffffff2b\n\t" 10475 "popfq\n" 10476 "exit:" %} 10477 ins_encode %{ 10478 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10479 emit_cmpfp_fixup(_masm); 10480 %} 10481 ins_pipe(pipe_slow); 10482 %} 10483 10484 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10485 match(Set cr (CmpD src1 src2)); 10486 10487 ins_cost(100); 10488 format %{ "ucomisd $src1, $src2 test" %} 10489 ins_encode %{ 10490 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10491 %} 10492 ins_pipe(pipe_slow); 10493 %} 10494 10495 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10496 %{ 10497 match(Set cr (CmpD src1 (LoadD src2))); 10498 10499 ins_cost(145); 10500 format %{ "ucomisd $src1, $src2\n\t" 10501 "jnp,s exit\n\t" 10502 "pushfq\t# saw NaN, set CF\n\t" 10503 "andq [rsp], #0xffffff2b\n\t" 10504 "popfq\n" 10505 "exit:" %} 10506 ins_encode %{ 10507 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10508 emit_cmpfp_fixup(_masm); 10509 %} 10510 ins_pipe(pipe_slow); 10511 %} 10512 10513 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10514 match(Set cr (CmpD src1 (LoadD src2))); 10515 10516 ins_cost(100); 10517 format %{ "ucomisd $src1, $src2" %} 10518 ins_encode %{ 10519 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10520 %} 10521 ins_pipe(pipe_slow); 10522 %} 10523 10524 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10525 match(Set cr (CmpD src con)); 10526 10527 ins_cost(145); 10528 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10529 "jnp,s exit\n\t" 10530 "pushfq\t# saw NaN, set CF\n\t" 10531 "andq [rsp], #0xffffff2b\n\t" 10532 "popfq\n" 10533 "exit:" %} 10534 ins_encode %{ 10535 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10536 emit_cmpfp_fixup(_masm); 10537 %} 10538 ins_pipe(pipe_slow); 10539 %} 10540 10541 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10542 match(Set cr (CmpD src con)); 10543 ins_cost(100); 10544 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10545 ins_encode %{ 10546 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10547 %} 10548 ins_pipe(pipe_slow); 10549 %} 10550 10551 // Compare into -1,0,1 10552 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10553 %{ 10554 match(Set dst (CmpF3 src1 src2)); 10555 effect(KILL cr); 10556 10557 ins_cost(275); 10558 format %{ "ucomiss $src1, $src2\n\t" 10559 "movl $dst, #-1\n\t" 10560 "jp,s done\n\t" 10561 "jb,s done\n\t" 10562 "setne $dst\n\t" 10563 "movzbl $dst, $dst\n" 10564 "done:" %} 10565 ins_encode %{ 10566 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10567 emit_cmpfp3(_masm, $dst$$Register); 10568 %} 10569 ins_pipe(pipe_slow); 10570 %} 10571 10572 // Compare into -1,0,1 10573 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10574 %{ 10575 match(Set dst (CmpF3 src1 (LoadF src2))); 10576 effect(KILL cr); 10577 10578 ins_cost(275); 10579 format %{ "ucomiss $src1, $src2\n\t" 10580 "movl $dst, #-1\n\t" 10581 "jp,s done\n\t" 10582 "jb,s done\n\t" 10583 "setne $dst\n\t" 10584 "movzbl $dst, $dst\n" 10585 "done:" %} 10586 ins_encode %{ 10587 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10588 emit_cmpfp3(_masm, $dst$$Register); 10589 %} 10590 ins_pipe(pipe_slow); 10591 %} 10592 10593 // Compare into -1,0,1 10594 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10595 match(Set dst (CmpF3 src con)); 10596 effect(KILL cr); 10597 10598 ins_cost(275); 10599 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10600 "movl $dst, #-1\n\t" 10601 "jp,s done\n\t" 10602 "jb,s done\n\t" 10603 "setne $dst\n\t" 10604 "movzbl $dst, $dst\n" 10605 "done:" %} 10606 ins_encode %{ 10607 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10608 emit_cmpfp3(_masm, $dst$$Register); 10609 %} 10610 ins_pipe(pipe_slow); 10611 %} 10612 10613 // Compare into -1,0,1 10614 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10615 %{ 10616 match(Set dst (CmpD3 src1 src2)); 10617 effect(KILL cr); 10618 10619 ins_cost(275); 10620 format %{ "ucomisd $src1, $src2\n\t" 10621 "movl $dst, #-1\n\t" 10622 "jp,s done\n\t" 10623 "jb,s done\n\t" 10624 "setne $dst\n\t" 10625 "movzbl $dst, $dst\n" 10626 "done:" %} 10627 ins_encode %{ 10628 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10629 emit_cmpfp3(_masm, $dst$$Register); 10630 %} 10631 ins_pipe(pipe_slow); 10632 %} 10633 10634 // Compare into -1,0,1 10635 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10636 %{ 10637 match(Set dst (CmpD3 src1 (LoadD src2))); 10638 effect(KILL cr); 10639 10640 ins_cost(275); 10641 format %{ "ucomisd $src1, $src2\n\t" 10642 "movl $dst, #-1\n\t" 10643 "jp,s done\n\t" 10644 "jb,s done\n\t" 10645 "setne $dst\n\t" 10646 "movzbl $dst, $dst\n" 10647 "done:" %} 10648 ins_encode %{ 10649 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10650 emit_cmpfp3(_masm, $dst$$Register); 10651 %} 10652 ins_pipe(pipe_slow); 10653 %} 10654 10655 // Compare into -1,0,1 10656 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10657 match(Set dst (CmpD3 src con)); 10658 effect(KILL cr); 10659 10660 ins_cost(275); 10661 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10662 "movl $dst, #-1\n\t" 10663 "jp,s done\n\t" 10664 "jb,s done\n\t" 10665 "setne $dst\n\t" 10666 "movzbl $dst, $dst\n" 10667 "done:" %} 10668 ins_encode %{ 10669 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10670 emit_cmpfp3(_masm, $dst$$Register); 10671 %} 10672 ins_pipe(pipe_slow); 10673 %} 10674 10675 //----------Arithmetic Conversion Instructions--------------------------------- 10676 10677 instruct roundFloat_nop(regF dst) 10678 %{ 10679 match(Set dst (RoundFloat dst)); 10680 10681 ins_cost(0); 10682 ins_encode(); 10683 ins_pipe(empty); 10684 %} 10685 10686 instruct roundDouble_nop(regD dst) 10687 %{ 10688 match(Set dst (RoundDouble dst)); 10689 10690 ins_cost(0); 10691 ins_encode(); 10692 ins_pipe(empty); 10693 %} 10694 10695 instruct convF2D_reg_reg(regD dst, regF src) 10696 %{ 10697 match(Set dst (ConvF2D src)); 10698 10699 format %{ "cvtss2sd $dst, $src" %} 10700 ins_encode %{ 10701 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10702 %} 10703 ins_pipe(pipe_slow); // XXX 10704 %} 10705 10706 instruct convF2D_reg_mem(regD dst, memory src) 10707 %{ 10708 match(Set dst (ConvF2D (LoadF src))); 10709 10710 format %{ "cvtss2sd $dst, $src" %} 10711 ins_encode %{ 10712 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10713 %} 10714 ins_pipe(pipe_slow); // XXX 10715 %} 10716 10717 instruct convD2F_reg_reg(regF dst, regD src) 10718 %{ 10719 match(Set dst (ConvD2F src)); 10720 10721 format %{ "cvtsd2ss $dst, $src" %} 10722 ins_encode %{ 10723 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10724 %} 10725 ins_pipe(pipe_slow); // XXX 10726 %} 10727 10728 instruct convD2F_reg_mem(regF dst, memory src) 10729 %{ 10730 match(Set dst (ConvD2F (LoadD src))); 10731 10732 format %{ "cvtsd2ss $dst, $src" %} 10733 ins_encode %{ 10734 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10735 %} 10736 ins_pipe(pipe_slow); // XXX 10737 %} 10738 10739 // XXX do mem variants 10740 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10741 %{ 10742 match(Set dst (ConvF2I src)); 10743 effect(KILL cr); 10744 10745 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10746 "cmpl $dst, #0x80000000\n\t" 10747 "jne,s done\n\t" 10748 "subq rsp, #8\n\t" 10749 "movss [rsp], $src\n\t" 10750 "call f2i_fixup\n\t" 10751 "popq $dst\n" 10752 "done: "%} 10753 ins_encode %{ 10754 Label done; 10755 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10756 __ cmpl($dst$$Register, 0x80000000); 10757 __ jccb(Assembler::notEqual, done); 10758 __ subptr(rsp, 8); 10759 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10760 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10761 __ pop($dst$$Register); 10762 __ bind(done); 10763 %} 10764 ins_pipe(pipe_slow); 10765 %} 10766 10767 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10768 %{ 10769 match(Set dst (ConvF2L src)); 10770 effect(KILL cr); 10771 10772 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10773 "cmpq $dst, [0x8000000000000000]\n\t" 10774 "jne,s done\n\t" 10775 "subq rsp, #8\n\t" 10776 "movss [rsp], $src\n\t" 10777 "call f2l_fixup\n\t" 10778 "popq $dst\n" 10779 "done: "%} 10780 ins_encode %{ 10781 Label done; 10782 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10783 __ cmp64($dst$$Register, 10784 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10785 __ jccb(Assembler::notEqual, done); 10786 __ subptr(rsp, 8); 10787 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10788 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10789 __ pop($dst$$Register); 10790 __ bind(done); 10791 %} 10792 ins_pipe(pipe_slow); 10793 %} 10794 10795 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10796 %{ 10797 match(Set dst (ConvD2I src)); 10798 effect(KILL cr); 10799 10800 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10801 "cmpl $dst, #0x80000000\n\t" 10802 "jne,s done\n\t" 10803 "subq rsp, #8\n\t" 10804 "movsd [rsp], $src\n\t" 10805 "call d2i_fixup\n\t" 10806 "popq $dst\n" 10807 "done: "%} 10808 ins_encode %{ 10809 Label done; 10810 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10811 __ cmpl($dst$$Register, 0x80000000); 10812 __ jccb(Assembler::notEqual, done); 10813 __ subptr(rsp, 8); 10814 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10815 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10816 __ pop($dst$$Register); 10817 __ bind(done); 10818 %} 10819 ins_pipe(pipe_slow); 10820 %} 10821 10822 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10823 %{ 10824 match(Set dst (ConvD2L src)); 10825 effect(KILL cr); 10826 10827 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10828 "cmpq $dst, [0x8000000000000000]\n\t" 10829 "jne,s done\n\t" 10830 "subq rsp, #8\n\t" 10831 "movsd [rsp], $src\n\t" 10832 "call d2l_fixup\n\t" 10833 "popq $dst\n" 10834 "done: "%} 10835 ins_encode %{ 10836 Label done; 10837 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10838 __ cmp64($dst$$Register, 10839 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10840 __ jccb(Assembler::notEqual, done); 10841 __ subptr(rsp, 8); 10842 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10843 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10844 __ pop($dst$$Register); 10845 __ bind(done); 10846 %} 10847 ins_pipe(pipe_slow); 10848 %} 10849 10850 instruct convI2F_reg_reg(regF dst, rRegI src) 10851 %{ 10852 predicate(!UseXmmI2F); 10853 match(Set dst (ConvI2F src)); 10854 10855 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10856 ins_encode %{ 10857 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10858 %} 10859 ins_pipe(pipe_slow); // XXX 10860 %} 10861 10862 instruct convI2F_reg_mem(regF dst, memory src) 10863 %{ 10864 match(Set dst (ConvI2F (LoadI src))); 10865 10866 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10867 ins_encode %{ 10868 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10869 %} 10870 ins_pipe(pipe_slow); // XXX 10871 %} 10872 10873 instruct convI2D_reg_reg(regD dst, rRegI src) 10874 %{ 10875 predicate(!UseXmmI2D); 10876 match(Set dst (ConvI2D src)); 10877 10878 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10879 ins_encode %{ 10880 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10881 %} 10882 ins_pipe(pipe_slow); // XXX 10883 %} 10884 10885 instruct convI2D_reg_mem(regD dst, memory src) 10886 %{ 10887 match(Set dst (ConvI2D (LoadI src))); 10888 10889 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10890 ins_encode %{ 10891 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10892 %} 10893 ins_pipe(pipe_slow); // XXX 10894 %} 10895 10896 instruct convXI2F_reg(regF dst, rRegI src) 10897 %{ 10898 predicate(UseXmmI2F); 10899 match(Set dst (ConvI2F src)); 10900 10901 format %{ "movdl $dst, $src\n\t" 10902 "cvtdq2psl $dst, $dst\t# i2f" %} 10903 ins_encode %{ 10904 __ movdl($dst$$XMMRegister, $src$$Register); 10905 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10906 %} 10907 ins_pipe(pipe_slow); // XXX 10908 %} 10909 10910 instruct convXI2D_reg(regD dst, rRegI src) 10911 %{ 10912 predicate(UseXmmI2D); 10913 match(Set dst (ConvI2D src)); 10914 10915 format %{ "movdl $dst, $src\n\t" 10916 "cvtdq2pdl $dst, $dst\t# i2d" %} 10917 ins_encode %{ 10918 __ movdl($dst$$XMMRegister, $src$$Register); 10919 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10920 %} 10921 ins_pipe(pipe_slow); // XXX 10922 %} 10923 10924 instruct convL2F_reg_reg(regF dst, rRegL src) 10925 %{ 10926 match(Set dst (ConvL2F src)); 10927 10928 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10929 ins_encode %{ 10930 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10931 %} 10932 ins_pipe(pipe_slow); // XXX 10933 %} 10934 10935 instruct convL2F_reg_mem(regF dst, memory src) 10936 %{ 10937 match(Set dst (ConvL2F (LoadL src))); 10938 10939 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10940 ins_encode %{ 10941 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10942 %} 10943 ins_pipe(pipe_slow); // XXX 10944 %} 10945 10946 instruct convL2D_reg_reg(regD dst, rRegL src) 10947 %{ 10948 match(Set dst (ConvL2D src)); 10949 10950 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10951 ins_encode %{ 10952 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10953 %} 10954 ins_pipe(pipe_slow); // XXX 10955 %} 10956 10957 instruct convL2D_reg_mem(regD dst, memory src) 10958 %{ 10959 match(Set dst (ConvL2D (LoadL src))); 10960 10961 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10962 ins_encode %{ 10963 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10964 %} 10965 ins_pipe(pipe_slow); // XXX 10966 %} 10967 10968 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10969 %{ 10970 match(Set dst (ConvI2L src)); 10971 10972 ins_cost(125); 10973 format %{ "movslq $dst, $src\t# i2l" %} 10974 ins_encode %{ 10975 __ movslq($dst$$Register, $src$$Register); 10976 %} 10977 ins_pipe(ialu_reg_reg); 10978 %} 10979 10980 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10981 // %{ 10982 // match(Set dst (ConvI2L src)); 10983 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10984 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10985 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10986 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10987 // ((const TypeNode*) n)->type()->is_long()->_lo == 10988 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10989 10990 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10991 // ins_encode(enc_copy(dst, src)); 10992 // // opcode(0x63); // needs REX.W 10993 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10994 // ins_pipe(ialu_reg_reg); 10995 // %} 10996 10997 // Zero-extend convert int to long 10998 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10999 %{ 11000 match(Set dst (AndL (ConvI2L src) mask)); 11001 11002 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11003 ins_encode %{ 11004 if ($dst$$reg != $src$$reg) { 11005 __ movl($dst$$Register, $src$$Register); 11006 } 11007 %} 11008 ins_pipe(ialu_reg_reg); 11009 %} 11010 11011 // Zero-extend convert int to long 11012 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11013 %{ 11014 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11015 11016 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11017 ins_encode %{ 11018 __ movl($dst$$Register, $src$$Address); 11019 %} 11020 ins_pipe(ialu_reg_mem); 11021 %} 11022 11023 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 11024 %{ 11025 match(Set dst (AndL src mask)); 11026 11027 format %{ "movl $dst, $src\t# zero-extend long" %} 11028 ins_encode %{ 11029 __ movl($dst$$Register, $src$$Register); 11030 %} 11031 ins_pipe(ialu_reg_reg); 11032 %} 11033 11034 instruct convL2I_reg_reg(rRegI dst, rRegL src) 11035 %{ 11036 match(Set dst (ConvL2I src)); 11037 11038 format %{ "movl $dst, $src\t# l2i" %} 11039 ins_encode %{ 11040 __ movl($dst$$Register, $src$$Register); 11041 %} 11042 ins_pipe(ialu_reg_reg); 11043 %} 11044 11045 11046 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 11047 match(Set dst (MoveF2I src)); 11048 effect(DEF dst, USE src); 11049 11050 ins_cost(125); 11051 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 11052 ins_encode %{ 11053 __ movl($dst$$Register, Address(rsp, $src$$disp)); 11054 %} 11055 ins_pipe(ialu_reg_mem); 11056 %} 11057 11058 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 11059 match(Set dst (MoveI2F src)); 11060 effect(DEF dst, USE src); 11061 11062 ins_cost(125); 11063 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 11064 ins_encode %{ 11065 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 11066 %} 11067 ins_pipe(pipe_slow); 11068 %} 11069 11070 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 11071 match(Set dst (MoveD2L src)); 11072 effect(DEF dst, USE src); 11073 11074 ins_cost(125); 11075 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 11076 ins_encode %{ 11077 __ movq($dst$$Register, Address(rsp, $src$$disp)); 11078 %} 11079 ins_pipe(ialu_reg_mem); 11080 %} 11081 11082 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 11083 predicate(!UseXmmLoadAndClearUpper); 11084 match(Set dst (MoveL2D src)); 11085 effect(DEF dst, USE src); 11086 11087 ins_cost(125); 11088 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 11089 ins_encode %{ 11090 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11091 %} 11092 ins_pipe(pipe_slow); 11093 %} 11094 11095 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 11096 predicate(UseXmmLoadAndClearUpper); 11097 match(Set dst (MoveL2D src)); 11098 effect(DEF dst, USE src); 11099 11100 ins_cost(125); 11101 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 11102 ins_encode %{ 11103 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11104 %} 11105 ins_pipe(pipe_slow); 11106 %} 11107 11108 11109 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 11110 match(Set dst (MoveF2I src)); 11111 effect(DEF dst, USE src); 11112 11113 ins_cost(95); // XXX 11114 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 11115 ins_encode %{ 11116 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 11117 %} 11118 ins_pipe(pipe_slow); 11119 %} 11120 11121 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 11122 match(Set dst (MoveI2F src)); 11123 effect(DEF dst, USE src); 11124 11125 ins_cost(100); 11126 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 11127 ins_encode %{ 11128 __ movl(Address(rsp, $dst$$disp), $src$$Register); 11129 %} 11130 ins_pipe( ialu_mem_reg ); 11131 %} 11132 11133 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 11134 match(Set dst (MoveD2L src)); 11135 effect(DEF dst, USE src); 11136 11137 ins_cost(95); // XXX 11138 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 11139 ins_encode %{ 11140 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 11141 %} 11142 ins_pipe(pipe_slow); 11143 %} 11144 11145 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 11146 match(Set dst (MoveL2D src)); 11147 effect(DEF dst, USE src); 11148 11149 ins_cost(100); 11150 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 11151 ins_encode %{ 11152 __ movq(Address(rsp, $dst$$disp), $src$$Register); 11153 %} 11154 ins_pipe(ialu_mem_reg); 11155 %} 11156 11157 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 11158 match(Set dst (MoveF2I src)); 11159 effect(DEF dst, USE src); 11160 ins_cost(85); 11161 format %{ "movd $dst,$src\t# MoveF2I" %} 11162 ins_encode %{ 11163 __ movdl($dst$$Register, $src$$XMMRegister); 11164 %} 11165 ins_pipe( pipe_slow ); 11166 %} 11167 11168 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 11169 match(Set dst (MoveD2L src)); 11170 effect(DEF dst, USE src); 11171 ins_cost(85); 11172 format %{ "movd $dst,$src\t# MoveD2L" %} 11173 ins_encode %{ 11174 __ movdq($dst$$Register, $src$$XMMRegister); 11175 %} 11176 ins_pipe( pipe_slow ); 11177 %} 11178 11179 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 11180 match(Set dst (MoveI2F src)); 11181 effect(DEF dst, USE src); 11182 ins_cost(100); 11183 format %{ "movd $dst,$src\t# MoveI2F" %} 11184 ins_encode %{ 11185 __ movdl($dst$$XMMRegister, $src$$Register); 11186 %} 11187 ins_pipe( pipe_slow ); 11188 %} 11189 11190 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 11191 match(Set dst (MoveL2D src)); 11192 effect(DEF dst, USE src); 11193 ins_cost(100); 11194 format %{ "movd $dst,$src\t# MoveL2D" %} 11195 ins_encode %{ 11196 __ movdq($dst$$XMMRegister, $src$$Register); 11197 %} 11198 ins_pipe( pipe_slow ); 11199 %} 11200 11201 11202 // ======================================================================= 11203 // fast clearing of an array 11204 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11205 Universe dummy, rFlagsReg cr) 11206 %{ 11207 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only()); 11208 match(Set dummy (ClearArray (Binary cnt base) val)); 11209 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11210 11211 format %{ $$template 11212 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11213 $$emit$$"jg LARGE\n\t" 11214 $$emit$$"dec rcx\n\t" 11215 $$emit$$"js DONE\t# Zero length\n\t" 11216 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11217 $$emit$$"dec rcx\n\t" 11218 $$emit$$"jge LOOP\n\t" 11219 $$emit$$"jmp DONE\n\t" 11220 $$emit$$"# LARGE:\n\t" 11221 if (UseFastStosb) { 11222 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11223 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 11224 } else if (UseXMMForObjInit) { 11225 $$emit$$"movdq $tmp, $val\n\t" 11226 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11227 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11228 $$emit$$"jmpq L_zero_64_bytes\n\t" 11229 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11230 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11231 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11232 $$emit$$"add 0x40,rax\n\t" 11233 $$emit$$"# L_zero_64_bytes:\n\t" 11234 $$emit$$"sub 0x8,rcx\n\t" 11235 $$emit$$"jge L_loop\n\t" 11236 $$emit$$"add 0x4,rcx\n\t" 11237 $$emit$$"jl L_tail\n\t" 11238 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11239 $$emit$$"add 0x20,rax\n\t" 11240 $$emit$$"sub 0x4,rcx\n\t" 11241 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11242 $$emit$$"add 0x4,rcx\n\t" 11243 $$emit$$"jle L_end\n\t" 11244 $$emit$$"dec rcx\n\t" 11245 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11246 $$emit$$"vmovq xmm0,(rax)\n\t" 11247 $$emit$$"add 0x8,rax\n\t" 11248 $$emit$$"dec rcx\n\t" 11249 $$emit$$"jge L_sloop\n\t" 11250 $$emit$$"# L_end:\n\t" 11251 } else { 11252 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11253 } 11254 $$emit$$"# DONE" 11255 %} 11256 ins_encode %{ 11257 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11258 $tmp$$XMMRegister, false, false); 11259 %} 11260 ins_pipe(pipe_slow); 11261 %} 11262 11263 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11264 Universe dummy, rFlagsReg cr) 11265 %{ 11266 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only()); 11267 match(Set dummy (ClearArray (Binary cnt base) val)); 11268 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11269 11270 format %{ $$template 11271 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11272 $$emit$$"jg LARGE\n\t" 11273 $$emit$$"dec rcx\n\t" 11274 $$emit$$"js DONE\t# Zero length\n\t" 11275 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11276 $$emit$$"dec rcx\n\t" 11277 $$emit$$"jge LOOP\n\t" 11278 $$emit$$"jmp DONE\n\t" 11279 $$emit$$"# LARGE:\n\t" 11280 if (UseXMMForObjInit) { 11281 $$emit$$"movdq $tmp, $val\n\t" 11282 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11283 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11284 $$emit$$"jmpq L_zero_64_bytes\n\t" 11285 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11286 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11287 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11288 $$emit$$"add 0x40,rax\n\t" 11289 $$emit$$"# L_zero_64_bytes:\n\t" 11290 $$emit$$"sub 0x8,rcx\n\t" 11291 $$emit$$"jge L_loop\n\t" 11292 $$emit$$"add 0x4,rcx\n\t" 11293 $$emit$$"jl L_tail\n\t" 11294 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11295 $$emit$$"add 0x20,rax\n\t" 11296 $$emit$$"sub 0x4,rcx\n\t" 11297 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11298 $$emit$$"add 0x4,rcx\n\t" 11299 $$emit$$"jle L_end\n\t" 11300 $$emit$$"dec rcx\n\t" 11301 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11302 $$emit$$"vmovq xmm0,(rax)\n\t" 11303 $$emit$$"add 0x8,rax\n\t" 11304 $$emit$$"dec rcx\n\t" 11305 $$emit$$"jge L_sloop\n\t" 11306 $$emit$$"# L_end:\n\t" 11307 } else { 11308 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11309 } 11310 $$emit$$"# DONE" 11311 %} 11312 ins_encode %{ 11313 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11314 $tmp$$XMMRegister, false, true); 11315 %} 11316 ins_pipe(pipe_slow); 11317 %} 11318 11319 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11320 Universe dummy, rFlagsReg cr) 11321 %{ 11322 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only()); 11323 match(Set dummy (ClearArray (Binary cnt base) val)); 11324 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11325 11326 format %{ $$template 11327 if (UseFastStosb) { 11328 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11329 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11330 } else if (UseXMMForObjInit) { 11331 $$emit$$"movdq $tmp, $val\n\t" 11332 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11333 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11334 $$emit$$"jmpq L_zero_64_bytes\n\t" 11335 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11336 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11337 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11338 $$emit$$"add 0x40,rax\n\t" 11339 $$emit$$"# L_zero_64_bytes:\n\t" 11340 $$emit$$"sub 0x8,rcx\n\t" 11341 $$emit$$"jge L_loop\n\t" 11342 $$emit$$"add 0x4,rcx\n\t" 11343 $$emit$$"jl L_tail\n\t" 11344 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11345 $$emit$$"add 0x20,rax\n\t" 11346 $$emit$$"sub 0x4,rcx\n\t" 11347 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11348 $$emit$$"add 0x4,rcx\n\t" 11349 $$emit$$"jle L_end\n\t" 11350 $$emit$$"dec rcx\n\t" 11351 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11352 $$emit$$"vmovq xmm0,(rax)\n\t" 11353 $$emit$$"add 0x8,rax\n\t" 11354 $$emit$$"dec rcx\n\t" 11355 $$emit$$"jge L_sloop\n\t" 11356 $$emit$$"# L_end:\n\t" 11357 } else { 11358 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11359 } 11360 %} 11361 ins_encode %{ 11362 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11363 $tmp$$XMMRegister, true, false); 11364 %} 11365 ins_pipe(pipe_slow); 11366 %} 11367 11368 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11369 Universe dummy, rFlagsReg cr) 11370 %{ 11371 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only()); 11372 match(Set dummy (ClearArray (Binary cnt base) val)); 11373 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11374 11375 format %{ $$template 11376 if (UseXMMForObjInit) { 11377 $$emit$$"movdq $tmp, $val\n\t" 11378 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11379 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11380 $$emit$$"jmpq L_zero_64_bytes\n\t" 11381 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11382 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11383 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11384 $$emit$$"add 0x40,rax\n\t" 11385 $$emit$$"# L_zero_64_bytes:\n\t" 11386 $$emit$$"sub 0x8,rcx\n\t" 11387 $$emit$$"jge L_loop\n\t" 11388 $$emit$$"add 0x4,rcx\n\t" 11389 $$emit$$"jl L_tail\n\t" 11390 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11391 $$emit$$"add 0x20,rax\n\t" 11392 $$emit$$"sub 0x4,rcx\n\t" 11393 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11394 $$emit$$"add 0x4,rcx\n\t" 11395 $$emit$$"jle L_end\n\t" 11396 $$emit$$"dec rcx\n\t" 11397 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11398 $$emit$$"vmovq xmm0,(rax)\n\t" 11399 $$emit$$"add 0x8,rax\n\t" 11400 $$emit$$"dec rcx\n\t" 11401 $$emit$$"jge L_sloop\n\t" 11402 $$emit$$"# L_end:\n\t" 11403 } else { 11404 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11405 } 11406 %} 11407 ins_encode %{ 11408 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11409 $tmp$$XMMRegister, true, true); 11410 %} 11411 ins_pipe(pipe_slow); 11412 %} 11413 11414 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11415 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11416 %{ 11417 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11418 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11419 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11420 11421 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11422 ins_encode %{ 11423 __ string_compare($str1$$Register, $str2$$Register, 11424 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11425 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11426 %} 11427 ins_pipe( pipe_slow ); 11428 %} 11429 11430 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11431 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11432 %{ 11433 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11434 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11435 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11436 11437 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11438 ins_encode %{ 11439 __ string_compare($str1$$Register, $str2$$Register, 11440 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11441 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11442 %} 11443 ins_pipe( pipe_slow ); 11444 %} 11445 11446 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11447 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11448 %{ 11449 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11450 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11451 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11452 11453 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11454 ins_encode %{ 11455 __ string_compare($str1$$Register, $str2$$Register, 11456 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11457 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11458 %} 11459 ins_pipe( pipe_slow ); 11460 %} 11461 11462 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11463 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11464 %{ 11465 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11466 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11467 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11468 11469 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11470 ins_encode %{ 11471 __ string_compare($str2$$Register, $str1$$Register, 11472 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11473 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11474 %} 11475 ins_pipe( pipe_slow ); 11476 %} 11477 11478 // fast search of substring with known size. 11479 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11480 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11481 %{ 11482 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11483 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11484 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11485 11486 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11487 ins_encode %{ 11488 int icnt2 = (int)$int_cnt2$$constant; 11489 if (icnt2 >= 16) { 11490 // IndexOf for constant substrings with size >= 16 elements 11491 // which don't need to be loaded through stack. 11492 __ string_indexofC8($str1$$Register, $str2$$Register, 11493 $cnt1$$Register, $cnt2$$Register, 11494 icnt2, $result$$Register, 11495 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11496 } else { 11497 // Small strings are loaded through stack if they cross page boundary. 11498 __ string_indexof($str1$$Register, $str2$$Register, 11499 $cnt1$$Register, $cnt2$$Register, 11500 icnt2, $result$$Register, 11501 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11502 } 11503 %} 11504 ins_pipe( pipe_slow ); 11505 %} 11506 11507 // fast search of substring with known size. 11508 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11509 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11510 %{ 11511 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11512 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11513 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11514 11515 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11516 ins_encode %{ 11517 int icnt2 = (int)$int_cnt2$$constant; 11518 if (icnt2 >= 8) { 11519 // IndexOf for constant substrings with size >= 8 elements 11520 // which don't need to be loaded through stack. 11521 __ string_indexofC8($str1$$Register, $str2$$Register, 11522 $cnt1$$Register, $cnt2$$Register, 11523 icnt2, $result$$Register, 11524 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11525 } else { 11526 // Small strings are loaded through stack if they cross page boundary. 11527 __ string_indexof($str1$$Register, $str2$$Register, 11528 $cnt1$$Register, $cnt2$$Register, 11529 icnt2, $result$$Register, 11530 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11531 } 11532 %} 11533 ins_pipe( pipe_slow ); 11534 %} 11535 11536 // fast search of substring with known size. 11537 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11538 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11539 %{ 11540 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11541 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11542 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11543 11544 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11545 ins_encode %{ 11546 int icnt2 = (int)$int_cnt2$$constant; 11547 if (icnt2 >= 8) { 11548 // IndexOf for constant substrings with size >= 8 elements 11549 // which don't need to be loaded through stack. 11550 __ string_indexofC8($str1$$Register, $str2$$Register, 11551 $cnt1$$Register, $cnt2$$Register, 11552 icnt2, $result$$Register, 11553 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11554 } else { 11555 // Small strings are loaded through stack if they cross page boundary. 11556 __ string_indexof($str1$$Register, $str2$$Register, 11557 $cnt1$$Register, $cnt2$$Register, 11558 icnt2, $result$$Register, 11559 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11560 } 11561 %} 11562 ins_pipe( pipe_slow ); 11563 %} 11564 11565 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11566 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11567 %{ 11568 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11569 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11570 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11571 11572 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11573 ins_encode %{ 11574 __ string_indexof($str1$$Register, $str2$$Register, 11575 $cnt1$$Register, $cnt2$$Register, 11576 (-1), $result$$Register, 11577 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11578 %} 11579 ins_pipe( pipe_slow ); 11580 %} 11581 11582 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11583 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11584 %{ 11585 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11586 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11587 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11588 11589 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11590 ins_encode %{ 11591 __ string_indexof($str1$$Register, $str2$$Register, 11592 $cnt1$$Register, $cnt2$$Register, 11593 (-1), $result$$Register, 11594 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11595 %} 11596 ins_pipe( pipe_slow ); 11597 %} 11598 11599 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11600 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11601 %{ 11602 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11603 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11604 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11605 11606 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11607 ins_encode %{ 11608 __ string_indexof($str1$$Register, $str2$$Register, 11609 $cnt1$$Register, $cnt2$$Register, 11610 (-1), $result$$Register, 11611 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11612 %} 11613 ins_pipe( pipe_slow ); 11614 %} 11615 11616 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11617 rbx_RegI result, legVecS vec1, legVecS vec2, legVecS vec3, rcx_RegI tmp, rFlagsReg cr) 11618 %{ 11619 predicate(UseSSE42Intrinsics); 11620 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11621 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11622 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11623 ins_encode %{ 11624 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11625 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11626 %} 11627 ins_pipe( pipe_slow ); 11628 %} 11629 11630 // fast string equals 11631 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11632 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11633 %{ 11634 match(Set result (StrEquals (Binary str1 str2) cnt)); 11635 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11636 11637 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11638 ins_encode %{ 11639 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11640 $cnt$$Register, $result$$Register, $tmp3$$Register, 11641 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11642 %} 11643 ins_pipe( pipe_slow ); 11644 %} 11645 11646 // fast array equals 11647 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11648 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11649 %{ 11650 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11651 match(Set result (AryEq ary1 ary2)); 11652 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11653 11654 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11655 ins_encode %{ 11656 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11657 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11658 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11659 %} 11660 ins_pipe( pipe_slow ); 11661 %} 11662 11663 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11664 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11665 %{ 11666 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11667 match(Set result (AryEq ary1 ary2)); 11668 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11669 11670 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11671 ins_encode %{ 11672 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11673 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11674 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11675 %} 11676 ins_pipe( pipe_slow ); 11677 %} 11678 11679 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11680 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11681 %{ 11682 match(Set result (HasNegatives ary1 len)); 11683 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11684 11685 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11686 ins_encode %{ 11687 __ has_negatives($ary1$$Register, $len$$Register, 11688 $result$$Register, $tmp3$$Register, 11689 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11690 %} 11691 ins_pipe( pipe_slow ); 11692 %} 11693 11694 // fast char[] to byte[] compression 11695 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11696 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11697 match(Set result (StrCompressedCopy src (Binary dst len))); 11698 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11699 11700 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11701 ins_encode %{ 11702 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11703 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11704 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11705 %} 11706 ins_pipe( pipe_slow ); 11707 %} 11708 11709 // fast byte[] to char[] inflation 11710 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11711 legVecS tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11712 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11713 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11714 11715 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11716 ins_encode %{ 11717 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11718 $tmp1$$XMMRegister, $tmp2$$Register); 11719 %} 11720 ins_pipe( pipe_slow ); 11721 %} 11722 11723 // encode char[] to byte[] in ISO_8859_1 11724 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11725 legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11726 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11727 match(Set result (EncodeISOArray src (Binary dst len))); 11728 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11729 11730 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11731 ins_encode %{ 11732 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11733 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11734 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11735 %} 11736 ins_pipe( pipe_slow ); 11737 %} 11738 11739 //----------Overflow Math Instructions----------------------------------------- 11740 11741 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11742 %{ 11743 match(Set cr (OverflowAddI op1 op2)); 11744 effect(DEF cr, USE_KILL op1, USE op2); 11745 11746 format %{ "addl $op1, $op2\t# overflow check int" %} 11747 11748 ins_encode %{ 11749 __ addl($op1$$Register, $op2$$Register); 11750 %} 11751 ins_pipe(ialu_reg_reg); 11752 %} 11753 11754 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11755 %{ 11756 match(Set cr (OverflowAddI op1 op2)); 11757 effect(DEF cr, USE_KILL op1, USE op2); 11758 11759 format %{ "addl $op1, $op2\t# overflow check int" %} 11760 11761 ins_encode %{ 11762 __ addl($op1$$Register, $op2$$constant); 11763 %} 11764 ins_pipe(ialu_reg_reg); 11765 %} 11766 11767 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11768 %{ 11769 match(Set cr (OverflowAddL op1 op2)); 11770 effect(DEF cr, USE_KILL op1, USE op2); 11771 11772 format %{ "addq $op1, $op2\t# overflow check long" %} 11773 ins_encode %{ 11774 __ addq($op1$$Register, $op2$$Register); 11775 %} 11776 ins_pipe(ialu_reg_reg); 11777 %} 11778 11779 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11780 %{ 11781 match(Set cr (OverflowAddL op1 op2)); 11782 effect(DEF cr, USE_KILL op1, USE op2); 11783 11784 format %{ "addq $op1, $op2\t# overflow check long" %} 11785 ins_encode %{ 11786 __ addq($op1$$Register, $op2$$constant); 11787 %} 11788 ins_pipe(ialu_reg_reg); 11789 %} 11790 11791 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11792 %{ 11793 match(Set cr (OverflowSubI op1 op2)); 11794 11795 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11796 ins_encode %{ 11797 __ cmpl($op1$$Register, $op2$$Register); 11798 %} 11799 ins_pipe(ialu_reg_reg); 11800 %} 11801 11802 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11803 %{ 11804 match(Set cr (OverflowSubI op1 op2)); 11805 11806 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11807 ins_encode %{ 11808 __ cmpl($op1$$Register, $op2$$constant); 11809 %} 11810 ins_pipe(ialu_reg_reg); 11811 %} 11812 11813 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11814 %{ 11815 match(Set cr (OverflowSubL op1 op2)); 11816 11817 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11818 ins_encode %{ 11819 __ cmpq($op1$$Register, $op2$$Register); 11820 %} 11821 ins_pipe(ialu_reg_reg); 11822 %} 11823 11824 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11825 %{ 11826 match(Set cr (OverflowSubL op1 op2)); 11827 11828 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11829 ins_encode %{ 11830 __ cmpq($op1$$Register, $op2$$constant); 11831 %} 11832 ins_pipe(ialu_reg_reg); 11833 %} 11834 11835 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11836 %{ 11837 match(Set cr (OverflowSubI zero op2)); 11838 effect(DEF cr, USE_KILL op2); 11839 11840 format %{ "negl $op2\t# overflow check int" %} 11841 ins_encode %{ 11842 __ negl($op2$$Register); 11843 %} 11844 ins_pipe(ialu_reg_reg); 11845 %} 11846 11847 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11848 %{ 11849 match(Set cr (OverflowSubL zero op2)); 11850 effect(DEF cr, USE_KILL op2); 11851 11852 format %{ "negq $op2\t# overflow check long" %} 11853 ins_encode %{ 11854 __ negq($op2$$Register); 11855 %} 11856 ins_pipe(ialu_reg_reg); 11857 %} 11858 11859 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11860 %{ 11861 match(Set cr (OverflowMulI op1 op2)); 11862 effect(DEF cr, USE_KILL op1, USE op2); 11863 11864 format %{ "imull $op1, $op2\t# overflow check int" %} 11865 ins_encode %{ 11866 __ imull($op1$$Register, $op2$$Register); 11867 %} 11868 ins_pipe(ialu_reg_reg_alu0); 11869 %} 11870 11871 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11872 %{ 11873 match(Set cr (OverflowMulI op1 op2)); 11874 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11875 11876 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11877 ins_encode %{ 11878 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11879 %} 11880 ins_pipe(ialu_reg_reg_alu0); 11881 %} 11882 11883 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11884 %{ 11885 match(Set cr (OverflowMulL op1 op2)); 11886 effect(DEF cr, USE_KILL op1, USE op2); 11887 11888 format %{ "imulq $op1, $op2\t# overflow check long" %} 11889 ins_encode %{ 11890 __ imulq($op1$$Register, $op2$$Register); 11891 %} 11892 ins_pipe(ialu_reg_reg_alu0); 11893 %} 11894 11895 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11896 %{ 11897 match(Set cr (OverflowMulL op1 op2)); 11898 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11899 11900 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11901 ins_encode %{ 11902 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11903 %} 11904 ins_pipe(ialu_reg_reg_alu0); 11905 %} 11906 11907 11908 //----------Control Flow Instructions------------------------------------------ 11909 // Signed compare Instructions 11910 11911 // XXX more variants!! 11912 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11913 %{ 11914 match(Set cr (CmpI op1 op2)); 11915 effect(DEF cr, USE op1, USE op2); 11916 11917 format %{ "cmpl $op1, $op2" %} 11918 opcode(0x3B); /* Opcode 3B /r */ 11919 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11920 ins_pipe(ialu_cr_reg_reg); 11921 %} 11922 11923 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11924 %{ 11925 match(Set cr (CmpI op1 op2)); 11926 11927 format %{ "cmpl $op1, $op2" %} 11928 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11929 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11930 ins_pipe(ialu_cr_reg_imm); 11931 %} 11932 11933 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11934 %{ 11935 match(Set cr (CmpI op1 (LoadI op2))); 11936 11937 ins_cost(500); // XXX 11938 format %{ "cmpl $op1, $op2" %} 11939 opcode(0x3B); /* Opcode 3B /r */ 11940 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11941 ins_pipe(ialu_cr_reg_mem); 11942 %} 11943 11944 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11945 %{ 11946 match(Set cr (CmpI src zero)); 11947 11948 format %{ "testl $src, $src" %} 11949 opcode(0x85); 11950 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11951 ins_pipe(ialu_cr_reg_imm); 11952 %} 11953 11954 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11955 %{ 11956 match(Set cr (CmpI (AndI src con) zero)); 11957 11958 format %{ "testl $src, $con" %} 11959 opcode(0xF7, 0x00); 11960 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11961 ins_pipe(ialu_cr_reg_imm); 11962 %} 11963 11964 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11965 %{ 11966 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11967 11968 format %{ "testl $src, $mem" %} 11969 opcode(0x85); 11970 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11971 ins_pipe(ialu_cr_reg_mem); 11972 %} 11973 11974 // Unsigned compare Instructions; really, same as signed except they 11975 // produce an rFlagsRegU instead of rFlagsReg. 11976 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11977 %{ 11978 match(Set cr (CmpU op1 op2)); 11979 11980 format %{ "cmpl $op1, $op2\t# unsigned" %} 11981 opcode(0x3B); /* Opcode 3B /r */ 11982 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11983 ins_pipe(ialu_cr_reg_reg); 11984 %} 11985 11986 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11987 %{ 11988 match(Set cr (CmpU op1 op2)); 11989 11990 format %{ "cmpl $op1, $op2\t# unsigned" %} 11991 opcode(0x81,0x07); /* Opcode 81 /7 */ 11992 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11993 ins_pipe(ialu_cr_reg_imm); 11994 %} 11995 11996 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11997 %{ 11998 match(Set cr (CmpU op1 (LoadI op2))); 11999 12000 ins_cost(500); // XXX 12001 format %{ "cmpl $op1, $op2\t# unsigned" %} 12002 opcode(0x3B); /* Opcode 3B /r */ 12003 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 12004 ins_pipe(ialu_cr_reg_mem); 12005 %} 12006 12007 // // // Cisc-spilled version of cmpU_rReg 12008 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 12009 // //%{ 12010 // // match(Set cr (CmpU (LoadI op1) op2)); 12011 // // 12012 // // format %{ "CMPu $op1,$op2" %} 12013 // // ins_cost(500); 12014 // // opcode(0x39); /* Opcode 39 /r */ 12015 // // ins_encode( OpcP, reg_mem( op1, op2) ); 12016 // //%} 12017 12018 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 12019 %{ 12020 match(Set cr (CmpU src zero)); 12021 12022 format %{ "testl $src, $src\t# unsigned" %} 12023 opcode(0x85); 12024 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 12025 ins_pipe(ialu_cr_reg_imm); 12026 %} 12027 12028 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 12029 %{ 12030 match(Set cr (CmpP op1 op2)); 12031 12032 format %{ "cmpq $op1, $op2\t# ptr" %} 12033 opcode(0x3B); /* Opcode 3B /r */ 12034 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12035 ins_pipe(ialu_cr_reg_reg); 12036 %} 12037 12038 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 12039 %{ 12040 match(Set cr (CmpP op1 (LoadP op2))); 12041 12042 ins_cost(500); // XXX 12043 format %{ "cmpq $op1, $op2\t# ptr" %} 12044 opcode(0x3B); /* Opcode 3B /r */ 12045 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12046 ins_pipe(ialu_cr_reg_mem); 12047 %} 12048 12049 // // // Cisc-spilled version of cmpP_rReg 12050 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 12051 // //%{ 12052 // // match(Set cr (CmpP (LoadP op1) op2)); 12053 // // 12054 // // format %{ "CMPu $op1,$op2" %} 12055 // // ins_cost(500); 12056 // // opcode(0x39); /* Opcode 39 /r */ 12057 // // ins_encode( OpcP, reg_mem( op1, op2) ); 12058 // //%} 12059 12060 // XXX this is generalized by compP_rReg_mem??? 12061 // Compare raw pointer (used in out-of-heap check). 12062 // Only works because non-oop pointers must be raw pointers 12063 // and raw pointers have no anti-dependencies. 12064 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 12065 %{ 12066 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 12067 match(Set cr (CmpP op1 (LoadP op2))); 12068 12069 format %{ "cmpq $op1, $op2\t# raw ptr" %} 12070 opcode(0x3B); /* Opcode 3B /r */ 12071 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12072 ins_pipe(ialu_cr_reg_mem); 12073 %} 12074 12075 // This will generate a signed flags result. This should be OK since 12076 // any compare to a zero should be eq/neq. 12077 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 12078 %{ 12079 match(Set cr (CmpP src zero)); 12080 12081 format %{ "testq $src, $src\t# ptr" %} 12082 opcode(0x85); 12083 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12084 ins_pipe(ialu_cr_reg_imm); 12085 %} 12086 12087 // This will generate a signed flags result. This should be OK since 12088 // any compare to a zero should be eq/neq. 12089 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 12090 %{ 12091 predicate(!UseCompressedOops || (CompressedOops::base() != NULL)); 12092 match(Set cr (CmpP (LoadP op) zero)); 12093 12094 ins_cost(500); // XXX 12095 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 12096 opcode(0xF7); /* Opcode F7 /0 */ 12097 ins_encode(REX_mem_wide(op), 12098 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 12099 ins_pipe(ialu_cr_reg_imm); 12100 %} 12101 12102 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 12103 %{ 12104 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 12105 match(Set cr (CmpP (LoadP mem) zero)); 12106 12107 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 12108 ins_encode %{ 12109 __ cmpq(r12, $mem$$Address); 12110 %} 12111 ins_pipe(ialu_cr_reg_mem); 12112 %} 12113 12114 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 12115 %{ 12116 match(Set cr (CmpN op1 op2)); 12117 12118 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12119 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 12120 ins_pipe(ialu_cr_reg_reg); 12121 %} 12122 12123 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 12124 %{ 12125 match(Set cr (CmpN src (LoadN mem))); 12126 12127 format %{ "cmpl $src, $mem\t# compressed ptr" %} 12128 ins_encode %{ 12129 __ cmpl($src$$Register, $mem$$Address); 12130 %} 12131 ins_pipe(ialu_cr_reg_mem); 12132 %} 12133 12134 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 12135 match(Set cr (CmpN op1 op2)); 12136 12137 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12138 ins_encode %{ 12139 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 12140 %} 12141 ins_pipe(ialu_cr_reg_imm); 12142 %} 12143 12144 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 12145 %{ 12146 match(Set cr (CmpN src (LoadN mem))); 12147 12148 format %{ "cmpl $mem, $src\t# compressed ptr" %} 12149 ins_encode %{ 12150 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 12151 %} 12152 ins_pipe(ialu_cr_reg_mem); 12153 %} 12154 12155 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 12156 match(Set cr (CmpN op1 op2)); 12157 12158 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 12159 ins_encode %{ 12160 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 12161 %} 12162 ins_pipe(ialu_cr_reg_imm); 12163 %} 12164 12165 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 12166 %{ 12167 match(Set cr (CmpN src (LoadNKlass mem))); 12168 12169 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 12170 ins_encode %{ 12171 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 12172 %} 12173 ins_pipe(ialu_cr_reg_mem); 12174 %} 12175 12176 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 12177 match(Set cr (CmpN src zero)); 12178 12179 format %{ "testl $src, $src\t# compressed ptr" %} 12180 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 12181 ins_pipe(ialu_cr_reg_imm); 12182 %} 12183 12184 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 12185 %{ 12186 predicate(CompressedOops::base() != NULL); 12187 match(Set cr (CmpN (LoadN mem) zero)); 12188 12189 ins_cost(500); // XXX 12190 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 12191 ins_encode %{ 12192 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 12193 %} 12194 ins_pipe(ialu_cr_reg_mem); 12195 %} 12196 12197 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 12198 %{ 12199 predicate(CompressedOops::base() == NULL && (CompressedKlassPointers::base() == NULL)); 12200 match(Set cr (CmpN (LoadN mem) zero)); 12201 12202 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 12203 ins_encode %{ 12204 __ cmpl(r12, $mem$$Address); 12205 %} 12206 ins_pipe(ialu_cr_reg_mem); 12207 %} 12208 12209 // Yanked all unsigned pointer compare operations. 12210 // Pointer compares are done with CmpP which is already unsigned. 12211 12212 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 12213 %{ 12214 match(Set cr (CmpL op1 op2)); 12215 12216 format %{ "cmpq $op1, $op2" %} 12217 opcode(0x3B); /* Opcode 3B /r */ 12218 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12219 ins_pipe(ialu_cr_reg_reg); 12220 %} 12221 12222 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 12223 %{ 12224 match(Set cr (CmpL op1 op2)); 12225 12226 format %{ "cmpq $op1, $op2" %} 12227 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12228 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12229 ins_pipe(ialu_cr_reg_imm); 12230 %} 12231 12232 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 12233 %{ 12234 match(Set cr (CmpL op1 (LoadL op2))); 12235 12236 format %{ "cmpq $op1, $op2" %} 12237 opcode(0x3B); /* Opcode 3B /r */ 12238 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12239 ins_pipe(ialu_cr_reg_mem); 12240 %} 12241 12242 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12243 %{ 12244 match(Set cr (CmpL src zero)); 12245 12246 format %{ "testq $src, $src" %} 12247 opcode(0x85); 12248 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12249 ins_pipe(ialu_cr_reg_imm); 12250 %} 12251 12252 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12253 %{ 12254 match(Set cr (CmpL (AndL src con) zero)); 12255 12256 format %{ "testq $src, $con\t# long" %} 12257 opcode(0xF7, 0x00); 12258 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 12259 ins_pipe(ialu_cr_reg_imm); 12260 %} 12261 12262 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12263 %{ 12264 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12265 12266 format %{ "testq $src, $mem" %} 12267 opcode(0x85); 12268 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12269 ins_pipe(ialu_cr_reg_mem); 12270 %} 12271 12272 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12273 %{ 12274 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12275 12276 format %{ "testq $src, $mem" %} 12277 opcode(0x85); 12278 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12279 ins_pipe(ialu_cr_reg_mem); 12280 %} 12281 12282 // Manifest a CmpL result in an integer register. Very painful. 12283 // This is the test to avoid. 12284 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12285 %{ 12286 match(Set dst (CmpL3 src1 src2)); 12287 effect(KILL flags); 12288 12289 ins_cost(275); // XXX 12290 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12291 "movl $dst, -1\n\t" 12292 "jl,s done\n\t" 12293 "setne $dst\n\t" 12294 "movzbl $dst, $dst\n\t" 12295 "done:" %} 12296 ins_encode(cmpl3_flag(src1, src2, dst)); 12297 ins_pipe(pipe_slow); 12298 %} 12299 12300 // Unsigned long compare Instructions; really, same as signed long except they 12301 // produce an rFlagsRegU instead of rFlagsReg. 12302 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12303 %{ 12304 match(Set cr (CmpUL op1 op2)); 12305 12306 format %{ "cmpq $op1, $op2\t# unsigned" %} 12307 opcode(0x3B); /* Opcode 3B /r */ 12308 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12309 ins_pipe(ialu_cr_reg_reg); 12310 %} 12311 12312 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12313 %{ 12314 match(Set cr (CmpUL op1 op2)); 12315 12316 format %{ "cmpq $op1, $op2\t# unsigned" %} 12317 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12318 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12319 ins_pipe(ialu_cr_reg_imm); 12320 %} 12321 12322 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12323 %{ 12324 match(Set cr (CmpUL op1 (LoadL op2))); 12325 12326 format %{ "cmpq $op1, $op2\t# unsigned" %} 12327 opcode(0x3B); /* Opcode 3B /r */ 12328 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12329 ins_pipe(ialu_cr_reg_mem); 12330 %} 12331 12332 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12333 %{ 12334 match(Set cr (CmpUL src zero)); 12335 12336 format %{ "testq $src, $src\t# unsigned" %} 12337 opcode(0x85); 12338 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12339 ins_pipe(ialu_cr_reg_imm); 12340 %} 12341 12342 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12343 %{ 12344 match(Set cr (CmpI (LoadB mem) imm)); 12345 12346 ins_cost(125); 12347 format %{ "cmpb $mem, $imm" %} 12348 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12349 ins_pipe(ialu_cr_reg_mem); 12350 %} 12351 12352 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 12353 %{ 12354 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12355 12356 ins_cost(125); 12357 format %{ "testb $mem, $imm\t# ubyte" %} 12358 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12359 ins_pipe(ialu_cr_reg_mem); 12360 %} 12361 12362 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 12363 %{ 12364 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12365 12366 ins_cost(125); 12367 format %{ "testb $mem, $imm\t# byte" %} 12368 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12369 ins_pipe(ialu_cr_reg_mem); 12370 %} 12371 12372 //----------Max and Min-------------------------------------------------------- 12373 // Min Instructions 12374 12375 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12376 %{ 12377 effect(USE_DEF dst, USE src, USE cr); 12378 12379 format %{ "cmovlgt $dst, $src\t# min" %} 12380 opcode(0x0F, 0x4F); 12381 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12382 ins_pipe(pipe_cmov_reg); 12383 %} 12384 12385 12386 instruct minI_rReg(rRegI dst, rRegI src) 12387 %{ 12388 match(Set dst (MinI dst src)); 12389 12390 ins_cost(200); 12391 expand %{ 12392 rFlagsReg cr; 12393 compI_rReg(cr, dst, src); 12394 cmovI_reg_g(dst, src, cr); 12395 %} 12396 %} 12397 12398 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12399 %{ 12400 effect(USE_DEF dst, USE src, USE cr); 12401 12402 format %{ "cmovllt $dst, $src\t# max" %} 12403 opcode(0x0F, 0x4C); 12404 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12405 ins_pipe(pipe_cmov_reg); 12406 %} 12407 12408 12409 instruct maxI_rReg(rRegI dst, rRegI src) 12410 %{ 12411 match(Set dst (MaxI dst src)); 12412 12413 ins_cost(200); 12414 expand %{ 12415 rFlagsReg cr; 12416 compI_rReg(cr, dst, src); 12417 cmovI_reg_l(dst, src, cr); 12418 %} 12419 %} 12420 12421 // ============================================================================ 12422 // Branch Instructions 12423 12424 // Jump Direct - Label defines a relative address from JMP+1 12425 instruct jmpDir(label labl) 12426 %{ 12427 match(Goto); 12428 effect(USE labl); 12429 12430 ins_cost(300); 12431 format %{ "jmp $labl" %} 12432 size(5); 12433 ins_encode %{ 12434 Label* L = $labl$$label; 12435 __ jmp(*L, false); // Always long jump 12436 %} 12437 ins_pipe(pipe_jmp); 12438 %} 12439 12440 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12441 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12442 %{ 12443 match(If cop cr); 12444 effect(USE labl); 12445 12446 ins_cost(300); 12447 format %{ "j$cop $labl" %} 12448 size(6); 12449 ins_encode %{ 12450 Label* L = $labl$$label; 12451 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12452 %} 12453 ins_pipe(pipe_jcc); 12454 %} 12455 12456 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12457 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12458 %{ 12459 predicate(!n->has_vector_mask_set()); 12460 match(CountedLoopEnd cop cr); 12461 effect(USE labl); 12462 12463 ins_cost(300); 12464 format %{ "j$cop $labl\t# loop end" %} 12465 size(6); 12466 ins_encode %{ 12467 Label* L = $labl$$label; 12468 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12469 %} 12470 ins_pipe(pipe_jcc); 12471 %} 12472 12473 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12474 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12475 predicate(!n->has_vector_mask_set()); 12476 match(CountedLoopEnd cop cmp); 12477 effect(USE labl); 12478 12479 ins_cost(300); 12480 format %{ "j$cop,u $labl\t# loop end" %} 12481 size(6); 12482 ins_encode %{ 12483 Label* L = $labl$$label; 12484 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12485 %} 12486 ins_pipe(pipe_jcc); 12487 %} 12488 12489 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12490 predicate(!n->has_vector_mask_set()); 12491 match(CountedLoopEnd cop cmp); 12492 effect(USE labl); 12493 12494 ins_cost(200); 12495 format %{ "j$cop,u $labl\t# loop end" %} 12496 size(6); 12497 ins_encode %{ 12498 Label* L = $labl$$label; 12499 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12500 %} 12501 ins_pipe(pipe_jcc); 12502 %} 12503 12504 // mask version 12505 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12506 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12507 %{ 12508 predicate(n->has_vector_mask_set()); 12509 match(CountedLoopEnd cop cr); 12510 effect(USE labl); 12511 12512 ins_cost(400); 12513 format %{ "j$cop $labl\t# loop end\n\t" 12514 "restorevectmask \t# vector mask restore for loops" %} 12515 size(10); 12516 ins_encode %{ 12517 Label* L = $labl$$label; 12518 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12519 __ restorevectmask(); 12520 %} 12521 ins_pipe(pipe_jcc); 12522 %} 12523 12524 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12525 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12526 predicate(n->has_vector_mask_set()); 12527 match(CountedLoopEnd cop cmp); 12528 effect(USE labl); 12529 12530 ins_cost(400); 12531 format %{ "j$cop,u $labl\t# loop end\n\t" 12532 "restorevectmask \t# vector mask restore for loops" %} 12533 size(10); 12534 ins_encode %{ 12535 Label* L = $labl$$label; 12536 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12537 __ restorevectmask(); 12538 %} 12539 ins_pipe(pipe_jcc); 12540 %} 12541 12542 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12543 predicate(n->has_vector_mask_set()); 12544 match(CountedLoopEnd cop cmp); 12545 effect(USE labl); 12546 12547 ins_cost(300); 12548 format %{ "j$cop,u $labl\t# loop end\n\t" 12549 "restorevectmask \t# vector mask restore for loops" %} 12550 size(10); 12551 ins_encode %{ 12552 Label* L = $labl$$label; 12553 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12554 __ restorevectmask(); 12555 %} 12556 ins_pipe(pipe_jcc); 12557 %} 12558 12559 // Jump Direct Conditional - using unsigned comparison 12560 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12561 match(If cop cmp); 12562 effect(USE labl); 12563 12564 ins_cost(300); 12565 format %{ "j$cop,u $labl" %} 12566 size(6); 12567 ins_encode %{ 12568 Label* L = $labl$$label; 12569 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12570 %} 12571 ins_pipe(pipe_jcc); 12572 %} 12573 12574 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12575 match(If cop cmp); 12576 effect(USE labl); 12577 12578 ins_cost(200); 12579 format %{ "j$cop,u $labl" %} 12580 size(6); 12581 ins_encode %{ 12582 Label* L = $labl$$label; 12583 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12584 %} 12585 ins_pipe(pipe_jcc); 12586 %} 12587 12588 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12589 match(If cop cmp); 12590 effect(USE labl); 12591 12592 ins_cost(200); 12593 format %{ $$template 12594 if ($cop$$cmpcode == Assembler::notEqual) { 12595 $$emit$$"jp,u $labl\n\t" 12596 $$emit$$"j$cop,u $labl" 12597 } else { 12598 $$emit$$"jp,u done\n\t" 12599 $$emit$$"j$cop,u $labl\n\t" 12600 $$emit$$"done:" 12601 } 12602 %} 12603 ins_encode %{ 12604 Label* l = $labl$$label; 12605 if ($cop$$cmpcode == Assembler::notEqual) { 12606 __ jcc(Assembler::parity, *l, false); 12607 __ jcc(Assembler::notEqual, *l, false); 12608 } else if ($cop$$cmpcode == Assembler::equal) { 12609 Label done; 12610 __ jccb(Assembler::parity, done); 12611 __ jcc(Assembler::equal, *l, false); 12612 __ bind(done); 12613 } else { 12614 ShouldNotReachHere(); 12615 } 12616 %} 12617 ins_pipe(pipe_jcc); 12618 %} 12619 12620 // ============================================================================ 12621 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12622 // superklass array for an instance of the superklass. Set a hidden 12623 // internal cache on a hit (cache is checked with exposed code in 12624 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12625 // encoding ALSO sets flags. 12626 12627 instruct partialSubtypeCheck(rdi_RegP result, 12628 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12629 rFlagsReg cr) 12630 %{ 12631 match(Set result (PartialSubtypeCheck sub super)); 12632 effect(KILL rcx, KILL cr); 12633 12634 ins_cost(1100); // slightly larger than the next version 12635 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12636 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12637 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12638 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12639 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12640 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12641 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12642 "miss:\t" %} 12643 12644 opcode(0x1); // Force a XOR of RDI 12645 ins_encode(enc_PartialSubtypeCheck()); 12646 ins_pipe(pipe_slow); 12647 %} 12648 12649 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12650 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12651 immP0 zero, 12652 rdi_RegP result) 12653 %{ 12654 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12655 effect(KILL rcx, KILL result); 12656 12657 ins_cost(1000); 12658 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12659 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12660 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12661 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12662 "jne,s miss\t\t# Missed: flags nz\n\t" 12663 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12664 "miss:\t" %} 12665 12666 opcode(0x0); // No need to XOR RDI 12667 ins_encode(enc_PartialSubtypeCheck()); 12668 ins_pipe(pipe_slow); 12669 %} 12670 12671 // ============================================================================ 12672 // Branch Instructions -- short offset versions 12673 // 12674 // These instructions are used to replace jumps of a long offset (the default 12675 // match) with jumps of a shorter offset. These instructions are all tagged 12676 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12677 // match rules in general matching. Instead, the ADLC generates a conversion 12678 // method in the MachNode which can be used to do in-place replacement of the 12679 // long variant with the shorter variant. The compiler will determine if a 12680 // branch can be taken by the is_short_branch_offset() predicate in the machine 12681 // specific code section of the file. 12682 12683 // Jump Direct - Label defines a relative address from JMP+1 12684 instruct jmpDir_short(label labl) %{ 12685 match(Goto); 12686 effect(USE labl); 12687 12688 ins_cost(300); 12689 format %{ "jmp,s $labl" %} 12690 size(2); 12691 ins_encode %{ 12692 Label* L = $labl$$label; 12693 __ jmpb(*L); 12694 %} 12695 ins_pipe(pipe_jmp); 12696 ins_short_branch(1); 12697 %} 12698 12699 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12700 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12701 match(If cop cr); 12702 effect(USE labl); 12703 12704 ins_cost(300); 12705 format %{ "j$cop,s $labl" %} 12706 size(2); 12707 ins_encode %{ 12708 Label* L = $labl$$label; 12709 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12710 %} 12711 ins_pipe(pipe_jcc); 12712 ins_short_branch(1); 12713 %} 12714 12715 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12716 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12717 match(CountedLoopEnd cop cr); 12718 effect(USE labl); 12719 12720 ins_cost(300); 12721 format %{ "j$cop,s $labl\t# loop end" %} 12722 size(2); 12723 ins_encode %{ 12724 Label* L = $labl$$label; 12725 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12726 %} 12727 ins_pipe(pipe_jcc); 12728 ins_short_branch(1); 12729 %} 12730 12731 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12732 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12733 match(CountedLoopEnd cop cmp); 12734 effect(USE labl); 12735 12736 ins_cost(300); 12737 format %{ "j$cop,us $labl\t# loop end" %} 12738 size(2); 12739 ins_encode %{ 12740 Label* L = $labl$$label; 12741 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12742 %} 12743 ins_pipe(pipe_jcc); 12744 ins_short_branch(1); 12745 %} 12746 12747 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12748 match(CountedLoopEnd cop cmp); 12749 effect(USE labl); 12750 12751 ins_cost(300); 12752 format %{ "j$cop,us $labl\t# loop end" %} 12753 size(2); 12754 ins_encode %{ 12755 Label* L = $labl$$label; 12756 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12757 %} 12758 ins_pipe(pipe_jcc); 12759 ins_short_branch(1); 12760 %} 12761 12762 // Jump Direct Conditional - using unsigned comparison 12763 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12764 match(If cop cmp); 12765 effect(USE labl); 12766 12767 ins_cost(300); 12768 format %{ "j$cop,us $labl" %} 12769 size(2); 12770 ins_encode %{ 12771 Label* L = $labl$$label; 12772 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12773 %} 12774 ins_pipe(pipe_jcc); 12775 ins_short_branch(1); 12776 %} 12777 12778 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12779 match(If cop cmp); 12780 effect(USE labl); 12781 12782 ins_cost(300); 12783 format %{ "j$cop,us $labl" %} 12784 size(2); 12785 ins_encode %{ 12786 Label* L = $labl$$label; 12787 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12788 %} 12789 ins_pipe(pipe_jcc); 12790 ins_short_branch(1); 12791 %} 12792 12793 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12794 match(If cop cmp); 12795 effect(USE labl); 12796 12797 ins_cost(300); 12798 format %{ $$template 12799 if ($cop$$cmpcode == Assembler::notEqual) { 12800 $$emit$$"jp,u,s $labl\n\t" 12801 $$emit$$"j$cop,u,s $labl" 12802 } else { 12803 $$emit$$"jp,u,s done\n\t" 12804 $$emit$$"j$cop,u,s $labl\n\t" 12805 $$emit$$"done:" 12806 } 12807 %} 12808 size(4); 12809 ins_encode %{ 12810 Label* l = $labl$$label; 12811 if ($cop$$cmpcode == Assembler::notEqual) { 12812 __ jccb(Assembler::parity, *l); 12813 __ jccb(Assembler::notEqual, *l); 12814 } else if ($cop$$cmpcode == Assembler::equal) { 12815 Label done; 12816 __ jccb(Assembler::parity, done); 12817 __ jccb(Assembler::equal, *l); 12818 __ bind(done); 12819 } else { 12820 ShouldNotReachHere(); 12821 } 12822 %} 12823 ins_pipe(pipe_jcc); 12824 ins_short_branch(1); 12825 %} 12826 12827 // ============================================================================ 12828 // inlined locking and unlocking 12829 12830 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12831 predicate(Compile::current()->use_rtm()); 12832 match(Set cr (FastLock object box)); 12833 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12834 ins_cost(300); 12835 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12836 ins_encode %{ 12837 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12838 $scr$$Register, $cx1$$Register, $cx2$$Register, 12839 _counters, _rtm_counters, _stack_rtm_counters, 12840 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12841 true, ra_->C->profile_rtm()); 12842 %} 12843 ins_pipe(pipe_slow); 12844 %} 12845 12846 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12847 predicate(!Compile::current()->use_rtm()); 12848 match(Set cr (FastLock object box)); 12849 effect(TEMP tmp, TEMP scr, USE_KILL box); 12850 ins_cost(300); 12851 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12852 ins_encode %{ 12853 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12854 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12855 %} 12856 ins_pipe(pipe_slow); 12857 %} 12858 12859 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12860 match(Set cr (FastUnlock object box)); 12861 effect(TEMP tmp, USE_KILL box); 12862 ins_cost(300); 12863 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12864 ins_encode %{ 12865 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12866 %} 12867 ins_pipe(pipe_slow); 12868 %} 12869 12870 12871 // ============================================================================ 12872 // Safepoint Instructions 12873 instruct safePoint_poll(rFlagsReg cr) 12874 %{ 12875 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12876 match(SafePoint); 12877 effect(KILL cr); 12878 12879 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12880 "# Safepoint: poll for GC" %} 12881 ins_cost(125); 12882 ins_encode %{ 12883 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12884 __ testl(rax, addr); 12885 %} 12886 ins_pipe(ialu_reg_mem); 12887 %} 12888 12889 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12890 %{ 12891 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12892 match(SafePoint poll); 12893 effect(KILL cr, USE poll); 12894 12895 format %{ "testl rax, [$poll]\t" 12896 "# Safepoint: poll for GC" %} 12897 ins_cost(125); 12898 ins_encode %{ 12899 __ relocate(relocInfo::poll_type); 12900 __ testl(rax, Address($poll$$Register, 0)); 12901 %} 12902 ins_pipe(ialu_reg_mem); 12903 %} 12904 12905 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12906 %{ 12907 predicate(SafepointMechanism::uses_thread_local_poll()); 12908 match(SafePoint poll); 12909 effect(KILL cr, USE poll); 12910 12911 format %{ "testl rax, [$poll]\t" 12912 "# Safepoint: poll for GC" %} 12913 ins_cost(125); 12914 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12915 ins_encode %{ 12916 __ relocate(relocInfo::poll_type); 12917 address pre_pc = __ pc(); 12918 __ testl(rax, Address($poll$$Register, 0)); 12919 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12920 %} 12921 ins_pipe(ialu_reg_mem); 12922 %} 12923 12924 // ============================================================================ 12925 // Procedure Call/Return Instructions 12926 // Call Java Static Instruction 12927 // Note: If this code changes, the corresponding ret_addr_offset() and 12928 // compute_padding() functions will have to be adjusted. 12929 instruct CallStaticJavaDirect(method meth) %{ 12930 match(CallStaticJava); 12931 effect(USE meth); 12932 12933 ins_cost(300); 12934 format %{ "call,static " %} 12935 opcode(0xE8); /* E8 cd */ 12936 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12937 ins_pipe(pipe_slow); 12938 ins_alignment(4); 12939 %} 12940 12941 // Call Java Dynamic Instruction 12942 // Note: If this code changes, the corresponding ret_addr_offset() and 12943 // compute_padding() functions will have to be adjusted. 12944 instruct CallDynamicJavaDirect(method meth) 12945 %{ 12946 match(CallDynamicJava); 12947 effect(USE meth); 12948 12949 ins_cost(300); 12950 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12951 "call,dynamic " %} 12952 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12953 ins_pipe(pipe_slow); 12954 ins_alignment(4); 12955 %} 12956 12957 // Call Runtime Instruction 12958 instruct CallRuntimeDirect(method meth) 12959 %{ 12960 match(CallRuntime); 12961 effect(USE meth); 12962 12963 ins_cost(300); 12964 format %{ "call,runtime " %} 12965 ins_encode(clear_avx, Java_To_Runtime(meth)); 12966 ins_pipe(pipe_slow); 12967 %} 12968 12969 // Call runtime without safepoint 12970 instruct CallLeafDirect(method meth) 12971 %{ 12972 match(CallLeaf); 12973 effect(USE meth); 12974 12975 ins_cost(300); 12976 format %{ "call_leaf,runtime " %} 12977 ins_encode(clear_avx, Java_To_Runtime(meth)); 12978 ins_pipe(pipe_slow); 12979 %} 12980 12981 // Call runtime without safepoint 12982 // entry point is null, target holds the address to call 12983 instruct CallLeafNoFPInDirect(rRegP target) 12984 %{ 12985 predicate(n->as_Call()->entry_point() == NULL); 12986 match(CallLeafNoFP target); 12987 12988 ins_cost(300); 12989 format %{ "call_leaf_nofp,runtime indirect " %} 12990 ins_encode %{ 12991 __ call($target$$Register); 12992 %} 12993 12994 ins_pipe(pipe_slow); 12995 %} 12996 12997 instruct CallLeafNoFPDirect(method meth) 12998 %{ 12999 predicate(n->as_Call()->entry_point() != NULL); 13000 match(CallLeafNoFP); 13001 effect(USE meth); 13002 13003 ins_cost(300); 13004 format %{ "call_leaf_nofp,runtime " %} 13005 ins_encode(clear_avx, Java_To_Runtime(meth)); 13006 ins_pipe(pipe_slow); 13007 %} 13008 13009 // Return Instruction 13010 // Remove the return address & jump to it. 13011 // Notice: We always emit a nop after a ret to make sure there is room 13012 // for safepoint patching 13013 instruct Ret() 13014 %{ 13015 match(Return); 13016 13017 format %{ "ret" %} 13018 opcode(0xC3); 13019 ins_encode(OpcP); 13020 ins_pipe(pipe_jmp); 13021 %} 13022 13023 // Tail Call; Jump from runtime stub to Java code. 13024 // Also known as an 'interprocedural jump'. 13025 // Target of jump will eventually return to caller. 13026 // TailJump below removes the return address. 13027 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 13028 %{ 13029 match(TailCall jump_target method_oop); 13030 13031 ins_cost(300); 13032 format %{ "jmp $jump_target\t# rbx holds method oop" %} 13033 opcode(0xFF, 0x4); /* Opcode FF /4 */ 13034 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 13035 ins_pipe(pipe_jmp); 13036 %} 13037 13038 // Tail Jump; remove the return address; jump to target. 13039 // TailCall above leaves the return address around. 13040 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 13041 %{ 13042 match(TailJump jump_target ex_oop); 13043 13044 ins_cost(300); 13045 format %{ "popq rdx\t# pop return address\n\t" 13046 "jmp $jump_target" %} 13047 opcode(0xFF, 0x4); /* Opcode FF /4 */ 13048 ins_encode(Opcode(0x5a), // popq rdx 13049 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 13050 ins_pipe(pipe_jmp); 13051 %} 13052 13053 // Create exception oop: created by stack-crawling runtime code. 13054 // Created exception is now available to this handler, and is setup 13055 // just prior to jumping to this handler. No code emitted. 13056 instruct CreateException(rax_RegP ex_oop) 13057 %{ 13058 match(Set ex_oop (CreateEx)); 13059 13060 size(0); 13061 // use the following format syntax 13062 format %{ "# exception oop is in rax; no code emitted" %} 13063 ins_encode(); 13064 ins_pipe(empty); 13065 %} 13066 13067 // Rethrow exception: 13068 // The exception oop will come in the first argument position. 13069 // Then JUMP (not call) to the rethrow stub code. 13070 instruct RethrowException() 13071 %{ 13072 match(Rethrow); 13073 13074 // use the following format syntax 13075 format %{ "jmp rethrow_stub" %} 13076 ins_encode(enc_rethrow); 13077 ins_pipe(pipe_jmp); 13078 %} 13079 13080 // ============================================================================ 13081 // This name is KNOWN by the ADLC and cannot be changed. 13082 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 13083 // for this guy. 13084 instruct tlsLoadP(r15_RegP dst) %{ 13085 match(Set dst (ThreadLocal)); 13086 effect(DEF dst); 13087 13088 size(0); 13089 format %{ "# TLS is in R15" %} 13090 ins_encode( /*empty encoding*/ ); 13091 ins_pipe(ialu_reg_reg); 13092 %} 13093 13094 13095 //----------PEEPHOLE RULES----------------------------------------------------- 13096 // These must follow all instruction definitions as they use the names 13097 // defined in the instructions definitions. 13098 // 13099 // peepmatch ( root_instr_name [preceding_instruction]* ); 13100 // 13101 // peepconstraint %{ 13102 // (instruction_number.operand_name relational_op instruction_number.operand_name 13103 // [, ...] ); 13104 // // instruction numbers are zero-based using left to right order in peepmatch 13105 // 13106 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13107 // // provide an instruction_number.operand_name for each operand that appears 13108 // // in the replacement instruction's match rule 13109 // 13110 // ---------VM FLAGS--------------------------------------------------------- 13111 // 13112 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13113 // 13114 // Each peephole rule is given an identifying number starting with zero and 13115 // increasing by one in the order seen by the parser. An individual peephole 13116 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13117 // on the command-line. 13118 // 13119 // ---------CURRENT LIMITATIONS---------------------------------------------- 13120 // 13121 // Only match adjacent instructions in same basic block 13122 // Only equality constraints 13123 // Only constraints between operands, not (0.dest_reg == RAX_enc) 13124 // Only one replacement instruction 13125 // 13126 // ---------EXAMPLE---------------------------------------------------------- 13127 // 13128 // // pertinent parts of existing instructions in architecture description 13129 // instruct movI(rRegI dst, rRegI src) 13130 // %{ 13131 // match(Set dst (CopyI src)); 13132 // %} 13133 // 13134 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 13135 // %{ 13136 // match(Set dst (AddI dst src)); 13137 // effect(KILL cr); 13138 // %} 13139 // 13140 // // Change (inc mov) to lea 13141 // peephole %{ 13142 // // increment preceeded by register-register move 13143 // peepmatch ( incI_rReg movI ); 13144 // // require that the destination register of the increment 13145 // // match the destination register of the move 13146 // peepconstraint ( 0.dst == 1.dst ); 13147 // // construct a replacement instruction that sets 13148 // // the destination to ( move's source register + one ) 13149 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 13150 // %} 13151 // 13152 13153 // Implementation no longer uses movX instructions since 13154 // machine-independent system no longer uses CopyX nodes. 13155 // 13156 // peephole 13157 // %{ 13158 // peepmatch (incI_rReg movI); 13159 // peepconstraint (0.dst == 1.dst); 13160 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13161 // %} 13162 13163 // peephole 13164 // %{ 13165 // peepmatch (decI_rReg movI); 13166 // peepconstraint (0.dst == 1.dst); 13167 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13168 // %} 13169 13170 // peephole 13171 // %{ 13172 // peepmatch (addI_rReg_imm movI); 13173 // peepconstraint (0.dst == 1.dst); 13174 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13175 // %} 13176 13177 // peephole 13178 // %{ 13179 // peepmatch (incL_rReg movL); 13180 // peepconstraint (0.dst == 1.dst); 13181 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13182 // %} 13183 13184 // peephole 13185 // %{ 13186 // peepmatch (decL_rReg movL); 13187 // peepconstraint (0.dst == 1.dst); 13188 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13189 // %} 13190 13191 // peephole 13192 // %{ 13193 // peepmatch (addL_rReg_imm movL); 13194 // peepconstraint (0.dst == 1.dst); 13195 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13196 // %} 13197 13198 // peephole 13199 // %{ 13200 // peepmatch (addP_rReg_imm movP); 13201 // peepconstraint (0.dst == 1.dst); 13202 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13203 // %} 13204 13205 // // Change load of spilled value to only a spill 13206 // instruct storeI(memory mem, rRegI src) 13207 // %{ 13208 // match(Set mem (StoreI mem src)); 13209 // %} 13210 // 13211 // instruct loadI(rRegI dst, memory mem) 13212 // %{ 13213 // match(Set dst (LoadI mem)); 13214 // %} 13215 // 13216 13217 peephole 13218 %{ 13219 peepmatch (loadI storeI); 13220 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13221 peepreplace (storeI(1.mem 1.mem 1.src)); 13222 %} 13223 13224 peephole 13225 %{ 13226 peepmatch (loadL storeL); 13227 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13228 peepreplace (storeL(1.mem 1.mem 1.src)); 13229 %} 13230 13231 //----------SMARTSPILL RULES--------------------------------------------------- 13232 // These must follow all instruction definitions as they use the names 13233 // defined in the instructions definitions.