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)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop((intptr_t)d32))), "cannot embed scavengable 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)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d64))), 578 "cannot embed scavengable oops in code"); 579 } 580 #endif 581 cbuf.relocate(cbuf.insts_mark(), rspec, format); 582 cbuf.insts()->emit_int64(d64); 583 } 584 585 // Access stack slot for load or store 586 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 587 { 588 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 589 if (-0x80 <= disp && disp < 0x80) { 590 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 591 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 592 emit_d8(cbuf, disp); // Displacement // R/M byte 593 } else { 594 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 595 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 596 emit_d32(cbuf, disp); // Displacement // R/M byte 597 } 598 } 599 600 // rRegI ereg, memory mem) %{ // emit_reg_mem 601 void encode_RegMem(CodeBuffer &cbuf, 602 int reg, 603 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 604 { 605 assert(disp_reloc == relocInfo::none, "cannot have disp"); 606 int regenc = reg & 7; 607 int baseenc = base & 7; 608 int indexenc = index & 7; 609 610 // There is no index & no scale, use form without SIB byte 611 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 612 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 613 if (disp == 0 && base != RBP_enc && base != R13_enc) { 614 emit_rm(cbuf, 0x0, regenc, baseenc); // * 615 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 616 // If 8-bit displacement, mode 0x1 617 emit_rm(cbuf, 0x1, regenc, baseenc); // * 618 emit_d8(cbuf, disp); 619 } else { 620 // If 32-bit displacement 621 if (base == -1) { // Special flag for absolute address 622 emit_rm(cbuf, 0x0, regenc, 0x5); // * 623 if (disp_reloc != relocInfo::none) { 624 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 625 } else { 626 emit_d32(cbuf, disp); 627 } 628 } else { 629 // Normal base + offset 630 emit_rm(cbuf, 0x2, regenc, baseenc); // * 631 if (disp_reloc != relocInfo::none) { 632 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 633 } else { 634 emit_d32(cbuf, disp); 635 } 636 } 637 } 638 } else { 639 // Else, encode with the SIB byte 640 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 641 if (disp == 0 && base != RBP_enc && base != R13_enc) { 642 // If no displacement 643 emit_rm(cbuf, 0x0, regenc, 0x4); // * 644 emit_rm(cbuf, scale, indexenc, baseenc); 645 } else { 646 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 647 // If 8-bit displacement, mode 0x1 648 emit_rm(cbuf, 0x1, regenc, 0x4); // * 649 emit_rm(cbuf, scale, indexenc, baseenc); 650 emit_d8(cbuf, disp); 651 } else { 652 // If 32-bit displacement 653 if (base == 0x04 ) { 654 emit_rm(cbuf, 0x2, regenc, 0x4); 655 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 656 } else { 657 emit_rm(cbuf, 0x2, regenc, 0x4); 658 emit_rm(cbuf, scale, indexenc, baseenc); // * 659 } 660 if (disp_reloc != relocInfo::none) { 661 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 662 } else { 663 emit_d32(cbuf, disp); 664 } 665 } 666 } 667 } 668 } 669 670 // This could be in MacroAssembler but it's fairly C2 specific 671 void emit_cmpfp_fixup(MacroAssembler& _masm) { 672 Label exit; 673 __ jccb(Assembler::noParity, exit); 674 __ pushf(); 675 // 676 // comiss/ucomiss instructions set ZF,PF,CF flags and 677 // zero OF,AF,SF for NaN values. 678 // Fixup flags by zeroing ZF,PF so that compare of NaN 679 // values returns 'less than' result (CF is set). 680 // Leave the rest of flags unchanged. 681 // 682 // 7 6 5 4 3 2 1 0 683 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 684 // 0 0 1 0 1 0 1 1 (0x2B) 685 // 686 __ andq(Address(rsp, 0), 0xffffff2b); 687 __ popf(); 688 __ bind(exit); 689 } 690 691 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 692 Label done; 693 __ movl(dst, -1); 694 __ jcc(Assembler::parity, done); 695 __ jcc(Assembler::below, done); 696 __ setb(Assembler::notEqual, dst); 697 __ movzbl(dst, dst); 698 __ bind(done); 699 } 700 701 // Math.min() # Math.max() 702 // -------------------------- 703 // ucomis[s/d] # 704 // ja -> b # a 705 // jp -> NaN # NaN 706 // jb -> a # b 707 // je # 708 // |-jz -> a | b # a & b 709 // | -> a # 710 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst, 711 XMMRegister a, XMMRegister b, 712 XMMRegister xmmt, Register rt, 713 bool min, bool single) { 714 715 Label nan, zero, below, above, done; 716 717 if (single) 718 __ ucomiss(a, b); 719 else 720 __ ucomisd(a, b); 721 722 if (dst->encoding() != (min ? b : a)->encoding()) 723 __ jccb(Assembler::above, above); // CF=0 & ZF=0 724 else 725 __ jccb(Assembler::above, done); 726 727 __ jccb(Assembler::parity, nan); // PF=1 728 __ jccb(Assembler::below, below); // CF=1 729 730 // equal 731 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 732 if (single) { 733 __ ucomiss(a, xmmt); 734 __ jccb(Assembler::equal, zero); 735 736 __ movflt(dst, a); 737 __ jmp(done); 738 } 739 else { 740 __ ucomisd(a, xmmt); 741 __ jccb(Assembler::equal, zero); 742 743 __ movdbl(dst, a); 744 __ jmp(done); 745 } 746 747 __ bind(zero); 748 if (min) 749 __ vpor(dst, a, b, Assembler::AVX_128bit); 750 else 751 __ vpand(dst, a, b, Assembler::AVX_128bit); 752 753 __ jmp(done); 754 755 __ bind(above); 756 if (single) 757 __ movflt(dst, min ? b : a); 758 else 759 __ movdbl(dst, min ? b : a); 760 761 __ jmp(done); 762 763 __ bind(nan); 764 if (single) { 765 __ movl(rt, 0x7fc00000); // Float.NaN 766 __ movdl(dst, rt); 767 } 768 else { 769 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 770 __ movdq(dst, rt); 771 } 772 __ jmp(done); 773 774 __ bind(below); 775 if (single) 776 __ movflt(dst, min ? a : b); 777 else 778 __ movdbl(dst, min ? a : b); 779 780 __ bind(done); 781 } 782 783 //============================================================================= 784 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 785 786 int Compile::ConstantTable::calculate_table_base_offset() const { 787 return 0; // absolute addressing, no offset 788 } 789 790 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 791 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 792 ShouldNotReachHere(); 793 } 794 795 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 796 // Empty encoding 797 } 798 799 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 800 return 0; 801 } 802 803 #ifndef PRODUCT 804 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 805 st->print("# MachConstantBaseNode (empty encoding)"); 806 } 807 #endif 808 809 810 //============================================================================= 811 #ifndef PRODUCT 812 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 813 Compile* C = ra_->C; 814 815 int framesize = C->frame_size_in_bytes(); 816 int bangsize = C->bang_size_in_bytes(); 817 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 818 // Remove wordSize for return addr which is already pushed. 819 framesize -= wordSize; 820 821 if (C->need_stack_bang(bangsize)) { 822 framesize -= wordSize; 823 st->print("# stack bang (%d bytes)", bangsize); 824 st->print("\n\t"); 825 st->print("pushq rbp\t# Save rbp"); 826 if (PreserveFramePointer) { 827 st->print("\n\t"); 828 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 829 } 830 if (framesize) { 831 st->print("\n\t"); 832 st->print("subq rsp, #%d\t# Create frame",framesize); 833 } 834 } else { 835 st->print("subq rsp, #%d\t# Create frame",framesize); 836 st->print("\n\t"); 837 framesize -= wordSize; 838 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 839 if (PreserveFramePointer) { 840 st->print("\n\t"); 841 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 842 if (framesize > 0) { 843 st->print("\n\t"); 844 st->print("addq rbp, #%d", framesize); 845 } 846 } 847 } 848 849 if (VerifyStackAtCalls) { 850 st->print("\n\t"); 851 framesize -= wordSize; 852 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 853 #ifdef ASSERT 854 st->print("\n\t"); 855 st->print("# stack alignment check"); 856 #endif 857 } 858 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 859 st->print("\n\t"); 860 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t"); 861 st->print("\n\t"); 862 st->print("je fast_entry\t"); 863 st->print("\n\t"); 864 st->print("call #nmethod_entry_barrier_stub\t"); 865 st->print("\n\tfast_entry:"); 866 } 867 st->cr(); 868 } 869 #endif 870 871 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 872 Compile* C = ra_->C; 873 MacroAssembler _masm(&cbuf); 874 875 __ verified_entry(C); 876 __ bind(*_verified_entry); 877 878 C->set_frame_complete(cbuf.insts_size()); 879 880 if (C->has_mach_constant_base_node()) { 881 // NOTE: We set the table base offset here because users might be 882 // emitted before MachConstantBaseNode. 883 Compile::ConstantTable& constant_table = C->constant_table(); 884 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 885 } 886 } 887 888 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 889 { 890 return MachNode::size(ra_); // too many variables; just compute it 891 // the hard way 892 } 893 894 int MachPrologNode::reloc() const 895 { 896 return 0; // a large enough number 897 } 898 899 //============================================================================= 900 #ifndef PRODUCT 901 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 902 { 903 Compile* C = ra_->C; 904 if (generate_vzeroupper(C)) { 905 st->print("vzeroupper"); 906 st->cr(); st->print("\t"); 907 } 908 909 int framesize = C->frame_size_in_bytes(); 910 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 911 // Remove word for return adr already pushed 912 // and RBP 913 framesize -= 2*wordSize; 914 915 if (framesize) { 916 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 917 st->print("\t"); 918 } 919 920 st->print_cr("popq rbp"); 921 if (do_polling() && C->is_method_compilation()) { 922 st->print("\t"); 923 if (SafepointMechanism::uses_thread_local_poll()) { 924 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 925 "testl rax, [rscratch1]\t" 926 "# Safepoint: poll for GC"); 927 } else if (Assembler::is_polling_page_far()) { 928 st->print_cr("movq rscratch1, #polling_page_address\n\t" 929 "testl rax, [rscratch1]\t" 930 "# Safepoint: poll for GC"); 931 } else { 932 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 933 "# Safepoint: poll for GC"); 934 } 935 } 936 } 937 #endif 938 939 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 940 { 941 Compile* C = ra_->C; 942 MacroAssembler _masm(&cbuf); 943 944 if (generate_vzeroupper(C)) { 945 // Clear upper bits of YMM registers when current compiled code uses 946 // wide vectors to avoid AVX <-> SSE transition penalty during call. 947 __ vzeroupper(); 948 } 949 950 __ restore_stack(C); 951 952 953 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 954 __ reserved_stack_check(); 955 } 956 957 if (do_polling() && C->is_method_compilation()) { 958 MacroAssembler _masm(&cbuf); 959 if (SafepointMechanism::uses_thread_local_poll()) { 960 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 961 __ relocate(relocInfo::poll_return_type); 962 __ testl(rax, Address(rscratch1, 0)); 963 } else { 964 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 965 if (Assembler::is_polling_page_far()) { 966 __ lea(rscratch1, polling_page); 967 __ relocate(relocInfo::poll_return_type); 968 __ testl(rax, Address(rscratch1, 0)); 969 } else { 970 __ testl(rax, polling_page); 971 } 972 } 973 } 974 } 975 976 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 977 { 978 return MachNode::size(ra_); // too many variables; just compute it 979 // the hard way 980 } 981 982 int MachEpilogNode::reloc() const 983 { 984 return 2; // a large enough number 985 } 986 987 const Pipeline* MachEpilogNode::pipeline() const 988 { 989 return MachNode::pipeline_class(); 990 } 991 992 int MachEpilogNode::safepoint_offset() const 993 { 994 return 0; 995 } 996 997 //============================================================================= 998 999 enum RC { 1000 rc_bad, 1001 rc_int, 1002 rc_float, 1003 rc_stack 1004 }; 1005 1006 static enum RC rc_class(OptoReg::Name reg) 1007 { 1008 if( !OptoReg::is_valid(reg) ) return rc_bad; 1009 1010 if (OptoReg::is_stack(reg)) return rc_stack; 1011 1012 VMReg r = OptoReg::as_VMReg(reg); 1013 1014 if (r->is_Register()) return rc_int; 1015 1016 assert(r->is_XMMRegister(), "must be"); 1017 return rc_float; 1018 } 1019 1020 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1021 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1022 int src_hi, int dst_hi, uint ireg, outputStream* st); 1023 1024 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1025 int stack_offset, int reg, uint ireg, outputStream* st); 1026 1027 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1028 int dst_offset, uint ireg, outputStream* st) { 1029 if (cbuf) { 1030 MacroAssembler _masm(cbuf); 1031 switch (ireg) { 1032 case Op_VecS: 1033 __ movq(Address(rsp, -8), rax); 1034 __ movl(rax, Address(rsp, src_offset)); 1035 __ movl(Address(rsp, dst_offset), rax); 1036 __ movq(rax, Address(rsp, -8)); 1037 break; 1038 case Op_VecD: 1039 __ pushq(Address(rsp, src_offset)); 1040 __ popq (Address(rsp, dst_offset)); 1041 break; 1042 case Op_VecX: 1043 __ pushq(Address(rsp, src_offset)); 1044 __ popq (Address(rsp, dst_offset)); 1045 __ pushq(Address(rsp, src_offset+8)); 1046 __ popq (Address(rsp, dst_offset+8)); 1047 break; 1048 case Op_VecY: 1049 __ vmovdqu(Address(rsp, -32), xmm0); 1050 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1051 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1052 __ vmovdqu(xmm0, Address(rsp, -32)); 1053 break; 1054 case Op_VecZ: 1055 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1056 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1057 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1058 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1059 break; 1060 default: 1061 ShouldNotReachHere(); 1062 } 1063 #ifndef PRODUCT 1064 } else { 1065 switch (ireg) { 1066 case Op_VecS: 1067 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1068 "movl rax, [rsp + #%d]\n\t" 1069 "movl [rsp + #%d], rax\n\t" 1070 "movq rax, [rsp - #8]", 1071 src_offset, dst_offset); 1072 break; 1073 case Op_VecD: 1074 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1075 "popq [rsp + #%d]", 1076 src_offset, dst_offset); 1077 break; 1078 case Op_VecX: 1079 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1080 "popq [rsp + #%d]\n\t" 1081 "pushq [rsp + #%d]\n\t" 1082 "popq [rsp + #%d]", 1083 src_offset, dst_offset, src_offset+8, dst_offset+8); 1084 break; 1085 case Op_VecY: 1086 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1087 "vmovdqu xmm0, [rsp + #%d]\n\t" 1088 "vmovdqu [rsp + #%d], xmm0\n\t" 1089 "vmovdqu xmm0, [rsp - #32]", 1090 src_offset, dst_offset); 1091 break; 1092 case Op_VecZ: 1093 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1094 "vmovdqu xmm0, [rsp + #%d]\n\t" 1095 "vmovdqu [rsp + #%d], xmm0\n\t" 1096 "vmovdqu xmm0, [rsp - #64]", 1097 src_offset, dst_offset); 1098 break; 1099 default: 1100 ShouldNotReachHere(); 1101 } 1102 #endif 1103 } 1104 } 1105 1106 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1107 PhaseRegAlloc* ra_, 1108 bool do_size, 1109 outputStream* st) const { 1110 assert(cbuf != NULL || st != NULL, "sanity"); 1111 // Get registers to move 1112 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1113 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1114 OptoReg::Name dst_second = ra_->get_reg_second(this); 1115 OptoReg::Name dst_first = ra_->get_reg_first(this); 1116 1117 enum RC src_second_rc = rc_class(src_second); 1118 enum RC src_first_rc = rc_class(src_first); 1119 enum RC dst_second_rc = rc_class(dst_second); 1120 enum RC dst_first_rc = rc_class(dst_first); 1121 1122 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1123 "must move at least 1 register" ); 1124 1125 if (src_first == dst_first && src_second == dst_second) { 1126 // Self copy, no move 1127 return 0; 1128 } 1129 if (bottom_type()->isa_vect() != NULL) { 1130 uint ireg = ideal_reg(); 1131 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1132 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1133 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1134 // mem -> mem 1135 int src_offset = ra_->reg2offset(src_first); 1136 int dst_offset = ra_->reg2offset(dst_first); 1137 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1138 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1139 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1140 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1141 int stack_offset = ra_->reg2offset(dst_first); 1142 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1143 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1144 int stack_offset = ra_->reg2offset(src_first); 1145 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1146 } else { 1147 ShouldNotReachHere(); 1148 } 1149 return 0; 1150 } 1151 if (src_first_rc == rc_stack) { 1152 // mem -> 1153 if (dst_first_rc == rc_stack) { 1154 // mem -> mem 1155 assert(src_second != dst_first, "overlap"); 1156 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1157 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1158 // 64-bit 1159 int src_offset = ra_->reg2offset(src_first); 1160 int dst_offset = ra_->reg2offset(dst_first); 1161 if (cbuf) { 1162 MacroAssembler _masm(cbuf); 1163 __ pushq(Address(rsp, src_offset)); 1164 __ popq (Address(rsp, dst_offset)); 1165 #ifndef PRODUCT 1166 } else { 1167 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1168 "popq [rsp + #%d]", 1169 src_offset, dst_offset); 1170 #endif 1171 } 1172 } else { 1173 // 32-bit 1174 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1175 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1176 // No pushl/popl, so: 1177 int src_offset = ra_->reg2offset(src_first); 1178 int dst_offset = ra_->reg2offset(dst_first); 1179 if (cbuf) { 1180 MacroAssembler _masm(cbuf); 1181 __ movq(Address(rsp, -8), rax); 1182 __ movl(rax, Address(rsp, src_offset)); 1183 __ movl(Address(rsp, dst_offset), rax); 1184 __ movq(rax, Address(rsp, -8)); 1185 #ifndef PRODUCT 1186 } else { 1187 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1188 "movl rax, [rsp + #%d]\n\t" 1189 "movl [rsp + #%d], rax\n\t" 1190 "movq rax, [rsp - #8]", 1191 src_offset, dst_offset); 1192 #endif 1193 } 1194 } 1195 return 0; 1196 } else if (dst_first_rc == rc_int) { 1197 // mem -> gpr 1198 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1199 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1200 // 64-bit 1201 int offset = ra_->reg2offset(src_first); 1202 if (cbuf) { 1203 MacroAssembler _masm(cbuf); 1204 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1205 #ifndef PRODUCT 1206 } else { 1207 st->print("movq %s, [rsp + #%d]\t# spill", 1208 Matcher::regName[dst_first], 1209 offset); 1210 #endif 1211 } 1212 } else { 1213 // 32-bit 1214 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1215 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1216 int offset = ra_->reg2offset(src_first); 1217 if (cbuf) { 1218 MacroAssembler _masm(cbuf); 1219 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1220 #ifndef PRODUCT 1221 } else { 1222 st->print("movl %s, [rsp + #%d]\t# spill", 1223 Matcher::regName[dst_first], 1224 offset); 1225 #endif 1226 } 1227 } 1228 return 0; 1229 } else if (dst_first_rc == rc_float) { 1230 // mem-> xmm 1231 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1232 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1233 // 64-bit 1234 int offset = ra_->reg2offset(src_first); 1235 if (cbuf) { 1236 MacroAssembler _masm(cbuf); 1237 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1238 #ifndef PRODUCT 1239 } else { 1240 st->print("%s %s, [rsp + #%d]\t# spill", 1241 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1242 Matcher::regName[dst_first], 1243 offset); 1244 #endif 1245 } 1246 } else { 1247 // 32-bit 1248 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1249 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1250 int offset = ra_->reg2offset(src_first); 1251 if (cbuf) { 1252 MacroAssembler _masm(cbuf); 1253 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1254 #ifndef PRODUCT 1255 } else { 1256 st->print("movss %s, [rsp + #%d]\t# spill", 1257 Matcher::regName[dst_first], 1258 offset); 1259 #endif 1260 } 1261 } 1262 return 0; 1263 } 1264 } else if (src_first_rc == rc_int) { 1265 // gpr -> 1266 if (dst_first_rc == rc_stack) { 1267 // gpr -> mem 1268 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1269 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1270 // 64-bit 1271 int offset = ra_->reg2offset(dst_first); 1272 if (cbuf) { 1273 MacroAssembler _masm(cbuf); 1274 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1275 #ifndef PRODUCT 1276 } else { 1277 st->print("movq [rsp + #%d], %s\t# spill", 1278 offset, 1279 Matcher::regName[src_first]); 1280 #endif 1281 } 1282 } else { 1283 // 32-bit 1284 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1285 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1286 int offset = ra_->reg2offset(dst_first); 1287 if (cbuf) { 1288 MacroAssembler _masm(cbuf); 1289 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1290 #ifndef PRODUCT 1291 } else { 1292 st->print("movl [rsp + #%d], %s\t# spill", 1293 offset, 1294 Matcher::regName[src_first]); 1295 #endif 1296 } 1297 } 1298 return 0; 1299 } else if (dst_first_rc == rc_int) { 1300 // gpr -> gpr 1301 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1302 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1303 // 64-bit 1304 if (cbuf) { 1305 MacroAssembler _masm(cbuf); 1306 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1307 as_Register(Matcher::_regEncode[src_first])); 1308 #ifndef PRODUCT 1309 } else { 1310 st->print("movq %s, %s\t# spill", 1311 Matcher::regName[dst_first], 1312 Matcher::regName[src_first]); 1313 #endif 1314 } 1315 return 0; 1316 } else { 1317 // 32-bit 1318 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1319 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1320 if (cbuf) { 1321 MacroAssembler _masm(cbuf); 1322 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1323 as_Register(Matcher::_regEncode[src_first])); 1324 #ifndef PRODUCT 1325 } else { 1326 st->print("movl %s, %s\t# spill", 1327 Matcher::regName[dst_first], 1328 Matcher::regName[src_first]); 1329 #endif 1330 } 1331 return 0; 1332 } 1333 } else if (dst_first_rc == rc_float) { 1334 // gpr -> xmm 1335 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1336 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1337 // 64-bit 1338 if (cbuf) { 1339 MacroAssembler _masm(cbuf); 1340 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1341 #ifndef PRODUCT 1342 } else { 1343 st->print("movdq %s, %s\t# spill", 1344 Matcher::regName[dst_first], 1345 Matcher::regName[src_first]); 1346 #endif 1347 } 1348 } else { 1349 // 32-bit 1350 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1351 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1352 if (cbuf) { 1353 MacroAssembler _masm(cbuf); 1354 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1355 #ifndef PRODUCT 1356 } else { 1357 st->print("movdl %s, %s\t# spill", 1358 Matcher::regName[dst_first], 1359 Matcher::regName[src_first]); 1360 #endif 1361 } 1362 } 1363 return 0; 1364 } 1365 } else if (src_first_rc == rc_float) { 1366 // xmm -> 1367 if (dst_first_rc == rc_stack) { 1368 // xmm -> mem 1369 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1370 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1371 // 64-bit 1372 int offset = ra_->reg2offset(dst_first); 1373 if (cbuf) { 1374 MacroAssembler _masm(cbuf); 1375 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1376 #ifndef PRODUCT 1377 } else { 1378 st->print("movsd [rsp + #%d], %s\t# spill", 1379 offset, 1380 Matcher::regName[src_first]); 1381 #endif 1382 } 1383 } else { 1384 // 32-bit 1385 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1386 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1387 int offset = ra_->reg2offset(dst_first); 1388 if (cbuf) { 1389 MacroAssembler _masm(cbuf); 1390 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1391 #ifndef PRODUCT 1392 } else { 1393 st->print("movss [rsp + #%d], %s\t# spill", 1394 offset, 1395 Matcher::regName[src_first]); 1396 #endif 1397 } 1398 } 1399 return 0; 1400 } else if (dst_first_rc == rc_int) { 1401 // xmm -> gpr 1402 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1403 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1404 // 64-bit 1405 if (cbuf) { 1406 MacroAssembler _masm(cbuf); 1407 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1408 #ifndef PRODUCT 1409 } else { 1410 st->print("movdq %s, %s\t# spill", 1411 Matcher::regName[dst_first], 1412 Matcher::regName[src_first]); 1413 #endif 1414 } 1415 } else { 1416 // 32-bit 1417 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1418 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1419 if (cbuf) { 1420 MacroAssembler _masm(cbuf); 1421 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1422 #ifndef PRODUCT 1423 } else { 1424 st->print("movdl %s, %s\t# spill", 1425 Matcher::regName[dst_first], 1426 Matcher::regName[src_first]); 1427 #endif 1428 } 1429 } 1430 return 0; 1431 } else if (dst_first_rc == rc_float) { 1432 // xmm -> xmm 1433 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1434 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1435 // 64-bit 1436 if (cbuf) { 1437 MacroAssembler _masm(cbuf); 1438 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1439 #ifndef PRODUCT 1440 } else { 1441 st->print("%s %s, %s\t# spill", 1442 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1443 Matcher::regName[dst_first], 1444 Matcher::regName[src_first]); 1445 #endif 1446 } 1447 } else { 1448 // 32-bit 1449 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1450 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1451 if (cbuf) { 1452 MacroAssembler _masm(cbuf); 1453 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1454 #ifndef PRODUCT 1455 } else { 1456 st->print("%s %s, %s\t# spill", 1457 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1458 Matcher::regName[dst_first], 1459 Matcher::regName[src_first]); 1460 #endif 1461 } 1462 } 1463 return 0; 1464 } 1465 } 1466 1467 assert(0," foo "); 1468 Unimplemented(); 1469 return 0; 1470 } 1471 1472 #ifndef PRODUCT 1473 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1474 implementation(NULL, ra_, false, st); 1475 } 1476 #endif 1477 1478 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1479 implementation(&cbuf, ra_, false, NULL); 1480 } 1481 1482 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1483 return MachNode::size(ra_); 1484 } 1485 1486 //============================================================================= 1487 #ifndef PRODUCT 1488 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1489 { 1490 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1491 int reg = ra_->get_reg_first(this); 1492 st->print("leaq %s, [rsp + #%d]\t# box lock", 1493 Matcher::regName[reg], offset); 1494 } 1495 #endif 1496 1497 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1498 { 1499 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1500 int reg = ra_->get_encode(this); 1501 if (offset >= 0x80) { 1502 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1503 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1504 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1505 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1506 emit_d32(cbuf, offset); 1507 } else { 1508 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1509 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1510 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1511 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1512 emit_d8(cbuf, offset); 1513 } 1514 } 1515 1516 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1517 { 1518 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1519 return (offset < 0x80) ? 5 : 8; // REX 1520 } 1521 1522 //============================================================================= 1523 #ifndef PRODUCT 1524 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1525 { 1526 st->print_cr("MachVEPNode"); 1527 } 1528 #endif 1529 1530 void MachVEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1531 { 1532 MacroAssembler masm(&cbuf); 1533 if (!_verified) { 1534 uint insts_size = cbuf.insts_size(); 1535 if (UseCompressedClassPointers) { 1536 masm.load_klass(rscratch1, j_rarg0); 1537 masm.cmpptr(rax, rscratch1); 1538 } else { 1539 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1540 } 1541 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1542 } else { 1543 // Unpack value type args passed as oop and then jump to 1544 // the verified entry point (skipping the unverified entry). 1545 masm.unpack_value_args(ra_->C, _receiver_only); 1546 masm.jmp(*_verified_entry); 1547 } 1548 } 1549 1550 uint MachVEPNode::size(PhaseRegAlloc* ra_) const 1551 { 1552 return MachNode::size(ra_); // too many variables; just compute it the hard way 1553 } 1554 1555 //============================================================================= 1556 #ifndef PRODUCT 1557 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1558 { 1559 if (UseCompressedClassPointers) { 1560 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1561 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1562 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1563 } else { 1564 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1565 "# Inline cache check"); 1566 } 1567 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1568 st->print_cr("\tnop\t# nops to align entry point"); 1569 } 1570 #endif 1571 1572 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1573 { 1574 MacroAssembler masm(&cbuf); 1575 uint insts_size = cbuf.insts_size(); 1576 if (UseCompressedClassPointers) { 1577 masm.load_klass(rscratch1, j_rarg0); 1578 masm.cmpptr(rax, rscratch1); 1579 } else { 1580 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1581 } 1582 1583 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1584 1585 /* WARNING these NOPs are critical so that verified entry point is properly 1586 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1587 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1588 if (OptoBreakpoint) { 1589 // Leave space for int3 1590 nops_cnt -= 1; 1591 } 1592 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1593 if (nops_cnt > 0) 1594 masm.nop(nops_cnt); 1595 } 1596 1597 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1598 { 1599 return MachNode::size(ra_); // too many variables; just compute it 1600 // the hard way 1601 } 1602 1603 1604 //============================================================================= 1605 1606 int Matcher::regnum_to_fpu_offset(int regnum) 1607 { 1608 return regnum - 32; // The FP registers are in the second chunk 1609 } 1610 1611 // This is UltraSparc specific, true just means we have fast l2f conversion 1612 const bool Matcher::convL2FSupported(void) { 1613 return true; 1614 } 1615 1616 // Is this branch offset short enough that a short branch can be used? 1617 // 1618 // NOTE: If the platform does not provide any short branch variants, then 1619 // this method should return false for offset 0. 1620 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1621 // The passed offset is relative to address of the branch. 1622 // On 86 a branch displacement is calculated relative to address 1623 // of a next instruction. 1624 offset -= br_size; 1625 1626 // the short version of jmpConUCF2 contains multiple branches, 1627 // making the reach slightly less 1628 if (rule == jmpConUCF2_rule) 1629 return (-126 <= offset && offset <= 125); 1630 return (-128 <= offset && offset <= 127); 1631 } 1632 1633 const bool Matcher::isSimpleConstant64(jlong value) { 1634 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1635 //return value == (int) value; // Cf. storeImmL and immL32. 1636 1637 // Probably always true, even if a temp register is required. 1638 return true; 1639 } 1640 1641 // The ecx parameter to rep stosq for the ClearArray node is in words. 1642 const bool Matcher::init_array_count_is_in_bytes = false; 1643 1644 // No additional cost for CMOVL. 1645 const int Matcher::long_cmove_cost() { return 0; } 1646 1647 // No CMOVF/CMOVD with SSE2 1648 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1649 1650 // Does the CPU require late expand (see block.cpp for description of late expand)? 1651 const bool Matcher::require_postalloc_expand = false; 1652 1653 // Do we need to mask the count passed to shift instructions or does 1654 // the cpu only look at the lower 5/6 bits anyway? 1655 const bool Matcher::need_masked_shift_count = false; 1656 1657 bool Matcher::narrow_oop_use_complex_address() { 1658 assert(UseCompressedOops, "only for compressed oops code"); 1659 return (LogMinObjAlignmentInBytes <= 3); 1660 } 1661 1662 bool Matcher::narrow_klass_use_complex_address() { 1663 assert(UseCompressedClassPointers, "only for compressed klass code"); 1664 return (LogKlassAlignmentInBytes <= 3); 1665 } 1666 1667 bool Matcher::const_oop_prefer_decode() { 1668 // Prefer ConN+DecodeN over ConP. 1669 return true; 1670 } 1671 1672 bool Matcher::const_klass_prefer_decode() { 1673 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1674 // or condisider the following: 1675 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1676 //return Universe::narrow_klass_base() == NULL; 1677 return true; 1678 } 1679 1680 // Is it better to copy float constants, or load them directly from 1681 // memory? Intel can load a float constant from a direct address, 1682 // requiring no extra registers. Most RISCs will have to materialize 1683 // an address into a register first, so they would do better to copy 1684 // the constant from stack. 1685 const bool Matcher::rematerialize_float_constants = true; // XXX 1686 1687 // If CPU can load and store mis-aligned doubles directly then no 1688 // fixup is needed. Else we split the double into 2 integer pieces 1689 // and move it piece-by-piece. Only happens when passing doubles into 1690 // C code as the Java calling convention forces doubles to be aligned. 1691 const bool Matcher::misaligned_doubles_ok = true; 1692 1693 // No-op on amd64 1694 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1695 1696 // Advertise here if the CPU requires explicit rounding operations to 1697 // implement the UseStrictFP mode. 1698 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1699 1700 // Are floats conerted to double when stored to stack during deoptimization? 1701 // On x64 it is stored without convertion so we can use normal access. 1702 bool Matcher::float_in_double() { return false; } 1703 1704 // Do ints take an entire long register or just half? 1705 const bool Matcher::int_in_long = true; 1706 1707 // Return whether or not this register is ever used as an argument. 1708 // This function is used on startup to build the trampoline stubs in 1709 // generateOptoStub. Registers not mentioned will be killed by the VM 1710 // call in the trampoline, and arguments in those registers not be 1711 // available to the callee. 1712 bool Matcher::can_be_java_arg(int reg) 1713 { 1714 return 1715 reg == RDI_num || reg == RDI_H_num || 1716 reg == RSI_num || reg == RSI_H_num || 1717 reg == RDX_num || reg == RDX_H_num || 1718 reg == RCX_num || reg == RCX_H_num || 1719 reg == R8_num || reg == R8_H_num || 1720 reg == R9_num || reg == R9_H_num || 1721 reg == R12_num || reg == R12_H_num || 1722 reg == XMM0_num || reg == XMM0b_num || 1723 reg == XMM1_num || reg == XMM1b_num || 1724 reg == XMM2_num || reg == XMM2b_num || 1725 reg == XMM3_num || reg == XMM3b_num || 1726 reg == XMM4_num || reg == XMM4b_num || 1727 reg == XMM5_num || reg == XMM5b_num || 1728 reg == XMM6_num || reg == XMM6b_num || 1729 reg == XMM7_num || reg == XMM7b_num; 1730 } 1731 1732 bool Matcher::is_spillable_arg(int reg) 1733 { 1734 return can_be_java_arg(reg); 1735 } 1736 1737 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1738 // In 64 bit mode a code which use multiply when 1739 // devisor is constant is faster than hardware 1740 // DIV instruction (it uses MulHiL). 1741 return false; 1742 } 1743 1744 // Register for DIVI projection of divmodI 1745 RegMask Matcher::divI_proj_mask() { 1746 return INT_RAX_REG_mask(); 1747 } 1748 1749 // Register for MODI projection of divmodI 1750 RegMask Matcher::modI_proj_mask() { 1751 return INT_RDX_REG_mask(); 1752 } 1753 1754 // Register for DIVL projection of divmodL 1755 RegMask Matcher::divL_proj_mask() { 1756 return LONG_RAX_REG_mask(); 1757 } 1758 1759 // Register for MODL projection of divmodL 1760 RegMask Matcher::modL_proj_mask() { 1761 return LONG_RDX_REG_mask(); 1762 } 1763 1764 // Register for saving SP into on method handle invokes. Not used on x86_64. 1765 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1766 return NO_REG_mask(); 1767 } 1768 1769 %} 1770 1771 //----------ENCODING BLOCK----------------------------------------------------- 1772 // This block specifies the encoding classes used by the compiler to 1773 // output byte streams. Encoding classes are parameterized macros 1774 // used by Machine Instruction Nodes in order to generate the bit 1775 // encoding of the instruction. Operands specify their base encoding 1776 // interface with the interface keyword. There are currently 1777 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1778 // COND_INTER. REG_INTER causes an operand to generate a function 1779 // which returns its register number when queried. CONST_INTER causes 1780 // an operand to generate a function which returns the value of the 1781 // constant when queried. MEMORY_INTER causes an operand to generate 1782 // four functions which return the Base Register, the Index Register, 1783 // the Scale Value, and the Offset Value of the operand when queried. 1784 // COND_INTER causes an operand to generate six functions which return 1785 // the encoding code (ie - encoding bits for the instruction) 1786 // associated with each basic boolean condition for a conditional 1787 // instruction. 1788 // 1789 // Instructions specify two basic values for encoding. Again, a 1790 // function is available to check if the constant displacement is an 1791 // oop. They use the ins_encode keyword to specify their encoding 1792 // classes (which must be a sequence of enc_class names, and their 1793 // parameters, specified in the encoding block), and they use the 1794 // opcode keyword to specify, in order, their primary, secondary, and 1795 // tertiary opcode. Only the opcode sections which a particular 1796 // instruction needs for encoding need to be specified. 1797 encode %{ 1798 // Build emit functions for each basic byte or larger field in the 1799 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1800 // from C++ code in the enc_class source block. Emit functions will 1801 // live in the main source block for now. In future, we can 1802 // generalize this by adding a syntax that specifies the sizes of 1803 // fields in an order, so that the adlc can build the emit functions 1804 // automagically 1805 1806 // Emit primary opcode 1807 enc_class OpcP 1808 %{ 1809 emit_opcode(cbuf, $primary); 1810 %} 1811 1812 // Emit secondary opcode 1813 enc_class OpcS 1814 %{ 1815 emit_opcode(cbuf, $secondary); 1816 %} 1817 1818 // Emit tertiary opcode 1819 enc_class OpcT 1820 %{ 1821 emit_opcode(cbuf, $tertiary); 1822 %} 1823 1824 // Emit opcode directly 1825 enc_class Opcode(immI d8) 1826 %{ 1827 emit_opcode(cbuf, $d8$$constant); 1828 %} 1829 1830 // Emit size prefix 1831 enc_class SizePrefix 1832 %{ 1833 emit_opcode(cbuf, 0x66); 1834 %} 1835 1836 enc_class reg(rRegI reg) 1837 %{ 1838 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1839 %} 1840 1841 enc_class reg_reg(rRegI dst, rRegI src) 1842 %{ 1843 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1844 %} 1845 1846 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1847 %{ 1848 emit_opcode(cbuf, $opcode$$constant); 1849 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1850 %} 1851 1852 enc_class cdql_enc(no_rax_rdx_RegI div) 1853 %{ 1854 // Full implementation of Java idiv and irem; checks for 1855 // special case as described in JVM spec., p.243 & p.271. 1856 // 1857 // normal case special case 1858 // 1859 // input : rax: dividend min_int 1860 // reg: divisor -1 1861 // 1862 // output: rax: quotient (= rax idiv reg) min_int 1863 // rdx: remainder (= rax irem reg) 0 1864 // 1865 // Code sequnce: 1866 // 1867 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1868 // 5: 75 07/08 jne e <normal> 1869 // 7: 33 d2 xor %edx,%edx 1870 // [div >= 8 -> offset + 1] 1871 // [REX_B] 1872 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1873 // c: 74 03/04 je 11 <done> 1874 // 000000000000000e <normal>: 1875 // e: 99 cltd 1876 // [div >= 8 -> offset + 1] 1877 // [REX_B] 1878 // f: f7 f9 idiv $div 1879 // 0000000000000011 <done>: 1880 1881 // cmp $0x80000000,%eax 1882 emit_opcode(cbuf, 0x3d); 1883 emit_d8(cbuf, 0x00); 1884 emit_d8(cbuf, 0x00); 1885 emit_d8(cbuf, 0x00); 1886 emit_d8(cbuf, 0x80); 1887 1888 // jne e <normal> 1889 emit_opcode(cbuf, 0x75); 1890 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1891 1892 // xor %edx,%edx 1893 emit_opcode(cbuf, 0x33); 1894 emit_d8(cbuf, 0xD2); 1895 1896 // cmp $0xffffffffffffffff,%ecx 1897 if ($div$$reg >= 8) { 1898 emit_opcode(cbuf, Assembler::REX_B); 1899 } 1900 emit_opcode(cbuf, 0x83); 1901 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1902 emit_d8(cbuf, 0xFF); 1903 1904 // je 11 <done> 1905 emit_opcode(cbuf, 0x74); 1906 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1907 1908 // <normal> 1909 // cltd 1910 emit_opcode(cbuf, 0x99); 1911 1912 // idivl (note: must be emitted by the user of this rule) 1913 // <done> 1914 %} 1915 1916 enc_class cdqq_enc(no_rax_rdx_RegL div) 1917 %{ 1918 // Full implementation of Java ldiv and lrem; checks for 1919 // special case as described in JVM spec., p.243 & p.271. 1920 // 1921 // normal case special case 1922 // 1923 // input : rax: dividend min_long 1924 // reg: divisor -1 1925 // 1926 // output: rax: quotient (= rax idiv reg) min_long 1927 // rdx: remainder (= rax irem reg) 0 1928 // 1929 // Code sequnce: 1930 // 1931 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1932 // 7: 00 00 80 1933 // a: 48 39 d0 cmp %rdx,%rax 1934 // d: 75 08 jne 17 <normal> 1935 // f: 33 d2 xor %edx,%edx 1936 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1937 // 15: 74 05 je 1c <done> 1938 // 0000000000000017 <normal>: 1939 // 17: 48 99 cqto 1940 // 19: 48 f7 f9 idiv $div 1941 // 000000000000001c <done>: 1942 1943 // mov $0x8000000000000000,%rdx 1944 emit_opcode(cbuf, Assembler::REX_W); 1945 emit_opcode(cbuf, 0xBA); 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, 0x00); 1953 emit_d8(cbuf, 0x80); 1954 1955 // cmp %rdx,%rax 1956 emit_opcode(cbuf, Assembler::REX_W); 1957 emit_opcode(cbuf, 0x39); 1958 emit_d8(cbuf, 0xD0); 1959 1960 // jne 17 <normal> 1961 emit_opcode(cbuf, 0x75); 1962 emit_d8(cbuf, 0x08); 1963 1964 // xor %edx,%edx 1965 emit_opcode(cbuf, 0x33); 1966 emit_d8(cbuf, 0xD2); 1967 1968 // cmp $0xffffffffffffffff,$div 1969 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1970 emit_opcode(cbuf, 0x83); 1971 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1972 emit_d8(cbuf, 0xFF); 1973 1974 // je 1e <done> 1975 emit_opcode(cbuf, 0x74); 1976 emit_d8(cbuf, 0x05); 1977 1978 // <normal> 1979 // cqto 1980 emit_opcode(cbuf, Assembler::REX_W); 1981 emit_opcode(cbuf, 0x99); 1982 1983 // idivq (note: must be emitted by the user of this rule) 1984 // <done> 1985 %} 1986 1987 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1988 enc_class OpcSE(immI imm) 1989 %{ 1990 // Emit primary opcode and set sign-extend bit 1991 // Check for 8-bit immediate, and set sign extend bit in opcode 1992 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1993 emit_opcode(cbuf, $primary | 0x02); 1994 } else { 1995 // 32-bit immediate 1996 emit_opcode(cbuf, $primary); 1997 } 1998 %} 1999 2000 enc_class OpcSErm(rRegI dst, immI imm) 2001 %{ 2002 // OpcSEr/m 2003 int dstenc = $dst$$reg; 2004 if (dstenc >= 8) { 2005 emit_opcode(cbuf, Assembler::REX_B); 2006 dstenc -= 8; 2007 } 2008 // Emit primary opcode and set sign-extend bit 2009 // Check for 8-bit immediate, and set sign extend bit in opcode 2010 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2011 emit_opcode(cbuf, $primary | 0x02); 2012 } else { 2013 // 32-bit immediate 2014 emit_opcode(cbuf, $primary); 2015 } 2016 // Emit r/m byte with secondary opcode, after primary opcode. 2017 emit_rm(cbuf, 0x3, $secondary, dstenc); 2018 %} 2019 2020 enc_class OpcSErm_wide(rRegL dst, immI imm) 2021 %{ 2022 // OpcSEr/m 2023 int dstenc = $dst$$reg; 2024 if (dstenc < 8) { 2025 emit_opcode(cbuf, Assembler::REX_W); 2026 } else { 2027 emit_opcode(cbuf, Assembler::REX_WB); 2028 dstenc -= 8; 2029 } 2030 // Emit primary opcode and set sign-extend bit 2031 // Check for 8-bit immediate, and set sign extend bit in opcode 2032 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2033 emit_opcode(cbuf, $primary | 0x02); 2034 } else { 2035 // 32-bit immediate 2036 emit_opcode(cbuf, $primary); 2037 } 2038 // Emit r/m byte with secondary opcode, after primary opcode. 2039 emit_rm(cbuf, 0x3, $secondary, dstenc); 2040 %} 2041 2042 enc_class Con8or32(immI imm) 2043 %{ 2044 // Check for 8-bit immediate, and set sign extend bit in opcode 2045 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2046 $$$emit8$imm$$constant; 2047 } else { 2048 // 32-bit immediate 2049 $$$emit32$imm$$constant; 2050 } 2051 %} 2052 2053 enc_class opc2_reg(rRegI dst) 2054 %{ 2055 // BSWAP 2056 emit_cc(cbuf, $secondary, $dst$$reg); 2057 %} 2058 2059 enc_class opc3_reg(rRegI dst) 2060 %{ 2061 // BSWAP 2062 emit_cc(cbuf, $tertiary, $dst$$reg); 2063 %} 2064 2065 enc_class reg_opc(rRegI div) 2066 %{ 2067 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2068 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2069 %} 2070 2071 enc_class enc_cmov(cmpOp cop) 2072 %{ 2073 // CMOV 2074 $$$emit8$primary; 2075 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2076 %} 2077 2078 enc_class enc_PartialSubtypeCheck() 2079 %{ 2080 Register Rrdi = as_Register(RDI_enc); // result register 2081 Register Rrax = as_Register(RAX_enc); // super class 2082 Register Rrcx = as_Register(RCX_enc); // killed 2083 Register Rrsi = as_Register(RSI_enc); // sub class 2084 Label miss; 2085 const bool set_cond_codes = true; 2086 2087 MacroAssembler _masm(&cbuf); 2088 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2089 NULL, &miss, 2090 /*set_cond_codes:*/ true); 2091 if ($primary) { 2092 __ xorptr(Rrdi, Rrdi); 2093 } 2094 __ bind(miss); 2095 %} 2096 2097 enc_class clear_avx %{ 2098 debug_only(int off0 = cbuf.insts_size()); 2099 if (generate_vzeroupper(Compile::current())) { 2100 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2101 // Clear upper bits of YMM registers when current compiled code uses 2102 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2103 MacroAssembler _masm(&cbuf); 2104 __ vzeroupper(); 2105 } 2106 debug_only(int off1 = cbuf.insts_size()); 2107 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2108 %} 2109 2110 enc_class Java_To_Runtime(method meth) %{ 2111 // No relocation needed 2112 MacroAssembler _masm(&cbuf); 2113 __ mov64(r10, (int64_t) $meth$$method); 2114 __ call(r10); 2115 %} 2116 2117 enc_class Java_To_Interpreter(method meth) 2118 %{ 2119 // CALL Java_To_Interpreter 2120 // This is the instruction starting address for relocation info. 2121 cbuf.set_insts_mark(); 2122 $$$emit8$primary; 2123 // CALL directly to the runtime 2124 emit_d32_reloc(cbuf, 2125 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2126 runtime_call_Relocation::spec(), 2127 RELOC_DISP32); 2128 %} 2129 2130 enc_class Java_Static_Call(method meth) 2131 %{ 2132 // JAVA STATIC CALL 2133 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2134 // determine who we intended to call. 2135 cbuf.set_insts_mark(); 2136 $$$emit8$primary; 2137 2138 if (!_method) { 2139 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2140 runtime_call_Relocation::spec(), 2141 RELOC_DISP32); 2142 } else { 2143 int method_index = resolved_method_index(cbuf); 2144 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2145 : static_call_Relocation::spec(method_index); 2146 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2147 rspec, RELOC_DISP32); 2148 // Emit stubs for static call. 2149 address mark = cbuf.insts_mark(); 2150 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2151 if (stub == NULL) { 2152 ciEnv::current()->record_failure("CodeCache is full"); 2153 return; 2154 } 2155 #if INCLUDE_AOT 2156 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2157 #endif 2158 } 2159 %} 2160 2161 enc_class Java_Dynamic_Call(method meth) %{ 2162 MacroAssembler _masm(&cbuf); 2163 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2164 %} 2165 2166 enc_class Java_Compiled_Call(method meth) 2167 %{ 2168 // JAVA COMPILED CALL 2169 int disp = in_bytes(Method:: from_compiled_offset()); 2170 2171 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2172 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2173 2174 // callq *disp(%rax) 2175 cbuf.set_insts_mark(); 2176 $$$emit8$primary; 2177 if (disp < 0x80) { 2178 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2179 emit_d8(cbuf, disp); // Displacement 2180 } else { 2181 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2182 emit_d32(cbuf, disp); // Displacement 2183 } 2184 %} 2185 2186 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2187 %{ 2188 // SAL, SAR, SHR 2189 int dstenc = $dst$$reg; 2190 if (dstenc >= 8) { 2191 emit_opcode(cbuf, Assembler::REX_B); 2192 dstenc -= 8; 2193 } 2194 $$$emit8$primary; 2195 emit_rm(cbuf, 0x3, $secondary, dstenc); 2196 $$$emit8$shift$$constant; 2197 %} 2198 2199 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2200 %{ 2201 // SAL, SAR, SHR 2202 int dstenc = $dst$$reg; 2203 if (dstenc < 8) { 2204 emit_opcode(cbuf, Assembler::REX_W); 2205 } else { 2206 emit_opcode(cbuf, Assembler::REX_WB); 2207 dstenc -= 8; 2208 } 2209 $$$emit8$primary; 2210 emit_rm(cbuf, 0x3, $secondary, dstenc); 2211 $$$emit8$shift$$constant; 2212 %} 2213 2214 enc_class load_immI(rRegI dst, immI src) 2215 %{ 2216 int dstenc = $dst$$reg; 2217 if (dstenc >= 8) { 2218 emit_opcode(cbuf, Assembler::REX_B); 2219 dstenc -= 8; 2220 } 2221 emit_opcode(cbuf, 0xB8 | dstenc); 2222 $$$emit32$src$$constant; 2223 %} 2224 2225 enc_class load_immL(rRegL dst, immL src) 2226 %{ 2227 int dstenc = $dst$$reg; 2228 if (dstenc < 8) { 2229 emit_opcode(cbuf, Assembler::REX_W); 2230 } else { 2231 emit_opcode(cbuf, Assembler::REX_WB); 2232 dstenc -= 8; 2233 } 2234 emit_opcode(cbuf, 0xB8 | dstenc); 2235 emit_d64(cbuf, $src$$constant); 2236 %} 2237 2238 enc_class load_immUL32(rRegL dst, immUL32 src) 2239 %{ 2240 // same as load_immI, but this time we care about zeroes in the high word 2241 int dstenc = $dst$$reg; 2242 if (dstenc >= 8) { 2243 emit_opcode(cbuf, Assembler::REX_B); 2244 dstenc -= 8; 2245 } 2246 emit_opcode(cbuf, 0xB8 | dstenc); 2247 $$$emit32$src$$constant; 2248 %} 2249 2250 enc_class load_immL32(rRegL dst, immL32 src) 2251 %{ 2252 int dstenc = $dst$$reg; 2253 if (dstenc < 8) { 2254 emit_opcode(cbuf, Assembler::REX_W); 2255 } else { 2256 emit_opcode(cbuf, Assembler::REX_WB); 2257 dstenc -= 8; 2258 } 2259 emit_opcode(cbuf, 0xC7); 2260 emit_rm(cbuf, 0x03, 0x00, dstenc); 2261 $$$emit32$src$$constant; 2262 %} 2263 2264 enc_class load_immP31(rRegP dst, immP32 src) 2265 %{ 2266 // same as load_immI, but this time we care about zeroes in the high word 2267 int dstenc = $dst$$reg; 2268 if (dstenc >= 8) { 2269 emit_opcode(cbuf, Assembler::REX_B); 2270 dstenc -= 8; 2271 } 2272 emit_opcode(cbuf, 0xB8 | dstenc); 2273 $$$emit32$src$$constant; 2274 %} 2275 2276 enc_class load_immP(rRegP dst, immP src) 2277 %{ 2278 int dstenc = $dst$$reg; 2279 if (dstenc < 8) { 2280 emit_opcode(cbuf, Assembler::REX_W); 2281 } else { 2282 emit_opcode(cbuf, Assembler::REX_WB); 2283 dstenc -= 8; 2284 } 2285 emit_opcode(cbuf, 0xB8 | dstenc); 2286 // This next line should be generated from ADLC 2287 if ($src->constant_reloc() != relocInfo::none) { 2288 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2289 } else { 2290 emit_d64(cbuf, $src$$constant); 2291 } 2292 %} 2293 2294 enc_class Con32(immI src) 2295 %{ 2296 // Output immediate 2297 $$$emit32$src$$constant; 2298 %} 2299 2300 enc_class Con32F_as_bits(immF src) 2301 %{ 2302 // Output Float immediate bits 2303 jfloat jf = $src$$constant; 2304 jint jf_as_bits = jint_cast(jf); 2305 emit_d32(cbuf, jf_as_bits); 2306 %} 2307 2308 enc_class Con16(immI src) 2309 %{ 2310 // Output immediate 2311 $$$emit16$src$$constant; 2312 %} 2313 2314 // How is this different from Con32??? XXX 2315 enc_class Con_d32(immI src) 2316 %{ 2317 emit_d32(cbuf,$src$$constant); 2318 %} 2319 2320 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2321 // Output immediate memory reference 2322 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2323 emit_d32(cbuf, 0x00); 2324 %} 2325 2326 enc_class lock_prefix() 2327 %{ 2328 emit_opcode(cbuf, 0xF0); // lock 2329 %} 2330 2331 enc_class REX_mem(memory mem) 2332 %{ 2333 if ($mem$$base >= 8) { 2334 if ($mem$$index < 8) { 2335 emit_opcode(cbuf, Assembler::REX_B); 2336 } else { 2337 emit_opcode(cbuf, Assembler::REX_XB); 2338 } 2339 } else { 2340 if ($mem$$index >= 8) { 2341 emit_opcode(cbuf, Assembler::REX_X); 2342 } 2343 } 2344 %} 2345 2346 enc_class REX_mem_wide(memory mem) 2347 %{ 2348 if ($mem$$base >= 8) { 2349 if ($mem$$index < 8) { 2350 emit_opcode(cbuf, Assembler::REX_WB); 2351 } else { 2352 emit_opcode(cbuf, Assembler::REX_WXB); 2353 } 2354 } else { 2355 if ($mem$$index < 8) { 2356 emit_opcode(cbuf, Assembler::REX_W); 2357 } else { 2358 emit_opcode(cbuf, Assembler::REX_WX); 2359 } 2360 } 2361 %} 2362 2363 // for byte regs 2364 enc_class REX_breg(rRegI reg) 2365 %{ 2366 if ($reg$$reg >= 4) { 2367 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2368 } 2369 %} 2370 2371 // for byte regs 2372 enc_class REX_reg_breg(rRegI dst, rRegI src) 2373 %{ 2374 if ($dst$$reg < 8) { 2375 if ($src$$reg >= 4) { 2376 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2377 } 2378 } else { 2379 if ($src$$reg < 8) { 2380 emit_opcode(cbuf, Assembler::REX_R); 2381 } else { 2382 emit_opcode(cbuf, Assembler::REX_RB); 2383 } 2384 } 2385 %} 2386 2387 // for byte regs 2388 enc_class REX_breg_mem(rRegI reg, memory mem) 2389 %{ 2390 if ($reg$$reg < 8) { 2391 if ($mem$$base < 8) { 2392 if ($mem$$index >= 8) { 2393 emit_opcode(cbuf, Assembler::REX_X); 2394 } else if ($reg$$reg >= 4) { 2395 emit_opcode(cbuf, Assembler::REX); 2396 } 2397 } else { 2398 if ($mem$$index < 8) { 2399 emit_opcode(cbuf, Assembler::REX_B); 2400 } else { 2401 emit_opcode(cbuf, Assembler::REX_XB); 2402 } 2403 } 2404 } else { 2405 if ($mem$$base < 8) { 2406 if ($mem$$index < 8) { 2407 emit_opcode(cbuf, Assembler::REX_R); 2408 } else { 2409 emit_opcode(cbuf, Assembler::REX_RX); 2410 } 2411 } else { 2412 if ($mem$$index < 8) { 2413 emit_opcode(cbuf, Assembler::REX_RB); 2414 } else { 2415 emit_opcode(cbuf, Assembler::REX_RXB); 2416 } 2417 } 2418 } 2419 %} 2420 2421 enc_class REX_reg(rRegI reg) 2422 %{ 2423 if ($reg$$reg >= 8) { 2424 emit_opcode(cbuf, Assembler::REX_B); 2425 } 2426 %} 2427 2428 enc_class REX_reg_wide(rRegI reg) 2429 %{ 2430 if ($reg$$reg < 8) { 2431 emit_opcode(cbuf, Assembler::REX_W); 2432 } else { 2433 emit_opcode(cbuf, Assembler::REX_WB); 2434 } 2435 %} 2436 2437 enc_class REX_reg_reg(rRegI dst, rRegI src) 2438 %{ 2439 if ($dst$$reg < 8) { 2440 if ($src$$reg >= 8) { 2441 emit_opcode(cbuf, Assembler::REX_B); 2442 } 2443 } else { 2444 if ($src$$reg < 8) { 2445 emit_opcode(cbuf, Assembler::REX_R); 2446 } else { 2447 emit_opcode(cbuf, Assembler::REX_RB); 2448 } 2449 } 2450 %} 2451 2452 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2453 %{ 2454 if ($dst$$reg < 8) { 2455 if ($src$$reg < 8) { 2456 emit_opcode(cbuf, Assembler::REX_W); 2457 } else { 2458 emit_opcode(cbuf, Assembler::REX_WB); 2459 } 2460 } else { 2461 if ($src$$reg < 8) { 2462 emit_opcode(cbuf, Assembler::REX_WR); 2463 } else { 2464 emit_opcode(cbuf, Assembler::REX_WRB); 2465 } 2466 } 2467 %} 2468 2469 enc_class REX_reg_mem(rRegI reg, memory mem) 2470 %{ 2471 if ($reg$$reg < 8) { 2472 if ($mem$$base < 8) { 2473 if ($mem$$index >= 8) { 2474 emit_opcode(cbuf, Assembler::REX_X); 2475 } 2476 } else { 2477 if ($mem$$index < 8) { 2478 emit_opcode(cbuf, Assembler::REX_B); 2479 } else { 2480 emit_opcode(cbuf, Assembler::REX_XB); 2481 } 2482 } 2483 } else { 2484 if ($mem$$base < 8) { 2485 if ($mem$$index < 8) { 2486 emit_opcode(cbuf, Assembler::REX_R); 2487 } else { 2488 emit_opcode(cbuf, Assembler::REX_RX); 2489 } 2490 } else { 2491 if ($mem$$index < 8) { 2492 emit_opcode(cbuf, Assembler::REX_RB); 2493 } else { 2494 emit_opcode(cbuf, Assembler::REX_RXB); 2495 } 2496 } 2497 } 2498 %} 2499 2500 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2501 %{ 2502 if ($reg$$reg < 8) { 2503 if ($mem$$base < 8) { 2504 if ($mem$$index < 8) { 2505 emit_opcode(cbuf, Assembler::REX_W); 2506 } else { 2507 emit_opcode(cbuf, Assembler::REX_WX); 2508 } 2509 } else { 2510 if ($mem$$index < 8) { 2511 emit_opcode(cbuf, Assembler::REX_WB); 2512 } else { 2513 emit_opcode(cbuf, Assembler::REX_WXB); 2514 } 2515 } 2516 } else { 2517 if ($mem$$base < 8) { 2518 if ($mem$$index < 8) { 2519 emit_opcode(cbuf, Assembler::REX_WR); 2520 } else { 2521 emit_opcode(cbuf, Assembler::REX_WRX); 2522 } 2523 } else { 2524 if ($mem$$index < 8) { 2525 emit_opcode(cbuf, Assembler::REX_WRB); 2526 } else { 2527 emit_opcode(cbuf, Assembler::REX_WRXB); 2528 } 2529 } 2530 } 2531 %} 2532 2533 enc_class reg_mem(rRegI ereg, memory mem) 2534 %{ 2535 // High registers handle in encode_RegMem 2536 int reg = $ereg$$reg; 2537 int base = $mem$$base; 2538 int index = $mem$$index; 2539 int scale = $mem$$scale; 2540 int disp = $mem$$disp; 2541 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2542 2543 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2544 %} 2545 2546 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2547 %{ 2548 int rm_byte_opcode = $rm_opcode$$constant; 2549 2550 // High registers handle in encode_RegMem 2551 int base = $mem$$base; 2552 int index = $mem$$index; 2553 int scale = $mem$$scale; 2554 int displace = $mem$$disp; 2555 2556 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2557 // working with static 2558 // globals 2559 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2560 disp_reloc); 2561 %} 2562 2563 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2564 %{ 2565 int reg_encoding = $dst$$reg; 2566 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2567 int index = 0x04; // 0x04 indicates no index 2568 int scale = 0x00; // 0x00 indicates no scale 2569 int displace = $src1$$constant; // 0x00 indicates no displacement 2570 relocInfo::relocType disp_reloc = relocInfo::none; 2571 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2572 disp_reloc); 2573 %} 2574 2575 enc_class neg_reg(rRegI dst) 2576 %{ 2577 int dstenc = $dst$$reg; 2578 if (dstenc >= 8) { 2579 emit_opcode(cbuf, Assembler::REX_B); 2580 dstenc -= 8; 2581 } 2582 // NEG $dst 2583 emit_opcode(cbuf, 0xF7); 2584 emit_rm(cbuf, 0x3, 0x03, dstenc); 2585 %} 2586 2587 enc_class neg_reg_wide(rRegI dst) 2588 %{ 2589 int dstenc = $dst$$reg; 2590 if (dstenc < 8) { 2591 emit_opcode(cbuf, Assembler::REX_W); 2592 } else { 2593 emit_opcode(cbuf, Assembler::REX_WB); 2594 dstenc -= 8; 2595 } 2596 // NEG $dst 2597 emit_opcode(cbuf, 0xF7); 2598 emit_rm(cbuf, 0x3, 0x03, dstenc); 2599 %} 2600 2601 enc_class setLT_reg(rRegI dst) 2602 %{ 2603 int dstenc = $dst$$reg; 2604 if (dstenc >= 8) { 2605 emit_opcode(cbuf, Assembler::REX_B); 2606 dstenc -= 8; 2607 } else if (dstenc >= 4) { 2608 emit_opcode(cbuf, Assembler::REX); 2609 } 2610 // SETLT $dst 2611 emit_opcode(cbuf, 0x0F); 2612 emit_opcode(cbuf, 0x9C); 2613 emit_rm(cbuf, 0x3, 0x0, dstenc); 2614 %} 2615 2616 enc_class setNZ_reg(rRegI dst) 2617 %{ 2618 int dstenc = $dst$$reg; 2619 if (dstenc >= 8) { 2620 emit_opcode(cbuf, Assembler::REX_B); 2621 dstenc -= 8; 2622 } else if (dstenc >= 4) { 2623 emit_opcode(cbuf, Assembler::REX); 2624 } 2625 // SETNZ $dst 2626 emit_opcode(cbuf, 0x0F); 2627 emit_opcode(cbuf, 0x95); 2628 emit_rm(cbuf, 0x3, 0x0, dstenc); 2629 %} 2630 2631 2632 // Compare the lonogs and set -1, 0, or 1 into dst 2633 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2634 %{ 2635 int src1enc = $src1$$reg; 2636 int src2enc = $src2$$reg; 2637 int dstenc = $dst$$reg; 2638 2639 // cmpq $src1, $src2 2640 if (src1enc < 8) { 2641 if (src2enc < 8) { 2642 emit_opcode(cbuf, Assembler::REX_W); 2643 } else { 2644 emit_opcode(cbuf, Assembler::REX_WB); 2645 } 2646 } else { 2647 if (src2enc < 8) { 2648 emit_opcode(cbuf, Assembler::REX_WR); 2649 } else { 2650 emit_opcode(cbuf, Assembler::REX_WRB); 2651 } 2652 } 2653 emit_opcode(cbuf, 0x3B); 2654 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2655 2656 // movl $dst, -1 2657 if (dstenc >= 8) { 2658 emit_opcode(cbuf, Assembler::REX_B); 2659 } 2660 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2661 emit_d32(cbuf, -1); 2662 2663 // jl,s done 2664 emit_opcode(cbuf, 0x7C); 2665 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2666 2667 // setne $dst 2668 if (dstenc >= 4) { 2669 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2670 } 2671 emit_opcode(cbuf, 0x0F); 2672 emit_opcode(cbuf, 0x95); 2673 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2674 2675 // movzbl $dst, $dst 2676 if (dstenc >= 4) { 2677 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2678 } 2679 emit_opcode(cbuf, 0x0F); 2680 emit_opcode(cbuf, 0xB6); 2681 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2682 %} 2683 2684 enc_class Push_ResultXD(regD dst) %{ 2685 MacroAssembler _masm(&cbuf); 2686 __ fstp_d(Address(rsp, 0)); 2687 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2688 __ addptr(rsp, 8); 2689 %} 2690 2691 enc_class Push_SrcXD(regD src) %{ 2692 MacroAssembler _masm(&cbuf); 2693 __ subptr(rsp, 8); 2694 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2695 __ fld_d(Address(rsp, 0)); 2696 %} 2697 2698 2699 enc_class enc_rethrow() 2700 %{ 2701 cbuf.set_insts_mark(); 2702 emit_opcode(cbuf, 0xE9); // jmp entry 2703 emit_d32_reloc(cbuf, 2704 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2705 runtime_call_Relocation::spec(), 2706 RELOC_DISP32); 2707 %} 2708 2709 %} 2710 2711 2712 2713 //----------FRAME-------------------------------------------------------------- 2714 // Definition of frame structure and management information. 2715 // 2716 // S T A C K L A Y O U T Allocators stack-slot number 2717 // | (to get allocators register number 2718 // G Owned by | | v add OptoReg::stack0()) 2719 // r CALLER | | 2720 // o | +--------+ pad to even-align allocators stack-slot 2721 // w V | pad0 | numbers; owned by CALLER 2722 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2723 // h ^ | in | 5 2724 // | | args | 4 Holes in incoming args owned by SELF 2725 // | | | | 3 2726 // | | +--------+ 2727 // V | | old out| Empty on Intel, window on Sparc 2728 // | old |preserve| Must be even aligned. 2729 // | SP-+--------+----> Matcher::_old_SP, even aligned 2730 // | | in | 3 area for Intel ret address 2731 // Owned by |preserve| Empty on Sparc. 2732 // SELF +--------+ 2733 // | | pad2 | 2 pad to align old SP 2734 // | +--------+ 1 2735 // | | locks | 0 2736 // | +--------+----> OptoReg::stack0(), even aligned 2737 // | | pad1 | 11 pad to align new SP 2738 // | +--------+ 2739 // | | | 10 2740 // | | spills | 9 spills 2741 // V | | 8 (pad0 slot for callee) 2742 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2743 // ^ | out | 7 2744 // | | args | 6 Holes in outgoing args owned by CALLEE 2745 // Owned by +--------+ 2746 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2747 // | new |preserve| Must be even-aligned. 2748 // | SP-+--------+----> Matcher::_new_SP, even aligned 2749 // | | | 2750 // 2751 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2752 // known from SELF's arguments and the Java calling convention. 2753 // Region 6-7 is determined per call site. 2754 // Note 2: If the calling convention leaves holes in the incoming argument 2755 // area, those holes are owned by SELF. Holes in the outgoing area 2756 // are owned by the CALLEE. Holes should not be nessecary in the 2757 // incoming area, as the Java calling convention is completely under 2758 // the control of the AD file. Doubles can be sorted and packed to 2759 // avoid holes. Holes in the outgoing arguments may be nessecary for 2760 // varargs C calling conventions. 2761 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2762 // even aligned with pad0 as needed. 2763 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2764 // region 6-11 is even aligned; it may be padded out more so that 2765 // the region from SP to FP meets the minimum stack alignment. 2766 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2767 // alignment. Region 11, pad1, may be dynamically extended so that 2768 // SP meets the minimum alignment. 2769 2770 frame 2771 %{ 2772 // What direction does stack grow in (assumed to be same for C & Java) 2773 stack_direction(TOWARDS_LOW); 2774 2775 // These three registers define part of the calling convention 2776 // between compiled code and the interpreter. 2777 inline_cache_reg(RAX); // Inline Cache Register 2778 interpreter_method_oop_reg(RBX); // Method Oop Register when 2779 // calling interpreter 2780 2781 // Optional: name the operand used by cisc-spilling to access 2782 // [stack_pointer + offset] 2783 cisc_spilling_operand_name(indOffset32); 2784 2785 // Number of stack slots consumed by locking an object 2786 sync_stack_slots(2); 2787 2788 // Compiled code's Frame Pointer 2789 frame_pointer(RSP); 2790 2791 // Interpreter stores its frame pointer in a register which is 2792 // stored to the stack by I2CAdaptors. 2793 // I2CAdaptors convert from interpreted java to compiled java. 2794 interpreter_frame_pointer(RBP); 2795 2796 // Stack alignment requirement 2797 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2798 2799 // Number of stack slots between incoming argument block and the start of 2800 // a new frame. The PROLOG must add this many slots to the stack. The 2801 // EPILOG must remove this many slots. amd64 needs two slots for 2802 // return address. 2803 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2804 2805 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2806 // for calls to C. Supports the var-args backing area for register parms. 2807 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2808 2809 // The after-PROLOG location of the return address. Location of 2810 // return address specifies a type (REG or STACK) and a number 2811 // representing the register number (i.e. - use a register name) or 2812 // stack slot. 2813 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2814 // Otherwise, it is above the locks and verification slot and alignment word 2815 return_addr(STACK - 2 + 2816 align_up((Compile::current()->in_preserve_stack_slots() + 2817 Compile::current()->fixed_slots()), 2818 stack_alignment_in_slots())); 2819 2820 // Body of function which returns an integer array locating 2821 // arguments either in registers or in stack slots. Passed an array 2822 // of ideal registers called "sig" and a "length" count. Stack-slot 2823 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2824 // arguments for a CALLEE. Incoming stack arguments are 2825 // automatically biased by the preserve_stack_slots field above. 2826 2827 calling_convention 2828 %{ 2829 // No difference between ingoing/outgoing just pass false 2830 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2831 %} 2832 2833 c_calling_convention 2834 %{ 2835 // This is obviously always outgoing 2836 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2837 %} 2838 2839 // Location of compiled Java return values. Same as C for now. 2840 return_value 2841 %{ 2842 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2843 "only return normal values"); 2844 2845 static const int lo[Op_RegL + 1] = { 2846 0, 2847 0, 2848 RAX_num, // Op_RegN 2849 RAX_num, // Op_RegI 2850 RAX_num, // Op_RegP 2851 XMM0_num, // Op_RegF 2852 XMM0_num, // Op_RegD 2853 RAX_num // Op_RegL 2854 }; 2855 static const int hi[Op_RegL + 1] = { 2856 0, 2857 0, 2858 OptoReg::Bad, // Op_RegN 2859 OptoReg::Bad, // Op_RegI 2860 RAX_H_num, // Op_RegP 2861 OptoReg::Bad, // Op_RegF 2862 XMM0b_num, // Op_RegD 2863 RAX_H_num // Op_RegL 2864 }; 2865 // Excluded flags and vector registers. 2866 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2867 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2868 %} 2869 %} 2870 2871 //----------ATTRIBUTES--------------------------------------------------------- 2872 //----------Operand Attributes------------------------------------------------- 2873 op_attrib op_cost(0); // Required cost attribute 2874 2875 //----------Instruction Attributes--------------------------------------------- 2876 ins_attrib ins_cost(100); // Required cost attribute 2877 ins_attrib ins_size(8); // Required size attribute (in bits) 2878 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2879 // a non-matching short branch variant 2880 // of some long branch? 2881 ins_attrib ins_alignment(1); // Required alignment attribute (must 2882 // be a power of 2) specifies the 2883 // alignment that some part of the 2884 // instruction (not necessarily the 2885 // start) requires. If > 1, a 2886 // compute_padding() function must be 2887 // provided for the instruction 2888 2889 //----------OPERANDS----------------------------------------------------------- 2890 // Operand definitions must precede instruction definitions for correct parsing 2891 // in the ADLC because operands constitute user defined types which are used in 2892 // instruction definitions. 2893 2894 //----------Simple Operands---------------------------------------------------- 2895 // Immediate Operands 2896 // Integer Immediate 2897 operand immI() 2898 %{ 2899 match(ConI); 2900 2901 op_cost(10); 2902 format %{ %} 2903 interface(CONST_INTER); 2904 %} 2905 2906 // Constant for test vs zero 2907 operand immI0() 2908 %{ 2909 predicate(n->get_int() == 0); 2910 match(ConI); 2911 2912 op_cost(0); 2913 format %{ %} 2914 interface(CONST_INTER); 2915 %} 2916 2917 // Constant for increment 2918 operand immI1() 2919 %{ 2920 predicate(n->get_int() == 1); 2921 match(ConI); 2922 2923 op_cost(0); 2924 format %{ %} 2925 interface(CONST_INTER); 2926 %} 2927 2928 // Constant for decrement 2929 operand immI_M1() 2930 %{ 2931 predicate(n->get_int() == -1); 2932 match(ConI); 2933 2934 op_cost(0); 2935 format %{ %} 2936 interface(CONST_INTER); 2937 %} 2938 2939 // Valid scale values for addressing modes 2940 operand immI2() 2941 %{ 2942 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2943 match(ConI); 2944 2945 format %{ %} 2946 interface(CONST_INTER); 2947 %} 2948 2949 operand immI8() 2950 %{ 2951 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2952 match(ConI); 2953 2954 op_cost(5); 2955 format %{ %} 2956 interface(CONST_INTER); 2957 %} 2958 2959 operand immU8() 2960 %{ 2961 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2962 match(ConI); 2963 2964 op_cost(5); 2965 format %{ %} 2966 interface(CONST_INTER); 2967 %} 2968 2969 operand immI16() 2970 %{ 2971 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2972 match(ConI); 2973 2974 op_cost(10); 2975 format %{ %} 2976 interface(CONST_INTER); 2977 %} 2978 2979 // Int Immediate non-negative 2980 operand immU31() 2981 %{ 2982 predicate(n->get_int() >= 0); 2983 match(ConI); 2984 2985 op_cost(0); 2986 format %{ %} 2987 interface(CONST_INTER); 2988 %} 2989 2990 // Constant for long shifts 2991 operand immI_32() 2992 %{ 2993 predicate( n->get_int() == 32 ); 2994 match(ConI); 2995 2996 op_cost(0); 2997 format %{ %} 2998 interface(CONST_INTER); 2999 %} 3000 3001 // Constant for long shifts 3002 operand immI_64() 3003 %{ 3004 predicate( n->get_int() == 64 ); 3005 match(ConI); 3006 3007 op_cost(0); 3008 format %{ %} 3009 interface(CONST_INTER); 3010 %} 3011 3012 // Pointer Immediate 3013 operand immP() 3014 %{ 3015 match(ConP); 3016 3017 op_cost(10); 3018 format %{ %} 3019 interface(CONST_INTER); 3020 %} 3021 3022 // NULL Pointer Immediate 3023 operand immP0() 3024 %{ 3025 predicate(n->get_ptr() == 0); 3026 match(ConP); 3027 3028 op_cost(5); 3029 format %{ %} 3030 interface(CONST_INTER); 3031 %} 3032 3033 // Pointer Immediate 3034 operand immN() %{ 3035 match(ConN); 3036 3037 op_cost(10); 3038 format %{ %} 3039 interface(CONST_INTER); 3040 %} 3041 3042 operand immNKlass() %{ 3043 match(ConNKlass); 3044 3045 op_cost(10); 3046 format %{ %} 3047 interface(CONST_INTER); 3048 %} 3049 3050 // NULL Pointer Immediate 3051 operand immN0() %{ 3052 predicate(n->get_narrowcon() == 0); 3053 match(ConN); 3054 3055 op_cost(5); 3056 format %{ %} 3057 interface(CONST_INTER); 3058 %} 3059 3060 operand immP31() 3061 %{ 3062 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3063 && (n->get_ptr() >> 31) == 0); 3064 match(ConP); 3065 3066 op_cost(5); 3067 format %{ %} 3068 interface(CONST_INTER); 3069 %} 3070 3071 3072 // Long Immediate 3073 operand immL() 3074 %{ 3075 match(ConL); 3076 3077 op_cost(20); 3078 format %{ %} 3079 interface(CONST_INTER); 3080 %} 3081 3082 // Long Immediate 8-bit 3083 operand immL8() 3084 %{ 3085 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3086 match(ConL); 3087 3088 op_cost(5); 3089 format %{ %} 3090 interface(CONST_INTER); 3091 %} 3092 3093 // Long Immediate 32-bit unsigned 3094 operand immUL32() 3095 %{ 3096 predicate(n->get_long() == (unsigned int) (n->get_long())); 3097 match(ConL); 3098 3099 op_cost(10); 3100 format %{ %} 3101 interface(CONST_INTER); 3102 %} 3103 3104 // Long Immediate 32-bit signed 3105 operand immL32() 3106 %{ 3107 predicate(n->get_long() == (int) (n->get_long())); 3108 match(ConL); 3109 3110 op_cost(15); 3111 format %{ %} 3112 interface(CONST_INTER); 3113 %} 3114 3115 // Long Immediate zero 3116 operand immL0() 3117 %{ 3118 predicate(n->get_long() == 0L); 3119 match(ConL); 3120 3121 op_cost(10); 3122 format %{ %} 3123 interface(CONST_INTER); 3124 %} 3125 3126 // Constant for increment 3127 operand immL1() 3128 %{ 3129 predicate(n->get_long() == 1); 3130 match(ConL); 3131 3132 format %{ %} 3133 interface(CONST_INTER); 3134 %} 3135 3136 // Constant for decrement 3137 operand immL_M1() 3138 %{ 3139 predicate(n->get_long() == -1); 3140 match(ConL); 3141 3142 format %{ %} 3143 interface(CONST_INTER); 3144 %} 3145 3146 // Long Immediate: the value 10 3147 operand immL10() 3148 %{ 3149 predicate(n->get_long() == 10); 3150 match(ConL); 3151 3152 format %{ %} 3153 interface(CONST_INTER); 3154 %} 3155 3156 // Long immediate from 0 to 127. 3157 // Used for a shorter form of long mul by 10. 3158 operand immL_127() 3159 %{ 3160 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3161 match(ConL); 3162 3163 op_cost(10); 3164 format %{ %} 3165 interface(CONST_INTER); 3166 %} 3167 3168 // Long Immediate: low 32-bit mask 3169 operand immL_32bits() 3170 %{ 3171 predicate(n->get_long() == 0xFFFFFFFFL); 3172 match(ConL); 3173 op_cost(20); 3174 3175 format %{ %} 3176 interface(CONST_INTER); 3177 %} 3178 3179 // Float Immediate zero 3180 operand immF0() 3181 %{ 3182 predicate(jint_cast(n->getf()) == 0); 3183 match(ConF); 3184 3185 op_cost(5); 3186 format %{ %} 3187 interface(CONST_INTER); 3188 %} 3189 3190 // Float Immediate 3191 operand immF() 3192 %{ 3193 match(ConF); 3194 3195 op_cost(15); 3196 format %{ %} 3197 interface(CONST_INTER); 3198 %} 3199 3200 // Double Immediate zero 3201 operand immD0() 3202 %{ 3203 predicate(jlong_cast(n->getd()) == 0); 3204 match(ConD); 3205 3206 op_cost(5); 3207 format %{ %} 3208 interface(CONST_INTER); 3209 %} 3210 3211 // Double Immediate 3212 operand immD() 3213 %{ 3214 match(ConD); 3215 3216 op_cost(15); 3217 format %{ %} 3218 interface(CONST_INTER); 3219 %} 3220 3221 // Immediates for special shifts (sign extend) 3222 3223 // Constants for increment 3224 operand immI_16() 3225 %{ 3226 predicate(n->get_int() == 16); 3227 match(ConI); 3228 3229 format %{ %} 3230 interface(CONST_INTER); 3231 %} 3232 3233 operand immI_24() 3234 %{ 3235 predicate(n->get_int() == 24); 3236 match(ConI); 3237 3238 format %{ %} 3239 interface(CONST_INTER); 3240 %} 3241 3242 // Constant for byte-wide masking 3243 operand immI_255() 3244 %{ 3245 predicate(n->get_int() == 255); 3246 match(ConI); 3247 3248 format %{ %} 3249 interface(CONST_INTER); 3250 %} 3251 3252 // Constant for short-wide masking 3253 operand immI_65535() 3254 %{ 3255 predicate(n->get_int() == 65535); 3256 match(ConI); 3257 3258 format %{ %} 3259 interface(CONST_INTER); 3260 %} 3261 3262 // Constant for byte-wide masking 3263 operand immL_255() 3264 %{ 3265 predicate(n->get_long() == 255); 3266 match(ConL); 3267 3268 format %{ %} 3269 interface(CONST_INTER); 3270 %} 3271 3272 // Constant for short-wide masking 3273 operand immL_65535() 3274 %{ 3275 predicate(n->get_long() == 65535); 3276 match(ConL); 3277 3278 format %{ %} 3279 interface(CONST_INTER); 3280 %} 3281 3282 // Register Operands 3283 // Integer Register 3284 operand rRegI() 3285 %{ 3286 constraint(ALLOC_IN_RC(int_reg)); 3287 match(RegI); 3288 3289 match(rax_RegI); 3290 match(rbx_RegI); 3291 match(rcx_RegI); 3292 match(rdx_RegI); 3293 match(rdi_RegI); 3294 3295 format %{ %} 3296 interface(REG_INTER); 3297 %} 3298 3299 // Special Registers 3300 operand rax_RegI() 3301 %{ 3302 constraint(ALLOC_IN_RC(int_rax_reg)); 3303 match(RegI); 3304 match(rRegI); 3305 3306 format %{ "RAX" %} 3307 interface(REG_INTER); 3308 %} 3309 3310 // Special Registers 3311 operand rbx_RegI() 3312 %{ 3313 constraint(ALLOC_IN_RC(int_rbx_reg)); 3314 match(RegI); 3315 match(rRegI); 3316 3317 format %{ "RBX" %} 3318 interface(REG_INTER); 3319 %} 3320 3321 operand rcx_RegI() 3322 %{ 3323 constraint(ALLOC_IN_RC(int_rcx_reg)); 3324 match(RegI); 3325 match(rRegI); 3326 3327 format %{ "RCX" %} 3328 interface(REG_INTER); 3329 %} 3330 3331 operand rdx_RegI() 3332 %{ 3333 constraint(ALLOC_IN_RC(int_rdx_reg)); 3334 match(RegI); 3335 match(rRegI); 3336 3337 format %{ "RDX" %} 3338 interface(REG_INTER); 3339 %} 3340 3341 operand rdi_RegI() 3342 %{ 3343 constraint(ALLOC_IN_RC(int_rdi_reg)); 3344 match(RegI); 3345 match(rRegI); 3346 3347 format %{ "RDI" %} 3348 interface(REG_INTER); 3349 %} 3350 3351 operand no_rcx_RegI() 3352 %{ 3353 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3354 match(RegI); 3355 match(rax_RegI); 3356 match(rbx_RegI); 3357 match(rdx_RegI); 3358 match(rdi_RegI); 3359 3360 format %{ %} 3361 interface(REG_INTER); 3362 %} 3363 3364 operand no_rax_rdx_RegI() 3365 %{ 3366 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3367 match(RegI); 3368 match(rbx_RegI); 3369 match(rcx_RegI); 3370 match(rdi_RegI); 3371 3372 format %{ %} 3373 interface(REG_INTER); 3374 %} 3375 3376 // Pointer Register 3377 operand any_RegP() 3378 %{ 3379 constraint(ALLOC_IN_RC(any_reg)); 3380 match(RegP); 3381 match(rax_RegP); 3382 match(rbx_RegP); 3383 match(rdi_RegP); 3384 match(rsi_RegP); 3385 match(rbp_RegP); 3386 match(r15_RegP); 3387 match(rRegP); 3388 3389 format %{ %} 3390 interface(REG_INTER); 3391 %} 3392 3393 operand rRegP() 3394 %{ 3395 constraint(ALLOC_IN_RC(ptr_reg)); 3396 match(RegP); 3397 match(rax_RegP); 3398 match(rbx_RegP); 3399 match(rdi_RegP); 3400 match(rsi_RegP); 3401 match(rbp_RegP); // See Q&A below about 3402 match(r15_RegP); // r15_RegP and rbp_RegP. 3403 3404 format %{ %} 3405 interface(REG_INTER); 3406 %} 3407 3408 operand rRegN() %{ 3409 constraint(ALLOC_IN_RC(int_reg)); 3410 match(RegN); 3411 3412 format %{ %} 3413 interface(REG_INTER); 3414 %} 3415 3416 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3417 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3418 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3419 // The output of an instruction is controlled by the allocator, which respects 3420 // register class masks, not match rules. Unless an instruction mentions 3421 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3422 // by the allocator as an input. 3423 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3424 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3425 // result, RBP is not included in the output of the instruction either. 3426 3427 operand no_rax_RegP() 3428 %{ 3429 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3430 match(RegP); 3431 match(rbx_RegP); 3432 match(rsi_RegP); 3433 match(rdi_RegP); 3434 3435 format %{ %} 3436 interface(REG_INTER); 3437 %} 3438 3439 // This operand is not allowed to use RBP even if 3440 // RBP is not used to hold the frame pointer. 3441 operand no_rbp_RegP() 3442 %{ 3443 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3444 match(RegP); 3445 match(rbx_RegP); 3446 match(rsi_RegP); 3447 match(rdi_RegP); 3448 3449 format %{ %} 3450 interface(REG_INTER); 3451 %} 3452 3453 operand no_rax_rbx_RegP() 3454 %{ 3455 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3456 match(RegP); 3457 match(rsi_RegP); 3458 match(rdi_RegP); 3459 3460 format %{ %} 3461 interface(REG_INTER); 3462 %} 3463 3464 // Special Registers 3465 // Return a pointer value 3466 operand rax_RegP() 3467 %{ 3468 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3469 match(RegP); 3470 match(rRegP); 3471 3472 format %{ %} 3473 interface(REG_INTER); 3474 %} 3475 3476 // Special Registers 3477 // Return a compressed pointer value 3478 operand rax_RegN() 3479 %{ 3480 constraint(ALLOC_IN_RC(int_rax_reg)); 3481 match(RegN); 3482 match(rRegN); 3483 3484 format %{ %} 3485 interface(REG_INTER); 3486 %} 3487 3488 // Used in AtomicAdd 3489 operand rbx_RegP() 3490 %{ 3491 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3492 match(RegP); 3493 match(rRegP); 3494 3495 format %{ %} 3496 interface(REG_INTER); 3497 %} 3498 3499 operand rsi_RegP() 3500 %{ 3501 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3502 match(RegP); 3503 match(rRegP); 3504 3505 format %{ %} 3506 interface(REG_INTER); 3507 %} 3508 3509 // Used in rep stosq 3510 operand rdi_RegP() 3511 %{ 3512 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3513 match(RegP); 3514 match(rRegP); 3515 3516 format %{ %} 3517 interface(REG_INTER); 3518 %} 3519 3520 operand r15_RegP() 3521 %{ 3522 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3523 match(RegP); 3524 match(rRegP); 3525 3526 format %{ %} 3527 interface(REG_INTER); 3528 %} 3529 3530 operand rRegL() 3531 %{ 3532 constraint(ALLOC_IN_RC(long_reg)); 3533 match(RegL); 3534 match(rax_RegL); 3535 match(rdx_RegL); 3536 3537 format %{ %} 3538 interface(REG_INTER); 3539 %} 3540 3541 // Special Registers 3542 operand no_rax_rdx_RegL() 3543 %{ 3544 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3545 match(RegL); 3546 match(rRegL); 3547 3548 format %{ %} 3549 interface(REG_INTER); 3550 %} 3551 3552 operand no_rax_RegL() 3553 %{ 3554 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3555 match(RegL); 3556 match(rRegL); 3557 match(rdx_RegL); 3558 3559 format %{ %} 3560 interface(REG_INTER); 3561 %} 3562 3563 operand no_rcx_RegL() 3564 %{ 3565 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3566 match(RegL); 3567 match(rRegL); 3568 3569 format %{ %} 3570 interface(REG_INTER); 3571 %} 3572 3573 operand rax_RegL() 3574 %{ 3575 constraint(ALLOC_IN_RC(long_rax_reg)); 3576 match(RegL); 3577 match(rRegL); 3578 3579 format %{ "RAX" %} 3580 interface(REG_INTER); 3581 %} 3582 3583 operand rcx_RegL() 3584 %{ 3585 constraint(ALLOC_IN_RC(long_rcx_reg)); 3586 match(RegL); 3587 match(rRegL); 3588 3589 format %{ %} 3590 interface(REG_INTER); 3591 %} 3592 3593 operand rdx_RegL() 3594 %{ 3595 constraint(ALLOC_IN_RC(long_rdx_reg)); 3596 match(RegL); 3597 match(rRegL); 3598 3599 format %{ %} 3600 interface(REG_INTER); 3601 %} 3602 3603 // Flags register, used as output of compare instructions 3604 operand rFlagsReg() 3605 %{ 3606 constraint(ALLOC_IN_RC(int_flags)); 3607 match(RegFlags); 3608 3609 format %{ "RFLAGS" %} 3610 interface(REG_INTER); 3611 %} 3612 3613 // Flags register, used as output of FLOATING POINT compare instructions 3614 operand rFlagsRegU() 3615 %{ 3616 constraint(ALLOC_IN_RC(int_flags)); 3617 match(RegFlags); 3618 3619 format %{ "RFLAGS_U" %} 3620 interface(REG_INTER); 3621 %} 3622 3623 operand rFlagsRegUCF() %{ 3624 constraint(ALLOC_IN_RC(int_flags)); 3625 match(RegFlags); 3626 predicate(false); 3627 3628 format %{ "RFLAGS_U_CF" %} 3629 interface(REG_INTER); 3630 %} 3631 3632 // Float register operands 3633 operand regF() %{ 3634 constraint(ALLOC_IN_RC(float_reg)); 3635 match(RegF); 3636 3637 format %{ %} 3638 interface(REG_INTER); 3639 %} 3640 3641 // Float register operands 3642 operand legRegF() %{ 3643 constraint(ALLOC_IN_RC(float_reg_legacy)); 3644 match(RegF); 3645 3646 format %{ %} 3647 interface(REG_INTER); 3648 %} 3649 3650 // Float register operands 3651 operand vlRegF() %{ 3652 constraint(ALLOC_IN_RC(float_reg_vl)); 3653 match(RegF); 3654 3655 format %{ %} 3656 interface(REG_INTER); 3657 %} 3658 3659 // Double register operands 3660 operand regD() %{ 3661 constraint(ALLOC_IN_RC(double_reg)); 3662 match(RegD); 3663 3664 format %{ %} 3665 interface(REG_INTER); 3666 %} 3667 3668 // Double register operands 3669 operand legRegD() %{ 3670 constraint(ALLOC_IN_RC(double_reg_legacy)); 3671 match(RegD); 3672 3673 format %{ %} 3674 interface(REG_INTER); 3675 %} 3676 3677 // Double register operands 3678 operand vlRegD() %{ 3679 constraint(ALLOC_IN_RC(double_reg_vl)); 3680 match(RegD); 3681 3682 format %{ %} 3683 interface(REG_INTER); 3684 %} 3685 3686 // Vectors 3687 operand vecS() %{ 3688 constraint(ALLOC_IN_RC(vectors_reg_vlbwdq)); 3689 match(VecS); 3690 3691 format %{ %} 3692 interface(REG_INTER); 3693 %} 3694 3695 // Vectors 3696 operand legVecS() %{ 3697 constraint(ALLOC_IN_RC(vectors_reg_legacy)); 3698 match(VecS); 3699 3700 format %{ %} 3701 interface(REG_INTER); 3702 %} 3703 3704 operand vecD() %{ 3705 constraint(ALLOC_IN_RC(vectord_reg_vlbwdq)); 3706 match(VecD); 3707 3708 format %{ %} 3709 interface(REG_INTER); 3710 %} 3711 3712 operand legVecD() %{ 3713 constraint(ALLOC_IN_RC(vectord_reg_legacy)); 3714 match(VecD); 3715 3716 format %{ %} 3717 interface(REG_INTER); 3718 %} 3719 3720 operand vecX() %{ 3721 constraint(ALLOC_IN_RC(vectorx_reg_vlbwdq)); 3722 match(VecX); 3723 3724 format %{ %} 3725 interface(REG_INTER); 3726 %} 3727 3728 operand legVecX() %{ 3729 constraint(ALLOC_IN_RC(vectorx_reg_legacy)); 3730 match(VecX); 3731 3732 format %{ %} 3733 interface(REG_INTER); 3734 %} 3735 3736 operand vecY() %{ 3737 constraint(ALLOC_IN_RC(vectory_reg_vlbwdq)); 3738 match(VecY); 3739 3740 format %{ %} 3741 interface(REG_INTER); 3742 %} 3743 3744 operand legVecY() %{ 3745 constraint(ALLOC_IN_RC(vectory_reg_legacy)); 3746 match(VecY); 3747 3748 format %{ %} 3749 interface(REG_INTER); 3750 %} 3751 3752 //----------Memory Operands---------------------------------------------------- 3753 // Direct Memory Operand 3754 // operand direct(immP addr) 3755 // %{ 3756 // match(addr); 3757 3758 // format %{ "[$addr]" %} 3759 // interface(MEMORY_INTER) %{ 3760 // base(0xFFFFFFFF); 3761 // index(0x4); 3762 // scale(0x0); 3763 // disp($addr); 3764 // %} 3765 // %} 3766 3767 // Indirect Memory Operand 3768 operand indirect(any_RegP reg) 3769 %{ 3770 constraint(ALLOC_IN_RC(ptr_reg)); 3771 match(reg); 3772 3773 format %{ "[$reg]" %} 3774 interface(MEMORY_INTER) %{ 3775 base($reg); 3776 index(0x4); 3777 scale(0x0); 3778 disp(0x0); 3779 %} 3780 %} 3781 3782 // Indirect Memory Plus Short Offset Operand 3783 operand indOffset8(any_RegP reg, immL8 off) 3784 %{ 3785 constraint(ALLOC_IN_RC(ptr_reg)); 3786 match(AddP reg off); 3787 3788 format %{ "[$reg + $off (8-bit)]" %} 3789 interface(MEMORY_INTER) %{ 3790 base($reg); 3791 index(0x4); 3792 scale(0x0); 3793 disp($off); 3794 %} 3795 %} 3796 3797 // Indirect Memory Plus Long Offset Operand 3798 operand indOffset32(any_RegP reg, immL32 off) 3799 %{ 3800 constraint(ALLOC_IN_RC(ptr_reg)); 3801 match(AddP reg off); 3802 3803 format %{ "[$reg + $off (32-bit)]" %} 3804 interface(MEMORY_INTER) %{ 3805 base($reg); 3806 index(0x4); 3807 scale(0x0); 3808 disp($off); 3809 %} 3810 %} 3811 3812 // Indirect Memory Plus Index Register Plus Offset Operand 3813 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3814 %{ 3815 constraint(ALLOC_IN_RC(ptr_reg)); 3816 match(AddP (AddP reg lreg) off); 3817 3818 op_cost(10); 3819 format %{"[$reg + $off + $lreg]" %} 3820 interface(MEMORY_INTER) %{ 3821 base($reg); 3822 index($lreg); 3823 scale(0x0); 3824 disp($off); 3825 %} 3826 %} 3827 3828 // Indirect Memory Plus Index Register Plus Offset Operand 3829 operand indIndex(any_RegP reg, rRegL lreg) 3830 %{ 3831 constraint(ALLOC_IN_RC(ptr_reg)); 3832 match(AddP reg lreg); 3833 3834 op_cost(10); 3835 format %{"[$reg + $lreg]" %} 3836 interface(MEMORY_INTER) %{ 3837 base($reg); 3838 index($lreg); 3839 scale(0x0); 3840 disp(0x0); 3841 %} 3842 %} 3843 3844 // Indirect Memory Times Scale Plus Index Register 3845 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3846 %{ 3847 constraint(ALLOC_IN_RC(ptr_reg)); 3848 match(AddP reg (LShiftL lreg scale)); 3849 3850 op_cost(10); 3851 format %{"[$reg + $lreg << $scale]" %} 3852 interface(MEMORY_INTER) %{ 3853 base($reg); 3854 index($lreg); 3855 scale($scale); 3856 disp(0x0); 3857 %} 3858 %} 3859 3860 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3861 %{ 3862 constraint(ALLOC_IN_RC(ptr_reg)); 3863 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3864 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3865 3866 op_cost(10); 3867 format %{"[$reg + pos $idx << $scale]" %} 3868 interface(MEMORY_INTER) %{ 3869 base($reg); 3870 index($idx); 3871 scale($scale); 3872 disp(0x0); 3873 %} 3874 %} 3875 3876 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3877 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3878 %{ 3879 constraint(ALLOC_IN_RC(ptr_reg)); 3880 match(AddP (AddP reg (LShiftL lreg scale)) off); 3881 3882 op_cost(10); 3883 format %{"[$reg + $off + $lreg << $scale]" %} 3884 interface(MEMORY_INTER) %{ 3885 base($reg); 3886 index($lreg); 3887 scale($scale); 3888 disp($off); 3889 %} 3890 %} 3891 3892 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3893 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3894 %{ 3895 constraint(ALLOC_IN_RC(ptr_reg)); 3896 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3897 match(AddP (AddP reg (ConvI2L idx)) off); 3898 3899 op_cost(10); 3900 format %{"[$reg + $off + $idx]" %} 3901 interface(MEMORY_INTER) %{ 3902 base($reg); 3903 index($idx); 3904 scale(0x0); 3905 disp($off); 3906 %} 3907 %} 3908 3909 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3910 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3911 %{ 3912 constraint(ALLOC_IN_RC(ptr_reg)); 3913 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3914 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3915 3916 op_cost(10); 3917 format %{"[$reg + $off + $idx << $scale]" %} 3918 interface(MEMORY_INTER) %{ 3919 base($reg); 3920 index($idx); 3921 scale($scale); 3922 disp($off); 3923 %} 3924 %} 3925 3926 // Indirect Narrow Oop Plus Offset Operand 3927 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3928 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3929 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3930 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3931 constraint(ALLOC_IN_RC(ptr_reg)); 3932 match(AddP (DecodeN reg) off); 3933 3934 op_cost(10); 3935 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3936 interface(MEMORY_INTER) %{ 3937 base(0xc); // R12 3938 index($reg); 3939 scale(0x3); 3940 disp($off); 3941 %} 3942 %} 3943 3944 // Indirect Memory Operand 3945 operand indirectNarrow(rRegN reg) 3946 %{ 3947 predicate(Universe::narrow_oop_shift() == 0); 3948 constraint(ALLOC_IN_RC(ptr_reg)); 3949 match(DecodeN reg); 3950 3951 format %{ "[$reg]" %} 3952 interface(MEMORY_INTER) %{ 3953 base($reg); 3954 index(0x4); 3955 scale(0x0); 3956 disp(0x0); 3957 %} 3958 %} 3959 3960 // Indirect Memory Plus Short Offset Operand 3961 operand indOffset8Narrow(rRegN reg, immL8 off) 3962 %{ 3963 predicate(Universe::narrow_oop_shift() == 0); 3964 constraint(ALLOC_IN_RC(ptr_reg)); 3965 match(AddP (DecodeN reg) off); 3966 3967 format %{ "[$reg + $off (8-bit)]" %} 3968 interface(MEMORY_INTER) %{ 3969 base($reg); 3970 index(0x4); 3971 scale(0x0); 3972 disp($off); 3973 %} 3974 %} 3975 3976 // Indirect Memory Plus Long Offset Operand 3977 operand indOffset32Narrow(rRegN reg, immL32 off) 3978 %{ 3979 predicate(Universe::narrow_oop_shift() == 0); 3980 constraint(ALLOC_IN_RC(ptr_reg)); 3981 match(AddP (DecodeN reg) off); 3982 3983 format %{ "[$reg + $off (32-bit)]" %} 3984 interface(MEMORY_INTER) %{ 3985 base($reg); 3986 index(0x4); 3987 scale(0x0); 3988 disp($off); 3989 %} 3990 %} 3991 3992 // Indirect Memory Plus Index Register Plus Offset Operand 3993 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3994 %{ 3995 predicate(Universe::narrow_oop_shift() == 0); 3996 constraint(ALLOC_IN_RC(ptr_reg)); 3997 match(AddP (AddP (DecodeN reg) lreg) off); 3998 3999 op_cost(10); 4000 format %{"[$reg + $off + $lreg]" %} 4001 interface(MEMORY_INTER) %{ 4002 base($reg); 4003 index($lreg); 4004 scale(0x0); 4005 disp($off); 4006 %} 4007 %} 4008 4009 // Indirect Memory Plus Index Register Plus Offset Operand 4010 operand indIndexNarrow(rRegN reg, rRegL lreg) 4011 %{ 4012 predicate(Universe::narrow_oop_shift() == 0); 4013 constraint(ALLOC_IN_RC(ptr_reg)); 4014 match(AddP (DecodeN reg) lreg); 4015 4016 op_cost(10); 4017 format %{"[$reg + $lreg]" %} 4018 interface(MEMORY_INTER) %{ 4019 base($reg); 4020 index($lreg); 4021 scale(0x0); 4022 disp(0x0); 4023 %} 4024 %} 4025 4026 // Indirect Memory Times Scale Plus Index Register 4027 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4028 %{ 4029 predicate(Universe::narrow_oop_shift() == 0); 4030 constraint(ALLOC_IN_RC(ptr_reg)); 4031 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4032 4033 op_cost(10); 4034 format %{"[$reg + $lreg << $scale]" %} 4035 interface(MEMORY_INTER) %{ 4036 base($reg); 4037 index($lreg); 4038 scale($scale); 4039 disp(0x0); 4040 %} 4041 %} 4042 4043 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4044 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4045 %{ 4046 predicate(Universe::narrow_oop_shift() == 0); 4047 constraint(ALLOC_IN_RC(ptr_reg)); 4048 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4049 4050 op_cost(10); 4051 format %{"[$reg + $off + $lreg << $scale]" %} 4052 interface(MEMORY_INTER) %{ 4053 base($reg); 4054 index($lreg); 4055 scale($scale); 4056 disp($off); 4057 %} 4058 %} 4059 4060 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4061 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4062 %{ 4063 constraint(ALLOC_IN_RC(ptr_reg)); 4064 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4065 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4066 4067 op_cost(10); 4068 format %{"[$reg + $off + $idx]" %} 4069 interface(MEMORY_INTER) %{ 4070 base($reg); 4071 index($idx); 4072 scale(0x0); 4073 disp($off); 4074 %} 4075 %} 4076 4077 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4078 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4079 %{ 4080 constraint(ALLOC_IN_RC(ptr_reg)); 4081 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4082 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4083 4084 op_cost(10); 4085 format %{"[$reg + $off + $idx << $scale]" %} 4086 interface(MEMORY_INTER) %{ 4087 base($reg); 4088 index($idx); 4089 scale($scale); 4090 disp($off); 4091 %} 4092 %} 4093 4094 //----------Special Memory Operands-------------------------------------------- 4095 // Stack Slot Operand - This operand is used for loading and storing temporary 4096 // values on the stack where a match requires a value to 4097 // flow through memory. 4098 operand stackSlotP(sRegP reg) 4099 %{ 4100 constraint(ALLOC_IN_RC(stack_slots)); 4101 // No match rule because this operand is only generated in matching 4102 4103 format %{ "[$reg]" %} 4104 interface(MEMORY_INTER) %{ 4105 base(0x4); // RSP 4106 index(0x4); // No Index 4107 scale(0x0); // No Scale 4108 disp($reg); // Stack Offset 4109 %} 4110 %} 4111 4112 operand stackSlotI(sRegI reg) 4113 %{ 4114 constraint(ALLOC_IN_RC(stack_slots)); 4115 // No match rule because this operand is only generated in matching 4116 4117 format %{ "[$reg]" %} 4118 interface(MEMORY_INTER) %{ 4119 base(0x4); // RSP 4120 index(0x4); // No Index 4121 scale(0x0); // No Scale 4122 disp($reg); // Stack Offset 4123 %} 4124 %} 4125 4126 operand stackSlotF(sRegF reg) 4127 %{ 4128 constraint(ALLOC_IN_RC(stack_slots)); 4129 // No match rule because this operand is only generated in matching 4130 4131 format %{ "[$reg]" %} 4132 interface(MEMORY_INTER) %{ 4133 base(0x4); // RSP 4134 index(0x4); // No Index 4135 scale(0x0); // No Scale 4136 disp($reg); // Stack Offset 4137 %} 4138 %} 4139 4140 operand stackSlotD(sRegD reg) 4141 %{ 4142 constraint(ALLOC_IN_RC(stack_slots)); 4143 // No match rule because this operand is only generated in matching 4144 4145 format %{ "[$reg]" %} 4146 interface(MEMORY_INTER) %{ 4147 base(0x4); // RSP 4148 index(0x4); // No Index 4149 scale(0x0); // No Scale 4150 disp($reg); // Stack Offset 4151 %} 4152 %} 4153 operand stackSlotL(sRegL reg) 4154 %{ 4155 constraint(ALLOC_IN_RC(stack_slots)); 4156 // No match rule because this operand is only generated in matching 4157 4158 format %{ "[$reg]" %} 4159 interface(MEMORY_INTER) %{ 4160 base(0x4); // RSP 4161 index(0x4); // No Index 4162 scale(0x0); // No Scale 4163 disp($reg); // Stack Offset 4164 %} 4165 %} 4166 4167 //----------Conditional Branch Operands---------------------------------------- 4168 // Comparison Op - This is the operation of the comparison, and is limited to 4169 // the following set of codes: 4170 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4171 // 4172 // Other attributes of the comparison, such as unsignedness, are specified 4173 // by the comparison instruction that sets a condition code flags register. 4174 // That result is represented by a flags operand whose subtype is appropriate 4175 // to the unsignedness (etc.) of the comparison. 4176 // 4177 // Later, the instruction which matches both the Comparison Op (a Bool) and 4178 // the flags (produced by the Cmp) specifies the coding of the comparison op 4179 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4180 4181 // Comparision Code 4182 operand cmpOp() 4183 %{ 4184 match(Bool); 4185 4186 format %{ "" %} 4187 interface(COND_INTER) %{ 4188 equal(0x4, "e"); 4189 not_equal(0x5, "ne"); 4190 less(0xC, "l"); 4191 greater_equal(0xD, "ge"); 4192 less_equal(0xE, "le"); 4193 greater(0xF, "g"); 4194 overflow(0x0, "o"); 4195 no_overflow(0x1, "no"); 4196 %} 4197 %} 4198 4199 // Comparison Code, unsigned compare. Used by FP also, with 4200 // C2 (unordered) turned into GT or LT already. The other bits 4201 // C0 and C3 are turned into Carry & Zero flags. 4202 operand cmpOpU() 4203 %{ 4204 match(Bool); 4205 4206 format %{ "" %} 4207 interface(COND_INTER) %{ 4208 equal(0x4, "e"); 4209 not_equal(0x5, "ne"); 4210 less(0x2, "b"); 4211 greater_equal(0x3, "nb"); 4212 less_equal(0x6, "be"); 4213 greater(0x7, "nbe"); 4214 overflow(0x0, "o"); 4215 no_overflow(0x1, "no"); 4216 %} 4217 %} 4218 4219 4220 // Floating comparisons that don't require any fixup for the unordered case 4221 operand cmpOpUCF() %{ 4222 match(Bool); 4223 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4224 n->as_Bool()->_test._test == BoolTest::ge || 4225 n->as_Bool()->_test._test == BoolTest::le || 4226 n->as_Bool()->_test._test == BoolTest::gt); 4227 format %{ "" %} 4228 interface(COND_INTER) %{ 4229 equal(0x4, "e"); 4230 not_equal(0x5, "ne"); 4231 less(0x2, "b"); 4232 greater_equal(0x3, "nb"); 4233 less_equal(0x6, "be"); 4234 greater(0x7, "nbe"); 4235 overflow(0x0, "o"); 4236 no_overflow(0x1, "no"); 4237 %} 4238 %} 4239 4240 4241 // Floating comparisons that can be fixed up with extra conditional jumps 4242 operand cmpOpUCF2() %{ 4243 match(Bool); 4244 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4245 n->as_Bool()->_test._test == BoolTest::eq); 4246 format %{ "" %} 4247 interface(COND_INTER) %{ 4248 equal(0x4, "e"); 4249 not_equal(0x5, "ne"); 4250 less(0x2, "b"); 4251 greater_equal(0x3, "nb"); 4252 less_equal(0x6, "be"); 4253 greater(0x7, "nbe"); 4254 overflow(0x0, "o"); 4255 no_overflow(0x1, "no"); 4256 %} 4257 %} 4258 4259 // Operands for bound floating pointer register arguments 4260 operand rxmm0() %{ 4261 constraint(ALLOC_IN_RC(xmm0_reg)); 4262 match(VecX); 4263 format%{%} 4264 interface(REG_INTER); 4265 %} 4266 operand rxmm1() %{ 4267 constraint(ALLOC_IN_RC(xmm1_reg)); 4268 match(VecX); 4269 format%{%} 4270 interface(REG_INTER); 4271 %} 4272 operand rxmm2() %{ 4273 constraint(ALLOC_IN_RC(xmm2_reg)); 4274 match(VecX); 4275 format%{%} 4276 interface(REG_INTER); 4277 %} 4278 operand rxmm3() %{ 4279 constraint(ALLOC_IN_RC(xmm3_reg)); 4280 match(VecX); 4281 format%{%} 4282 interface(REG_INTER); 4283 %} 4284 operand rxmm4() %{ 4285 constraint(ALLOC_IN_RC(xmm4_reg)); 4286 match(VecX); 4287 format%{%} 4288 interface(REG_INTER); 4289 %} 4290 operand rxmm5() %{ 4291 constraint(ALLOC_IN_RC(xmm5_reg)); 4292 match(VecX); 4293 format%{%} 4294 interface(REG_INTER); 4295 %} 4296 operand rxmm6() %{ 4297 constraint(ALLOC_IN_RC(xmm6_reg)); 4298 match(VecX); 4299 format%{%} 4300 interface(REG_INTER); 4301 %} 4302 operand rxmm7() %{ 4303 constraint(ALLOC_IN_RC(xmm7_reg)); 4304 match(VecX); 4305 format%{%} 4306 interface(REG_INTER); 4307 %} 4308 operand rxmm8() %{ 4309 constraint(ALLOC_IN_RC(xmm8_reg)); 4310 match(VecX); 4311 format%{%} 4312 interface(REG_INTER); 4313 %} 4314 operand rxmm9() %{ 4315 constraint(ALLOC_IN_RC(xmm9_reg)); 4316 match(VecX); 4317 format%{%} 4318 interface(REG_INTER); 4319 %} 4320 operand rxmm10() %{ 4321 constraint(ALLOC_IN_RC(xmm10_reg)); 4322 match(VecX); 4323 format%{%} 4324 interface(REG_INTER); 4325 %} 4326 operand rxmm11() %{ 4327 constraint(ALLOC_IN_RC(xmm11_reg)); 4328 match(VecX); 4329 format%{%} 4330 interface(REG_INTER); 4331 %} 4332 operand rxmm12() %{ 4333 constraint(ALLOC_IN_RC(xmm12_reg)); 4334 match(VecX); 4335 format%{%} 4336 interface(REG_INTER); 4337 %} 4338 operand rxmm13() %{ 4339 constraint(ALLOC_IN_RC(xmm13_reg)); 4340 match(VecX); 4341 format%{%} 4342 interface(REG_INTER); 4343 %} 4344 operand rxmm14() %{ 4345 constraint(ALLOC_IN_RC(xmm14_reg)); 4346 match(VecX); 4347 format%{%} 4348 interface(REG_INTER); 4349 %} 4350 operand rxmm15() %{ 4351 constraint(ALLOC_IN_RC(xmm15_reg)); 4352 match(VecX); 4353 format%{%} 4354 interface(REG_INTER); 4355 %} 4356 operand rxmm16() %{ 4357 constraint(ALLOC_IN_RC(xmm16_reg)); 4358 match(VecX); 4359 format%{%} 4360 interface(REG_INTER); 4361 %} 4362 operand rxmm17() %{ 4363 constraint(ALLOC_IN_RC(xmm17_reg)); 4364 match(VecX); 4365 format%{%} 4366 interface(REG_INTER); 4367 %} 4368 operand rxmm18() %{ 4369 constraint(ALLOC_IN_RC(xmm18_reg)); 4370 match(VecX); 4371 format%{%} 4372 interface(REG_INTER); 4373 %} 4374 operand rxmm19() %{ 4375 constraint(ALLOC_IN_RC(xmm19_reg)); 4376 match(VecX); 4377 format%{%} 4378 interface(REG_INTER); 4379 %} 4380 operand rxmm20() %{ 4381 constraint(ALLOC_IN_RC(xmm20_reg)); 4382 match(VecX); 4383 format%{%} 4384 interface(REG_INTER); 4385 %} 4386 operand rxmm21() %{ 4387 constraint(ALLOC_IN_RC(xmm21_reg)); 4388 match(VecX); 4389 format%{%} 4390 interface(REG_INTER); 4391 %} 4392 operand rxmm22() %{ 4393 constraint(ALLOC_IN_RC(xmm22_reg)); 4394 match(VecX); 4395 format%{%} 4396 interface(REG_INTER); 4397 %} 4398 operand rxmm23() %{ 4399 constraint(ALLOC_IN_RC(xmm23_reg)); 4400 match(VecX); 4401 format%{%} 4402 interface(REG_INTER); 4403 %} 4404 operand rxmm24() %{ 4405 constraint(ALLOC_IN_RC(xmm24_reg)); 4406 match(VecX); 4407 format%{%} 4408 interface(REG_INTER); 4409 %} 4410 operand rxmm25() %{ 4411 constraint(ALLOC_IN_RC(xmm25_reg)); 4412 match(VecX); 4413 format%{%} 4414 interface(REG_INTER); 4415 %} 4416 operand rxmm26() %{ 4417 constraint(ALLOC_IN_RC(xmm26_reg)); 4418 match(VecX); 4419 format%{%} 4420 interface(REG_INTER); 4421 %} 4422 operand rxmm27() %{ 4423 constraint(ALLOC_IN_RC(xmm27_reg)); 4424 match(VecX); 4425 format%{%} 4426 interface(REG_INTER); 4427 %} 4428 operand rxmm28() %{ 4429 constraint(ALLOC_IN_RC(xmm28_reg)); 4430 match(VecX); 4431 format%{%} 4432 interface(REG_INTER); 4433 %} 4434 operand rxmm29() %{ 4435 constraint(ALLOC_IN_RC(xmm29_reg)); 4436 match(VecX); 4437 format%{%} 4438 interface(REG_INTER); 4439 %} 4440 operand rxmm30() %{ 4441 constraint(ALLOC_IN_RC(xmm30_reg)); 4442 match(VecX); 4443 format%{%} 4444 interface(REG_INTER); 4445 %} 4446 operand rxmm31() %{ 4447 constraint(ALLOC_IN_RC(xmm31_reg)); 4448 match(VecX); 4449 format%{%} 4450 interface(REG_INTER); 4451 %} 4452 4453 //----------OPERAND CLASSES---------------------------------------------------- 4454 // Operand Classes are groups of operands that are used as to simplify 4455 // instruction definitions by not requiring the AD writer to specify separate 4456 // instructions for every form of operand when the instruction accepts 4457 // multiple operand types with the same basic encoding and format. The classic 4458 // case of this is memory operands. 4459 4460 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4461 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4462 indCompressedOopOffset, 4463 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4464 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4465 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4466 4467 //----------PIPELINE----------------------------------------------------------- 4468 // Rules which define the behavior of the target architectures pipeline. 4469 pipeline %{ 4470 4471 //----------ATTRIBUTES--------------------------------------------------------- 4472 attributes %{ 4473 variable_size_instructions; // Fixed size instructions 4474 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4475 instruction_unit_size = 1; // An instruction is 1 bytes long 4476 instruction_fetch_unit_size = 16; // The processor fetches one line 4477 instruction_fetch_units = 1; // of 16 bytes 4478 4479 // List of nop instructions 4480 nops( MachNop ); 4481 %} 4482 4483 //----------RESOURCES---------------------------------------------------------- 4484 // Resources are the functional units available to the machine 4485 4486 // Generic P2/P3 pipeline 4487 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4488 // 3 instructions decoded per cycle. 4489 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4490 // 3 ALU op, only ALU0 handles mul instructions. 4491 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4492 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4493 BR, FPU, 4494 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4495 4496 //----------PIPELINE DESCRIPTION----------------------------------------------- 4497 // Pipeline Description specifies the stages in the machine's pipeline 4498 4499 // Generic P2/P3 pipeline 4500 pipe_desc(S0, S1, S2, S3, S4, S5); 4501 4502 //----------PIPELINE CLASSES--------------------------------------------------- 4503 // Pipeline Classes describe the stages in which input and output are 4504 // referenced by the hardware pipeline. 4505 4506 // Naming convention: ialu or fpu 4507 // Then: _reg 4508 // Then: _reg if there is a 2nd register 4509 // Then: _long if it's a pair of instructions implementing a long 4510 // Then: _fat if it requires the big decoder 4511 // Or: _mem if it requires the big decoder and a memory unit. 4512 4513 // Integer ALU reg operation 4514 pipe_class ialu_reg(rRegI dst) 4515 %{ 4516 single_instruction; 4517 dst : S4(write); 4518 dst : S3(read); 4519 DECODE : S0; // any decoder 4520 ALU : S3; // any alu 4521 %} 4522 4523 // Long ALU reg operation 4524 pipe_class ialu_reg_long(rRegL dst) 4525 %{ 4526 instruction_count(2); 4527 dst : S4(write); 4528 dst : S3(read); 4529 DECODE : S0(2); // any 2 decoders 4530 ALU : S3(2); // both alus 4531 %} 4532 4533 // Integer ALU reg operation using big decoder 4534 pipe_class ialu_reg_fat(rRegI dst) 4535 %{ 4536 single_instruction; 4537 dst : S4(write); 4538 dst : S3(read); 4539 D0 : S0; // big decoder only 4540 ALU : S3; // any alu 4541 %} 4542 4543 // Long ALU reg operation using big decoder 4544 pipe_class ialu_reg_long_fat(rRegL dst) 4545 %{ 4546 instruction_count(2); 4547 dst : S4(write); 4548 dst : S3(read); 4549 D0 : S0(2); // big decoder only; twice 4550 ALU : S3(2); // any 2 alus 4551 %} 4552 4553 // Integer ALU reg-reg operation 4554 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4555 %{ 4556 single_instruction; 4557 dst : S4(write); 4558 src : S3(read); 4559 DECODE : S0; // any decoder 4560 ALU : S3; // any alu 4561 %} 4562 4563 // Long ALU reg-reg operation 4564 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4565 %{ 4566 instruction_count(2); 4567 dst : S4(write); 4568 src : S3(read); 4569 DECODE : S0(2); // any 2 decoders 4570 ALU : S3(2); // both alus 4571 %} 4572 4573 // Integer ALU reg-reg operation 4574 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4575 %{ 4576 single_instruction; 4577 dst : S4(write); 4578 src : S3(read); 4579 D0 : S0; // big decoder only 4580 ALU : S3; // any alu 4581 %} 4582 4583 // Long ALU reg-reg operation 4584 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4585 %{ 4586 instruction_count(2); 4587 dst : S4(write); 4588 src : S3(read); 4589 D0 : S0(2); // big decoder only; twice 4590 ALU : S3(2); // both alus 4591 %} 4592 4593 // Integer ALU reg-mem operation 4594 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4595 %{ 4596 single_instruction; 4597 dst : S5(write); 4598 mem : S3(read); 4599 D0 : S0; // big decoder only 4600 ALU : S4; // any alu 4601 MEM : S3; // any mem 4602 %} 4603 4604 // Integer mem operation (prefetch) 4605 pipe_class ialu_mem(memory mem) 4606 %{ 4607 single_instruction; 4608 mem : S3(read); 4609 D0 : S0; // big decoder only 4610 MEM : S3; // any mem 4611 %} 4612 4613 // Integer Store to Memory 4614 pipe_class ialu_mem_reg(memory mem, rRegI src) 4615 %{ 4616 single_instruction; 4617 mem : S3(read); 4618 src : S5(read); 4619 D0 : S0; // big decoder only 4620 ALU : S4; // any alu 4621 MEM : S3; 4622 %} 4623 4624 // // Long Store to Memory 4625 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4626 // %{ 4627 // instruction_count(2); 4628 // mem : S3(read); 4629 // src : S5(read); 4630 // D0 : S0(2); // big decoder only; twice 4631 // ALU : S4(2); // any 2 alus 4632 // MEM : S3(2); // Both mems 4633 // %} 4634 4635 // Integer Store to Memory 4636 pipe_class ialu_mem_imm(memory mem) 4637 %{ 4638 single_instruction; 4639 mem : S3(read); 4640 D0 : S0; // big decoder only 4641 ALU : S4; // any alu 4642 MEM : S3; 4643 %} 4644 4645 // Integer ALU0 reg-reg operation 4646 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4647 %{ 4648 single_instruction; 4649 dst : S4(write); 4650 src : S3(read); 4651 D0 : S0; // Big decoder only 4652 ALU0 : S3; // only alu0 4653 %} 4654 4655 // Integer ALU0 reg-mem operation 4656 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4657 %{ 4658 single_instruction; 4659 dst : S5(write); 4660 mem : S3(read); 4661 D0 : S0; // big decoder only 4662 ALU0 : S4; // ALU0 only 4663 MEM : S3; // any mem 4664 %} 4665 4666 // Integer ALU reg-reg operation 4667 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4668 %{ 4669 single_instruction; 4670 cr : S4(write); 4671 src1 : S3(read); 4672 src2 : S3(read); 4673 DECODE : S0; // any decoder 4674 ALU : S3; // any alu 4675 %} 4676 4677 // Integer ALU reg-imm operation 4678 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4679 %{ 4680 single_instruction; 4681 cr : S4(write); 4682 src1 : S3(read); 4683 DECODE : S0; // any decoder 4684 ALU : S3; // any alu 4685 %} 4686 4687 // Integer ALU reg-mem operation 4688 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4689 %{ 4690 single_instruction; 4691 cr : S4(write); 4692 src1 : S3(read); 4693 src2 : S3(read); 4694 D0 : S0; // big decoder only 4695 ALU : S4; // any alu 4696 MEM : S3; 4697 %} 4698 4699 // Conditional move reg-reg 4700 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4701 %{ 4702 instruction_count(4); 4703 y : S4(read); 4704 q : S3(read); 4705 p : S3(read); 4706 DECODE : S0(4); // any decoder 4707 %} 4708 4709 // Conditional move reg-reg 4710 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4711 %{ 4712 single_instruction; 4713 dst : S4(write); 4714 src : S3(read); 4715 cr : S3(read); 4716 DECODE : S0; // any decoder 4717 %} 4718 4719 // Conditional move reg-mem 4720 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4721 %{ 4722 single_instruction; 4723 dst : S4(write); 4724 src : S3(read); 4725 cr : S3(read); 4726 DECODE : S0; // any decoder 4727 MEM : S3; 4728 %} 4729 4730 // Conditional move reg-reg long 4731 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4732 %{ 4733 single_instruction; 4734 dst : S4(write); 4735 src : S3(read); 4736 cr : S3(read); 4737 DECODE : S0(2); // any 2 decoders 4738 %} 4739 4740 // XXX 4741 // // Conditional move double reg-reg 4742 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4743 // %{ 4744 // single_instruction; 4745 // dst : S4(write); 4746 // src : S3(read); 4747 // cr : S3(read); 4748 // DECODE : S0; // any decoder 4749 // %} 4750 4751 // Float reg-reg operation 4752 pipe_class fpu_reg(regD dst) 4753 %{ 4754 instruction_count(2); 4755 dst : S3(read); 4756 DECODE : S0(2); // any 2 decoders 4757 FPU : S3; 4758 %} 4759 4760 // Float reg-reg operation 4761 pipe_class fpu_reg_reg(regD dst, regD src) 4762 %{ 4763 instruction_count(2); 4764 dst : S4(write); 4765 src : S3(read); 4766 DECODE : S0(2); // any 2 decoders 4767 FPU : S3; 4768 %} 4769 4770 // Float reg-reg operation 4771 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4772 %{ 4773 instruction_count(3); 4774 dst : S4(write); 4775 src1 : S3(read); 4776 src2 : S3(read); 4777 DECODE : S0(3); // any 3 decoders 4778 FPU : S3(2); 4779 %} 4780 4781 // Float reg-reg operation 4782 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4783 %{ 4784 instruction_count(4); 4785 dst : S4(write); 4786 src1 : S3(read); 4787 src2 : S3(read); 4788 src3 : S3(read); 4789 DECODE : S0(4); // any 3 decoders 4790 FPU : S3(2); 4791 %} 4792 4793 // Float reg-reg operation 4794 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4795 %{ 4796 instruction_count(4); 4797 dst : S4(write); 4798 src1 : S3(read); 4799 src2 : S3(read); 4800 src3 : S3(read); 4801 DECODE : S1(3); // any 3 decoders 4802 D0 : S0; // Big decoder only 4803 FPU : S3(2); 4804 MEM : S3; 4805 %} 4806 4807 // Float reg-mem operation 4808 pipe_class fpu_reg_mem(regD dst, memory mem) 4809 %{ 4810 instruction_count(2); 4811 dst : S5(write); 4812 mem : S3(read); 4813 D0 : S0; // big decoder only 4814 DECODE : S1; // any decoder for FPU POP 4815 FPU : S4; 4816 MEM : S3; // any mem 4817 %} 4818 4819 // Float reg-mem operation 4820 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4821 %{ 4822 instruction_count(3); 4823 dst : S5(write); 4824 src1 : S3(read); 4825 mem : S3(read); 4826 D0 : S0; // big decoder only 4827 DECODE : S1(2); // any decoder for FPU POP 4828 FPU : S4; 4829 MEM : S3; // any mem 4830 %} 4831 4832 // Float mem-reg operation 4833 pipe_class fpu_mem_reg(memory mem, regD src) 4834 %{ 4835 instruction_count(2); 4836 src : S5(read); 4837 mem : S3(read); 4838 DECODE : S0; // any decoder for FPU PUSH 4839 D0 : S1; // big decoder only 4840 FPU : S4; 4841 MEM : S3; // any mem 4842 %} 4843 4844 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4845 %{ 4846 instruction_count(3); 4847 src1 : S3(read); 4848 src2 : S3(read); 4849 mem : S3(read); 4850 DECODE : S0(2); // any decoder for FPU PUSH 4851 D0 : S1; // big decoder only 4852 FPU : S4; 4853 MEM : S3; // any mem 4854 %} 4855 4856 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4857 %{ 4858 instruction_count(3); 4859 src1 : S3(read); 4860 src2 : S3(read); 4861 mem : S4(read); 4862 DECODE : S0; // any decoder for FPU PUSH 4863 D0 : S0(2); // big decoder only 4864 FPU : S4; 4865 MEM : S3(2); // any mem 4866 %} 4867 4868 pipe_class fpu_mem_mem(memory dst, memory src1) 4869 %{ 4870 instruction_count(2); 4871 src1 : S3(read); 4872 dst : S4(read); 4873 D0 : S0(2); // big decoder only 4874 MEM : S3(2); // any mem 4875 %} 4876 4877 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4878 %{ 4879 instruction_count(3); 4880 src1 : S3(read); 4881 src2 : S3(read); 4882 dst : S4(read); 4883 D0 : S0(3); // big decoder only 4884 FPU : S4; 4885 MEM : S3(3); // any mem 4886 %} 4887 4888 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4889 %{ 4890 instruction_count(3); 4891 src1 : S4(read); 4892 mem : S4(read); 4893 DECODE : S0; // any decoder for FPU PUSH 4894 D0 : S0(2); // big decoder only 4895 FPU : S4; 4896 MEM : S3(2); // any mem 4897 %} 4898 4899 // Float load constant 4900 pipe_class fpu_reg_con(regD dst) 4901 %{ 4902 instruction_count(2); 4903 dst : S5(write); 4904 D0 : S0; // big decoder only for the load 4905 DECODE : S1; // any decoder for FPU POP 4906 FPU : S4; 4907 MEM : S3; // any mem 4908 %} 4909 4910 // Float load constant 4911 pipe_class fpu_reg_reg_con(regD dst, regD src) 4912 %{ 4913 instruction_count(3); 4914 dst : S5(write); 4915 src : S3(read); 4916 D0 : S0; // big decoder only for the load 4917 DECODE : S1(2); // any decoder for FPU POP 4918 FPU : S4; 4919 MEM : S3; // any mem 4920 %} 4921 4922 // UnConditional branch 4923 pipe_class pipe_jmp(label labl) 4924 %{ 4925 single_instruction; 4926 BR : S3; 4927 %} 4928 4929 // Conditional branch 4930 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4931 %{ 4932 single_instruction; 4933 cr : S1(read); 4934 BR : S3; 4935 %} 4936 4937 // Allocation idiom 4938 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4939 %{ 4940 instruction_count(1); force_serialization; 4941 fixed_latency(6); 4942 heap_ptr : S3(read); 4943 DECODE : S0(3); 4944 D0 : S2; 4945 MEM : S3; 4946 ALU : S3(2); 4947 dst : S5(write); 4948 BR : S5; 4949 %} 4950 4951 // Generic big/slow expanded idiom 4952 pipe_class pipe_slow() 4953 %{ 4954 instruction_count(10); multiple_bundles; force_serialization; 4955 fixed_latency(100); 4956 D0 : S0(2); 4957 MEM : S3(2); 4958 %} 4959 4960 // The real do-nothing guy 4961 pipe_class empty() 4962 %{ 4963 instruction_count(0); 4964 %} 4965 4966 // Define the class for the Nop node 4967 define 4968 %{ 4969 MachNop = empty; 4970 %} 4971 4972 %} 4973 4974 //----------INSTRUCTIONS------------------------------------------------------- 4975 // 4976 // match -- States which machine-independent subtree may be replaced 4977 // by this instruction. 4978 // ins_cost -- The estimated cost of this instruction is used by instruction 4979 // selection to identify a minimum cost tree of machine 4980 // instructions that matches a tree of machine-independent 4981 // instructions. 4982 // format -- A string providing the disassembly for this instruction. 4983 // The value of an instruction's operand may be inserted 4984 // by referring to it with a '$' prefix. 4985 // opcode -- Three instruction opcodes may be provided. These are referred 4986 // to within an encode class as $primary, $secondary, and $tertiary 4987 // rrspectively. The primary opcode is commonly used to 4988 // indicate the type of machine instruction, while secondary 4989 // and tertiary are often used for prefix options or addressing 4990 // modes. 4991 // ins_encode -- A list of encode classes with parameters. The encode class 4992 // name must have been defined in an 'enc_class' specification 4993 // in the encode section of the architecture description. 4994 4995 4996 //----------Load/Store/Move Instructions--------------------------------------- 4997 //----------Load Instructions-------------------------------------------------- 4998 4999 // Load Byte (8 bit signed) 5000 instruct loadB(rRegI dst, memory mem) 5001 %{ 5002 match(Set dst (LoadB mem)); 5003 5004 ins_cost(125); 5005 format %{ "movsbl $dst, $mem\t# byte" %} 5006 5007 ins_encode %{ 5008 __ movsbl($dst$$Register, $mem$$Address); 5009 %} 5010 5011 ins_pipe(ialu_reg_mem); 5012 %} 5013 5014 // Load Byte (8 bit signed) into Long Register 5015 instruct loadB2L(rRegL dst, memory mem) 5016 %{ 5017 match(Set dst (ConvI2L (LoadB mem))); 5018 5019 ins_cost(125); 5020 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5021 5022 ins_encode %{ 5023 __ movsbq($dst$$Register, $mem$$Address); 5024 %} 5025 5026 ins_pipe(ialu_reg_mem); 5027 %} 5028 5029 // Load Unsigned Byte (8 bit UNsigned) 5030 instruct loadUB(rRegI dst, memory mem) 5031 %{ 5032 match(Set dst (LoadUB mem)); 5033 5034 ins_cost(125); 5035 format %{ "movzbl $dst, $mem\t# ubyte" %} 5036 5037 ins_encode %{ 5038 __ movzbl($dst$$Register, $mem$$Address); 5039 %} 5040 5041 ins_pipe(ialu_reg_mem); 5042 %} 5043 5044 // Load Unsigned Byte (8 bit UNsigned) into Long Register 5045 instruct loadUB2L(rRegL dst, memory mem) 5046 %{ 5047 match(Set dst (ConvI2L (LoadUB mem))); 5048 5049 ins_cost(125); 5050 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5051 5052 ins_encode %{ 5053 __ movzbq($dst$$Register, $mem$$Address); 5054 %} 5055 5056 ins_pipe(ialu_reg_mem); 5057 %} 5058 5059 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 5060 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5061 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5062 effect(KILL cr); 5063 5064 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 5065 "andl $dst, right_n_bits($mask, 8)" %} 5066 ins_encode %{ 5067 Register Rdst = $dst$$Register; 5068 __ movzbq(Rdst, $mem$$Address); 5069 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 5070 %} 5071 ins_pipe(ialu_reg_mem); 5072 %} 5073 5074 // Load Short (16 bit signed) 5075 instruct loadS(rRegI dst, memory mem) 5076 %{ 5077 match(Set dst (LoadS mem)); 5078 5079 ins_cost(125); 5080 format %{ "movswl $dst, $mem\t# short" %} 5081 5082 ins_encode %{ 5083 __ movswl($dst$$Register, $mem$$Address); 5084 %} 5085 5086 ins_pipe(ialu_reg_mem); 5087 %} 5088 5089 // Load Short (16 bit signed) to Byte (8 bit signed) 5090 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5091 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5092 5093 ins_cost(125); 5094 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5095 ins_encode %{ 5096 __ movsbl($dst$$Register, $mem$$Address); 5097 %} 5098 ins_pipe(ialu_reg_mem); 5099 %} 5100 5101 // Load Short (16 bit signed) into Long Register 5102 instruct loadS2L(rRegL dst, memory mem) 5103 %{ 5104 match(Set dst (ConvI2L (LoadS mem))); 5105 5106 ins_cost(125); 5107 format %{ "movswq $dst, $mem\t# short -> long" %} 5108 5109 ins_encode %{ 5110 __ movswq($dst$$Register, $mem$$Address); 5111 %} 5112 5113 ins_pipe(ialu_reg_mem); 5114 %} 5115 5116 // Load Unsigned Short/Char (16 bit UNsigned) 5117 instruct loadUS(rRegI dst, memory mem) 5118 %{ 5119 match(Set dst (LoadUS mem)); 5120 5121 ins_cost(125); 5122 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5123 5124 ins_encode %{ 5125 __ movzwl($dst$$Register, $mem$$Address); 5126 %} 5127 5128 ins_pipe(ialu_reg_mem); 5129 %} 5130 5131 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5132 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5133 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5134 5135 ins_cost(125); 5136 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5137 ins_encode %{ 5138 __ movsbl($dst$$Register, $mem$$Address); 5139 %} 5140 ins_pipe(ialu_reg_mem); 5141 %} 5142 5143 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5144 instruct loadUS2L(rRegL dst, memory mem) 5145 %{ 5146 match(Set dst (ConvI2L (LoadUS mem))); 5147 5148 ins_cost(125); 5149 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5150 5151 ins_encode %{ 5152 __ movzwq($dst$$Register, $mem$$Address); 5153 %} 5154 5155 ins_pipe(ialu_reg_mem); 5156 %} 5157 5158 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5159 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5160 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5161 5162 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5163 ins_encode %{ 5164 __ movzbq($dst$$Register, $mem$$Address); 5165 %} 5166 ins_pipe(ialu_reg_mem); 5167 %} 5168 5169 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5170 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5171 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5172 effect(KILL cr); 5173 5174 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5175 "andl $dst, right_n_bits($mask, 16)" %} 5176 ins_encode %{ 5177 Register Rdst = $dst$$Register; 5178 __ movzwq(Rdst, $mem$$Address); 5179 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5180 %} 5181 ins_pipe(ialu_reg_mem); 5182 %} 5183 5184 // Load Integer 5185 instruct loadI(rRegI dst, memory mem) 5186 %{ 5187 match(Set dst (LoadI mem)); 5188 5189 ins_cost(125); 5190 format %{ "movl $dst, $mem\t# int" %} 5191 5192 ins_encode %{ 5193 __ movl($dst$$Register, $mem$$Address); 5194 %} 5195 5196 ins_pipe(ialu_reg_mem); 5197 %} 5198 5199 // Load Integer (32 bit signed) to Byte (8 bit signed) 5200 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5201 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5202 5203 ins_cost(125); 5204 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5205 ins_encode %{ 5206 __ movsbl($dst$$Register, $mem$$Address); 5207 %} 5208 ins_pipe(ialu_reg_mem); 5209 %} 5210 5211 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5212 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5213 match(Set dst (AndI (LoadI mem) mask)); 5214 5215 ins_cost(125); 5216 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5217 ins_encode %{ 5218 __ movzbl($dst$$Register, $mem$$Address); 5219 %} 5220 ins_pipe(ialu_reg_mem); 5221 %} 5222 5223 // Load Integer (32 bit signed) to Short (16 bit signed) 5224 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5225 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5226 5227 ins_cost(125); 5228 format %{ "movswl $dst, $mem\t# int -> short" %} 5229 ins_encode %{ 5230 __ movswl($dst$$Register, $mem$$Address); 5231 %} 5232 ins_pipe(ialu_reg_mem); 5233 %} 5234 5235 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5236 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5237 match(Set dst (AndI (LoadI mem) mask)); 5238 5239 ins_cost(125); 5240 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5241 ins_encode %{ 5242 __ movzwl($dst$$Register, $mem$$Address); 5243 %} 5244 ins_pipe(ialu_reg_mem); 5245 %} 5246 5247 // Load Integer into Long Register 5248 instruct loadI2L(rRegL dst, memory mem) 5249 %{ 5250 match(Set dst (ConvI2L (LoadI mem))); 5251 5252 ins_cost(125); 5253 format %{ "movslq $dst, $mem\t# int -> long" %} 5254 5255 ins_encode %{ 5256 __ movslq($dst$$Register, $mem$$Address); 5257 %} 5258 5259 ins_pipe(ialu_reg_mem); 5260 %} 5261 5262 // Load Integer with mask 0xFF into Long Register 5263 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5264 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5265 5266 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5267 ins_encode %{ 5268 __ movzbq($dst$$Register, $mem$$Address); 5269 %} 5270 ins_pipe(ialu_reg_mem); 5271 %} 5272 5273 // Load Integer with mask 0xFFFF into Long Register 5274 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5275 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5276 5277 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5278 ins_encode %{ 5279 __ movzwq($dst$$Register, $mem$$Address); 5280 %} 5281 ins_pipe(ialu_reg_mem); 5282 %} 5283 5284 // Load Integer with a 31-bit mask into Long Register 5285 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5286 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5287 effect(KILL cr); 5288 5289 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5290 "andl $dst, $mask" %} 5291 ins_encode %{ 5292 Register Rdst = $dst$$Register; 5293 __ movl(Rdst, $mem$$Address); 5294 __ andl(Rdst, $mask$$constant); 5295 %} 5296 ins_pipe(ialu_reg_mem); 5297 %} 5298 5299 // Load Unsigned Integer into Long Register 5300 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5301 %{ 5302 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5303 5304 ins_cost(125); 5305 format %{ "movl $dst, $mem\t# uint -> long" %} 5306 5307 ins_encode %{ 5308 __ movl($dst$$Register, $mem$$Address); 5309 %} 5310 5311 ins_pipe(ialu_reg_mem); 5312 %} 5313 5314 // Load Long 5315 instruct loadL(rRegL dst, memory mem) 5316 %{ 5317 match(Set dst (LoadL mem)); 5318 5319 ins_cost(125); 5320 format %{ "movq $dst, $mem\t# long" %} 5321 5322 ins_encode %{ 5323 __ movq($dst$$Register, $mem$$Address); 5324 %} 5325 5326 ins_pipe(ialu_reg_mem); // XXX 5327 %} 5328 5329 // Load Range 5330 instruct loadRange(rRegI dst, memory mem) 5331 %{ 5332 match(Set dst (LoadRange mem)); 5333 5334 ins_cost(125); // XXX 5335 format %{ "movl $dst, $mem\t# range" %} 5336 opcode(0x8B); 5337 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5338 ins_pipe(ialu_reg_mem); 5339 %} 5340 5341 // Load Pointer 5342 instruct loadP(rRegP dst, memory mem) 5343 %{ 5344 match(Set dst (LoadP mem)); 5345 5346 ins_cost(125); // XXX 5347 format %{ "movq $dst, $mem\t# ptr" %} 5348 opcode(0x8B); 5349 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5350 ins_pipe(ialu_reg_mem); // XXX 5351 %} 5352 5353 // Load Compressed Pointer 5354 instruct loadN(rRegN dst, memory mem) 5355 %{ 5356 match(Set dst (LoadN mem)); 5357 5358 ins_cost(125); // XXX 5359 format %{ "movl $dst, $mem\t# compressed ptr" %} 5360 ins_encode %{ 5361 __ movl($dst$$Register, $mem$$Address); 5362 %} 5363 ins_pipe(ialu_reg_mem); // XXX 5364 %} 5365 5366 5367 // Load Klass Pointer 5368 instruct loadKlass(rRegP dst, memory mem) 5369 %{ 5370 match(Set dst (LoadKlass mem)); 5371 5372 ins_cost(125); // XXX 5373 format %{ "movq $dst, $mem\t# class\n\t" 5374 "shlq $dst, oopDesc::storage_props_nof_bits\n\t" 5375 "shrq $dst, oopDesc::storage_props_nof_bits" %} 5376 ins_encode %{ 5377 __ movptr($dst$$Register, $mem$$Address); 5378 __ shlq($dst$$Register, oopDesc::storage_props_nof_bits); 5379 __ shrq($dst$$Register, oopDesc::storage_props_nof_bits); 5380 %} 5381 ins_pipe(ialu_reg_mem); // XXX 5382 %} 5383 5384 // Load narrow Klass Pointer 5385 instruct loadNKlass(rRegN dst, memory mem) 5386 %{ 5387 match(Set dst (LoadNKlass mem)); 5388 5389 ins_cost(125); // XXX 5390 format %{ "movl $dst, $mem\t# compressed klass ptr\n\t" 5391 "andl $dst, oopDesc::compressed_klass_mask()" %} 5392 ins_encode %{ 5393 __ movl($dst$$Register, $mem$$Address); 5394 __ andl($dst$$Register, oopDesc::compressed_klass_mask()); 5395 %} 5396 ins_pipe(ialu_reg_mem); // XXX 5397 %} 5398 5399 // Load Float 5400 instruct loadF(regF dst, memory mem) 5401 %{ 5402 match(Set dst (LoadF mem)); 5403 5404 ins_cost(145); // XXX 5405 format %{ "movss $dst, $mem\t# float" %} 5406 ins_encode %{ 5407 __ movflt($dst$$XMMRegister, $mem$$Address); 5408 %} 5409 ins_pipe(pipe_slow); // XXX 5410 %} 5411 5412 // Load Float 5413 instruct MoveF2VL(vlRegF dst, regF src) %{ 5414 match(Set dst src); 5415 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5416 ins_encode %{ 5417 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5418 %} 5419 ins_pipe( fpu_reg_reg ); 5420 %} 5421 5422 // Load Float 5423 instruct MoveF2LEG(legRegF dst, regF src) %{ 5424 match(Set dst src); 5425 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5426 ins_encode %{ 5427 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5428 %} 5429 ins_pipe( fpu_reg_reg ); 5430 %} 5431 5432 // Load Float 5433 instruct MoveVL2F(regF dst, vlRegF src) %{ 5434 match(Set dst src); 5435 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5436 ins_encode %{ 5437 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5438 %} 5439 ins_pipe( fpu_reg_reg ); 5440 %} 5441 5442 // Load Float 5443 instruct MoveLEG2F(regF dst, legRegF src) %{ 5444 match(Set dst src); 5445 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5446 ins_encode %{ 5447 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5448 %} 5449 ins_pipe( fpu_reg_reg ); 5450 %} 5451 5452 // Load Double 5453 instruct loadD_partial(regD dst, memory mem) 5454 %{ 5455 predicate(!UseXmmLoadAndClearUpper); 5456 match(Set dst (LoadD mem)); 5457 5458 ins_cost(145); // XXX 5459 format %{ "movlpd $dst, $mem\t# double" %} 5460 ins_encode %{ 5461 __ movdbl($dst$$XMMRegister, $mem$$Address); 5462 %} 5463 ins_pipe(pipe_slow); // XXX 5464 %} 5465 5466 instruct loadD(regD dst, memory mem) 5467 %{ 5468 predicate(UseXmmLoadAndClearUpper); 5469 match(Set dst (LoadD mem)); 5470 5471 ins_cost(145); // XXX 5472 format %{ "movsd $dst, $mem\t# double" %} 5473 ins_encode %{ 5474 __ movdbl($dst$$XMMRegister, $mem$$Address); 5475 %} 5476 ins_pipe(pipe_slow); // XXX 5477 %} 5478 5479 // Load Double 5480 instruct MoveD2VL(vlRegD dst, regD src) %{ 5481 match(Set dst src); 5482 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5483 ins_encode %{ 5484 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5485 %} 5486 ins_pipe( fpu_reg_reg ); 5487 %} 5488 5489 // Load Double 5490 instruct MoveD2LEG(legRegD dst, regD src) %{ 5491 match(Set dst src); 5492 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5493 ins_encode %{ 5494 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5495 %} 5496 ins_pipe( fpu_reg_reg ); 5497 %} 5498 5499 // Load Double 5500 instruct MoveVL2D(regD dst, vlRegD src) %{ 5501 match(Set dst src); 5502 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5503 ins_encode %{ 5504 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5505 %} 5506 ins_pipe( fpu_reg_reg ); 5507 %} 5508 5509 // Load Double 5510 instruct MoveLEG2D(regD dst, legRegD src) %{ 5511 match(Set dst src); 5512 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5513 ins_encode %{ 5514 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5515 %} 5516 ins_pipe( fpu_reg_reg ); 5517 %} 5518 5519 // Following pseudo code describes the algorithm for max[FD]: 5520 // Min algorithm is on similar lines 5521 // btmp = (b < +0.0) ? a : b 5522 // atmp = (b < +0.0) ? b : a 5523 // Tmp = Max_Float(atmp , btmp) 5524 // Res = (atmp == NaN) ? atmp : Tmp 5525 5526 // max = java.lang.Math.max(float a, float b) 5527 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5528 predicate(UseAVX > 0 && !n->is_reduction()); 5529 match(Set dst (MaxF a b)); 5530 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5531 format %{ 5532 "blendvps $btmp,$b,$a,$b \n\t" 5533 "blendvps $atmp,$a,$b,$b \n\t" 5534 "vmaxss $tmp,$atmp,$btmp \n\t" 5535 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5536 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5537 %} 5538 ins_encode %{ 5539 int vector_len = Assembler::AVX_128bit; 5540 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5541 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5542 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5543 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5544 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5545 %} 5546 ins_pipe( pipe_slow ); 5547 %} 5548 5549 instruct maxF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{ 5550 predicate(UseAVX > 0 && n->is_reduction()); 5551 match(Set dst (MaxF a b)); 5552 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5553 5554 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 5555 ins_encode %{ 5556 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5557 false /*min*/, true /*single*/); 5558 %} 5559 ins_pipe( pipe_slow ); 5560 %} 5561 5562 // max = java.lang.Math.max(double a, double b) 5563 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5564 predicate(UseAVX > 0 && !n->is_reduction()); 5565 match(Set dst (MaxD a b)); 5566 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 5567 format %{ 5568 "blendvpd $btmp,$b,$a,$b \n\t" 5569 "blendvpd $atmp,$a,$b,$b \n\t" 5570 "vmaxsd $tmp,$atmp,$btmp \n\t" 5571 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5572 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5573 %} 5574 ins_encode %{ 5575 int vector_len = Assembler::AVX_128bit; 5576 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5577 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5578 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5579 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5580 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5581 %} 5582 ins_pipe( pipe_slow ); 5583 %} 5584 5585 instruct maxD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{ 5586 predicate(UseAVX > 0 && n->is_reduction()); 5587 match(Set dst (MaxD a b)); 5588 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5589 5590 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 5591 ins_encode %{ 5592 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5593 false /*min*/, false /*single*/); 5594 %} 5595 ins_pipe( pipe_slow ); 5596 %} 5597 5598 // min = java.lang.Math.min(float a, float b) 5599 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5600 predicate(UseAVX > 0 && !n->is_reduction()); 5601 match(Set dst (MinF a b)); 5602 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5603 format %{ 5604 "blendvps $atmp,$a,$b,$a \n\t" 5605 "blendvps $btmp,$b,$a,$a \n\t" 5606 "vminss $tmp,$atmp,$btmp \n\t" 5607 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5608 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5609 %} 5610 ins_encode %{ 5611 int vector_len = Assembler::AVX_128bit; 5612 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5613 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5614 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5615 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5616 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5617 %} 5618 ins_pipe( pipe_slow ); 5619 %} 5620 5621 instruct minF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{ 5622 predicate(UseAVX > 0 && n->is_reduction()); 5623 match(Set dst (MinF a b)); 5624 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5625 5626 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 5627 ins_encode %{ 5628 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5629 true /*min*/, true /*single*/); 5630 %} 5631 ins_pipe( pipe_slow ); 5632 %} 5633 5634 // min = java.lang.Math.min(double a, double b) 5635 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5636 predicate(UseAVX > 0 && !n->is_reduction()); 5637 match(Set dst (MinD a b)); 5638 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5639 format %{ 5640 "blendvpd $atmp,$a,$b,$a \n\t" 5641 "blendvpd $btmp,$b,$a,$a \n\t" 5642 "vminsd $tmp,$atmp,$btmp \n\t" 5643 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5644 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5645 %} 5646 ins_encode %{ 5647 int vector_len = Assembler::AVX_128bit; 5648 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5649 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5650 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5651 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5652 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5653 %} 5654 ins_pipe( pipe_slow ); 5655 %} 5656 5657 instruct minD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{ 5658 predicate(UseAVX > 0 && n->is_reduction()); 5659 match(Set dst (MinD a b)); 5660 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5661 5662 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 5663 ins_encode %{ 5664 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5665 true /*min*/, false /*single*/); 5666 %} 5667 ins_pipe( pipe_slow ); 5668 %} 5669 5670 // Load Effective Address 5671 instruct leaP8(rRegP dst, indOffset8 mem) 5672 %{ 5673 match(Set dst mem); 5674 5675 ins_cost(110); // XXX 5676 format %{ "leaq $dst, $mem\t# ptr 8" %} 5677 opcode(0x8D); 5678 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5679 ins_pipe(ialu_reg_reg_fat); 5680 %} 5681 5682 instruct leaP32(rRegP dst, indOffset32 mem) 5683 %{ 5684 match(Set dst mem); 5685 5686 ins_cost(110); 5687 format %{ "leaq $dst, $mem\t# ptr 32" %} 5688 opcode(0x8D); 5689 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5690 ins_pipe(ialu_reg_reg_fat); 5691 %} 5692 5693 // instruct leaPIdx(rRegP dst, indIndex mem) 5694 // %{ 5695 // match(Set dst mem); 5696 5697 // ins_cost(110); 5698 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5699 // opcode(0x8D); 5700 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5701 // ins_pipe(ialu_reg_reg_fat); 5702 // %} 5703 5704 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5705 %{ 5706 match(Set dst mem); 5707 5708 ins_cost(110); 5709 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5710 opcode(0x8D); 5711 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5712 ins_pipe(ialu_reg_reg_fat); 5713 %} 5714 5715 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5716 %{ 5717 match(Set dst mem); 5718 5719 ins_cost(110); 5720 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5721 opcode(0x8D); 5722 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5723 ins_pipe(ialu_reg_reg_fat); 5724 %} 5725 5726 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5727 %{ 5728 match(Set dst mem); 5729 5730 ins_cost(110); 5731 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5732 opcode(0x8D); 5733 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5734 ins_pipe(ialu_reg_reg_fat); 5735 %} 5736 5737 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5738 %{ 5739 match(Set dst mem); 5740 5741 ins_cost(110); 5742 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5743 opcode(0x8D); 5744 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5745 ins_pipe(ialu_reg_reg_fat); 5746 %} 5747 5748 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5749 %{ 5750 match(Set dst mem); 5751 5752 ins_cost(110); 5753 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5754 opcode(0x8D); 5755 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5756 ins_pipe(ialu_reg_reg_fat); 5757 %} 5758 5759 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5760 %{ 5761 match(Set dst mem); 5762 5763 ins_cost(110); 5764 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5765 opcode(0x8D); 5766 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5767 ins_pipe(ialu_reg_reg_fat); 5768 %} 5769 5770 // Load Effective Address which uses Narrow (32-bits) oop 5771 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5772 %{ 5773 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5774 match(Set dst mem); 5775 5776 ins_cost(110); 5777 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5778 opcode(0x8D); 5779 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5780 ins_pipe(ialu_reg_reg_fat); 5781 %} 5782 5783 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5784 %{ 5785 predicate(Universe::narrow_oop_shift() == 0); 5786 match(Set dst mem); 5787 5788 ins_cost(110); // XXX 5789 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5790 opcode(0x8D); 5791 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5792 ins_pipe(ialu_reg_reg_fat); 5793 %} 5794 5795 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5796 %{ 5797 predicate(Universe::narrow_oop_shift() == 0); 5798 match(Set dst mem); 5799 5800 ins_cost(110); 5801 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5802 opcode(0x8D); 5803 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5804 ins_pipe(ialu_reg_reg_fat); 5805 %} 5806 5807 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5808 %{ 5809 predicate(Universe::narrow_oop_shift() == 0); 5810 match(Set dst mem); 5811 5812 ins_cost(110); 5813 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5814 opcode(0x8D); 5815 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5816 ins_pipe(ialu_reg_reg_fat); 5817 %} 5818 5819 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5820 %{ 5821 predicate(Universe::narrow_oop_shift() == 0); 5822 match(Set dst mem); 5823 5824 ins_cost(110); 5825 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5826 opcode(0x8D); 5827 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5828 ins_pipe(ialu_reg_reg_fat); 5829 %} 5830 5831 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5832 %{ 5833 predicate(Universe::narrow_oop_shift() == 0); 5834 match(Set dst mem); 5835 5836 ins_cost(110); 5837 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5838 opcode(0x8D); 5839 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5840 ins_pipe(ialu_reg_reg_fat); 5841 %} 5842 5843 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5844 %{ 5845 predicate(Universe::narrow_oop_shift() == 0); 5846 match(Set dst mem); 5847 5848 ins_cost(110); 5849 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5850 opcode(0x8D); 5851 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5852 ins_pipe(ialu_reg_reg_fat); 5853 %} 5854 5855 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5856 %{ 5857 predicate(Universe::narrow_oop_shift() == 0); 5858 match(Set dst mem); 5859 5860 ins_cost(110); 5861 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5862 opcode(0x8D); 5863 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5864 ins_pipe(ialu_reg_reg_fat); 5865 %} 5866 5867 instruct loadConI(rRegI dst, immI src) 5868 %{ 5869 match(Set dst src); 5870 5871 format %{ "movl $dst, $src\t# int" %} 5872 ins_encode(load_immI(dst, src)); 5873 ins_pipe(ialu_reg_fat); // XXX 5874 %} 5875 5876 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5877 %{ 5878 match(Set dst src); 5879 effect(KILL cr); 5880 5881 ins_cost(50); 5882 format %{ "xorl $dst, $dst\t# int" %} 5883 opcode(0x33); /* + rd */ 5884 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5885 ins_pipe(ialu_reg); 5886 %} 5887 5888 instruct loadConL(rRegL dst, immL src) 5889 %{ 5890 match(Set dst src); 5891 5892 ins_cost(150); 5893 format %{ "movq $dst, $src\t# long" %} 5894 ins_encode(load_immL(dst, src)); 5895 ins_pipe(ialu_reg); 5896 %} 5897 5898 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5899 %{ 5900 match(Set dst src); 5901 effect(KILL cr); 5902 5903 ins_cost(50); 5904 format %{ "xorl $dst, $dst\t# long" %} 5905 opcode(0x33); /* + rd */ 5906 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5907 ins_pipe(ialu_reg); // XXX 5908 %} 5909 5910 instruct loadConUL32(rRegL dst, immUL32 src) 5911 %{ 5912 match(Set dst src); 5913 5914 ins_cost(60); 5915 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5916 ins_encode(load_immUL32(dst, src)); 5917 ins_pipe(ialu_reg); 5918 %} 5919 5920 instruct loadConL32(rRegL dst, immL32 src) 5921 %{ 5922 match(Set dst src); 5923 5924 ins_cost(70); 5925 format %{ "movq $dst, $src\t# long (32-bit)" %} 5926 ins_encode(load_immL32(dst, src)); 5927 ins_pipe(ialu_reg); 5928 %} 5929 5930 instruct loadConP(rRegP dst, immP con) %{ 5931 match(Set dst con); 5932 5933 format %{ "movq $dst, $con\t# ptr" %} 5934 ins_encode(load_immP(dst, con)); 5935 ins_pipe(ialu_reg_fat); // XXX 5936 %} 5937 5938 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5939 %{ 5940 match(Set dst src); 5941 effect(KILL cr); 5942 5943 ins_cost(50); 5944 format %{ "xorl $dst, $dst\t# ptr" %} 5945 opcode(0x33); /* + rd */ 5946 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5947 ins_pipe(ialu_reg); 5948 %} 5949 5950 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5951 %{ 5952 match(Set dst src); 5953 effect(KILL cr); 5954 5955 ins_cost(60); 5956 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5957 ins_encode(load_immP31(dst, src)); 5958 ins_pipe(ialu_reg); 5959 %} 5960 5961 instruct loadConF(regF dst, immF con) %{ 5962 match(Set dst con); 5963 ins_cost(125); 5964 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5965 ins_encode %{ 5966 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5967 %} 5968 ins_pipe(pipe_slow); 5969 %} 5970 5971 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5972 match(Set dst src); 5973 effect(KILL cr); 5974 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5975 ins_encode %{ 5976 __ xorq($dst$$Register, $dst$$Register); 5977 %} 5978 ins_pipe(ialu_reg); 5979 %} 5980 5981 instruct loadConN(rRegN dst, immN src) %{ 5982 match(Set dst src); 5983 5984 ins_cost(125); 5985 format %{ "movl $dst, $src\t# compressed ptr" %} 5986 ins_encode %{ 5987 address con = (address)$src$$constant; 5988 if (con == NULL) { 5989 ShouldNotReachHere(); 5990 } else { 5991 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5992 } 5993 %} 5994 ins_pipe(ialu_reg_fat); // XXX 5995 %} 5996 5997 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5998 match(Set dst src); 5999 6000 ins_cost(125); 6001 format %{ "movl $dst, $src\t# compressed klass ptr" %} 6002 ins_encode %{ 6003 address con = (address)$src$$constant; 6004 if (con == NULL) { 6005 ShouldNotReachHere(); 6006 } else { 6007 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 6008 } 6009 %} 6010 ins_pipe(ialu_reg_fat); // XXX 6011 %} 6012 6013 instruct loadConF0(regF dst, immF0 src) 6014 %{ 6015 match(Set dst src); 6016 ins_cost(100); 6017 6018 format %{ "xorps $dst, $dst\t# float 0.0" %} 6019 ins_encode %{ 6020 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 6021 %} 6022 ins_pipe(pipe_slow); 6023 %} 6024 6025 // Use the same format since predicate() can not be used here. 6026 instruct loadConD(regD dst, immD con) %{ 6027 match(Set dst con); 6028 ins_cost(125); 6029 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 6030 ins_encode %{ 6031 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 6032 %} 6033 ins_pipe(pipe_slow); 6034 %} 6035 6036 instruct loadConD0(regD dst, immD0 src) 6037 %{ 6038 match(Set dst src); 6039 ins_cost(100); 6040 6041 format %{ "xorpd $dst, $dst\t# double 0.0" %} 6042 ins_encode %{ 6043 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 6044 %} 6045 ins_pipe(pipe_slow); 6046 %} 6047 6048 instruct loadSSI(rRegI dst, stackSlotI src) 6049 %{ 6050 match(Set dst src); 6051 6052 ins_cost(125); 6053 format %{ "movl $dst, $src\t# int stk" %} 6054 opcode(0x8B); 6055 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6056 ins_pipe(ialu_reg_mem); 6057 %} 6058 6059 instruct loadSSL(rRegL dst, stackSlotL src) 6060 %{ 6061 match(Set dst src); 6062 6063 ins_cost(125); 6064 format %{ "movq $dst, $src\t# long stk" %} 6065 opcode(0x8B); 6066 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6067 ins_pipe(ialu_reg_mem); 6068 %} 6069 6070 instruct loadSSP(rRegP dst, stackSlotP src) 6071 %{ 6072 match(Set dst src); 6073 6074 ins_cost(125); 6075 format %{ "movq $dst, $src\t# ptr stk" %} 6076 opcode(0x8B); 6077 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6078 ins_pipe(ialu_reg_mem); 6079 %} 6080 6081 instruct loadSSF(regF dst, stackSlotF src) 6082 %{ 6083 match(Set dst src); 6084 6085 ins_cost(125); 6086 format %{ "movss $dst, $src\t# float stk" %} 6087 ins_encode %{ 6088 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 6089 %} 6090 ins_pipe(pipe_slow); // XXX 6091 %} 6092 6093 // Use the same format since predicate() can not be used here. 6094 instruct loadSSD(regD dst, stackSlotD src) 6095 %{ 6096 match(Set dst src); 6097 6098 ins_cost(125); 6099 format %{ "movsd $dst, $src\t# double stk" %} 6100 ins_encode %{ 6101 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 6102 %} 6103 ins_pipe(pipe_slow); // XXX 6104 %} 6105 6106 // Prefetch instructions for allocation. 6107 // Must be safe to execute with invalid address (cannot fault). 6108 6109 instruct prefetchAlloc( memory mem ) %{ 6110 predicate(AllocatePrefetchInstr==3); 6111 match(PrefetchAllocation mem); 6112 ins_cost(125); 6113 6114 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 6115 ins_encode %{ 6116 __ prefetchw($mem$$Address); 6117 %} 6118 ins_pipe(ialu_mem); 6119 %} 6120 6121 instruct prefetchAllocNTA( memory mem ) %{ 6122 predicate(AllocatePrefetchInstr==0); 6123 match(PrefetchAllocation mem); 6124 ins_cost(125); 6125 6126 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 6127 ins_encode %{ 6128 __ prefetchnta($mem$$Address); 6129 %} 6130 ins_pipe(ialu_mem); 6131 %} 6132 6133 instruct prefetchAllocT0( memory mem ) %{ 6134 predicate(AllocatePrefetchInstr==1); 6135 match(PrefetchAllocation mem); 6136 ins_cost(125); 6137 6138 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 6139 ins_encode %{ 6140 __ prefetcht0($mem$$Address); 6141 %} 6142 ins_pipe(ialu_mem); 6143 %} 6144 6145 instruct prefetchAllocT2( memory mem ) %{ 6146 predicate(AllocatePrefetchInstr==2); 6147 match(PrefetchAllocation mem); 6148 ins_cost(125); 6149 6150 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 6151 ins_encode %{ 6152 __ prefetcht2($mem$$Address); 6153 %} 6154 ins_pipe(ialu_mem); 6155 %} 6156 6157 //----------Store Instructions------------------------------------------------- 6158 6159 // Store Byte 6160 instruct storeB(memory mem, rRegI src) 6161 %{ 6162 match(Set mem (StoreB mem src)); 6163 6164 ins_cost(125); // XXX 6165 format %{ "movb $mem, $src\t# byte" %} 6166 opcode(0x88); 6167 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6168 ins_pipe(ialu_mem_reg); 6169 %} 6170 6171 // Store Char/Short 6172 instruct storeC(memory mem, rRegI src) 6173 %{ 6174 match(Set mem (StoreC mem src)); 6175 6176 ins_cost(125); // XXX 6177 format %{ "movw $mem, $src\t# char/short" %} 6178 opcode(0x89); 6179 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6180 ins_pipe(ialu_mem_reg); 6181 %} 6182 6183 // Store Integer 6184 instruct storeI(memory mem, rRegI src) 6185 %{ 6186 match(Set mem (StoreI mem src)); 6187 6188 ins_cost(125); // XXX 6189 format %{ "movl $mem, $src\t# int" %} 6190 opcode(0x89); 6191 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6192 ins_pipe(ialu_mem_reg); 6193 %} 6194 6195 // Store Long 6196 instruct storeL(memory mem, rRegL src) 6197 %{ 6198 match(Set mem (StoreL mem src)); 6199 6200 ins_cost(125); // XXX 6201 format %{ "movq $mem, $src\t# long" %} 6202 opcode(0x89); 6203 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6204 ins_pipe(ialu_mem_reg); // XXX 6205 %} 6206 6207 // Store Pointer 6208 instruct storeP(memory mem, any_RegP src) 6209 %{ 6210 match(Set mem (StoreP mem src)); 6211 6212 ins_cost(125); // XXX 6213 format %{ "movq $mem, $src\t# ptr" %} 6214 opcode(0x89); 6215 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6216 ins_pipe(ialu_mem_reg); 6217 %} 6218 6219 instruct storeImmP0(memory mem, immP0 zero) 6220 %{ 6221 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6222 match(Set mem (StoreP mem zero)); 6223 6224 ins_cost(125); // XXX 6225 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6226 ins_encode %{ 6227 __ movq($mem$$Address, r12); 6228 %} 6229 ins_pipe(ialu_mem_reg); 6230 %} 6231 6232 // Store NULL Pointer, mark word, or other simple pointer constant. 6233 instruct storeImmP(memory mem, immP31 src) 6234 %{ 6235 match(Set mem (StoreP mem src)); 6236 6237 ins_cost(150); // XXX 6238 format %{ "movq $mem, $src\t# ptr" %} 6239 opcode(0xC7); /* C7 /0 */ 6240 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6241 ins_pipe(ialu_mem_imm); 6242 %} 6243 6244 // Store Compressed Pointer 6245 instruct storeN(memory mem, rRegN src) 6246 %{ 6247 match(Set mem (StoreN mem src)); 6248 6249 ins_cost(125); // XXX 6250 format %{ "movl $mem, $src\t# compressed ptr" %} 6251 ins_encode %{ 6252 __ movl($mem$$Address, $src$$Register); 6253 %} 6254 ins_pipe(ialu_mem_reg); 6255 %} 6256 6257 instruct storeNKlass(memory mem, rRegN src) 6258 %{ 6259 match(Set mem (StoreNKlass mem src)); 6260 6261 ins_cost(125); // XXX 6262 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6263 ins_encode %{ 6264 __ movl($mem$$Address, $src$$Register); 6265 %} 6266 ins_pipe(ialu_mem_reg); 6267 %} 6268 6269 instruct storeImmN0(memory mem, immN0 zero) 6270 %{ 6271 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 6272 match(Set mem (StoreN mem zero)); 6273 6274 ins_cost(125); // XXX 6275 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6276 ins_encode %{ 6277 __ movl($mem$$Address, r12); 6278 %} 6279 ins_pipe(ialu_mem_reg); 6280 %} 6281 6282 instruct storeImmN(memory mem, immN src) 6283 %{ 6284 match(Set mem (StoreN mem src)); 6285 6286 ins_cost(150); // XXX 6287 format %{ "movl $mem, $src\t# compressed ptr" %} 6288 ins_encode %{ 6289 address con = (address)$src$$constant; 6290 if (con == NULL) { 6291 __ movl($mem$$Address, (int32_t)0); 6292 } else { 6293 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6294 } 6295 %} 6296 ins_pipe(ialu_mem_imm); 6297 %} 6298 6299 instruct storeImmNKlass(memory mem, immNKlass src) 6300 %{ 6301 match(Set mem (StoreNKlass mem src)); 6302 6303 ins_cost(150); // XXX 6304 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6305 ins_encode %{ 6306 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6307 %} 6308 ins_pipe(ialu_mem_imm); 6309 %} 6310 6311 // Store Integer Immediate 6312 instruct storeImmI0(memory mem, immI0 zero) 6313 %{ 6314 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6315 match(Set mem (StoreI mem zero)); 6316 6317 ins_cost(125); // XXX 6318 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6319 ins_encode %{ 6320 __ movl($mem$$Address, r12); 6321 %} 6322 ins_pipe(ialu_mem_reg); 6323 %} 6324 6325 instruct storeImmI(memory mem, immI src) 6326 %{ 6327 match(Set mem (StoreI mem src)); 6328 6329 ins_cost(150); 6330 format %{ "movl $mem, $src\t# int" %} 6331 opcode(0xC7); /* C7 /0 */ 6332 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6333 ins_pipe(ialu_mem_imm); 6334 %} 6335 6336 // Store Long Immediate 6337 instruct storeImmL0(memory mem, immL0 zero) 6338 %{ 6339 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6340 match(Set mem (StoreL mem zero)); 6341 6342 ins_cost(125); // XXX 6343 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6344 ins_encode %{ 6345 __ movq($mem$$Address, r12); 6346 %} 6347 ins_pipe(ialu_mem_reg); 6348 %} 6349 6350 instruct storeImmL(memory mem, immL32 src) 6351 %{ 6352 match(Set mem (StoreL mem src)); 6353 6354 ins_cost(150); 6355 format %{ "movq $mem, $src\t# long" %} 6356 opcode(0xC7); /* C7 /0 */ 6357 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6358 ins_pipe(ialu_mem_imm); 6359 %} 6360 6361 // Store Short/Char Immediate 6362 instruct storeImmC0(memory mem, immI0 zero) 6363 %{ 6364 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6365 match(Set mem (StoreC mem zero)); 6366 6367 ins_cost(125); // XXX 6368 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6369 ins_encode %{ 6370 __ movw($mem$$Address, r12); 6371 %} 6372 ins_pipe(ialu_mem_reg); 6373 %} 6374 6375 instruct storeImmI16(memory mem, immI16 src) 6376 %{ 6377 predicate(UseStoreImmI16); 6378 match(Set mem (StoreC mem src)); 6379 6380 ins_cost(150); 6381 format %{ "movw $mem, $src\t# short/char" %} 6382 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6383 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6384 ins_pipe(ialu_mem_imm); 6385 %} 6386 6387 // Store Byte Immediate 6388 instruct storeImmB0(memory mem, immI0 zero) 6389 %{ 6390 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6391 match(Set mem (StoreB mem zero)); 6392 6393 ins_cost(125); // XXX 6394 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6395 ins_encode %{ 6396 __ movb($mem$$Address, r12); 6397 %} 6398 ins_pipe(ialu_mem_reg); 6399 %} 6400 6401 instruct storeImmB(memory mem, immI8 src) 6402 %{ 6403 match(Set mem (StoreB mem src)); 6404 6405 ins_cost(150); // XXX 6406 format %{ "movb $mem, $src\t# byte" %} 6407 opcode(0xC6); /* C6 /0 */ 6408 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6409 ins_pipe(ialu_mem_imm); 6410 %} 6411 6412 // Store CMS card-mark Immediate 6413 instruct storeImmCM0_reg(memory mem, immI0 zero) 6414 %{ 6415 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6416 match(Set mem (StoreCM mem zero)); 6417 6418 ins_cost(125); // XXX 6419 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6420 ins_encode %{ 6421 __ movb($mem$$Address, r12); 6422 %} 6423 ins_pipe(ialu_mem_reg); 6424 %} 6425 6426 instruct storeImmCM0(memory mem, immI0 src) 6427 %{ 6428 match(Set mem (StoreCM mem src)); 6429 6430 ins_cost(150); // XXX 6431 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6432 opcode(0xC6); /* C6 /0 */ 6433 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6434 ins_pipe(ialu_mem_imm); 6435 %} 6436 6437 // Store Float 6438 instruct storeF(memory mem, regF src) 6439 %{ 6440 match(Set mem (StoreF mem src)); 6441 6442 ins_cost(95); // XXX 6443 format %{ "movss $mem, $src\t# float" %} 6444 ins_encode %{ 6445 __ movflt($mem$$Address, $src$$XMMRegister); 6446 %} 6447 ins_pipe(pipe_slow); // XXX 6448 %} 6449 6450 // Store immediate Float value (it is faster than store from XMM register) 6451 instruct storeF0(memory mem, immF0 zero) 6452 %{ 6453 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6454 match(Set mem (StoreF mem zero)); 6455 6456 ins_cost(25); // XXX 6457 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6458 ins_encode %{ 6459 __ movl($mem$$Address, r12); 6460 %} 6461 ins_pipe(ialu_mem_reg); 6462 %} 6463 6464 instruct storeF_imm(memory mem, immF src) 6465 %{ 6466 match(Set mem (StoreF mem src)); 6467 6468 ins_cost(50); 6469 format %{ "movl $mem, $src\t# float" %} 6470 opcode(0xC7); /* C7 /0 */ 6471 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6472 ins_pipe(ialu_mem_imm); 6473 %} 6474 6475 // Store Double 6476 instruct storeD(memory mem, regD src) 6477 %{ 6478 match(Set mem (StoreD mem src)); 6479 6480 ins_cost(95); // XXX 6481 format %{ "movsd $mem, $src\t# double" %} 6482 ins_encode %{ 6483 __ movdbl($mem$$Address, $src$$XMMRegister); 6484 %} 6485 ins_pipe(pipe_slow); // XXX 6486 %} 6487 6488 // Store immediate double 0.0 (it is faster than store from XMM register) 6489 instruct storeD0_imm(memory mem, immD0 src) 6490 %{ 6491 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6492 match(Set mem (StoreD mem src)); 6493 6494 ins_cost(50); 6495 format %{ "movq $mem, $src\t# double 0." %} 6496 opcode(0xC7); /* C7 /0 */ 6497 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6498 ins_pipe(ialu_mem_imm); 6499 %} 6500 6501 instruct storeD0(memory mem, immD0 zero) 6502 %{ 6503 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6504 match(Set mem (StoreD mem zero)); 6505 6506 ins_cost(25); // XXX 6507 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6508 ins_encode %{ 6509 __ movq($mem$$Address, r12); 6510 %} 6511 ins_pipe(ialu_mem_reg); 6512 %} 6513 6514 instruct storeSSI(stackSlotI dst, rRegI src) 6515 %{ 6516 match(Set dst src); 6517 6518 ins_cost(100); 6519 format %{ "movl $dst, $src\t# int stk" %} 6520 opcode(0x89); 6521 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6522 ins_pipe( ialu_mem_reg ); 6523 %} 6524 6525 instruct storeSSL(stackSlotL dst, rRegL src) 6526 %{ 6527 match(Set dst src); 6528 6529 ins_cost(100); 6530 format %{ "movq $dst, $src\t# long stk" %} 6531 opcode(0x89); 6532 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6533 ins_pipe(ialu_mem_reg); 6534 %} 6535 6536 instruct storeSSP(stackSlotP dst, rRegP src) 6537 %{ 6538 match(Set dst src); 6539 6540 ins_cost(100); 6541 format %{ "movq $dst, $src\t# ptr stk" %} 6542 opcode(0x89); 6543 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6544 ins_pipe(ialu_mem_reg); 6545 %} 6546 6547 instruct storeSSF(stackSlotF dst, regF src) 6548 %{ 6549 match(Set dst src); 6550 6551 ins_cost(95); // XXX 6552 format %{ "movss $dst, $src\t# float stk" %} 6553 ins_encode %{ 6554 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6555 %} 6556 ins_pipe(pipe_slow); // XXX 6557 %} 6558 6559 instruct storeSSD(stackSlotD dst, regD src) 6560 %{ 6561 match(Set dst src); 6562 6563 ins_cost(95); // XXX 6564 format %{ "movsd $dst, $src\t# double stk" %} 6565 ins_encode %{ 6566 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6567 %} 6568 ins_pipe(pipe_slow); // XXX 6569 %} 6570 6571 //----------BSWAP Instructions------------------------------------------------- 6572 instruct bytes_reverse_int(rRegI dst) %{ 6573 match(Set dst (ReverseBytesI dst)); 6574 6575 format %{ "bswapl $dst" %} 6576 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6577 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6578 ins_pipe( ialu_reg ); 6579 %} 6580 6581 instruct bytes_reverse_long(rRegL dst) %{ 6582 match(Set dst (ReverseBytesL dst)); 6583 6584 format %{ "bswapq $dst" %} 6585 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6586 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6587 ins_pipe( ialu_reg); 6588 %} 6589 6590 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6591 match(Set dst (ReverseBytesUS dst)); 6592 effect(KILL cr); 6593 6594 format %{ "bswapl $dst\n\t" 6595 "shrl $dst,16\n\t" %} 6596 ins_encode %{ 6597 __ bswapl($dst$$Register); 6598 __ shrl($dst$$Register, 16); 6599 %} 6600 ins_pipe( ialu_reg ); 6601 %} 6602 6603 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6604 match(Set dst (ReverseBytesS dst)); 6605 effect(KILL cr); 6606 6607 format %{ "bswapl $dst\n\t" 6608 "sar $dst,16\n\t" %} 6609 ins_encode %{ 6610 __ bswapl($dst$$Register); 6611 __ sarl($dst$$Register, 16); 6612 %} 6613 ins_pipe( ialu_reg ); 6614 %} 6615 6616 //---------- Zeros Count Instructions ------------------------------------------ 6617 6618 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6619 predicate(UseCountLeadingZerosInstruction); 6620 match(Set dst (CountLeadingZerosI src)); 6621 effect(KILL cr); 6622 6623 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6624 ins_encode %{ 6625 __ lzcntl($dst$$Register, $src$$Register); 6626 %} 6627 ins_pipe(ialu_reg); 6628 %} 6629 6630 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6631 predicate(!UseCountLeadingZerosInstruction); 6632 match(Set dst (CountLeadingZerosI src)); 6633 effect(KILL cr); 6634 6635 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6636 "jnz skip\n\t" 6637 "movl $dst, -1\n" 6638 "skip:\n\t" 6639 "negl $dst\n\t" 6640 "addl $dst, 31" %} 6641 ins_encode %{ 6642 Register Rdst = $dst$$Register; 6643 Register Rsrc = $src$$Register; 6644 Label skip; 6645 __ bsrl(Rdst, Rsrc); 6646 __ jccb(Assembler::notZero, skip); 6647 __ movl(Rdst, -1); 6648 __ bind(skip); 6649 __ negl(Rdst); 6650 __ addl(Rdst, BitsPerInt - 1); 6651 %} 6652 ins_pipe(ialu_reg); 6653 %} 6654 6655 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6656 predicate(UseCountLeadingZerosInstruction); 6657 match(Set dst (CountLeadingZerosL src)); 6658 effect(KILL cr); 6659 6660 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6661 ins_encode %{ 6662 __ lzcntq($dst$$Register, $src$$Register); 6663 %} 6664 ins_pipe(ialu_reg); 6665 %} 6666 6667 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6668 predicate(!UseCountLeadingZerosInstruction); 6669 match(Set dst (CountLeadingZerosL src)); 6670 effect(KILL cr); 6671 6672 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6673 "jnz skip\n\t" 6674 "movl $dst, -1\n" 6675 "skip:\n\t" 6676 "negl $dst\n\t" 6677 "addl $dst, 63" %} 6678 ins_encode %{ 6679 Register Rdst = $dst$$Register; 6680 Register Rsrc = $src$$Register; 6681 Label skip; 6682 __ bsrq(Rdst, Rsrc); 6683 __ jccb(Assembler::notZero, skip); 6684 __ movl(Rdst, -1); 6685 __ bind(skip); 6686 __ negl(Rdst); 6687 __ addl(Rdst, BitsPerLong - 1); 6688 %} 6689 ins_pipe(ialu_reg); 6690 %} 6691 6692 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6693 predicate(UseCountTrailingZerosInstruction); 6694 match(Set dst (CountTrailingZerosI src)); 6695 effect(KILL cr); 6696 6697 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6698 ins_encode %{ 6699 __ tzcntl($dst$$Register, $src$$Register); 6700 %} 6701 ins_pipe(ialu_reg); 6702 %} 6703 6704 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6705 predicate(!UseCountTrailingZerosInstruction); 6706 match(Set dst (CountTrailingZerosI src)); 6707 effect(KILL cr); 6708 6709 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6710 "jnz done\n\t" 6711 "movl $dst, 32\n" 6712 "done:" %} 6713 ins_encode %{ 6714 Register Rdst = $dst$$Register; 6715 Label done; 6716 __ bsfl(Rdst, $src$$Register); 6717 __ jccb(Assembler::notZero, done); 6718 __ movl(Rdst, BitsPerInt); 6719 __ bind(done); 6720 %} 6721 ins_pipe(ialu_reg); 6722 %} 6723 6724 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6725 predicate(UseCountTrailingZerosInstruction); 6726 match(Set dst (CountTrailingZerosL src)); 6727 effect(KILL cr); 6728 6729 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6730 ins_encode %{ 6731 __ tzcntq($dst$$Register, $src$$Register); 6732 %} 6733 ins_pipe(ialu_reg); 6734 %} 6735 6736 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6737 predicate(!UseCountTrailingZerosInstruction); 6738 match(Set dst (CountTrailingZerosL src)); 6739 effect(KILL cr); 6740 6741 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6742 "jnz done\n\t" 6743 "movl $dst, 64\n" 6744 "done:" %} 6745 ins_encode %{ 6746 Register Rdst = $dst$$Register; 6747 Label done; 6748 __ bsfq(Rdst, $src$$Register); 6749 __ jccb(Assembler::notZero, done); 6750 __ movl(Rdst, BitsPerLong); 6751 __ bind(done); 6752 %} 6753 ins_pipe(ialu_reg); 6754 %} 6755 6756 6757 //---------- Population Count Instructions ------------------------------------- 6758 6759 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6760 predicate(UsePopCountInstruction); 6761 match(Set dst (PopCountI src)); 6762 effect(KILL cr); 6763 6764 format %{ "popcnt $dst, $src" %} 6765 ins_encode %{ 6766 __ popcntl($dst$$Register, $src$$Register); 6767 %} 6768 ins_pipe(ialu_reg); 6769 %} 6770 6771 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6772 predicate(UsePopCountInstruction); 6773 match(Set dst (PopCountI (LoadI mem))); 6774 effect(KILL cr); 6775 6776 format %{ "popcnt $dst, $mem" %} 6777 ins_encode %{ 6778 __ popcntl($dst$$Register, $mem$$Address); 6779 %} 6780 ins_pipe(ialu_reg); 6781 %} 6782 6783 // Note: Long.bitCount(long) returns an int. 6784 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6785 predicate(UsePopCountInstruction); 6786 match(Set dst (PopCountL src)); 6787 effect(KILL cr); 6788 6789 format %{ "popcnt $dst, $src" %} 6790 ins_encode %{ 6791 __ popcntq($dst$$Register, $src$$Register); 6792 %} 6793 ins_pipe(ialu_reg); 6794 %} 6795 6796 // Note: Long.bitCount(long) returns an int. 6797 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6798 predicate(UsePopCountInstruction); 6799 match(Set dst (PopCountL (LoadL mem))); 6800 effect(KILL cr); 6801 6802 format %{ "popcnt $dst, $mem" %} 6803 ins_encode %{ 6804 __ popcntq($dst$$Register, $mem$$Address); 6805 %} 6806 ins_pipe(ialu_reg); 6807 %} 6808 6809 6810 //----------MemBar Instructions----------------------------------------------- 6811 // Memory barrier flavors 6812 6813 instruct membar_acquire() 6814 %{ 6815 match(MemBarAcquire); 6816 match(LoadFence); 6817 ins_cost(0); 6818 6819 size(0); 6820 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6821 ins_encode(); 6822 ins_pipe(empty); 6823 %} 6824 6825 instruct membar_acquire_lock() 6826 %{ 6827 match(MemBarAcquireLock); 6828 ins_cost(0); 6829 6830 size(0); 6831 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6832 ins_encode(); 6833 ins_pipe(empty); 6834 %} 6835 6836 instruct membar_release() 6837 %{ 6838 match(MemBarRelease); 6839 match(StoreFence); 6840 ins_cost(0); 6841 6842 size(0); 6843 format %{ "MEMBAR-release ! (empty encoding)" %} 6844 ins_encode(); 6845 ins_pipe(empty); 6846 %} 6847 6848 instruct membar_release_lock() 6849 %{ 6850 match(MemBarReleaseLock); 6851 ins_cost(0); 6852 6853 size(0); 6854 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6855 ins_encode(); 6856 ins_pipe(empty); 6857 %} 6858 6859 instruct membar_volatile(rFlagsReg cr) %{ 6860 match(MemBarVolatile); 6861 effect(KILL cr); 6862 ins_cost(400); 6863 6864 format %{ 6865 $$template 6866 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6867 %} 6868 ins_encode %{ 6869 __ membar(Assembler::StoreLoad); 6870 %} 6871 ins_pipe(pipe_slow); 6872 %} 6873 6874 instruct unnecessary_membar_volatile() 6875 %{ 6876 match(MemBarVolatile); 6877 predicate(Matcher::post_store_load_barrier(n)); 6878 ins_cost(0); 6879 6880 size(0); 6881 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6882 ins_encode(); 6883 ins_pipe(empty); 6884 %} 6885 6886 instruct membar_storestore() %{ 6887 match(MemBarStoreStore); 6888 ins_cost(0); 6889 6890 size(0); 6891 format %{ "MEMBAR-storestore (empty encoding)" %} 6892 ins_encode( ); 6893 ins_pipe(empty); 6894 %} 6895 6896 //----------Move Instructions-------------------------------------------------- 6897 6898 instruct castX2P(rRegP dst, rRegL src) 6899 %{ 6900 match(Set dst (CastX2P src)); 6901 6902 format %{ "movq $dst, $src\t# long->ptr" %} 6903 ins_encode %{ 6904 if ($dst$$reg != $src$$reg) { 6905 __ movptr($dst$$Register, $src$$Register); 6906 } 6907 %} 6908 ins_pipe(ialu_reg_reg); // XXX 6909 %} 6910 6911 instruct castN2X(rRegL dst, rRegN src) 6912 %{ 6913 match(Set dst (CastP2X src)); 6914 6915 format %{ "movq $dst, $src\t# ptr -> long" %} 6916 ins_encode %{ 6917 if ($dst$$reg != $src$$reg) { 6918 __ movptr($dst$$Register, $src$$Register); 6919 } 6920 %} 6921 ins_pipe(ialu_reg_reg); // XXX 6922 %} 6923 6924 instruct castP2X(rRegL dst, rRegP src) 6925 %{ 6926 match(Set dst (CastP2X src)); 6927 6928 format %{ "movq $dst, $src\t# ptr -> long" %} 6929 ins_encode %{ 6930 if ($dst$$reg != $src$$reg) { 6931 __ movptr($dst$$Register, $src$$Register); 6932 } 6933 %} 6934 ins_pipe(ialu_reg_reg); // XXX 6935 %} 6936 6937 // Convert oop into int for vectors alignment masking 6938 instruct convP2I(rRegI dst, rRegP src) 6939 %{ 6940 match(Set dst (ConvL2I (CastP2X src))); 6941 6942 format %{ "movl $dst, $src\t# ptr -> int" %} 6943 ins_encode %{ 6944 __ movl($dst$$Register, $src$$Register); 6945 %} 6946 ins_pipe(ialu_reg_reg); // XXX 6947 %} 6948 6949 // Convert compressed oop into int for vectors alignment masking 6950 // in case of 32bit oops (heap < 4Gb). 6951 instruct convN2I(rRegI dst, rRegN src) 6952 %{ 6953 predicate(Universe::narrow_oop_shift() == 0); 6954 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6955 6956 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6957 ins_encode %{ 6958 __ movl($dst$$Register, $src$$Register); 6959 %} 6960 ins_pipe(ialu_reg_reg); // XXX 6961 %} 6962 6963 // Convert oop pointer into compressed form 6964 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6965 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6966 match(Set dst (EncodeP src)); 6967 effect(KILL cr); 6968 format %{ "encode_heap_oop $dst,$src" %} 6969 ins_encode %{ 6970 Register s = $src$$Register; 6971 Register d = $dst$$Register; 6972 if (s != d) { 6973 __ movq(d, s); 6974 } 6975 __ encode_heap_oop(d); 6976 %} 6977 ins_pipe(ialu_reg_long); 6978 %} 6979 6980 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6981 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6982 match(Set dst (EncodeP src)); 6983 effect(KILL cr); 6984 format %{ "encode_heap_oop_not_null $dst,$src" %} 6985 ins_encode %{ 6986 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6987 %} 6988 ins_pipe(ialu_reg_long); 6989 %} 6990 6991 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6992 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6993 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6994 match(Set dst (DecodeN src)); 6995 effect(KILL cr); 6996 format %{ "decode_heap_oop $dst,$src" %} 6997 ins_encode %{ 6998 Register s = $src$$Register; 6999 Register d = $dst$$Register; 7000 if (s != d) { 7001 __ movq(d, s); 7002 } 7003 __ decode_heap_oop(d); 7004 %} 7005 ins_pipe(ialu_reg_long); 7006 %} 7007 7008 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7009 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7010 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7011 match(Set dst (DecodeN src)); 7012 effect(KILL cr); 7013 format %{ "decode_heap_oop_not_null $dst,$src" %} 7014 ins_encode %{ 7015 Register s = $src$$Register; 7016 Register d = $dst$$Register; 7017 if (s != d) { 7018 __ decode_heap_oop_not_null(d, s); 7019 } else { 7020 __ decode_heap_oop_not_null(d); 7021 } 7022 %} 7023 ins_pipe(ialu_reg_long); 7024 %} 7025 7026 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7027 match(Set dst (EncodePKlass src)); 7028 effect(KILL cr); 7029 format %{ "encode_klass_not_null $dst,$src" %} 7030 ins_encode %{ 7031 __ encode_klass_not_null($dst$$Register, $src$$Register); 7032 %} 7033 ins_pipe(ialu_reg_long); 7034 %} 7035 7036 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7037 match(Set dst (DecodeNKlass src)); 7038 effect(KILL cr); 7039 format %{ "decode_klass_not_null $dst,$src" %} 7040 ins_encode %{ 7041 Register s = $src$$Register; 7042 Register d = $dst$$Register; 7043 if (s != d) { 7044 __ decode_klass_not_null(d, s); 7045 } else { 7046 __ decode_klass_not_null(d); 7047 } 7048 %} 7049 ins_pipe(ialu_reg_long); 7050 %} 7051 7052 7053 //----------Conditional Move--------------------------------------------------- 7054 // Jump 7055 // dummy instruction for generating temp registers 7056 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7057 match(Jump (LShiftL switch_val shift)); 7058 ins_cost(350); 7059 predicate(false); 7060 effect(TEMP dest); 7061 7062 format %{ "leaq $dest, [$constantaddress]\n\t" 7063 "jmp [$dest + $switch_val << $shift]\n\t" %} 7064 ins_encode %{ 7065 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7066 // to do that and the compiler is using that register as one it can allocate. 7067 // So we build it all by hand. 7068 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 7069 // ArrayAddress dispatch(table, index); 7070 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 7071 __ lea($dest$$Register, $constantaddress); 7072 __ jmp(dispatch); 7073 %} 7074 ins_pipe(pipe_jmp); 7075 %} 7076 7077 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7078 match(Jump (AddL (LShiftL switch_val shift) offset)); 7079 ins_cost(350); 7080 effect(TEMP dest); 7081 7082 format %{ "leaq $dest, [$constantaddress]\n\t" 7083 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7084 ins_encode %{ 7085 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7086 // to do that and the compiler is using that register as one it can allocate. 7087 // So we build it all by hand. 7088 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7089 // ArrayAddress dispatch(table, index); 7090 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7091 __ lea($dest$$Register, $constantaddress); 7092 __ jmp(dispatch); 7093 %} 7094 ins_pipe(pipe_jmp); 7095 %} 7096 7097 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7098 match(Jump switch_val); 7099 ins_cost(350); 7100 effect(TEMP dest); 7101 7102 format %{ "leaq $dest, [$constantaddress]\n\t" 7103 "jmp [$dest + $switch_val]\n\t" %} 7104 ins_encode %{ 7105 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7106 // to do that and the compiler is using that register as one it can allocate. 7107 // So we build it all by hand. 7108 // Address index(noreg, switch_reg, Address::times_1); 7109 // ArrayAddress dispatch(table, index); 7110 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 7111 __ lea($dest$$Register, $constantaddress); 7112 __ jmp(dispatch); 7113 %} 7114 ins_pipe(pipe_jmp); 7115 %} 7116 7117 // Conditional move 7118 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 7119 %{ 7120 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7121 7122 ins_cost(200); // XXX 7123 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7124 opcode(0x0F, 0x40); 7125 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7126 ins_pipe(pipe_cmov_reg); 7127 %} 7128 7129 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 7130 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7131 7132 ins_cost(200); // XXX 7133 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7134 opcode(0x0F, 0x40); 7135 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7136 ins_pipe(pipe_cmov_reg); 7137 %} 7138 7139 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 7140 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7141 ins_cost(200); 7142 expand %{ 7143 cmovI_regU(cop, cr, dst, src); 7144 %} 7145 %} 7146 7147 // Conditional move 7148 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7149 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7150 7151 ins_cost(250); // XXX 7152 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7153 opcode(0x0F, 0x40); 7154 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7155 ins_pipe(pipe_cmov_mem); 7156 %} 7157 7158 // Conditional move 7159 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7160 %{ 7161 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7162 7163 ins_cost(250); // XXX 7164 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7165 opcode(0x0F, 0x40); 7166 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7167 ins_pipe(pipe_cmov_mem); 7168 %} 7169 7170 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7171 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7172 ins_cost(250); 7173 expand %{ 7174 cmovI_memU(cop, cr, dst, src); 7175 %} 7176 %} 7177 7178 // Conditional move 7179 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7180 %{ 7181 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7182 7183 ins_cost(200); // XXX 7184 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7185 opcode(0x0F, 0x40); 7186 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7187 ins_pipe(pipe_cmov_reg); 7188 %} 7189 7190 // Conditional move 7191 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7192 %{ 7193 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7194 7195 ins_cost(200); // XXX 7196 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7197 opcode(0x0F, 0x40); 7198 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7199 ins_pipe(pipe_cmov_reg); 7200 %} 7201 7202 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7203 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7204 ins_cost(200); 7205 expand %{ 7206 cmovN_regU(cop, cr, dst, src); 7207 %} 7208 %} 7209 7210 // Conditional move 7211 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7212 %{ 7213 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7214 7215 ins_cost(200); // XXX 7216 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7217 opcode(0x0F, 0x40); 7218 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7219 ins_pipe(pipe_cmov_reg); // XXX 7220 %} 7221 7222 // Conditional move 7223 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7224 %{ 7225 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7226 7227 ins_cost(200); // XXX 7228 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7229 opcode(0x0F, 0x40); 7230 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7231 ins_pipe(pipe_cmov_reg); // XXX 7232 %} 7233 7234 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7235 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7236 ins_cost(200); 7237 expand %{ 7238 cmovP_regU(cop, cr, dst, src); 7239 %} 7240 %} 7241 7242 // DISABLED: Requires the ADLC to emit a bottom_type call that 7243 // correctly meets the two pointer arguments; one is an incoming 7244 // register but the other is a memory operand. ALSO appears to 7245 // be buggy with implicit null checks. 7246 // 7247 //// Conditional move 7248 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7249 //%{ 7250 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7251 // ins_cost(250); 7252 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7253 // opcode(0x0F,0x40); 7254 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7255 // ins_pipe( pipe_cmov_mem ); 7256 //%} 7257 // 7258 //// Conditional move 7259 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7260 //%{ 7261 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7262 // ins_cost(250); 7263 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7264 // opcode(0x0F,0x40); 7265 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7266 // ins_pipe( pipe_cmov_mem ); 7267 //%} 7268 7269 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7270 %{ 7271 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7272 7273 ins_cost(200); // XXX 7274 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7275 opcode(0x0F, 0x40); 7276 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7277 ins_pipe(pipe_cmov_reg); // XXX 7278 %} 7279 7280 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7281 %{ 7282 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7283 7284 ins_cost(200); // XXX 7285 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7286 opcode(0x0F, 0x40); 7287 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7288 ins_pipe(pipe_cmov_mem); // XXX 7289 %} 7290 7291 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7292 %{ 7293 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7294 7295 ins_cost(200); // XXX 7296 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7297 opcode(0x0F, 0x40); 7298 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7299 ins_pipe(pipe_cmov_reg); // XXX 7300 %} 7301 7302 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7303 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7304 ins_cost(200); 7305 expand %{ 7306 cmovL_regU(cop, cr, dst, src); 7307 %} 7308 %} 7309 7310 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7311 %{ 7312 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7313 7314 ins_cost(200); // XXX 7315 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7316 opcode(0x0F, 0x40); 7317 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7318 ins_pipe(pipe_cmov_mem); // XXX 7319 %} 7320 7321 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7322 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7323 ins_cost(200); 7324 expand %{ 7325 cmovL_memU(cop, cr, dst, src); 7326 %} 7327 %} 7328 7329 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7330 %{ 7331 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7332 7333 ins_cost(200); // XXX 7334 format %{ "jn$cop skip\t# signed cmove float\n\t" 7335 "movss $dst, $src\n" 7336 "skip:" %} 7337 ins_encode %{ 7338 Label Lskip; 7339 // Invert sense of branch from sense of CMOV 7340 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7341 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7342 __ bind(Lskip); 7343 %} 7344 ins_pipe(pipe_slow); 7345 %} 7346 7347 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7348 // %{ 7349 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7350 7351 // ins_cost(200); // XXX 7352 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7353 // "movss $dst, $src\n" 7354 // "skip:" %} 7355 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7356 // ins_pipe(pipe_slow); 7357 // %} 7358 7359 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7360 %{ 7361 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7362 7363 ins_cost(200); // XXX 7364 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7365 "movss $dst, $src\n" 7366 "skip:" %} 7367 ins_encode %{ 7368 Label Lskip; 7369 // Invert sense of branch from sense of CMOV 7370 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7371 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7372 __ bind(Lskip); 7373 %} 7374 ins_pipe(pipe_slow); 7375 %} 7376 7377 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7378 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7379 ins_cost(200); 7380 expand %{ 7381 cmovF_regU(cop, cr, dst, src); 7382 %} 7383 %} 7384 7385 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7386 %{ 7387 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7388 7389 ins_cost(200); // XXX 7390 format %{ "jn$cop skip\t# signed cmove double\n\t" 7391 "movsd $dst, $src\n" 7392 "skip:" %} 7393 ins_encode %{ 7394 Label Lskip; 7395 // Invert sense of branch from sense of CMOV 7396 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7397 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7398 __ bind(Lskip); 7399 %} 7400 ins_pipe(pipe_slow); 7401 %} 7402 7403 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7404 %{ 7405 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7406 7407 ins_cost(200); // XXX 7408 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7409 "movsd $dst, $src\n" 7410 "skip:" %} 7411 ins_encode %{ 7412 Label Lskip; 7413 // Invert sense of branch from sense of CMOV 7414 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7415 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7416 __ bind(Lskip); 7417 %} 7418 ins_pipe(pipe_slow); 7419 %} 7420 7421 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7422 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7423 ins_cost(200); 7424 expand %{ 7425 cmovD_regU(cop, cr, dst, src); 7426 %} 7427 %} 7428 7429 //----------Arithmetic Instructions-------------------------------------------- 7430 //----------Addition Instructions---------------------------------------------- 7431 7432 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7433 %{ 7434 match(Set dst (AddI dst src)); 7435 effect(KILL cr); 7436 7437 format %{ "addl $dst, $src\t# int" %} 7438 opcode(0x03); 7439 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7440 ins_pipe(ialu_reg_reg); 7441 %} 7442 7443 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7444 %{ 7445 match(Set dst (AddI dst src)); 7446 effect(KILL cr); 7447 7448 format %{ "addl $dst, $src\t# int" %} 7449 opcode(0x81, 0x00); /* /0 id */ 7450 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7451 ins_pipe( ialu_reg ); 7452 %} 7453 7454 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7455 %{ 7456 match(Set dst (AddI dst (LoadI src))); 7457 effect(KILL cr); 7458 7459 ins_cost(125); // XXX 7460 format %{ "addl $dst, $src\t# int" %} 7461 opcode(0x03); 7462 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7463 ins_pipe(ialu_reg_mem); 7464 %} 7465 7466 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7467 %{ 7468 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7469 effect(KILL cr); 7470 7471 ins_cost(150); // XXX 7472 format %{ "addl $dst, $src\t# int" %} 7473 opcode(0x01); /* Opcode 01 /r */ 7474 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7475 ins_pipe(ialu_mem_reg); 7476 %} 7477 7478 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7479 %{ 7480 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7481 effect(KILL cr); 7482 7483 ins_cost(125); // XXX 7484 format %{ "addl $dst, $src\t# int" %} 7485 opcode(0x81); /* Opcode 81 /0 id */ 7486 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7487 ins_pipe(ialu_mem_imm); 7488 %} 7489 7490 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7491 %{ 7492 predicate(UseIncDec); 7493 match(Set dst (AddI dst src)); 7494 effect(KILL cr); 7495 7496 format %{ "incl $dst\t# int" %} 7497 opcode(0xFF, 0x00); // FF /0 7498 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7499 ins_pipe(ialu_reg); 7500 %} 7501 7502 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7503 %{ 7504 predicate(UseIncDec); 7505 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7506 effect(KILL cr); 7507 7508 ins_cost(125); // XXX 7509 format %{ "incl $dst\t# int" %} 7510 opcode(0xFF); /* Opcode FF /0 */ 7511 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7512 ins_pipe(ialu_mem_imm); 7513 %} 7514 7515 // XXX why does that use AddI 7516 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7517 %{ 7518 predicate(UseIncDec); 7519 match(Set dst (AddI dst src)); 7520 effect(KILL cr); 7521 7522 format %{ "decl $dst\t# int" %} 7523 opcode(0xFF, 0x01); // FF /1 7524 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7525 ins_pipe(ialu_reg); 7526 %} 7527 7528 // XXX why does that use AddI 7529 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7530 %{ 7531 predicate(UseIncDec); 7532 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7533 effect(KILL cr); 7534 7535 ins_cost(125); // XXX 7536 format %{ "decl $dst\t# int" %} 7537 opcode(0xFF); /* Opcode FF /1 */ 7538 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7539 ins_pipe(ialu_mem_imm); 7540 %} 7541 7542 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7543 %{ 7544 match(Set dst (AddI src0 src1)); 7545 7546 ins_cost(110); 7547 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7548 opcode(0x8D); /* 0x8D /r */ 7549 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7550 ins_pipe(ialu_reg_reg); 7551 %} 7552 7553 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7554 %{ 7555 match(Set dst (AddL dst src)); 7556 effect(KILL cr); 7557 7558 format %{ "addq $dst, $src\t# long" %} 7559 opcode(0x03); 7560 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7561 ins_pipe(ialu_reg_reg); 7562 %} 7563 7564 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7565 %{ 7566 match(Set dst (AddL dst src)); 7567 effect(KILL cr); 7568 7569 format %{ "addq $dst, $src\t# long" %} 7570 opcode(0x81, 0x00); /* /0 id */ 7571 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7572 ins_pipe( ialu_reg ); 7573 %} 7574 7575 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7576 %{ 7577 match(Set dst (AddL dst (LoadL src))); 7578 effect(KILL cr); 7579 7580 ins_cost(125); // XXX 7581 format %{ "addq $dst, $src\t# long" %} 7582 opcode(0x03); 7583 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7584 ins_pipe(ialu_reg_mem); 7585 %} 7586 7587 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7588 %{ 7589 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7590 effect(KILL cr); 7591 7592 ins_cost(150); // XXX 7593 format %{ "addq $dst, $src\t# long" %} 7594 opcode(0x01); /* Opcode 01 /r */ 7595 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7596 ins_pipe(ialu_mem_reg); 7597 %} 7598 7599 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7600 %{ 7601 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7602 effect(KILL cr); 7603 7604 ins_cost(125); // XXX 7605 format %{ "addq $dst, $src\t# long" %} 7606 opcode(0x81); /* Opcode 81 /0 id */ 7607 ins_encode(REX_mem_wide(dst), 7608 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7609 ins_pipe(ialu_mem_imm); 7610 %} 7611 7612 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7613 %{ 7614 predicate(UseIncDec); 7615 match(Set dst (AddL dst src)); 7616 effect(KILL cr); 7617 7618 format %{ "incq $dst\t# long" %} 7619 opcode(0xFF, 0x00); // FF /0 7620 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7621 ins_pipe(ialu_reg); 7622 %} 7623 7624 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7625 %{ 7626 predicate(UseIncDec); 7627 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7628 effect(KILL cr); 7629 7630 ins_cost(125); // XXX 7631 format %{ "incq $dst\t# long" %} 7632 opcode(0xFF); /* Opcode FF /0 */ 7633 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7634 ins_pipe(ialu_mem_imm); 7635 %} 7636 7637 // XXX why does that use AddL 7638 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7639 %{ 7640 predicate(UseIncDec); 7641 match(Set dst (AddL dst src)); 7642 effect(KILL cr); 7643 7644 format %{ "decq $dst\t# long" %} 7645 opcode(0xFF, 0x01); // FF /1 7646 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7647 ins_pipe(ialu_reg); 7648 %} 7649 7650 // XXX why does that use AddL 7651 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7652 %{ 7653 predicate(UseIncDec); 7654 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7655 effect(KILL cr); 7656 7657 ins_cost(125); // XXX 7658 format %{ "decq $dst\t# long" %} 7659 opcode(0xFF); /* Opcode FF /1 */ 7660 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7661 ins_pipe(ialu_mem_imm); 7662 %} 7663 7664 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7665 %{ 7666 match(Set dst (AddL src0 src1)); 7667 7668 ins_cost(110); 7669 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7670 opcode(0x8D); /* 0x8D /r */ 7671 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7672 ins_pipe(ialu_reg_reg); 7673 %} 7674 7675 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7676 %{ 7677 match(Set dst (AddP dst src)); 7678 effect(KILL cr); 7679 7680 format %{ "addq $dst, $src\t# ptr" %} 7681 opcode(0x03); 7682 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7683 ins_pipe(ialu_reg_reg); 7684 %} 7685 7686 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7687 %{ 7688 match(Set dst (AddP dst src)); 7689 effect(KILL cr); 7690 7691 format %{ "addq $dst, $src\t# ptr" %} 7692 opcode(0x81, 0x00); /* /0 id */ 7693 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7694 ins_pipe( ialu_reg ); 7695 %} 7696 7697 // XXX addP mem ops ???? 7698 7699 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7700 %{ 7701 match(Set dst (AddP src0 src1)); 7702 7703 ins_cost(110); 7704 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7705 opcode(0x8D); /* 0x8D /r */ 7706 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7707 ins_pipe(ialu_reg_reg); 7708 %} 7709 7710 instruct checkCastPP(rRegP dst) 7711 %{ 7712 match(Set dst (CheckCastPP dst)); 7713 7714 size(0); 7715 format %{ "# checkcastPP of $dst" %} 7716 ins_encode(/* empty encoding */); 7717 ins_pipe(empty); 7718 %} 7719 7720 instruct castPP(rRegP dst) 7721 %{ 7722 match(Set dst (CastPP dst)); 7723 7724 size(0); 7725 format %{ "# castPP of $dst" %} 7726 ins_encode(/* empty encoding */); 7727 ins_pipe(empty); 7728 %} 7729 7730 instruct castII(rRegI dst) 7731 %{ 7732 match(Set dst (CastII dst)); 7733 7734 size(0); 7735 format %{ "# castII of $dst" %} 7736 ins_encode(/* empty encoding */); 7737 ins_cost(0); 7738 ins_pipe(empty); 7739 %} 7740 7741 // LoadP-locked same as a regular LoadP when used with compare-swap 7742 instruct loadPLocked(rRegP dst, memory mem) 7743 %{ 7744 match(Set dst (LoadPLocked mem)); 7745 7746 ins_cost(125); // XXX 7747 format %{ "movq $dst, $mem\t# ptr locked" %} 7748 opcode(0x8B); 7749 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7750 ins_pipe(ialu_reg_mem); // XXX 7751 %} 7752 7753 // Conditional-store of the updated heap-top. 7754 // Used during allocation of the shared heap. 7755 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7756 7757 instruct storePConditional(memory heap_top_ptr, 7758 rax_RegP oldval, rRegP newval, 7759 rFlagsReg cr) 7760 %{ 7761 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7762 7763 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7764 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7765 opcode(0x0F, 0xB1); 7766 ins_encode(lock_prefix, 7767 REX_reg_mem_wide(newval, heap_top_ptr), 7768 OpcP, OpcS, 7769 reg_mem(newval, heap_top_ptr)); 7770 ins_pipe(pipe_cmpxchg); 7771 %} 7772 7773 // Conditional-store of an int value. 7774 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7775 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7776 %{ 7777 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7778 effect(KILL oldval); 7779 7780 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7781 opcode(0x0F, 0xB1); 7782 ins_encode(lock_prefix, 7783 REX_reg_mem(newval, mem), 7784 OpcP, OpcS, 7785 reg_mem(newval, mem)); 7786 ins_pipe(pipe_cmpxchg); 7787 %} 7788 7789 // Conditional-store of a long value. 7790 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7791 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7792 %{ 7793 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7794 effect(KILL oldval); 7795 7796 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7797 opcode(0x0F, 0xB1); 7798 ins_encode(lock_prefix, 7799 REX_reg_mem_wide(newval, mem), 7800 OpcP, OpcS, 7801 reg_mem(newval, mem)); 7802 ins_pipe(pipe_cmpxchg); 7803 %} 7804 7805 7806 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7807 instruct compareAndSwapP(rRegI res, 7808 memory mem_ptr, 7809 rax_RegP oldval, rRegP newval, 7810 rFlagsReg cr) 7811 %{ 7812 predicate(VM_Version::supports_cx8()); 7813 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7814 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7815 effect(KILL cr, KILL oldval); 7816 7817 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7818 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7819 "sete $res\n\t" 7820 "movzbl $res, $res" %} 7821 opcode(0x0F, 0xB1); 7822 ins_encode(lock_prefix, 7823 REX_reg_mem_wide(newval, mem_ptr), 7824 OpcP, OpcS, 7825 reg_mem(newval, mem_ptr), 7826 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7827 REX_reg_breg(res, res), // movzbl 7828 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7829 ins_pipe( pipe_cmpxchg ); 7830 %} 7831 7832 instruct compareAndSwapL(rRegI res, 7833 memory mem_ptr, 7834 rax_RegL oldval, rRegL newval, 7835 rFlagsReg cr) 7836 %{ 7837 predicate(VM_Version::supports_cx8()); 7838 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7839 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7840 effect(KILL cr, KILL oldval); 7841 7842 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7843 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7844 "sete $res\n\t" 7845 "movzbl $res, $res" %} 7846 opcode(0x0F, 0xB1); 7847 ins_encode(lock_prefix, 7848 REX_reg_mem_wide(newval, mem_ptr), 7849 OpcP, OpcS, 7850 reg_mem(newval, mem_ptr), 7851 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7852 REX_reg_breg(res, res), // movzbl 7853 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7854 ins_pipe( pipe_cmpxchg ); 7855 %} 7856 7857 instruct compareAndSwapI(rRegI res, 7858 memory mem_ptr, 7859 rax_RegI oldval, rRegI newval, 7860 rFlagsReg cr) 7861 %{ 7862 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7863 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7864 effect(KILL cr, KILL oldval); 7865 7866 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7867 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7868 "sete $res\n\t" 7869 "movzbl $res, $res" %} 7870 opcode(0x0F, 0xB1); 7871 ins_encode(lock_prefix, 7872 REX_reg_mem(newval, mem_ptr), 7873 OpcP, OpcS, 7874 reg_mem(newval, mem_ptr), 7875 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7876 REX_reg_breg(res, res), // movzbl 7877 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7878 ins_pipe( pipe_cmpxchg ); 7879 %} 7880 7881 instruct compareAndSwapB(rRegI res, 7882 memory mem_ptr, 7883 rax_RegI oldval, rRegI newval, 7884 rFlagsReg cr) 7885 %{ 7886 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7887 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7888 effect(KILL cr, KILL oldval); 7889 7890 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7891 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7892 "sete $res\n\t" 7893 "movzbl $res, $res" %} 7894 opcode(0x0F, 0xB0); 7895 ins_encode(lock_prefix, 7896 REX_breg_mem(newval, mem_ptr), 7897 OpcP, OpcS, 7898 reg_mem(newval, mem_ptr), 7899 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7900 REX_reg_breg(res, res), // movzbl 7901 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7902 ins_pipe( pipe_cmpxchg ); 7903 %} 7904 7905 instruct compareAndSwapS(rRegI res, 7906 memory mem_ptr, 7907 rax_RegI oldval, rRegI newval, 7908 rFlagsReg cr) 7909 %{ 7910 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7911 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7912 effect(KILL cr, KILL oldval); 7913 7914 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7915 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7916 "sete $res\n\t" 7917 "movzbl $res, $res" %} 7918 opcode(0x0F, 0xB1); 7919 ins_encode(lock_prefix, 7920 SizePrefix, 7921 REX_reg_mem(newval, mem_ptr), 7922 OpcP, OpcS, 7923 reg_mem(newval, mem_ptr), 7924 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7925 REX_reg_breg(res, res), // movzbl 7926 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7927 ins_pipe( pipe_cmpxchg ); 7928 %} 7929 7930 instruct compareAndSwapN(rRegI res, 7931 memory mem_ptr, 7932 rax_RegN oldval, rRegN newval, 7933 rFlagsReg cr) %{ 7934 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7935 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7936 effect(KILL cr, KILL oldval); 7937 7938 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7939 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7940 "sete $res\n\t" 7941 "movzbl $res, $res" %} 7942 opcode(0x0F, 0xB1); 7943 ins_encode(lock_prefix, 7944 REX_reg_mem(newval, mem_ptr), 7945 OpcP, OpcS, 7946 reg_mem(newval, mem_ptr), 7947 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7948 REX_reg_breg(res, res), // movzbl 7949 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7950 ins_pipe( pipe_cmpxchg ); 7951 %} 7952 7953 instruct compareAndExchangeB( 7954 memory mem_ptr, 7955 rax_RegI oldval, rRegI newval, 7956 rFlagsReg cr) 7957 %{ 7958 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7959 effect(KILL cr); 7960 7961 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7962 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7963 opcode(0x0F, 0xB0); 7964 ins_encode(lock_prefix, 7965 REX_breg_mem(newval, mem_ptr), 7966 OpcP, OpcS, 7967 reg_mem(newval, mem_ptr) // lock cmpxchg 7968 ); 7969 ins_pipe( pipe_cmpxchg ); 7970 %} 7971 7972 instruct compareAndExchangeS( 7973 memory mem_ptr, 7974 rax_RegI oldval, rRegI newval, 7975 rFlagsReg cr) 7976 %{ 7977 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7978 effect(KILL cr); 7979 7980 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7981 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7982 opcode(0x0F, 0xB1); 7983 ins_encode(lock_prefix, 7984 SizePrefix, 7985 REX_reg_mem(newval, mem_ptr), 7986 OpcP, OpcS, 7987 reg_mem(newval, mem_ptr) // lock cmpxchg 7988 ); 7989 ins_pipe( pipe_cmpxchg ); 7990 %} 7991 7992 instruct compareAndExchangeI( 7993 memory mem_ptr, 7994 rax_RegI oldval, rRegI newval, 7995 rFlagsReg cr) 7996 %{ 7997 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7998 effect(KILL cr); 7999 8000 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8001 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8002 opcode(0x0F, 0xB1); 8003 ins_encode(lock_prefix, 8004 REX_reg_mem(newval, mem_ptr), 8005 OpcP, OpcS, 8006 reg_mem(newval, mem_ptr) // lock cmpxchg 8007 ); 8008 ins_pipe( pipe_cmpxchg ); 8009 %} 8010 8011 instruct compareAndExchangeL( 8012 memory mem_ptr, 8013 rax_RegL oldval, rRegL newval, 8014 rFlagsReg cr) 8015 %{ 8016 predicate(VM_Version::supports_cx8()); 8017 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 8018 effect(KILL cr); 8019 8020 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8021 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8022 opcode(0x0F, 0xB1); 8023 ins_encode(lock_prefix, 8024 REX_reg_mem_wide(newval, mem_ptr), 8025 OpcP, OpcS, 8026 reg_mem(newval, mem_ptr) // lock cmpxchg 8027 ); 8028 ins_pipe( pipe_cmpxchg ); 8029 %} 8030 8031 instruct compareAndExchangeN( 8032 memory mem_ptr, 8033 rax_RegN oldval, rRegN newval, 8034 rFlagsReg cr) %{ 8035 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 8036 effect(KILL cr); 8037 8038 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8039 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8040 opcode(0x0F, 0xB1); 8041 ins_encode(lock_prefix, 8042 REX_reg_mem(newval, mem_ptr), 8043 OpcP, OpcS, 8044 reg_mem(newval, mem_ptr) // lock cmpxchg 8045 ); 8046 ins_pipe( pipe_cmpxchg ); 8047 %} 8048 8049 instruct compareAndExchangeP( 8050 memory mem_ptr, 8051 rax_RegP oldval, rRegP newval, 8052 rFlagsReg cr) 8053 %{ 8054 predicate(VM_Version::supports_cx8()); 8055 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 8056 effect(KILL cr); 8057 8058 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8059 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8060 opcode(0x0F, 0xB1); 8061 ins_encode(lock_prefix, 8062 REX_reg_mem_wide(newval, mem_ptr), 8063 OpcP, OpcS, 8064 reg_mem(newval, mem_ptr) // lock cmpxchg 8065 ); 8066 ins_pipe( pipe_cmpxchg ); 8067 %} 8068 8069 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8070 predicate(n->as_LoadStore()->result_not_used()); 8071 match(Set dummy (GetAndAddB mem add)); 8072 effect(KILL cr); 8073 format %{ "ADDB [$mem],$add" %} 8074 ins_encode %{ 8075 __ lock(); 8076 __ addb($mem$$Address, $add$$constant); 8077 %} 8078 ins_pipe( pipe_cmpxchg ); 8079 %} 8080 8081 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 8082 match(Set newval (GetAndAddB mem newval)); 8083 effect(KILL cr); 8084 format %{ "XADDB [$mem],$newval" %} 8085 ins_encode %{ 8086 __ lock(); 8087 __ xaddb($mem$$Address, $newval$$Register); 8088 %} 8089 ins_pipe( pipe_cmpxchg ); 8090 %} 8091 8092 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8093 predicate(n->as_LoadStore()->result_not_used()); 8094 match(Set dummy (GetAndAddS mem add)); 8095 effect(KILL cr); 8096 format %{ "ADDW [$mem],$add" %} 8097 ins_encode %{ 8098 __ lock(); 8099 __ addw($mem$$Address, $add$$constant); 8100 %} 8101 ins_pipe( pipe_cmpxchg ); 8102 %} 8103 8104 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 8105 match(Set newval (GetAndAddS mem newval)); 8106 effect(KILL cr); 8107 format %{ "XADDW [$mem],$newval" %} 8108 ins_encode %{ 8109 __ lock(); 8110 __ xaddw($mem$$Address, $newval$$Register); 8111 %} 8112 ins_pipe( pipe_cmpxchg ); 8113 %} 8114 8115 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8116 predicate(n->as_LoadStore()->result_not_used()); 8117 match(Set dummy (GetAndAddI mem add)); 8118 effect(KILL cr); 8119 format %{ "ADDL [$mem],$add" %} 8120 ins_encode %{ 8121 __ lock(); 8122 __ addl($mem$$Address, $add$$constant); 8123 %} 8124 ins_pipe( pipe_cmpxchg ); 8125 %} 8126 8127 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 8128 match(Set newval (GetAndAddI mem newval)); 8129 effect(KILL cr); 8130 format %{ "XADDL [$mem],$newval" %} 8131 ins_encode %{ 8132 __ lock(); 8133 __ xaddl($mem$$Address, $newval$$Register); 8134 %} 8135 ins_pipe( pipe_cmpxchg ); 8136 %} 8137 8138 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8139 predicate(n->as_LoadStore()->result_not_used()); 8140 match(Set dummy (GetAndAddL mem add)); 8141 effect(KILL cr); 8142 format %{ "ADDQ [$mem],$add" %} 8143 ins_encode %{ 8144 __ lock(); 8145 __ addq($mem$$Address, $add$$constant); 8146 %} 8147 ins_pipe( pipe_cmpxchg ); 8148 %} 8149 8150 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 8151 match(Set newval (GetAndAddL mem newval)); 8152 effect(KILL cr); 8153 format %{ "XADDQ [$mem],$newval" %} 8154 ins_encode %{ 8155 __ lock(); 8156 __ xaddq($mem$$Address, $newval$$Register); 8157 %} 8158 ins_pipe( pipe_cmpxchg ); 8159 %} 8160 8161 instruct xchgB( memory mem, rRegI newval) %{ 8162 match(Set newval (GetAndSetB mem newval)); 8163 format %{ "XCHGB $newval,[$mem]" %} 8164 ins_encode %{ 8165 __ xchgb($newval$$Register, $mem$$Address); 8166 %} 8167 ins_pipe( pipe_cmpxchg ); 8168 %} 8169 8170 instruct xchgS( memory mem, rRegI newval) %{ 8171 match(Set newval (GetAndSetS mem newval)); 8172 format %{ "XCHGW $newval,[$mem]" %} 8173 ins_encode %{ 8174 __ xchgw($newval$$Register, $mem$$Address); 8175 %} 8176 ins_pipe( pipe_cmpxchg ); 8177 %} 8178 8179 instruct xchgI( memory mem, rRegI newval) %{ 8180 match(Set newval (GetAndSetI mem newval)); 8181 format %{ "XCHGL $newval,[$mem]" %} 8182 ins_encode %{ 8183 __ xchgl($newval$$Register, $mem$$Address); 8184 %} 8185 ins_pipe( pipe_cmpxchg ); 8186 %} 8187 8188 instruct xchgL( memory mem, rRegL newval) %{ 8189 match(Set newval (GetAndSetL mem newval)); 8190 format %{ "XCHGL $newval,[$mem]" %} 8191 ins_encode %{ 8192 __ xchgq($newval$$Register, $mem$$Address); 8193 %} 8194 ins_pipe( pipe_cmpxchg ); 8195 %} 8196 8197 instruct xchgP( memory mem, rRegP newval) %{ 8198 match(Set newval (GetAndSetP mem newval)); 8199 format %{ "XCHGQ $newval,[$mem]" %} 8200 ins_encode %{ 8201 __ xchgq($newval$$Register, $mem$$Address); 8202 %} 8203 ins_pipe( pipe_cmpxchg ); 8204 %} 8205 8206 instruct xchgN( memory mem, rRegN newval) %{ 8207 match(Set newval (GetAndSetN mem newval)); 8208 format %{ "XCHGL $newval,$mem]" %} 8209 ins_encode %{ 8210 __ xchgl($newval$$Register, $mem$$Address); 8211 %} 8212 ins_pipe( pipe_cmpxchg ); 8213 %} 8214 8215 //----------Subtraction Instructions------------------------------------------- 8216 8217 // Integer Subtraction Instructions 8218 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8219 %{ 8220 match(Set dst (SubI dst src)); 8221 effect(KILL cr); 8222 8223 format %{ "subl $dst, $src\t# int" %} 8224 opcode(0x2B); 8225 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8226 ins_pipe(ialu_reg_reg); 8227 %} 8228 8229 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8230 %{ 8231 match(Set dst (SubI dst src)); 8232 effect(KILL cr); 8233 8234 format %{ "subl $dst, $src\t# int" %} 8235 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8236 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8237 ins_pipe(ialu_reg); 8238 %} 8239 8240 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8241 %{ 8242 match(Set dst (SubI dst (LoadI src))); 8243 effect(KILL cr); 8244 8245 ins_cost(125); 8246 format %{ "subl $dst, $src\t# int" %} 8247 opcode(0x2B); 8248 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8249 ins_pipe(ialu_reg_mem); 8250 %} 8251 8252 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8253 %{ 8254 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8255 effect(KILL cr); 8256 8257 ins_cost(150); 8258 format %{ "subl $dst, $src\t# int" %} 8259 opcode(0x29); /* Opcode 29 /r */ 8260 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8261 ins_pipe(ialu_mem_reg); 8262 %} 8263 8264 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8265 %{ 8266 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8267 effect(KILL cr); 8268 8269 ins_cost(125); // XXX 8270 format %{ "subl $dst, $src\t# int" %} 8271 opcode(0x81); /* Opcode 81 /5 id */ 8272 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8273 ins_pipe(ialu_mem_imm); 8274 %} 8275 8276 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8277 %{ 8278 match(Set dst (SubL dst src)); 8279 effect(KILL cr); 8280 8281 format %{ "subq $dst, $src\t# long" %} 8282 opcode(0x2B); 8283 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8284 ins_pipe(ialu_reg_reg); 8285 %} 8286 8287 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8288 %{ 8289 match(Set dst (SubL dst src)); 8290 effect(KILL cr); 8291 8292 format %{ "subq $dst, $src\t# long" %} 8293 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8294 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8295 ins_pipe(ialu_reg); 8296 %} 8297 8298 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8299 %{ 8300 match(Set dst (SubL dst (LoadL src))); 8301 effect(KILL cr); 8302 8303 ins_cost(125); 8304 format %{ "subq $dst, $src\t# long" %} 8305 opcode(0x2B); 8306 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8307 ins_pipe(ialu_reg_mem); 8308 %} 8309 8310 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8311 %{ 8312 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8313 effect(KILL cr); 8314 8315 ins_cost(150); 8316 format %{ "subq $dst, $src\t# long" %} 8317 opcode(0x29); /* Opcode 29 /r */ 8318 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8319 ins_pipe(ialu_mem_reg); 8320 %} 8321 8322 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8323 %{ 8324 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8325 effect(KILL cr); 8326 8327 ins_cost(125); // XXX 8328 format %{ "subq $dst, $src\t# long" %} 8329 opcode(0x81); /* Opcode 81 /5 id */ 8330 ins_encode(REX_mem_wide(dst), 8331 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8332 ins_pipe(ialu_mem_imm); 8333 %} 8334 8335 // Subtract from a pointer 8336 // XXX hmpf??? 8337 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8338 %{ 8339 match(Set dst (AddP dst (SubI zero src))); 8340 effect(KILL cr); 8341 8342 format %{ "subq $dst, $src\t# ptr - int" %} 8343 opcode(0x2B); 8344 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8345 ins_pipe(ialu_reg_reg); 8346 %} 8347 8348 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8349 %{ 8350 match(Set dst (SubI zero dst)); 8351 effect(KILL cr); 8352 8353 format %{ "negl $dst\t# int" %} 8354 opcode(0xF7, 0x03); // Opcode F7 /3 8355 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8356 ins_pipe(ialu_reg); 8357 %} 8358 8359 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8360 %{ 8361 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8362 effect(KILL cr); 8363 8364 format %{ "negl $dst\t# int" %} 8365 opcode(0xF7, 0x03); // Opcode F7 /3 8366 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8367 ins_pipe(ialu_reg); 8368 %} 8369 8370 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8371 %{ 8372 match(Set dst (SubL zero dst)); 8373 effect(KILL cr); 8374 8375 format %{ "negq $dst\t# long" %} 8376 opcode(0xF7, 0x03); // Opcode F7 /3 8377 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8378 ins_pipe(ialu_reg); 8379 %} 8380 8381 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8382 %{ 8383 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8384 effect(KILL cr); 8385 8386 format %{ "negq $dst\t# long" %} 8387 opcode(0xF7, 0x03); // Opcode F7 /3 8388 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8389 ins_pipe(ialu_reg); 8390 %} 8391 8392 //----------Multiplication/Division Instructions------------------------------- 8393 // Integer Multiplication Instructions 8394 // Multiply Register 8395 8396 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8397 %{ 8398 match(Set dst (MulI dst src)); 8399 effect(KILL cr); 8400 8401 ins_cost(300); 8402 format %{ "imull $dst, $src\t# int" %} 8403 opcode(0x0F, 0xAF); 8404 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8405 ins_pipe(ialu_reg_reg_alu0); 8406 %} 8407 8408 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8409 %{ 8410 match(Set dst (MulI src imm)); 8411 effect(KILL cr); 8412 8413 ins_cost(300); 8414 format %{ "imull $dst, $src, $imm\t# int" %} 8415 opcode(0x69); /* 69 /r id */ 8416 ins_encode(REX_reg_reg(dst, src), 8417 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8418 ins_pipe(ialu_reg_reg_alu0); 8419 %} 8420 8421 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8422 %{ 8423 match(Set dst (MulI dst (LoadI src))); 8424 effect(KILL cr); 8425 8426 ins_cost(350); 8427 format %{ "imull $dst, $src\t# int" %} 8428 opcode(0x0F, 0xAF); 8429 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8430 ins_pipe(ialu_reg_mem_alu0); 8431 %} 8432 8433 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8434 %{ 8435 match(Set dst (MulI (LoadI src) imm)); 8436 effect(KILL cr); 8437 8438 ins_cost(300); 8439 format %{ "imull $dst, $src, $imm\t# int" %} 8440 opcode(0x69); /* 69 /r id */ 8441 ins_encode(REX_reg_mem(dst, src), 8442 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8443 ins_pipe(ialu_reg_mem_alu0); 8444 %} 8445 8446 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8447 %{ 8448 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8449 effect(KILL cr, KILL src2); 8450 8451 expand %{ mulI_rReg(dst, src1, cr); 8452 mulI_rReg(src2, src3, cr); 8453 addI_rReg(dst, src2, cr); %} 8454 %} 8455 8456 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8457 %{ 8458 match(Set dst (MulL dst src)); 8459 effect(KILL cr); 8460 8461 ins_cost(300); 8462 format %{ "imulq $dst, $src\t# long" %} 8463 opcode(0x0F, 0xAF); 8464 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8465 ins_pipe(ialu_reg_reg_alu0); 8466 %} 8467 8468 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8469 %{ 8470 match(Set dst (MulL src imm)); 8471 effect(KILL cr); 8472 8473 ins_cost(300); 8474 format %{ "imulq $dst, $src, $imm\t# long" %} 8475 opcode(0x69); /* 69 /r id */ 8476 ins_encode(REX_reg_reg_wide(dst, src), 8477 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8478 ins_pipe(ialu_reg_reg_alu0); 8479 %} 8480 8481 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8482 %{ 8483 match(Set dst (MulL dst (LoadL src))); 8484 effect(KILL cr); 8485 8486 ins_cost(350); 8487 format %{ "imulq $dst, $src\t# long" %} 8488 opcode(0x0F, 0xAF); 8489 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8490 ins_pipe(ialu_reg_mem_alu0); 8491 %} 8492 8493 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8494 %{ 8495 match(Set dst (MulL (LoadL src) imm)); 8496 effect(KILL cr); 8497 8498 ins_cost(300); 8499 format %{ "imulq $dst, $src, $imm\t# long" %} 8500 opcode(0x69); /* 69 /r id */ 8501 ins_encode(REX_reg_mem_wide(dst, src), 8502 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8503 ins_pipe(ialu_reg_mem_alu0); 8504 %} 8505 8506 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8507 %{ 8508 match(Set dst (MulHiL src rax)); 8509 effect(USE_KILL rax, KILL cr); 8510 8511 ins_cost(300); 8512 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8513 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8514 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8515 ins_pipe(ialu_reg_reg_alu0); 8516 %} 8517 8518 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8519 rFlagsReg cr) 8520 %{ 8521 match(Set rax (DivI rax div)); 8522 effect(KILL rdx, KILL cr); 8523 8524 ins_cost(30*100+10*100); // XXX 8525 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8526 "jne,s normal\n\t" 8527 "xorl rdx, rdx\n\t" 8528 "cmpl $div, -1\n\t" 8529 "je,s done\n" 8530 "normal: cdql\n\t" 8531 "idivl $div\n" 8532 "done:" %} 8533 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8534 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8535 ins_pipe(ialu_reg_reg_alu0); 8536 %} 8537 8538 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8539 rFlagsReg cr) 8540 %{ 8541 match(Set rax (DivL rax div)); 8542 effect(KILL rdx, KILL cr); 8543 8544 ins_cost(30*100+10*100); // XXX 8545 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8546 "cmpq rax, rdx\n\t" 8547 "jne,s normal\n\t" 8548 "xorl rdx, rdx\n\t" 8549 "cmpq $div, -1\n\t" 8550 "je,s done\n" 8551 "normal: cdqq\n\t" 8552 "idivq $div\n" 8553 "done:" %} 8554 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8555 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8556 ins_pipe(ialu_reg_reg_alu0); 8557 %} 8558 8559 // Integer DIVMOD with Register, both quotient and mod results 8560 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8561 rFlagsReg cr) 8562 %{ 8563 match(DivModI rax div); 8564 effect(KILL cr); 8565 8566 ins_cost(30*100+10*100); // XXX 8567 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8568 "jne,s normal\n\t" 8569 "xorl rdx, rdx\n\t" 8570 "cmpl $div, -1\n\t" 8571 "je,s done\n" 8572 "normal: cdql\n\t" 8573 "idivl $div\n" 8574 "done:" %} 8575 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8576 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8577 ins_pipe(pipe_slow); 8578 %} 8579 8580 // Long DIVMOD with Register, both quotient and mod results 8581 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8582 rFlagsReg cr) 8583 %{ 8584 match(DivModL rax div); 8585 effect(KILL cr); 8586 8587 ins_cost(30*100+10*100); // XXX 8588 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8589 "cmpq rax, rdx\n\t" 8590 "jne,s normal\n\t" 8591 "xorl rdx, rdx\n\t" 8592 "cmpq $div, -1\n\t" 8593 "je,s done\n" 8594 "normal: cdqq\n\t" 8595 "idivq $div\n" 8596 "done:" %} 8597 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8598 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8599 ins_pipe(pipe_slow); 8600 %} 8601 8602 //----------- DivL-By-Constant-Expansions-------------------------------------- 8603 // DivI cases are handled by the compiler 8604 8605 // Magic constant, reciprocal of 10 8606 instruct loadConL_0x6666666666666667(rRegL dst) 8607 %{ 8608 effect(DEF dst); 8609 8610 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8611 ins_encode(load_immL(dst, 0x6666666666666667)); 8612 ins_pipe(ialu_reg); 8613 %} 8614 8615 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8616 %{ 8617 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8618 8619 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8620 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8621 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8622 ins_pipe(ialu_reg_reg_alu0); 8623 %} 8624 8625 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8626 %{ 8627 effect(USE_DEF dst, KILL cr); 8628 8629 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8630 opcode(0xC1, 0x7); /* C1 /7 ib */ 8631 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8632 ins_pipe(ialu_reg); 8633 %} 8634 8635 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8636 %{ 8637 effect(USE_DEF dst, KILL cr); 8638 8639 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8640 opcode(0xC1, 0x7); /* C1 /7 ib */ 8641 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8642 ins_pipe(ialu_reg); 8643 %} 8644 8645 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8646 %{ 8647 match(Set dst (DivL src div)); 8648 8649 ins_cost((5+8)*100); 8650 expand %{ 8651 rax_RegL rax; // Killed temp 8652 rFlagsReg cr; // Killed 8653 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8654 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8655 sarL_rReg_63(src, cr); // sarq src, 63 8656 sarL_rReg_2(dst, cr); // sarq rdx, 2 8657 subL_rReg(dst, src, cr); // subl rdx, src 8658 %} 8659 %} 8660 8661 //----------------------------------------------------------------------------- 8662 8663 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8664 rFlagsReg cr) 8665 %{ 8666 match(Set rdx (ModI rax div)); 8667 effect(KILL rax, KILL cr); 8668 8669 ins_cost(300); // XXX 8670 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8671 "jne,s normal\n\t" 8672 "xorl rdx, rdx\n\t" 8673 "cmpl $div, -1\n\t" 8674 "je,s done\n" 8675 "normal: cdql\n\t" 8676 "idivl $div\n" 8677 "done:" %} 8678 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8679 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8680 ins_pipe(ialu_reg_reg_alu0); 8681 %} 8682 8683 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8684 rFlagsReg cr) 8685 %{ 8686 match(Set rdx (ModL rax div)); 8687 effect(KILL rax, KILL cr); 8688 8689 ins_cost(300); // XXX 8690 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8691 "cmpq rax, rdx\n\t" 8692 "jne,s normal\n\t" 8693 "xorl rdx, rdx\n\t" 8694 "cmpq $div, -1\n\t" 8695 "je,s done\n" 8696 "normal: cdqq\n\t" 8697 "idivq $div\n" 8698 "done:" %} 8699 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8700 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8701 ins_pipe(ialu_reg_reg_alu0); 8702 %} 8703 8704 // Integer Shift Instructions 8705 // Shift Left by one 8706 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8707 %{ 8708 match(Set dst (LShiftI dst shift)); 8709 effect(KILL cr); 8710 8711 format %{ "sall $dst, $shift" %} 8712 opcode(0xD1, 0x4); /* D1 /4 */ 8713 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8714 ins_pipe(ialu_reg); 8715 %} 8716 8717 // Shift Left by one 8718 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8719 %{ 8720 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8721 effect(KILL cr); 8722 8723 format %{ "sall $dst, $shift\t" %} 8724 opcode(0xD1, 0x4); /* D1 /4 */ 8725 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8726 ins_pipe(ialu_mem_imm); 8727 %} 8728 8729 // Shift Left by 8-bit immediate 8730 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8731 %{ 8732 match(Set dst (LShiftI dst shift)); 8733 effect(KILL cr); 8734 8735 format %{ "sall $dst, $shift" %} 8736 opcode(0xC1, 0x4); /* C1 /4 ib */ 8737 ins_encode(reg_opc_imm(dst, shift)); 8738 ins_pipe(ialu_reg); 8739 %} 8740 8741 // Shift Left by 8-bit immediate 8742 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8743 %{ 8744 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8745 effect(KILL cr); 8746 8747 format %{ "sall $dst, $shift" %} 8748 opcode(0xC1, 0x4); /* C1 /4 ib */ 8749 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8750 ins_pipe(ialu_mem_imm); 8751 %} 8752 8753 // Shift Left by variable 8754 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8755 %{ 8756 match(Set dst (LShiftI dst shift)); 8757 effect(KILL cr); 8758 8759 format %{ "sall $dst, $shift" %} 8760 opcode(0xD3, 0x4); /* D3 /4 */ 8761 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8762 ins_pipe(ialu_reg_reg); 8763 %} 8764 8765 // Shift Left by variable 8766 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8767 %{ 8768 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8769 effect(KILL cr); 8770 8771 format %{ "sall $dst, $shift" %} 8772 opcode(0xD3, 0x4); /* D3 /4 */ 8773 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8774 ins_pipe(ialu_mem_reg); 8775 %} 8776 8777 // Arithmetic shift right by one 8778 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8779 %{ 8780 match(Set dst (RShiftI dst shift)); 8781 effect(KILL cr); 8782 8783 format %{ "sarl $dst, $shift" %} 8784 opcode(0xD1, 0x7); /* D1 /7 */ 8785 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8786 ins_pipe(ialu_reg); 8787 %} 8788 8789 // Arithmetic shift right by one 8790 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8791 %{ 8792 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8793 effect(KILL cr); 8794 8795 format %{ "sarl $dst, $shift" %} 8796 opcode(0xD1, 0x7); /* D1 /7 */ 8797 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8798 ins_pipe(ialu_mem_imm); 8799 %} 8800 8801 // Arithmetic Shift Right by 8-bit immediate 8802 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8803 %{ 8804 match(Set dst (RShiftI dst shift)); 8805 effect(KILL cr); 8806 8807 format %{ "sarl $dst, $shift" %} 8808 opcode(0xC1, 0x7); /* C1 /7 ib */ 8809 ins_encode(reg_opc_imm(dst, shift)); 8810 ins_pipe(ialu_mem_imm); 8811 %} 8812 8813 // Arithmetic Shift Right by 8-bit immediate 8814 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8815 %{ 8816 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8817 effect(KILL cr); 8818 8819 format %{ "sarl $dst, $shift" %} 8820 opcode(0xC1, 0x7); /* C1 /7 ib */ 8821 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8822 ins_pipe(ialu_mem_imm); 8823 %} 8824 8825 // Arithmetic Shift Right by variable 8826 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8827 %{ 8828 match(Set dst (RShiftI dst shift)); 8829 effect(KILL cr); 8830 8831 format %{ "sarl $dst, $shift" %} 8832 opcode(0xD3, 0x7); /* D3 /7 */ 8833 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8834 ins_pipe(ialu_reg_reg); 8835 %} 8836 8837 // Arithmetic Shift Right by variable 8838 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8839 %{ 8840 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8841 effect(KILL cr); 8842 8843 format %{ "sarl $dst, $shift" %} 8844 opcode(0xD3, 0x7); /* D3 /7 */ 8845 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8846 ins_pipe(ialu_mem_reg); 8847 %} 8848 8849 // Logical shift right by one 8850 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8851 %{ 8852 match(Set dst (URShiftI dst shift)); 8853 effect(KILL cr); 8854 8855 format %{ "shrl $dst, $shift" %} 8856 opcode(0xD1, 0x5); /* D1 /5 */ 8857 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8858 ins_pipe(ialu_reg); 8859 %} 8860 8861 // Logical shift right by one 8862 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8863 %{ 8864 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8865 effect(KILL cr); 8866 8867 format %{ "shrl $dst, $shift" %} 8868 opcode(0xD1, 0x5); /* D1 /5 */ 8869 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8870 ins_pipe(ialu_mem_imm); 8871 %} 8872 8873 // Logical Shift Right by 8-bit immediate 8874 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8875 %{ 8876 match(Set dst (URShiftI dst shift)); 8877 effect(KILL cr); 8878 8879 format %{ "shrl $dst, $shift" %} 8880 opcode(0xC1, 0x5); /* C1 /5 ib */ 8881 ins_encode(reg_opc_imm(dst, shift)); 8882 ins_pipe(ialu_reg); 8883 %} 8884 8885 // Logical Shift Right by 8-bit immediate 8886 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8887 %{ 8888 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8889 effect(KILL cr); 8890 8891 format %{ "shrl $dst, $shift" %} 8892 opcode(0xC1, 0x5); /* C1 /5 ib */ 8893 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8894 ins_pipe(ialu_mem_imm); 8895 %} 8896 8897 // Logical Shift Right by variable 8898 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8899 %{ 8900 match(Set dst (URShiftI dst shift)); 8901 effect(KILL cr); 8902 8903 format %{ "shrl $dst, $shift" %} 8904 opcode(0xD3, 0x5); /* D3 /5 */ 8905 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8906 ins_pipe(ialu_reg_reg); 8907 %} 8908 8909 // Logical Shift Right by variable 8910 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8911 %{ 8912 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8913 effect(KILL cr); 8914 8915 format %{ "shrl $dst, $shift" %} 8916 opcode(0xD3, 0x5); /* D3 /5 */ 8917 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8918 ins_pipe(ialu_mem_reg); 8919 %} 8920 8921 // Long Shift Instructions 8922 // Shift Left by one 8923 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8924 %{ 8925 match(Set dst (LShiftL dst shift)); 8926 effect(KILL cr); 8927 8928 format %{ "salq $dst, $shift" %} 8929 opcode(0xD1, 0x4); /* D1 /4 */ 8930 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8931 ins_pipe(ialu_reg); 8932 %} 8933 8934 // Shift Left by one 8935 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8936 %{ 8937 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8938 effect(KILL cr); 8939 8940 format %{ "salq $dst, $shift" %} 8941 opcode(0xD1, 0x4); /* D1 /4 */ 8942 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8943 ins_pipe(ialu_mem_imm); 8944 %} 8945 8946 // Shift Left by 8-bit immediate 8947 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8948 %{ 8949 match(Set dst (LShiftL dst shift)); 8950 effect(KILL cr); 8951 8952 format %{ "salq $dst, $shift" %} 8953 opcode(0xC1, 0x4); /* C1 /4 ib */ 8954 ins_encode(reg_opc_imm_wide(dst, shift)); 8955 ins_pipe(ialu_reg); 8956 %} 8957 8958 // Shift Left by 8-bit immediate 8959 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8960 %{ 8961 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8962 effect(KILL cr); 8963 8964 format %{ "salq $dst, $shift" %} 8965 opcode(0xC1, 0x4); /* C1 /4 ib */ 8966 ins_encode(REX_mem_wide(dst), OpcP, 8967 RM_opc_mem(secondary, dst), Con8or32(shift)); 8968 ins_pipe(ialu_mem_imm); 8969 %} 8970 8971 // Shift Left by variable 8972 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8973 %{ 8974 match(Set dst (LShiftL dst shift)); 8975 effect(KILL cr); 8976 8977 format %{ "salq $dst, $shift" %} 8978 opcode(0xD3, 0x4); /* D3 /4 */ 8979 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8980 ins_pipe(ialu_reg_reg); 8981 %} 8982 8983 // Shift Left by variable 8984 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8985 %{ 8986 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8987 effect(KILL cr); 8988 8989 format %{ "salq $dst, $shift" %} 8990 opcode(0xD3, 0x4); /* D3 /4 */ 8991 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8992 ins_pipe(ialu_mem_reg); 8993 %} 8994 8995 // Arithmetic shift right by one 8996 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8997 %{ 8998 match(Set dst (RShiftL dst shift)); 8999 effect(KILL cr); 9000 9001 format %{ "sarq $dst, $shift" %} 9002 opcode(0xD1, 0x7); /* D1 /7 */ 9003 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9004 ins_pipe(ialu_reg); 9005 %} 9006 9007 // Arithmetic shift right by one 9008 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9009 %{ 9010 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9011 effect(KILL cr); 9012 9013 format %{ "sarq $dst, $shift" %} 9014 opcode(0xD1, 0x7); /* D1 /7 */ 9015 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9016 ins_pipe(ialu_mem_imm); 9017 %} 9018 9019 // Arithmetic Shift Right by 8-bit immediate 9020 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9021 %{ 9022 match(Set dst (RShiftL dst shift)); 9023 effect(KILL cr); 9024 9025 format %{ "sarq $dst, $shift" %} 9026 opcode(0xC1, 0x7); /* C1 /7 ib */ 9027 ins_encode(reg_opc_imm_wide(dst, shift)); 9028 ins_pipe(ialu_mem_imm); 9029 %} 9030 9031 // Arithmetic Shift Right by 8-bit immediate 9032 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9033 %{ 9034 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9035 effect(KILL cr); 9036 9037 format %{ "sarq $dst, $shift" %} 9038 opcode(0xC1, 0x7); /* C1 /7 ib */ 9039 ins_encode(REX_mem_wide(dst), OpcP, 9040 RM_opc_mem(secondary, dst), Con8or32(shift)); 9041 ins_pipe(ialu_mem_imm); 9042 %} 9043 9044 // Arithmetic Shift Right by variable 9045 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9046 %{ 9047 match(Set dst (RShiftL dst shift)); 9048 effect(KILL cr); 9049 9050 format %{ "sarq $dst, $shift" %} 9051 opcode(0xD3, 0x7); /* D3 /7 */ 9052 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9053 ins_pipe(ialu_reg_reg); 9054 %} 9055 9056 // Arithmetic Shift Right by variable 9057 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9058 %{ 9059 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9060 effect(KILL cr); 9061 9062 format %{ "sarq $dst, $shift" %} 9063 opcode(0xD3, 0x7); /* D3 /7 */ 9064 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9065 ins_pipe(ialu_mem_reg); 9066 %} 9067 9068 // Logical shift right by one 9069 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9070 %{ 9071 match(Set dst (URShiftL dst shift)); 9072 effect(KILL cr); 9073 9074 format %{ "shrq $dst, $shift" %} 9075 opcode(0xD1, 0x5); /* D1 /5 */ 9076 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 9077 ins_pipe(ialu_reg); 9078 %} 9079 9080 // Logical shift right by one 9081 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9082 %{ 9083 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9084 effect(KILL cr); 9085 9086 format %{ "shrq $dst, $shift" %} 9087 opcode(0xD1, 0x5); /* D1 /5 */ 9088 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9089 ins_pipe(ialu_mem_imm); 9090 %} 9091 9092 // Logical Shift Right by 8-bit immediate 9093 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9094 %{ 9095 match(Set dst (URShiftL dst shift)); 9096 effect(KILL cr); 9097 9098 format %{ "shrq $dst, $shift" %} 9099 opcode(0xC1, 0x5); /* C1 /5 ib */ 9100 ins_encode(reg_opc_imm_wide(dst, shift)); 9101 ins_pipe(ialu_reg); 9102 %} 9103 9104 9105 // Logical Shift Right by 8-bit immediate 9106 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9107 %{ 9108 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9109 effect(KILL cr); 9110 9111 format %{ "shrq $dst, $shift" %} 9112 opcode(0xC1, 0x5); /* C1 /5 ib */ 9113 ins_encode(REX_mem_wide(dst), OpcP, 9114 RM_opc_mem(secondary, dst), Con8or32(shift)); 9115 ins_pipe(ialu_mem_imm); 9116 %} 9117 9118 // Logical Shift Right by variable 9119 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9120 %{ 9121 match(Set dst (URShiftL dst shift)); 9122 effect(KILL cr); 9123 9124 format %{ "shrq $dst, $shift" %} 9125 opcode(0xD3, 0x5); /* D3 /5 */ 9126 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9127 ins_pipe(ialu_reg_reg); 9128 %} 9129 9130 // Logical Shift Right by variable 9131 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9132 %{ 9133 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9134 effect(KILL cr); 9135 9136 format %{ "shrq $dst, $shift" %} 9137 opcode(0xD3, 0x5); /* D3 /5 */ 9138 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9139 ins_pipe(ialu_mem_reg); 9140 %} 9141 9142 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9143 // This idiom is used by the compiler for the i2b bytecode. 9144 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9145 %{ 9146 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9147 9148 format %{ "movsbl $dst, $src\t# i2b" %} 9149 opcode(0x0F, 0xBE); 9150 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9151 ins_pipe(ialu_reg_reg); 9152 %} 9153 9154 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9155 // This idiom is used by the compiler the i2s bytecode. 9156 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9157 %{ 9158 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9159 9160 format %{ "movswl $dst, $src\t# i2s" %} 9161 opcode(0x0F, 0xBF); 9162 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9163 ins_pipe(ialu_reg_reg); 9164 %} 9165 9166 // ROL/ROR instructions 9167 9168 // ROL expand 9169 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9170 effect(KILL cr, USE_DEF dst); 9171 9172 format %{ "roll $dst" %} 9173 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9174 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9175 ins_pipe(ialu_reg); 9176 %} 9177 9178 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9179 effect(USE_DEF dst, USE shift, KILL cr); 9180 9181 format %{ "roll $dst, $shift" %} 9182 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9183 ins_encode( reg_opc_imm(dst, shift) ); 9184 ins_pipe(ialu_reg); 9185 %} 9186 9187 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9188 %{ 9189 effect(USE_DEF dst, USE shift, KILL cr); 9190 9191 format %{ "roll $dst, $shift" %} 9192 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9193 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9194 ins_pipe(ialu_reg_reg); 9195 %} 9196 // end of ROL expand 9197 9198 // Rotate Left by one 9199 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9200 %{ 9201 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9202 9203 expand %{ 9204 rolI_rReg_imm1(dst, cr); 9205 %} 9206 %} 9207 9208 // Rotate Left by 8-bit immediate 9209 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9210 %{ 9211 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9212 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9213 9214 expand %{ 9215 rolI_rReg_imm8(dst, lshift, cr); 9216 %} 9217 %} 9218 9219 // Rotate Left by variable 9220 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9221 %{ 9222 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9223 9224 expand %{ 9225 rolI_rReg_CL(dst, shift, cr); 9226 %} 9227 %} 9228 9229 // Rotate Left by variable 9230 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9231 %{ 9232 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9233 9234 expand %{ 9235 rolI_rReg_CL(dst, shift, cr); 9236 %} 9237 %} 9238 9239 // ROR expand 9240 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9241 %{ 9242 effect(USE_DEF dst, KILL cr); 9243 9244 format %{ "rorl $dst" %} 9245 opcode(0xD1, 0x1); /* D1 /1 */ 9246 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9247 ins_pipe(ialu_reg); 9248 %} 9249 9250 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9251 %{ 9252 effect(USE_DEF dst, USE shift, KILL cr); 9253 9254 format %{ "rorl $dst, $shift" %} 9255 opcode(0xC1, 0x1); /* C1 /1 ib */ 9256 ins_encode(reg_opc_imm(dst, shift)); 9257 ins_pipe(ialu_reg); 9258 %} 9259 9260 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9261 %{ 9262 effect(USE_DEF dst, USE shift, KILL cr); 9263 9264 format %{ "rorl $dst, $shift" %} 9265 opcode(0xD3, 0x1); /* D3 /1 */ 9266 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9267 ins_pipe(ialu_reg_reg); 9268 %} 9269 // end of ROR expand 9270 9271 // Rotate Right by one 9272 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9273 %{ 9274 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9275 9276 expand %{ 9277 rorI_rReg_imm1(dst, cr); 9278 %} 9279 %} 9280 9281 // Rotate Right by 8-bit immediate 9282 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9283 %{ 9284 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9285 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9286 9287 expand %{ 9288 rorI_rReg_imm8(dst, rshift, cr); 9289 %} 9290 %} 9291 9292 // Rotate Right by variable 9293 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9294 %{ 9295 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9296 9297 expand %{ 9298 rorI_rReg_CL(dst, shift, cr); 9299 %} 9300 %} 9301 9302 // Rotate Right by variable 9303 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9304 %{ 9305 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9306 9307 expand %{ 9308 rorI_rReg_CL(dst, shift, cr); 9309 %} 9310 %} 9311 9312 // for long rotate 9313 // ROL expand 9314 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9315 effect(USE_DEF dst, KILL cr); 9316 9317 format %{ "rolq $dst" %} 9318 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9319 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9320 ins_pipe(ialu_reg); 9321 %} 9322 9323 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9324 effect(USE_DEF dst, USE shift, KILL cr); 9325 9326 format %{ "rolq $dst, $shift" %} 9327 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9328 ins_encode( reg_opc_imm_wide(dst, shift) ); 9329 ins_pipe(ialu_reg); 9330 %} 9331 9332 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9333 %{ 9334 effect(USE_DEF dst, USE shift, KILL cr); 9335 9336 format %{ "rolq $dst, $shift" %} 9337 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9338 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9339 ins_pipe(ialu_reg_reg); 9340 %} 9341 // end of ROL expand 9342 9343 // Rotate Left by one 9344 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9345 %{ 9346 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9347 9348 expand %{ 9349 rolL_rReg_imm1(dst, cr); 9350 %} 9351 %} 9352 9353 // Rotate Left by 8-bit immediate 9354 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9355 %{ 9356 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9357 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9358 9359 expand %{ 9360 rolL_rReg_imm8(dst, lshift, cr); 9361 %} 9362 %} 9363 9364 // Rotate Left by variable 9365 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9366 %{ 9367 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9368 9369 expand %{ 9370 rolL_rReg_CL(dst, shift, cr); 9371 %} 9372 %} 9373 9374 // Rotate Left by variable 9375 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9376 %{ 9377 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9378 9379 expand %{ 9380 rolL_rReg_CL(dst, shift, cr); 9381 %} 9382 %} 9383 9384 // ROR expand 9385 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9386 %{ 9387 effect(USE_DEF dst, KILL cr); 9388 9389 format %{ "rorq $dst" %} 9390 opcode(0xD1, 0x1); /* D1 /1 */ 9391 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9392 ins_pipe(ialu_reg); 9393 %} 9394 9395 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9396 %{ 9397 effect(USE_DEF dst, USE shift, KILL cr); 9398 9399 format %{ "rorq $dst, $shift" %} 9400 opcode(0xC1, 0x1); /* C1 /1 ib */ 9401 ins_encode(reg_opc_imm_wide(dst, shift)); 9402 ins_pipe(ialu_reg); 9403 %} 9404 9405 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9406 %{ 9407 effect(USE_DEF dst, USE shift, KILL cr); 9408 9409 format %{ "rorq $dst, $shift" %} 9410 opcode(0xD3, 0x1); /* D3 /1 */ 9411 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9412 ins_pipe(ialu_reg_reg); 9413 %} 9414 // end of ROR expand 9415 9416 // Rotate Right by one 9417 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9418 %{ 9419 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9420 9421 expand %{ 9422 rorL_rReg_imm1(dst, cr); 9423 %} 9424 %} 9425 9426 // Rotate Right by 8-bit immediate 9427 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9428 %{ 9429 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9430 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9431 9432 expand %{ 9433 rorL_rReg_imm8(dst, rshift, cr); 9434 %} 9435 %} 9436 9437 // Rotate Right by variable 9438 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9439 %{ 9440 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9441 9442 expand %{ 9443 rorL_rReg_CL(dst, shift, cr); 9444 %} 9445 %} 9446 9447 // Rotate Right by variable 9448 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9449 %{ 9450 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9451 9452 expand %{ 9453 rorL_rReg_CL(dst, shift, cr); 9454 %} 9455 %} 9456 9457 // Logical Instructions 9458 9459 // Integer Logical Instructions 9460 9461 // And Instructions 9462 // And Register with Register 9463 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9464 %{ 9465 match(Set dst (AndI dst src)); 9466 effect(KILL cr); 9467 9468 format %{ "andl $dst, $src\t# int" %} 9469 opcode(0x23); 9470 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9471 ins_pipe(ialu_reg_reg); 9472 %} 9473 9474 // And Register with Immediate 255 9475 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9476 %{ 9477 match(Set dst (AndI dst src)); 9478 9479 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9480 opcode(0x0F, 0xB6); 9481 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9482 ins_pipe(ialu_reg); 9483 %} 9484 9485 // And Register with Immediate 255 and promote to long 9486 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9487 %{ 9488 match(Set dst (ConvI2L (AndI src mask))); 9489 9490 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9491 opcode(0x0F, 0xB6); 9492 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9493 ins_pipe(ialu_reg); 9494 %} 9495 9496 // And Register with Immediate 65535 9497 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9498 %{ 9499 match(Set dst (AndI dst src)); 9500 9501 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9502 opcode(0x0F, 0xB7); 9503 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9504 ins_pipe(ialu_reg); 9505 %} 9506 9507 // And Register with Immediate 65535 and promote to long 9508 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9509 %{ 9510 match(Set dst (ConvI2L (AndI src mask))); 9511 9512 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9513 opcode(0x0F, 0xB7); 9514 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9515 ins_pipe(ialu_reg); 9516 %} 9517 9518 // And Register with Immediate 9519 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9520 %{ 9521 match(Set dst (AndI dst src)); 9522 effect(KILL cr); 9523 9524 format %{ "andl $dst, $src\t# int" %} 9525 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9526 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9527 ins_pipe(ialu_reg); 9528 %} 9529 9530 // And Register with Memory 9531 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9532 %{ 9533 match(Set dst (AndI dst (LoadI src))); 9534 effect(KILL cr); 9535 9536 ins_cost(125); 9537 format %{ "andl $dst, $src\t# int" %} 9538 opcode(0x23); 9539 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9540 ins_pipe(ialu_reg_mem); 9541 %} 9542 9543 // And Memory with Register 9544 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9545 %{ 9546 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9547 effect(KILL cr); 9548 9549 ins_cost(150); 9550 format %{ "andb $dst, $src\t# byte" %} 9551 opcode(0x20); 9552 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9553 ins_pipe(ialu_mem_reg); 9554 %} 9555 9556 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9557 %{ 9558 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9559 effect(KILL cr); 9560 9561 ins_cost(150); 9562 format %{ "andl $dst, $src\t# int" %} 9563 opcode(0x21); /* Opcode 21 /r */ 9564 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9565 ins_pipe(ialu_mem_reg); 9566 %} 9567 9568 // And Memory with Immediate 9569 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9570 %{ 9571 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9572 effect(KILL cr); 9573 9574 ins_cost(125); 9575 format %{ "andl $dst, $src\t# int" %} 9576 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9577 ins_encode(REX_mem(dst), OpcSE(src), 9578 RM_opc_mem(secondary, dst), Con8or32(src)); 9579 ins_pipe(ialu_mem_imm); 9580 %} 9581 9582 // BMI1 instructions 9583 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9584 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9585 predicate(UseBMI1Instructions); 9586 effect(KILL cr); 9587 9588 ins_cost(125); 9589 format %{ "andnl $dst, $src1, $src2" %} 9590 9591 ins_encode %{ 9592 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9593 %} 9594 ins_pipe(ialu_reg_mem); 9595 %} 9596 9597 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9598 match(Set dst (AndI (XorI src1 minus_1) src2)); 9599 predicate(UseBMI1Instructions); 9600 effect(KILL cr); 9601 9602 format %{ "andnl $dst, $src1, $src2" %} 9603 9604 ins_encode %{ 9605 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9606 %} 9607 ins_pipe(ialu_reg); 9608 %} 9609 9610 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9611 match(Set dst (AndI (SubI imm_zero src) src)); 9612 predicate(UseBMI1Instructions); 9613 effect(KILL cr); 9614 9615 format %{ "blsil $dst, $src" %} 9616 9617 ins_encode %{ 9618 __ blsil($dst$$Register, $src$$Register); 9619 %} 9620 ins_pipe(ialu_reg); 9621 %} 9622 9623 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9624 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9625 predicate(UseBMI1Instructions); 9626 effect(KILL cr); 9627 9628 ins_cost(125); 9629 format %{ "blsil $dst, $src" %} 9630 9631 ins_encode %{ 9632 __ blsil($dst$$Register, $src$$Address); 9633 %} 9634 ins_pipe(ialu_reg_mem); 9635 %} 9636 9637 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9638 %{ 9639 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9640 predicate(UseBMI1Instructions); 9641 effect(KILL cr); 9642 9643 ins_cost(125); 9644 format %{ "blsmskl $dst, $src" %} 9645 9646 ins_encode %{ 9647 __ blsmskl($dst$$Register, $src$$Address); 9648 %} 9649 ins_pipe(ialu_reg_mem); 9650 %} 9651 9652 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9653 %{ 9654 match(Set dst (XorI (AddI src minus_1) src)); 9655 predicate(UseBMI1Instructions); 9656 effect(KILL cr); 9657 9658 format %{ "blsmskl $dst, $src" %} 9659 9660 ins_encode %{ 9661 __ blsmskl($dst$$Register, $src$$Register); 9662 %} 9663 9664 ins_pipe(ialu_reg); 9665 %} 9666 9667 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9668 %{ 9669 match(Set dst (AndI (AddI src minus_1) src) ); 9670 predicate(UseBMI1Instructions); 9671 effect(KILL cr); 9672 9673 format %{ "blsrl $dst, $src" %} 9674 9675 ins_encode %{ 9676 __ blsrl($dst$$Register, $src$$Register); 9677 %} 9678 9679 ins_pipe(ialu_reg_mem); 9680 %} 9681 9682 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9683 %{ 9684 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9685 predicate(UseBMI1Instructions); 9686 effect(KILL cr); 9687 9688 ins_cost(125); 9689 format %{ "blsrl $dst, $src" %} 9690 9691 ins_encode %{ 9692 __ blsrl($dst$$Register, $src$$Address); 9693 %} 9694 9695 ins_pipe(ialu_reg); 9696 %} 9697 9698 // Or Instructions 9699 // Or Register with Register 9700 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9701 %{ 9702 match(Set dst (OrI dst src)); 9703 effect(KILL cr); 9704 9705 format %{ "orl $dst, $src\t# int" %} 9706 opcode(0x0B); 9707 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9708 ins_pipe(ialu_reg_reg); 9709 %} 9710 9711 // Or Register with Immediate 9712 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9713 %{ 9714 match(Set dst (OrI dst src)); 9715 effect(KILL cr); 9716 9717 format %{ "orl $dst, $src\t# int" %} 9718 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9719 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9720 ins_pipe(ialu_reg); 9721 %} 9722 9723 // Or Register with Memory 9724 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9725 %{ 9726 match(Set dst (OrI dst (LoadI src))); 9727 effect(KILL cr); 9728 9729 ins_cost(125); 9730 format %{ "orl $dst, $src\t# int" %} 9731 opcode(0x0B); 9732 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9733 ins_pipe(ialu_reg_mem); 9734 %} 9735 9736 // Or Memory with Register 9737 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9738 %{ 9739 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9740 effect(KILL cr); 9741 9742 ins_cost(150); 9743 format %{ "orb $dst, $src\t# byte" %} 9744 opcode(0x08); 9745 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9746 ins_pipe(ialu_mem_reg); 9747 %} 9748 9749 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9750 %{ 9751 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9752 effect(KILL cr); 9753 9754 ins_cost(150); 9755 format %{ "orl $dst, $src\t# int" %} 9756 opcode(0x09); /* Opcode 09 /r */ 9757 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9758 ins_pipe(ialu_mem_reg); 9759 %} 9760 9761 // Or Memory with Immediate 9762 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9763 %{ 9764 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9765 effect(KILL cr); 9766 9767 ins_cost(125); 9768 format %{ "orl $dst, $src\t# int" %} 9769 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9770 ins_encode(REX_mem(dst), OpcSE(src), 9771 RM_opc_mem(secondary, dst), Con8or32(src)); 9772 ins_pipe(ialu_mem_imm); 9773 %} 9774 9775 // Xor Instructions 9776 // Xor Register with Register 9777 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9778 %{ 9779 match(Set dst (XorI dst src)); 9780 effect(KILL cr); 9781 9782 format %{ "xorl $dst, $src\t# int" %} 9783 opcode(0x33); 9784 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9785 ins_pipe(ialu_reg_reg); 9786 %} 9787 9788 // Xor Register with Immediate -1 9789 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9790 match(Set dst (XorI dst imm)); 9791 9792 format %{ "not $dst" %} 9793 ins_encode %{ 9794 __ notl($dst$$Register); 9795 %} 9796 ins_pipe(ialu_reg); 9797 %} 9798 9799 // Xor Register with Immediate 9800 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9801 %{ 9802 match(Set dst (XorI dst src)); 9803 effect(KILL cr); 9804 9805 format %{ "xorl $dst, $src\t# int" %} 9806 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9807 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9808 ins_pipe(ialu_reg); 9809 %} 9810 9811 // Xor Register with Memory 9812 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9813 %{ 9814 match(Set dst (XorI dst (LoadI src))); 9815 effect(KILL cr); 9816 9817 ins_cost(125); 9818 format %{ "xorl $dst, $src\t# int" %} 9819 opcode(0x33); 9820 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9821 ins_pipe(ialu_reg_mem); 9822 %} 9823 9824 // Xor Memory with Register 9825 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9826 %{ 9827 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9828 effect(KILL cr); 9829 9830 ins_cost(150); 9831 format %{ "xorb $dst, $src\t# byte" %} 9832 opcode(0x30); 9833 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9834 ins_pipe(ialu_mem_reg); 9835 %} 9836 9837 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9838 %{ 9839 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9840 effect(KILL cr); 9841 9842 ins_cost(150); 9843 format %{ "xorl $dst, $src\t# int" %} 9844 opcode(0x31); /* Opcode 31 /r */ 9845 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9846 ins_pipe(ialu_mem_reg); 9847 %} 9848 9849 // Xor Memory with Immediate 9850 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9851 %{ 9852 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9853 effect(KILL cr); 9854 9855 ins_cost(125); 9856 format %{ "xorl $dst, $src\t# int" %} 9857 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9858 ins_encode(REX_mem(dst), OpcSE(src), 9859 RM_opc_mem(secondary, dst), Con8or32(src)); 9860 ins_pipe(ialu_mem_imm); 9861 %} 9862 9863 9864 // Long Logical Instructions 9865 9866 // And Instructions 9867 // And Register with Register 9868 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9869 %{ 9870 match(Set dst (AndL dst src)); 9871 effect(KILL cr); 9872 9873 format %{ "andq $dst, $src\t# long" %} 9874 opcode(0x23); 9875 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9876 ins_pipe(ialu_reg_reg); 9877 %} 9878 9879 // And Register with Immediate 255 9880 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9881 %{ 9882 match(Set dst (AndL dst src)); 9883 9884 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9885 opcode(0x0F, 0xB6); 9886 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9887 ins_pipe(ialu_reg); 9888 %} 9889 9890 // And Register with Immediate 65535 9891 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9892 %{ 9893 match(Set dst (AndL dst src)); 9894 9895 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9896 opcode(0x0F, 0xB7); 9897 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9898 ins_pipe(ialu_reg); 9899 %} 9900 9901 // And Register with Immediate 9902 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9903 %{ 9904 match(Set dst (AndL dst src)); 9905 effect(KILL cr); 9906 9907 format %{ "andq $dst, $src\t# long" %} 9908 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9909 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9910 ins_pipe(ialu_reg); 9911 %} 9912 9913 // And Register with Memory 9914 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9915 %{ 9916 match(Set dst (AndL dst (LoadL src))); 9917 effect(KILL cr); 9918 9919 ins_cost(125); 9920 format %{ "andq $dst, $src\t# long" %} 9921 opcode(0x23); 9922 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9923 ins_pipe(ialu_reg_mem); 9924 %} 9925 9926 // And Memory with Register 9927 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9928 %{ 9929 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9930 effect(KILL cr); 9931 9932 ins_cost(150); 9933 format %{ "andq $dst, $src\t# long" %} 9934 opcode(0x21); /* Opcode 21 /r */ 9935 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9936 ins_pipe(ialu_mem_reg); 9937 %} 9938 9939 // And Memory with Immediate 9940 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9941 %{ 9942 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9943 effect(KILL cr); 9944 9945 ins_cost(125); 9946 format %{ "andq $dst, $src\t# long" %} 9947 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9948 ins_encode(REX_mem_wide(dst), OpcSE(src), 9949 RM_opc_mem(secondary, dst), Con8or32(src)); 9950 ins_pipe(ialu_mem_imm); 9951 %} 9952 9953 // BMI1 instructions 9954 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9955 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9956 predicate(UseBMI1Instructions); 9957 effect(KILL cr); 9958 9959 ins_cost(125); 9960 format %{ "andnq $dst, $src1, $src2" %} 9961 9962 ins_encode %{ 9963 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9964 %} 9965 ins_pipe(ialu_reg_mem); 9966 %} 9967 9968 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9969 match(Set dst (AndL (XorL src1 minus_1) src2)); 9970 predicate(UseBMI1Instructions); 9971 effect(KILL cr); 9972 9973 format %{ "andnq $dst, $src1, $src2" %} 9974 9975 ins_encode %{ 9976 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9977 %} 9978 ins_pipe(ialu_reg_mem); 9979 %} 9980 9981 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9982 match(Set dst (AndL (SubL imm_zero src) src)); 9983 predicate(UseBMI1Instructions); 9984 effect(KILL cr); 9985 9986 format %{ "blsiq $dst, $src" %} 9987 9988 ins_encode %{ 9989 __ blsiq($dst$$Register, $src$$Register); 9990 %} 9991 ins_pipe(ialu_reg); 9992 %} 9993 9994 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9995 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9996 predicate(UseBMI1Instructions); 9997 effect(KILL cr); 9998 9999 ins_cost(125); 10000 format %{ "blsiq $dst, $src" %} 10001 10002 ins_encode %{ 10003 __ blsiq($dst$$Register, $src$$Address); 10004 %} 10005 ins_pipe(ialu_reg_mem); 10006 %} 10007 10008 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10009 %{ 10010 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 10011 predicate(UseBMI1Instructions); 10012 effect(KILL cr); 10013 10014 ins_cost(125); 10015 format %{ "blsmskq $dst, $src" %} 10016 10017 ins_encode %{ 10018 __ blsmskq($dst$$Register, $src$$Address); 10019 %} 10020 ins_pipe(ialu_reg_mem); 10021 %} 10022 10023 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10024 %{ 10025 match(Set dst (XorL (AddL src minus_1) src)); 10026 predicate(UseBMI1Instructions); 10027 effect(KILL cr); 10028 10029 format %{ "blsmskq $dst, $src" %} 10030 10031 ins_encode %{ 10032 __ blsmskq($dst$$Register, $src$$Register); 10033 %} 10034 10035 ins_pipe(ialu_reg); 10036 %} 10037 10038 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10039 %{ 10040 match(Set dst (AndL (AddL src minus_1) src) ); 10041 predicate(UseBMI1Instructions); 10042 effect(KILL cr); 10043 10044 format %{ "blsrq $dst, $src" %} 10045 10046 ins_encode %{ 10047 __ blsrq($dst$$Register, $src$$Register); 10048 %} 10049 10050 ins_pipe(ialu_reg); 10051 %} 10052 10053 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10054 %{ 10055 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 10056 predicate(UseBMI1Instructions); 10057 effect(KILL cr); 10058 10059 ins_cost(125); 10060 format %{ "blsrq $dst, $src" %} 10061 10062 ins_encode %{ 10063 __ blsrq($dst$$Register, $src$$Address); 10064 %} 10065 10066 ins_pipe(ialu_reg); 10067 %} 10068 10069 // Or Instructions 10070 // Or Register with Register 10071 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10072 %{ 10073 match(Set dst (OrL dst src)); 10074 effect(KILL cr); 10075 10076 format %{ "orq $dst, $src\t# long" %} 10077 opcode(0x0B); 10078 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10079 ins_pipe(ialu_reg_reg); 10080 %} 10081 10082 // Use any_RegP to match R15 (TLS register) without spilling. 10083 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 10084 match(Set dst (OrL dst (CastP2X src))); 10085 effect(KILL cr); 10086 10087 format %{ "orq $dst, $src\t# long" %} 10088 opcode(0x0B); 10089 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10090 ins_pipe(ialu_reg_reg); 10091 %} 10092 10093 10094 // Or Register with Immediate 10095 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10096 %{ 10097 match(Set dst (OrL dst src)); 10098 effect(KILL cr); 10099 10100 format %{ "orq $dst, $src\t# long" %} 10101 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 10102 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10103 ins_pipe(ialu_reg); 10104 %} 10105 10106 // Or Register with Memory 10107 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10108 %{ 10109 match(Set dst (OrL dst (LoadL src))); 10110 effect(KILL cr); 10111 10112 ins_cost(125); 10113 format %{ "orq $dst, $src\t# long" %} 10114 opcode(0x0B); 10115 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10116 ins_pipe(ialu_reg_mem); 10117 %} 10118 10119 // Or Memory with Register 10120 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10121 %{ 10122 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10123 effect(KILL cr); 10124 10125 ins_cost(150); 10126 format %{ "orq $dst, $src\t# long" %} 10127 opcode(0x09); /* Opcode 09 /r */ 10128 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10129 ins_pipe(ialu_mem_reg); 10130 %} 10131 10132 // Or Memory with Immediate 10133 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10134 %{ 10135 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10136 effect(KILL cr); 10137 10138 ins_cost(125); 10139 format %{ "orq $dst, $src\t# long" %} 10140 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 10141 ins_encode(REX_mem_wide(dst), OpcSE(src), 10142 RM_opc_mem(secondary, dst), Con8or32(src)); 10143 ins_pipe(ialu_mem_imm); 10144 %} 10145 10146 // Xor Instructions 10147 // Xor Register with Register 10148 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10149 %{ 10150 match(Set dst (XorL dst src)); 10151 effect(KILL cr); 10152 10153 format %{ "xorq $dst, $src\t# long" %} 10154 opcode(0x33); 10155 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10156 ins_pipe(ialu_reg_reg); 10157 %} 10158 10159 // Xor Register with Immediate -1 10160 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10161 match(Set dst (XorL dst imm)); 10162 10163 format %{ "notq $dst" %} 10164 ins_encode %{ 10165 __ notq($dst$$Register); 10166 %} 10167 ins_pipe(ialu_reg); 10168 %} 10169 10170 // Xor Register with Immediate 10171 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10172 %{ 10173 match(Set dst (XorL dst src)); 10174 effect(KILL cr); 10175 10176 format %{ "xorq $dst, $src\t# long" %} 10177 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10178 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10179 ins_pipe(ialu_reg); 10180 %} 10181 10182 // Xor Register with Memory 10183 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10184 %{ 10185 match(Set dst (XorL dst (LoadL src))); 10186 effect(KILL cr); 10187 10188 ins_cost(125); 10189 format %{ "xorq $dst, $src\t# long" %} 10190 opcode(0x33); 10191 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10192 ins_pipe(ialu_reg_mem); 10193 %} 10194 10195 // Xor Memory with Register 10196 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10197 %{ 10198 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10199 effect(KILL cr); 10200 10201 ins_cost(150); 10202 format %{ "xorq $dst, $src\t# long" %} 10203 opcode(0x31); /* Opcode 31 /r */ 10204 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10205 ins_pipe(ialu_mem_reg); 10206 %} 10207 10208 // Xor Memory with Immediate 10209 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10210 %{ 10211 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10212 effect(KILL cr); 10213 10214 ins_cost(125); 10215 format %{ "xorq $dst, $src\t# long" %} 10216 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10217 ins_encode(REX_mem_wide(dst), OpcSE(src), 10218 RM_opc_mem(secondary, dst), Con8or32(src)); 10219 ins_pipe(ialu_mem_imm); 10220 %} 10221 10222 // Convert Int to Boolean 10223 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10224 %{ 10225 match(Set dst (Conv2B src)); 10226 effect(KILL cr); 10227 10228 format %{ "testl $src, $src\t# ci2b\n\t" 10229 "setnz $dst\n\t" 10230 "movzbl $dst, $dst" %} 10231 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10232 setNZ_reg(dst), 10233 REX_reg_breg(dst, dst), // movzbl 10234 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10235 ins_pipe(pipe_slow); // XXX 10236 %} 10237 10238 // Convert Pointer to Boolean 10239 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10240 %{ 10241 match(Set dst (Conv2B src)); 10242 effect(KILL cr); 10243 10244 format %{ "testq $src, $src\t# cp2b\n\t" 10245 "setnz $dst\n\t" 10246 "movzbl $dst, $dst" %} 10247 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10248 setNZ_reg(dst), 10249 REX_reg_breg(dst, dst), // movzbl 10250 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10251 ins_pipe(pipe_slow); // XXX 10252 %} 10253 10254 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10255 %{ 10256 match(Set dst (CmpLTMask p q)); 10257 effect(KILL cr); 10258 10259 ins_cost(400); 10260 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10261 "setlt $dst\n\t" 10262 "movzbl $dst, $dst\n\t" 10263 "negl $dst" %} 10264 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10265 setLT_reg(dst), 10266 REX_reg_breg(dst, dst), // movzbl 10267 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10268 neg_reg(dst)); 10269 ins_pipe(pipe_slow); 10270 %} 10271 10272 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10273 %{ 10274 match(Set dst (CmpLTMask dst zero)); 10275 effect(KILL cr); 10276 10277 ins_cost(100); 10278 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10279 ins_encode %{ 10280 __ sarl($dst$$Register, 31); 10281 %} 10282 ins_pipe(ialu_reg); 10283 %} 10284 10285 /* Better to save a register than avoid a branch */ 10286 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10287 %{ 10288 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10289 effect(KILL cr); 10290 ins_cost(300); 10291 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10292 "jge done\n\t" 10293 "addl $p,$y\n" 10294 "done: " %} 10295 ins_encode %{ 10296 Register Rp = $p$$Register; 10297 Register Rq = $q$$Register; 10298 Register Ry = $y$$Register; 10299 Label done; 10300 __ subl(Rp, Rq); 10301 __ jccb(Assembler::greaterEqual, done); 10302 __ addl(Rp, Ry); 10303 __ bind(done); 10304 %} 10305 ins_pipe(pipe_cmplt); 10306 %} 10307 10308 /* Better to save a register than avoid a branch */ 10309 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10310 %{ 10311 match(Set y (AndI (CmpLTMask p q) y)); 10312 effect(KILL cr); 10313 10314 ins_cost(300); 10315 10316 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10317 "jlt done\n\t" 10318 "xorl $y, $y\n" 10319 "done: " %} 10320 ins_encode %{ 10321 Register Rp = $p$$Register; 10322 Register Rq = $q$$Register; 10323 Register Ry = $y$$Register; 10324 Label done; 10325 __ cmpl(Rp, Rq); 10326 __ jccb(Assembler::less, done); 10327 __ xorl(Ry, Ry); 10328 __ bind(done); 10329 %} 10330 ins_pipe(pipe_cmplt); 10331 %} 10332 10333 10334 //---------- FP Instructions------------------------------------------------ 10335 10336 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10337 %{ 10338 match(Set cr (CmpF src1 src2)); 10339 10340 ins_cost(145); 10341 format %{ "ucomiss $src1, $src2\n\t" 10342 "jnp,s exit\n\t" 10343 "pushfq\t# saw NaN, set CF\n\t" 10344 "andq [rsp], #0xffffff2b\n\t" 10345 "popfq\n" 10346 "exit:" %} 10347 ins_encode %{ 10348 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10349 emit_cmpfp_fixup(_masm); 10350 %} 10351 ins_pipe(pipe_slow); 10352 %} 10353 10354 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10355 match(Set cr (CmpF src1 src2)); 10356 10357 ins_cost(100); 10358 format %{ "ucomiss $src1, $src2" %} 10359 ins_encode %{ 10360 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10361 %} 10362 ins_pipe(pipe_slow); 10363 %} 10364 10365 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10366 %{ 10367 match(Set cr (CmpF src1 (LoadF src2))); 10368 10369 ins_cost(145); 10370 format %{ "ucomiss $src1, $src2\n\t" 10371 "jnp,s exit\n\t" 10372 "pushfq\t# saw NaN, set CF\n\t" 10373 "andq [rsp], #0xffffff2b\n\t" 10374 "popfq\n" 10375 "exit:" %} 10376 ins_encode %{ 10377 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10378 emit_cmpfp_fixup(_masm); 10379 %} 10380 ins_pipe(pipe_slow); 10381 %} 10382 10383 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10384 match(Set cr (CmpF src1 (LoadF src2))); 10385 10386 ins_cost(100); 10387 format %{ "ucomiss $src1, $src2" %} 10388 ins_encode %{ 10389 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10390 %} 10391 ins_pipe(pipe_slow); 10392 %} 10393 10394 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10395 match(Set cr (CmpF src con)); 10396 10397 ins_cost(145); 10398 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10399 "jnp,s exit\n\t" 10400 "pushfq\t# saw NaN, set CF\n\t" 10401 "andq [rsp], #0xffffff2b\n\t" 10402 "popfq\n" 10403 "exit:" %} 10404 ins_encode %{ 10405 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10406 emit_cmpfp_fixup(_masm); 10407 %} 10408 ins_pipe(pipe_slow); 10409 %} 10410 10411 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10412 match(Set cr (CmpF src con)); 10413 ins_cost(100); 10414 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10415 ins_encode %{ 10416 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10417 %} 10418 ins_pipe(pipe_slow); 10419 %} 10420 10421 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10422 %{ 10423 match(Set cr (CmpD src1 src2)); 10424 10425 ins_cost(145); 10426 format %{ "ucomisd $src1, $src2\n\t" 10427 "jnp,s exit\n\t" 10428 "pushfq\t# saw NaN, set CF\n\t" 10429 "andq [rsp], #0xffffff2b\n\t" 10430 "popfq\n" 10431 "exit:" %} 10432 ins_encode %{ 10433 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10434 emit_cmpfp_fixup(_masm); 10435 %} 10436 ins_pipe(pipe_slow); 10437 %} 10438 10439 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10440 match(Set cr (CmpD src1 src2)); 10441 10442 ins_cost(100); 10443 format %{ "ucomisd $src1, $src2 test" %} 10444 ins_encode %{ 10445 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10446 %} 10447 ins_pipe(pipe_slow); 10448 %} 10449 10450 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10451 %{ 10452 match(Set cr (CmpD src1 (LoadD src2))); 10453 10454 ins_cost(145); 10455 format %{ "ucomisd $src1, $src2\n\t" 10456 "jnp,s exit\n\t" 10457 "pushfq\t# saw NaN, set CF\n\t" 10458 "andq [rsp], #0xffffff2b\n\t" 10459 "popfq\n" 10460 "exit:" %} 10461 ins_encode %{ 10462 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10463 emit_cmpfp_fixup(_masm); 10464 %} 10465 ins_pipe(pipe_slow); 10466 %} 10467 10468 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10469 match(Set cr (CmpD src1 (LoadD src2))); 10470 10471 ins_cost(100); 10472 format %{ "ucomisd $src1, $src2" %} 10473 ins_encode %{ 10474 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10475 %} 10476 ins_pipe(pipe_slow); 10477 %} 10478 10479 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10480 match(Set cr (CmpD src con)); 10481 10482 ins_cost(145); 10483 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10484 "jnp,s exit\n\t" 10485 "pushfq\t# saw NaN, set CF\n\t" 10486 "andq [rsp], #0xffffff2b\n\t" 10487 "popfq\n" 10488 "exit:" %} 10489 ins_encode %{ 10490 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10491 emit_cmpfp_fixup(_masm); 10492 %} 10493 ins_pipe(pipe_slow); 10494 %} 10495 10496 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10497 match(Set cr (CmpD src con)); 10498 ins_cost(100); 10499 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10500 ins_encode %{ 10501 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10502 %} 10503 ins_pipe(pipe_slow); 10504 %} 10505 10506 // Compare into -1,0,1 10507 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10508 %{ 10509 match(Set dst (CmpF3 src1 src2)); 10510 effect(KILL cr); 10511 10512 ins_cost(275); 10513 format %{ "ucomiss $src1, $src2\n\t" 10514 "movl $dst, #-1\n\t" 10515 "jp,s done\n\t" 10516 "jb,s done\n\t" 10517 "setne $dst\n\t" 10518 "movzbl $dst, $dst\n" 10519 "done:" %} 10520 ins_encode %{ 10521 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10522 emit_cmpfp3(_masm, $dst$$Register); 10523 %} 10524 ins_pipe(pipe_slow); 10525 %} 10526 10527 // Compare into -1,0,1 10528 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10529 %{ 10530 match(Set dst (CmpF3 src1 (LoadF src2))); 10531 effect(KILL cr); 10532 10533 ins_cost(275); 10534 format %{ "ucomiss $src1, $src2\n\t" 10535 "movl $dst, #-1\n\t" 10536 "jp,s done\n\t" 10537 "jb,s done\n\t" 10538 "setne $dst\n\t" 10539 "movzbl $dst, $dst\n" 10540 "done:" %} 10541 ins_encode %{ 10542 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10543 emit_cmpfp3(_masm, $dst$$Register); 10544 %} 10545 ins_pipe(pipe_slow); 10546 %} 10547 10548 // Compare into -1,0,1 10549 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10550 match(Set dst (CmpF3 src con)); 10551 effect(KILL cr); 10552 10553 ins_cost(275); 10554 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10555 "movl $dst, #-1\n\t" 10556 "jp,s done\n\t" 10557 "jb,s done\n\t" 10558 "setne $dst\n\t" 10559 "movzbl $dst, $dst\n" 10560 "done:" %} 10561 ins_encode %{ 10562 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10563 emit_cmpfp3(_masm, $dst$$Register); 10564 %} 10565 ins_pipe(pipe_slow); 10566 %} 10567 10568 // Compare into -1,0,1 10569 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10570 %{ 10571 match(Set dst (CmpD3 src1 src2)); 10572 effect(KILL cr); 10573 10574 ins_cost(275); 10575 format %{ "ucomisd $src1, $src2\n\t" 10576 "movl $dst, #-1\n\t" 10577 "jp,s done\n\t" 10578 "jb,s done\n\t" 10579 "setne $dst\n\t" 10580 "movzbl $dst, $dst\n" 10581 "done:" %} 10582 ins_encode %{ 10583 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10584 emit_cmpfp3(_masm, $dst$$Register); 10585 %} 10586 ins_pipe(pipe_slow); 10587 %} 10588 10589 // Compare into -1,0,1 10590 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10591 %{ 10592 match(Set dst (CmpD3 src1 (LoadD src2))); 10593 effect(KILL cr); 10594 10595 ins_cost(275); 10596 format %{ "ucomisd $src1, $src2\n\t" 10597 "movl $dst, #-1\n\t" 10598 "jp,s done\n\t" 10599 "jb,s done\n\t" 10600 "setne $dst\n\t" 10601 "movzbl $dst, $dst\n" 10602 "done:" %} 10603 ins_encode %{ 10604 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10605 emit_cmpfp3(_masm, $dst$$Register); 10606 %} 10607 ins_pipe(pipe_slow); 10608 %} 10609 10610 // Compare into -1,0,1 10611 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10612 match(Set dst (CmpD3 src con)); 10613 effect(KILL cr); 10614 10615 ins_cost(275); 10616 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10617 "movl $dst, #-1\n\t" 10618 "jp,s done\n\t" 10619 "jb,s done\n\t" 10620 "setne $dst\n\t" 10621 "movzbl $dst, $dst\n" 10622 "done:" %} 10623 ins_encode %{ 10624 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10625 emit_cmpfp3(_masm, $dst$$Register); 10626 %} 10627 ins_pipe(pipe_slow); 10628 %} 10629 10630 //----------Arithmetic Conversion Instructions--------------------------------- 10631 10632 instruct roundFloat_nop(regF dst) 10633 %{ 10634 match(Set dst (RoundFloat dst)); 10635 10636 ins_cost(0); 10637 ins_encode(); 10638 ins_pipe(empty); 10639 %} 10640 10641 instruct roundDouble_nop(regD dst) 10642 %{ 10643 match(Set dst (RoundDouble dst)); 10644 10645 ins_cost(0); 10646 ins_encode(); 10647 ins_pipe(empty); 10648 %} 10649 10650 instruct convF2D_reg_reg(regD dst, regF src) 10651 %{ 10652 match(Set dst (ConvF2D src)); 10653 10654 format %{ "cvtss2sd $dst, $src" %} 10655 ins_encode %{ 10656 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10657 %} 10658 ins_pipe(pipe_slow); // XXX 10659 %} 10660 10661 instruct convF2D_reg_mem(regD dst, memory src) 10662 %{ 10663 match(Set dst (ConvF2D (LoadF src))); 10664 10665 format %{ "cvtss2sd $dst, $src" %} 10666 ins_encode %{ 10667 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10668 %} 10669 ins_pipe(pipe_slow); // XXX 10670 %} 10671 10672 instruct convD2F_reg_reg(regF dst, regD src) 10673 %{ 10674 match(Set dst (ConvD2F src)); 10675 10676 format %{ "cvtsd2ss $dst, $src" %} 10677 ins_encode %{ 10678 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10679 %} 10680 ins_pipe(pipe_slow); // XXX 10681 %} 10682 10683 instruct convD2F_reg_mem(regF dst, memory src) 10684 %{ 10685 match(Set dst (ConvD2F (LoadD src))); 10686 10687 format %{ "cvtsd2ss $dst, $src" %} 10688 ins_encode %{ 10689 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10690 %} 10691 ins_pipe(pipe_slow); // XXX 10692 %} 10693 10694 // XXX do mem variants 10695 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10696 %{ 10697 match(Set dst (ConvF2I src)); 10698 effect(KILL cr); 10699 10700 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10701 "cmpl $dst, #0x80000000\n\t" 10702 "jne,s done\n\t" 10703 "subq rsp, #8\n\t" 10704 "movss [rsp], $src\n\t" 10705 "call f2i_fixup\n\t" 10706 "popq $dst\n" 10707 "done: "%} 10708 ins_encode %{ 10709 Label done; 10710 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10711 __ cmpl($dst$$Register, 0x80000000); 10712 __ jccb(Assembler::notEqual, done); 10713 __ subptr(rsp, 8); 10714 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10715 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10716 __ pop($dst$$Register); 10717 __ bind(done); 10718 %} 10719 ins_pipe(pipe_slow); 10720 %} 10721 10722 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10723 %{ 10724 match(Set dst (ConvF2L src)); 10725 effect(KILL cr); 10726 10727 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10728 "cmpq $dst, [0x8000000000000000]\n\t" 10729 "jne,s done\n\t" 10730 "subq rsp, #8\n\t" 10731 "movss [rsp], $src\n\t" 10732 "call f2l_fixup\n\t" 10733 "popq $dst\n" 10734 "done: "%} 10735 ins_encode %{ 10736 Label done; 10737 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10738 __ cmp64($dst$$Register, 10739 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10740 __ jccb(Assembler::notEqual, done); 10741 __ subptr(rsp, 8); 10742 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10743 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10744 __ pop($dst$$Register); 10745 __ bind(done); 10746 %} 10747 ins_pipe(pipe_slow); 10748 %} 10749 10750 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10751 %{ 10752 match(Set dst (ConvD2I src)); 10753 effect(KILL cr); 10754 10755 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10756 "cmpl $dst, #0x80000000\n\t" 10757 "jne,s done\n\t" 10758 "subq rsp, #8\n\t" 10759 "movsd [rsp], $src\n\t" 10760 "call d2i_fixup\n\t" 10761 "popq $dst\n" 10762 "done: "%} 10763 ins_encode %{ 10764 Label done; 10765 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10766 __ cmpl($dst$$Register, 0x80000000); 10767 __ jccb(Assembler::notEqual, done); 10768 __ subptr(rsp, 8); 10769 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10770 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10771 __ pop($dst$$Register); 10772 __ bind(done); 10773 %} 10774 ins_pipe(pipe_slow); 10775 %} 10776 10777 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10778 %{ 10779 match(Set dst (ConvD2L src)); 10780 effect(KILL cr); 10781 10782 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10783 "cmpq $dst, [0x8000000000000000]\n\t" 10784 "jne,s done\n\t" 10785 "subq rsp, #8\n\t" 10786 "movsd [rsp], $src\n\t" 10787 "call d2l_fixup\n\t" 10788 "popq $dst\n" 10789 "done: "%} 10790 ins_encode %{ 10791 Label done; 10792 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10793 __ cmp64($dst$$Register, 10794 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10795 __ jccb(Assembler::notEqual, done); 10796 __ subptr(rsp, 8); 10797 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10798 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10799 __ pop($dst$$Register); 10800 __ bind(done); 10801 %} 10802 ins_pipe(pipe_slow); 10803 %} 10804 10805 instruct convI2F_reg_reg(regF dst, rRegI src) 10806 %{ 10807 predicate(!UseXmmI2F); 10808 match(Set dst (ConvI2F src)); 10809 10810 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10811 ins_encode %{ 10812 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10813 %} 10814 ins_pipe(pipe_slow); // XXX 10815 %} 10816 10817 instruct convI2F_reg_mem(regF dst, memory src) 10818 %{ 10819 match(Set dst (ConvI2F (LoadI src))); 10820 10821 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10822 ins_encode %{ 10823 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10824 %} 10825 ins_pipe(pipe_slow); // XXX 10826 %} 10827 10828 instruct convI2D_reg_reg(regD dst, rRegI src) 10829 %{ 10830 predicate(!UseXmmI2D); 10831 match(Set dst (ConvI2D src)); 10832 10833 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10834 ins_encode %{ 10835 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10836 %} 10837 ins_pipe(pipe_slow); // XXX 10838 %} 10839 10840 instruct convI2D_reg_mem(regD dst, memory src) 10841 %{ 10842 match(Set dst (ConvI2D (LoadI src))); 10843 10844 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10845 ins_encode %{ 10846 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10847 %} 10848 ins_pipe(pipe_slow); // XXX 10849 %} 10850 10851 instruct convXI2F_reg(regF dst, rRegI src) 10852 %{ 10853 predicate(UseXmmI2F); 10854 match(Set dst (ConvI2F src)); 10855 10856 format %{ "movdl $dst, $src\n\t" 10857 "cvtdq2psl $dst, $dst\t# i2f" %} 10858 ins_encode %{ 10859 __ movdl($dst$$XMMRegister, $src$$Register); 10860 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10861 %} 10862 ins_pipe(pipe_slow); // XXX 10863 %} 10864 10865 instruct convXI2D_reg(regD dst, rRegI src) 10866 %{ 10867 predicate(UseXmmI2D); 10868 match(Set dst (ConvI2D src)); 10869 10870 format %{ "movdl $dst, $src\n\t" 10871 "cvtdq2pdl $dst, $dst\t# i2d" %} 10872 ins_encode %{ 10873 __ movdl($dst$$XMMRegister, $src$$Register); 10874 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10875 %} 10876 ins_pipe(pipe_slow); // XXX 10877 %} 10878 10879 instruct convL2F_reg_reg(regF dst, rRegL src) 10880 %{ 10881 match(Set dst (ConvL2F src)); 10882 10883 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10884 ins_encode %{ 10885 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10886 %} 10887 ins_pipe(pipe_slow); // XXX 10888 %} 10889 10890 instruct convL2F_reg_mem(regF dst, memory src) 10891 %{ 10892 match(Set dst (ConvL2F (LoadL src))); 10893 10894 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10895 ins_encode %{ 10896 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10897 %} 10898 ins_pipe(pipe_slow); // XXX 10899 %} 10900 10901 instruct convL2D_reg_reg(regD dst, rRegL src) 10902 %{ 10903 match(Set dst (ConvL2D src)); 10904 10905 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10906 ins_encode %{ 10907 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10908 %} 10909 ins_pipe(pipe_slow); // XXX 10910 %} 10911 10912 instruct convL2D_reg_mem(regD dst, memory src) 10913 %{ 10914 match(Set dst (ConvL2D (LoadL src))); 10915 10916 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10917 ins_encode %{ 10918 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10919 %} 10920 ins_pipe(pipe_slow); // XXX 10921 %} 10922 10923 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10924 %{ 10925 match(Set dst (ConvI2L src)); 10926 10927 ins_cost(125); 10928 format %{ "movslq $dst, $src\t# i2l" %} 10929 ins_encode %{ 10930 __ movslq($dst$$Register, $src$$Register); 10931 %} 10932 ins_pipe(ialu_reg_reg); 10933 %} 10934 10935 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10936 // %{ 10937 // match(Set dst (ConvI2L src)); 10938 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10939 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10940 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10941 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10942 // ((const TypeNode*) n)->type()->is_long()->_lo == 10943 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10944 10945 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10946 // ins_encode(enc_copy(dst, src)); 10947 // // opcode(0x63); // needs REX.W 10948 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10949 // ins_pipe(ialu_reg_reg); 10950 // %} 10951 10952 // Zero-extend convert int to long 10953 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10954 %{ 10955 match(Set dst (AndL (ConvI2L src) mask)); 10956 10957 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10958 ins_encode %{ 10959 if ($dst$$reg != $src$$reg) { 10960 __ movl($dst$$Register, $src$$Register); 10961 } 10962 %} 10963 ins_pipe(ialu_reg_reg); 10964 %} 10965 10966 // Zero-extend convert int to long 10967 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10968 %{ 10969 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10970 10971 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10972 ins_encode %{ 10973 __ movl($dst$$Register, $src$$Address); 10974 %} 10975 ins_pipe(ialu_reg_mem); 10976 %} 10977 10978 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10979 %{ 10980 match(Set dst (AndL src mask)); 10981 10982 format %{ "movl $dst, $src\t# zero-extend long" %} 10983 ins_encode %{ 10984 __ movl($dst$$Register, $src$$Register); 10985 %} 10986 ins_pipe(ialu_reg_reg); 10987 %} 10988 10989 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10990 %{ 10991 match(Set dst (ConvL2I src)); 10992 10993 format %{ "movl $dst, $src\t# l2i" %} 10994 ins_encode %{ 10995 __ movl($dst$$Register, $src$$Register); 10996 %} 10997 ins_pipe(ialu_reg_reg); 10998 %} 10999 11000 11001 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 11002 match(Set dst (MoveF2I src)); 11003 effect(DEF dst, USE src); 11004 11005 ins_cost(125); 11006 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 11007 ins_encode %{ 11008 __ movl($dst$$Register, Address(rsp, $src$$disp)); 11009 %} 11010 ins_pipe(ialu_reg_mem); 11011 %} 11012 11013 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 11014 match(Set dst (MoveI2F src)); 11015 effect(DEF dst, USE src); 11016 11017 ins_cost(125); 11018 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 11019 ins_encode %{ 11020 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 11021 %} 11022 ins_pipe(pipe_slow); 11023 %} 11024 11025 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 11026 match(Set dst (MoveD2L src)); 11027 effect(DEF dst, USE src); 11028 11029 ins_cost(125); 11030 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 11031 ins_encode %{ 11032 __ movq($dst$$Register, Address(rsp, $src$$disp)); 11033 %} 11034 ins_pipe(ialu_reg_mem); 11035 %} 11036 11037 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 11038 predicate(!UseXmmLoadAndClearUpper); 11039 match(Set dst (MoveL2D src)); 11040 effect(DEF dst, USE src); 11041 11042 ins_cost(125); 11043 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 11044 ins_encode %{ 11045 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11046 %} 11047 ins_pipe(pipe_slow); 11048 %} 11049 11050 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 11051 predicate(UseXmmLoadAndClearUpper); 11052 match(Set dst (MoveL2D src)); 11053 effect(DEF dst, USE src); 11054 11055 ins_cost(125); 11056 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 11057 ins_encode %{ 11058 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11059 %} 11060 ins_pipe(pipe_slow); 11061 %} 11062 11063 11064 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 11065 match(Set dst (MoveF2I src)); 11066 effect(DEF dst, USE src); 11067 11068 ins_cost(95); // XXX 11069 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 11070 ins_encode %{ 11071 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 11072 %} 11073 ins_pipe(pipe_slow); 11074 %} 11075 11076 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 11077 match(Set dst (MoveI2F src)); 11078 effect(DEF dst, USE src); 11079 11080 ins_cost(100); 11081 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 11082 ins_encode %{ 11083 __ movl(Address(rsp, $dst$$disp), $src$$Register); 11084 %} 11085 ins_pipe( ialu_mem_reg ); 11086 %} 11087 11088 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 11089 match(Set dst (MoveD2L src)); 11090 effect(DEF dst, USE src); 11091 11092 ins_cost(95); // XXX 11093 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 11094 ins_encode %{ 11095 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 11096 %} 11097 ins_pipe(pipe_slow); 11098 %} 11099 11100 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 11101 match(Set dst (MoveL2D src)); 11102 effect(DEF dst, USE src); 11103 11104 ins_cost(100); 11105 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 11106 ins_encode %{ 11107 __ movq(Address(rsp, $dst$$disp), $src$$Register); 11108 %} 11109 ins_pipe(ialu_mem_reg); 11110 %} 11111 11112 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 11113 match(Set dst (MoveF2I src)); 11114 effect(DEF dst, USE src); 11115 ins_cost(85); 11116 format %{ "movd $dst,$src\t# MoveF2I" %} 11117 ins_encode %{ 11118 __ movdl($dst$$Register, $src$$XMMRegister); 11119 %} 11120 ins_pipe( pipe_slow ); 11121 %} 11122 11123 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 11124 match(Set dst (MoveD2L src)); 11125 effect(DEF dst, USE src); 11126 ins_cost(85); 11127 format %{ "movd $dst,$src\t# MoveD2L" %} 11128 ins_encode %{ 11129 __ movdq($dst$$Register, $src$$XMMRegister); 11130 %} 11131 ins_pipe( pipe_slow ); 11132 %} 11133 11134 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 11135 match(Set dst (MoveI2F src)); 11136 effect(DEF dst, USE src); 11137 ins_cost(100); 11138 format %{ "movd $dst,$src\t# MoveI2F" %} 11139 ins_encode %{ 11140 __ movdl($dst$$XMMRegister, $src$$Register); 11141 %} 11142 ins_pipe( pipe_slow ); 11143 %} 11144 11145 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 11146 match(Set dst (MoveL2D src)); 11147 effect(DEF dst, USE src); 11148 ins_cost(100); 11149 format %{ "movd $dst,$src\t# MoveL2D" %} 11150 ins_encode %{ 11151 __ movdq($dst$$XMMRegister, $src$$Register); 11152 %} 11153 ins_pipe( pipe_slow ); 11154 %} 11155 11156 11157 // ======================================================================= 11158 // fast clearing of an array 11159 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11160 Universe dummy, rFlagsReg cr) 11161 %{ 11162 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only()); 11163 match(Set dummy (ClearArray (Binary cnt base) val)); 11164 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11165 11166 format %{ $$template 11167 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11168 $$emit$$"jg LARGE\n\t" 11169 $$emit$$"dec rcx\n\t" 11170 $$emit$$"js DONE\t# Zero length\n\t" 11171 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11172 $$emit$$"dec rcx\n\t" 11173 $$emit$$"jge LOOP\n\t" 11174 $$emit$$"jmp DONE\n\t" 11175 $$emit$$"# LARGE:\n\t" 11176 if (UseFastStosb) { 11177 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11178 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 11179 } else if (UseXMMForObjInit) { 11180 $$emit$$"movdq $tmp, $val\n\t" 11181 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11182 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11183 $$emit$$"jmpq L_zero_64_bytes\n\t" 11184 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11185 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11186 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11187 $$emit$$"add 0x40,rax\n\t" 11188 $$emit$$"# L_zero_64_bytes:\n\t" 11189 $$emit$$"sub 0x8,rcx\n\t" 11190 $$emit$$"jge L_loop\n\t" 11191 $$emit$$"add 0x4,rcx\n\t" 11192 $$emit$$"jl L_tail\n\t" 11193 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11194 $$emit$$"add 0x20,rax\n\t" 11195 $$emit$$"sub 0x4,rcx\n\t" 11196 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11197 $$emit$$"add 0x4,rcx\n\t" 11198 $$emit$$"jle L_end\n\t" 11199 $$emit$$"dec rcx\n\t" 11200 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11201 $$emit$$"vmovq xmm0,(rax)\n\t" 11202 $$emit$$"add 0x8,rax\n\t" 11203 $$emit$$"dec rcx\n\t" 11204 $$emit$$"jge L_sloop\n\t" 11205 $$emit$$"# L_end:\n\t" 11206 } else { 11207 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11208 } 11209 $$emit$$"# DONE" 11210 %} 11211 ins_encode %{ 11212 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11213 $tmp$$XMMRegister, false, false); 11214 %} 11215 ins_pipe(pipe_slow); 11216 %} 11217 11218 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11219 Universe dummy, rFlagsReg cr) 11220 %{ 11221 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only()); 11222 match(Set dummy (ClearArray (Binary cnt base) val)); 11223 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11224 11225 format %{ $$template 11226 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11227 $$emit$$"jg LARGE\n\t" 11228 $$emit$$"dec rcx\n\t" 11229 $$emit$$"js DONE\t# Zero length\n\t" 11230 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11231 $$emit$$"dec rcx\n\t" 11232 $$emit$$"jge LOOP\n\t" 11233 $$emit$$"jmp DONE\n\t" 11234 $$emit$$"# LARGE:\n\t" 11235 if (UseXMMForObjInit) { 11236 $$emit$$"movdq $tmp, $val\n\t" 11237 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11238 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11239 $$emit$$"jmpq L_zero_64_bytes\n\t" 11240 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11241 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11242 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11243 $$emit$$"add 0x40,rax\n\t" 11244 $$emit$$"# L_zero_64_bytes:\n\t" 11245 $$emit$$"sub 0x8,rcx\n\t" 11246 $$emit$$"jge L_loop\n\t" 11247 $$emit$$"add 0x4,rcx\n\t" 11248 $$emit$$"jl L_tail\n\t" 11249 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11250 $$emit$$"add 0x20,rax\n\t" 11251 $$emit$$"sub 0x4,rcx\n\t" 11252 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11253 $$emit$$"add 0x4,rcx\n\t" 11254 $$emit$$"jle L_end\n\t" 11255 $$emit$$"dec rcx\n\t" 11256 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11257 $$emit$$"vmovq xmm0,(rax)\n\t" 11258 $$emit$$"add 0x8,rax\n\t" 11259 $$emit$$"dec rcx\n\t" 11260 $$emit$$"jge L_sloop\n\t" 11261 $$emit$$"# L_end:\n\t" 11262 } else { 11263 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11264 } 11265 $$emit$$"# DONE" 11266 %} 11267 ins_encode %{ 11268 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11269 $tmp$$XMMRegister, false, true); 11270 %} 11271 ins_pipe(pipe_slow); 11272 %} 11273 11274 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11275 Universe dummy, rFlagsReg cr) 11276 %{ 11277 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only()); 11278 match(Set dummy (ClearArray (Binary cnt base) val)); 11279 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11280 11281 format %{ $$template 11282 if (UseFastStosb) { 11283 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11284 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11285 } else if (UseXMMForObjInit) { 11286 $$emit$$"movdq $tmp, $val\n\t" 11287 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11288 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11289 $$emit$$"jmpq L_zero_64_bytes\n\t" 11290 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11291 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11292 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11293 $$emit$$"add 0x40,rax\n\t" 11294 $$emit$$"# L_zero_64_bytes:\n\t" 11295 $$emit$$"sub 0x8,rcx\n\t" 11296 $$emit$$"jge L_loop\n\t" 11297 $$emit$$"add 0x4,rcx\n\t" 11298 $$emit$$"jl L_tail\n\t" 11299 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11300 $$emit$$"add 0x20,rax\n\t" 11301 $$emit$$"sub 0x4,rcx\n\t" 11302 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11303 $$emit$$"add 0x4,rcx\n\t" 11304 $$emit$$"jle L_end\n\t" 11305 $$emit$$"dec rcx\n\t" 11306 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11307 $$emit$$"vmovq xmm0,(rax)\n\t" 11308 $$emit$$"add 0x8,rax\n\t" 11309 $$emit$$"dec rcx\n\t" 11310 $$emit$$"jge L_sloop\n\t" 11311 $$emit$$"# L_end:\n\t" 11312 } else { 11313 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11314 } 11315 %} 11316 ins_encode %{ 11317 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11318 $tmp$$XMMRegister, true, false); 11319 %} 11320 ins_pipe(pipe_slow); 11321 %} 11322 11323 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11324 Universe dummy, rFlagsReg cr) 11325 %{ 11326 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only()); 11327 match(Set dummy (ClearArray (Binary cnt base) val)); 11328 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11329 11330 format %{ $$template 11331 if (UseXMMForObjInit) { 11332 $$emit$$"movdq $tmp, $val\n\t" 11333 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11334 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11335 $$emit$$"jmpq L_zero_64_bytes\n\t" 11336 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11337 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11338 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11339 $$emit$$"add 0x40,rax\n\t" 11340 $$emit$$"# L_zero_64_bytes:\n\t" 11341 $$emit$$"sub 0x8,rcx\n\t" 11342 $$emit$$"jge L_loop\n\t" 11343 $$emit$$"add 0x4,rcx\n\t" 11344 $$emit$$"jl L_tail\n\t" 11345 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11346 $$emit$$"add 0x20,rax\n\t" 11347 $$emit$$"sub 0x4,rcx\n\t" 11348 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11349 $$emit$$"add 0x4,rcx\n\t" 11350 $$emit$$"jle L_end\n\t" 11351 $$emit$$"dec rcx\n\t" 11352 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11353 $$emit$$"vmovq xmm0,(rax)\n\t" 11354 $$emit$$"add 0x8,rax\n\t" 11355 $$emit$$"dec rcx\n\t" 11356 $$emit$$"jge L_sloop\n\t" 11357 $$emit$$"# L_end:\n\t" 11358 } else { 11359 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11360 } 11361 %} 11362 ins_encode %{ 11363 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11364 $tmp$$XMMRegister, true, true); 11365 %} 11366 ins_pipe(pipe_slow); 11367 %} 11368 11369 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11370 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11371 %{ 11372 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11373 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11374 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11375 11376 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11377 ins_encode %{ 11378 __ string_compare($str1$$Register, $str2$$Register, 11379 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11380 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11381 %} 11382 ins_pipe( pipe_slow ); 11383 %} 11384 11385 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11386 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11387 %{ 11388 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11389 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11390 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11391 11392 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11393 ins_encode %{ 11394 __ string_compare($str1$$Register, $str2$$Register, 11395 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11396 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11397 %} 11398 ins_pipe( pipe_slow ); 11399 %} 11400 11401 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11402 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11403 %{ 11404 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11405 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11406 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11407 11408 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11409 ins_encode %{ 11410 __ string_compare($str1$$Register, $str2$$Register, 11411 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11412 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11413 %} 11414 ins_pipe( pipe_slow ); 11415 %} 11416 11417 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11418 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11419 %{ 11420 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11421 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11422 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11423 11424 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11425 ins_encode %{ 11426 __ string_compare($str2$$Register, $str1$$Register, 11427 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11428 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11429 %} 11430 ins_pipe( pipe_slow ); 11431 %} 11432 11433 // fast search of substring with known size. 11434 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11435 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11436 %{ 11437 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11438 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11439 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11440 11441 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11442 ins_encode %{ 11443 int icnt2 = (int)$int_cnt2$$constant; 11444 if (icnt2 >= 16) { 11445 // IndexOf for constant substrings with size >= 16 elements 11446 // which don't need to be loaded through stack. 11447 __ string_indexofC8($str1$$Register, $str2$$Register, 11448 $cnt1$$Register, $cnt2$$Register, 11449 icnt2, $result$$Register, 11450 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11451 } else { 11452 // Small strings are loaded through stack if they cross page boundary. 11453 __ string_indexof($str1$$Register, $str2$$Register, 11454 $cnt1$$Register, $cnt2$$Register, 11455 icnt2, $result$$Register, 11456 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11457 } 11458 %} 11459 ins_pipe( pipe_slow ); 11460 %} 11461 11462 // fast search of substring with known size. 11463 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11464 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11465 %{ 11466 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11467 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11468 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11469 11470 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11471 ins_encode %{ 11472 int icnt2 = (int)$int_cnt2$$constant; 11473 if (icnt2 >= 8) { 11474 // IndexOf for constant substrings with size >= 8 elements 11475 // which don't need to be loaded through stack. 11476 __ string_indexofC8($str1$$Register, $str2$$Register, 11477 $cnt1$$Register, $cnt2$$Register, 11478 icnt2, $result$$Register, 11479 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11480 } else { 11481 // Small strings are loaded through stack if they cross page boundary. 11482 __ string_indexof($str1$$Register, $str2$$Register, 11483 $cnt1$$Register, $cnt2$$Register, 11484 icnt2, $result$$Register, 11485 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11486 } 11487 %} 11488 ins_pipe( pipe_slow ); 11489 %} 11490 11491 // fast search of substring with known size. 11492 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11493 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11494 %{ 11495 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11496 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11497 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11498 11499 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11500 ins_encode %{ 11501 int icnt2 = (int)$int_cnt2$$constant; 11502 if (icnt2 >= 8) { 11503 // IndexOf for constant substrings with size >= 8 elements 11504 // which don't need to be loaded through stack. 11505 __ string_indexofC8($str1$$Register, $str2$$Register, 11506 $cnt1$$Register, $cnt2$$Register, 11507 icnt2, $result$$Register, 11508 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11509 } else { 11510 // Small strings are loaded through stack if they cross page boundary. 11511 __ string_indexof($str1$$Register, $str2$$Register, 11512 $cnt1$$Register, $cnt2$$Register, 11513 icnt2, $result$$Register, 11514 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11515 } 11516 %} 11517 ins_pipe( pipe_slow ); 11518 %} 11519 11520 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11521 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11522 %{ 11523 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11524 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11525 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11526 11527 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11528 ins_encode %{ 11529 __ string_indexof($str1$$Register, $str2$$Register, 11530 $cnt1$$Register, $cnt2$$Register, 11531 (-1), $result$$Register, 11532 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11533 %} 11534 ins_pipe( pipe_slow ); 11535 %} 11536 11537 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11538 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11539 %{ 11540 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11541 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11542 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11543 11544 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11545 ins_encode %{ 11546 __ string_indexof($str1$$Register, $str2$$Register, 11547 $cnt1$$Register, $cnt2$$Register, 11548 (-1), $result$$Register, 11549 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11550 %} 11551 ins_pipe( pipe_slow ); 11552 %} 11553 11554 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11555 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11556 %{ 11557 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11558 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11559 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11560 11561 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11562 ins_encode %{ 11563 __ string_indexof($str1$$Register, $str2$$Register, 11564 $cnt1$$Register, $cnt2$$Register, 11565 (-1), $result$$Register, 11566 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11567 %} 11568 ins_pipe( pipe_slow ); 11569 %} 11570 11571 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11572 rbx_RegI result, legVecS vec1, legVecS vec2, legVecS vec3, rcx_RegI tmp, rFlagsReg cr) 11573 %{ 11574 predicate(UseSSE42Intrinsics); 11575 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11576 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11577 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11578 ins_encode %{ 11579 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11580 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11581 %} 11582 ins_pipe( pipe_slow ); 11583 %} 11584 11585 // fast string equals 11586 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11587 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11588 %{ 11589 match(Set result (StrEquals (Binary str1 str2) cnt)); 11590 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11591 11592 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11593 ins_encode %{ 11594 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11595 $cnt$$Register, $result$$Register, $tmp3$$Register, 11596 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11597 %} 11598 ins_pipe( pipe_slow ); 11599 %} 11600 11601 // fast array equals 11602 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11603 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11604 %{ 11605 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11606 match(Set result (AryEq ary1 ary2)); 11607 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11608 11609 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11610 ins_encode %{ 11611 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11612 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11613 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11614 %} 11615 ins_pipe( pipe_slow ); 11616 %} 11617 11618 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11619 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11620 %{ 11621 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11622 match(Set result (AryEq ary1 ary2)); 11623 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11624 11625 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11626 ins_encode %{ 11627 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11628 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11629 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11630 %} 11631 ins_pipe( pipe_slow ); 11632 %} 11633 11634 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11635 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11636 %{ 11637 match(Set result (HasNegatives ary1 len)); 11638 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11639 11640 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11641 ins_encode %{ 11642 __ has_negatives($ary1$$Register, $len$$Register, 11643 $result$$Register, $tmp3$$Register, 11644 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11645 %} 11646 ins_pipe( pipe_slow ); 11647 %} 11648 11649 // fast char[] to byte[] compression 11650 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11651 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11652 match(Set result (StrCompressedCopy src (Binary dst len))); 11653 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11654 11655 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11656 ins_encode %{ 11657 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11658 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11659 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11660 %} 11661 ins_pipe( pipe_slow ); 11662 %} 11663 11664 // fast byte[] to char[] inflation 11665 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11666 legVecS tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11667 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11668 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11669 11670 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11671 ins_encode %{ 11672 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11673 $tmp1$$XMMRegister, $tmp2$$Register); 11674 %} 11675 ins_pipe( pipe_slow ); 11676 %} 11677 11678 // encode char[] to byte[] in ISO_8859_1 11679 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11680 legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11681 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11682 match(Set result (EncodeISOArray src (Binary dst len))); 11683 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11684 11685 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11686 ins_encode %{ 11687 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11688 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11689 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11690 %} 11691 ins_pipe( pipe_slow ); 11692 %} 11693 11694 //----------Overflow Math Instructions----------------------------------------- 11695 11696 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11697 %{ 11698 match(Set cr (OverflowAddI op1 op2)); 11699 effect(DEF cr, USE_KILL op1, USE op2); 11700 11701 format %{ "addl $op1, $op2\t# overflow check int" %} 11702 11703 ins_encode %{ 11704 __ addl($op1$$Register, $op2$$Register); 11705 %} 11706 ins_pipe(ialu_reg_reg); 11707 %} 11708 11709 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11710 %{ 11711 match(Set cr (OverflowAddI op1 op2)); 11712 effect(DEF cr, USE_KILL op1, USE op2); 11713 11714 format %{ "addl $op1, $op2\t# overflow check int" %} 11715 11716 ins_encode %{ 11717 __ addl($op1$$Register, $op2$$constant); 11718 %} 11719 ins_pipe(ialu_reg_reg); 11720 %} 11721 11722 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11723 %{ 11724 match(Set cr (OverflowAddL op1 op2)); 11725 effect(DEF cr, USE_KILL op1, USE op2); 11726 11727 format %{ "addq $op1, $op2\t# overflow check long" %} 11728 ins_encode %{ 11729 __ addq($op1$$Register, $op2$$Register); 11730 %} 11731 ins_pipe(ialu_reg_reg); 11732 %} 11733 11734 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11735 %{ 11736 match(Set cr (OverflowAddL op1 op2)); 11737 effect(DEF cr, USE_KILL op1, USE op2); 11738 11739 format %{ "addq $op1, $op2\t# overflow check long" %} 11740 ins_encode %{ 11741 __ addq($op1$$Register, $op2$$constant); 11742 %} 11743 ins_pipe(ialu_reg_reg); 11744 %} 11745 11746 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11747 %{ 11748 match(Set cr (OverflowSubI op1 op2)); 11749 11750 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11751 ins_encode %{ 11752 __ cmpl($op1$$Register, $op2$$Register); 11753 %} 11754 ins_pipe(ialu_reg_reg); 11755 %} 11756 11757 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11758 %{ 11759 match(Set cr (OverflowSubI op1 op2)); 11760 11761 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11762 ins_encode %{ 11763 __ cmpl($op1$$Register, $op2$$constant); 11764 %} 11765 ins_pipe(ialu_reg_reg); 11766 %} 11767 11768 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11769 %{ 11770 match(Set cr (OverflowSubL op1 op2)); 11771 11772 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11773 ins_encode %{ 11774 __ cmpq($op1$$Register, $op2$$Register); 11775 %} 11776 ins_pipe(ialu_reg_reg); 11777 %} 11778 11779 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11780 %{ 11781 match(Set cr (OverflowSubL op1 op2)); 11782 11783 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11784 ins_encode %{ 11785 __ cmpq($op1$$Register, $op2$$constant); 11786 %} 11787 ins_pipe(ialu_reg_reg); 11788 %} 11789 11790 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11791 %{ 11792 match(Set cr (OverflowSubI zero op2)); 11793 effect(DEF cr, USE_KILL op2); 11794 11795 format %{ "negl $op2\t# overflow check int" %} 11796 ins_encode %{ 11797 __ negl($op2$$Register); 11798 %} 11799 ins_pipe(ialu_reg_reg); 11800 %} 11801 11802 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11803 %{ 11804 match(Set cr (OverflowSubL zero op2)); 11805 effect(DEF cr, USE_KILL op2); 11806 11807 format %{ "negq $op2\t# overflow check long" %} 11808 ins_encode %{ 11809 __ negq($op2$$Register); 11810 %} 11811 ins_pipe(ialu_reg_reg); 11812 %} 11813 11814 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11815 %{ 11816 match(Set cr (OverflowMulI op1 op2)); 11817 effect(DEF cr, USE_KILL op1, USE op2); 11818 11819 format %{ "imull $op1, $op2\t# overflow check int" %} 11820 ins_encode %{ 11821 __ imull($op1$$Register, $op2$$Register); 11822 %} 11823 ins_pipe(ialu_reg_reg_alu0); 11824 %} 11825 11826 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11827 %{ 11828 match(Set cr (OverflowMulI op1 op2)); 11829 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11830 11831 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11832 ins_encode %{ 11833 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11834 %} 11835 ins_pipe(ialu_reg_reg_alu0); 11836 %} 11837 11838 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11839 %{ 11840 match(Set cr (OverflowMulL op1 op2)); 11841 effect(DEF cr, USE_KILL op1, USE op2); 11842 11843 format %{ "imulq $op1, $op2\t# overflow check long" %} 11844 ins_encode %{ 11845 __ imulq($op1$$Register, $op2$$Register); 11846 %} 11847 ins_pipe(ialu_reg_reg_alu0); 11848 %} 11849 11850 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11851 %{ 11852 match(Set cr (OverflowMulL op1 op2)); 11853 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11854 11855 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11856 ins_encode %{ 11857 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11858 %} 11859 ins_pipe(ialu_reg_reg_alu0); 11860 %} 11861 11862 11863 //----------Control Flow Instructions------------------------------------------ 11864 // Signed compare Instructions 11865 11866 // XXX more variants!! 11867 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11868 %{ 11869 match(Set cr (CmpI op1 op2)); 11870 effect(DEF cr, USE op1, USE op2); 11871 11872 format %{ "cmpl $op1, $op2" %} 11873 opcode(0x3B); /* Opcode 3B /r */ 11874 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11875 ins_pipe(ialu_cr_reg_reg); 11876 %} 11877 11878 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11879 %{ 11880 match(Set cr (CmpI op1 op2)); 11881 11882 format %{ "cmpl $op1, $op2" %} 11883 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11884 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11885 ins_pipe(ialu_cr_reg_imm); 11886 %} 11887 11888 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11889 %{ 11890 match(Set cr (CmpI op1 (LoadI op2))); 11891 11892 ins_cost(500); // XXX 11893 format %{ "cmpl $op1, $op2" %} 11894 opcode(0x3B); /* Opcode 3B /r */ 11895 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11896 ins_pipe(ialu_cr_reg_mem); 11897 %} 11898 11899 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11900 %{ 11901 match(Set cr (CmpI src zero)); 11902 11903 format %{ "testl $src, $src" %} 11904 opcode(0x85); 11905 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11906 ins_pipe(ialu_cr_reg_imm); 11907 %} 11908 11909 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11910 %{ 11911 match(Set cr (CmpI (AndI src con) zero)); 11912 11913 format %{ "testl $src, $con" %} 11914 opcode(0xF7, 0x00); 11915 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11916 ins_pipe(ialu_cr_reg_imm); 11917 %} 11918 11919 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11920 %{ 11921 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11922 11923 format %{ "testl $src, $mem" %} 11924 opcode(0x85); 11925 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11926 ins_pipe(ialu_cr_reg_mem); 11927 %} 11928 11929 // Unsigned compare Instructions; really, same as signed except they 11930 // produce an rFlagsRegU instead of rFlagsReg. 11931 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11932 %{ 11933 match(Set cr (CmpU op1 op2)); 11934 11935 format %{ "cmpl $op1, $op2\t# unsigned" %} 11936 opcode(0x3B); /* Opcode 3B /r */ 11937 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11938 ins_pipe(ialu_cr_reg_reg); 11939 %} 11940 11941 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11942 %{ 11943 match(Set cr (CmpU op1 op2)); 11944 11945 format %{ "cmpl $op1, $op2\t# unsigned" %} 11946 opcode(0x81,0x07); /* Opcode 81 /7 */ 11947 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11948 ins_pipe(ialu_cr_reg_imm); 11949 %} 11950 11951 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11952 %{ 11953 match(Set cr (CmpU op1 (LoadI op2))); 11954 11955 ins_cost(500); // XXX 11956 format %{ "cmpl $op1, $op2\t# unsigned" %} 11957 opcode(0x3B); /* Opcode 3B /r */ 11958 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11959 ins_pipe(ialu_cr_reg_mem); 11960 %} 11961 11962 // // // Cisc-spilled version of cmpU_rReg 11963 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11964 // //%{ 11965 // // match(Set cr (CmpU (LoadI op1) op2)); 11966 // // 11967 // // format %{ "CMPu $op1,$op2" %} 11968 // // ins_cost(500); 11969 // // opcode(0x39); /* Opcode 39 /r */ 11970 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11971 // //%} 11972 11973 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11974 %{ 11975 match(Set cr (CmpU src zero)); 11976 11977 format %{ "testl $src, $src\t# unsigned" %} 11978 opcode(0x85); 11979 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11980 ins_pipe(ialu_cr_reg_imm); 11981 %} 11982 11983 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11984 %{ 11985 match(Set cr (CmpP op1 op2)); 11986 11987 format %{ "cmpq $op1, $op2\t# ptr" %} 11988 opcode(0x3B); /* Opcode 3B /r */ 11989 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11990 ins_pipe(ialu_cr_reg_reg); 11991 %} 11992 11993 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11994 %{ 11995 match(Set cr (CmpP op1 (LoadP op2))); 11996 11997 ins_cost(500); // XXX 11998 format %{ "cmpq $op1, $op2\t# ptr" %} 11999 opcode(0x3B); /* Opcode 3B /r */ 12000 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12001 ins_pipe(ialu_cr_reg_mem); 12002 %} 12003 12004 // // // Cisc-spilled version of cmpP_rReg 12005 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 12006 // //%{ 12007 // // match(Set cr (CmpP (LoadP op1) op2)); 12008 // // 12009 // // format %{ "CMPu $op1,$op2" %} 12010 // // ins_cost(500); 12011 // // opcode(0x39); /* Opcode 39 /r */ 12012 // // ins_encode( OpcP, reg_mem( op1, op2) ); 12013 // //%} 12014 12015 // XXX this is generalized by compP_rReg_mem??? 12016 // Compare raw pointer (used in out-of-heap check). 12017 // Only works because non-oop pointers must be raw pointers 12018 // and raw pointers have no anti-dependencies. 12019 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 12020 %{ 12021 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 12022 match(Set cr (CmpP op1 (LoadP op2))); 12023 12024 format %{ "cmpq $op1, $op2\t# raw ptr" %} 12025 opcode(0x3B); /* Opcode 3B /r */ 12026 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12027 ins_pipe(ialu_cr_reg_mem); 12028 %} 12029 12030 // This will generate a signed flags result. This should be OK since 12031 // any compare to a zero should be eq/neq. 12032 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 12033 %{ 12034 match(Set cr (CmpP src zero)); 12035 12036 format %{ "testq $src, $src\t# ptr" %} 12037 opcode(0x85); 12038 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12039 ins_pipe(ialu_cr_reg_imm); 12040 %} 12041 12042 // This will generate a signed flags result. This should be OK since 12043 // any compare to a zero should be eq/neq. 12044 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 12045 %{ 12046 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 12047 match(Set cr (CmpP (LoadP op) zero)); 12048 12049 ins_cost(500); // XXX 12050 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 12051 opcode(0xF7); /* Opcode F7 /0 */ 12052 ins_encode(REX_mem_wide(op), 12053 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 12054 ins_pipe(ialu_cr_reg_imm); 12055 %} 12056 12057 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 12058 %{ 12059 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 12060 match(Set cr (CmpP (LoadP mem) zero)); 12061 12062 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 12063 ins_encode %{ 12064 __ cmpq(r12, $mem$$Address); 12065 %} 12066 ins_pipe(ialu_cr_reg_mem); 12067 %} 12068 12069 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 12070 %{ 12071 match(Set cr (CmpN op1 op2)); 12072 12073 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12074 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 12075 ins_pipe(ialu_cr_reg_reg); 12076 %} 12077 12078 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 12079 %{ 12080 match(Set cr (CmpN src (LoadN mem))); 12081 12082 format %{ "cmpl $src, $mem\t# compressed ptr" %} 12083 ins_encode %{ 12084 __ cmpl($src$$Register, $mem$$Address); 12085 %} 12086 ins_pipe(ialu_cr_reg_mem); 12087 %} 12088 12089 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 12090 match(Set cr (CmpN op1 op2)); 12091 12092 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12093 ins_encode %{ 12094 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 12095 %} 12096 ins_pipe(ialu_cr_reg_imm); 12097 %} 12098 12099 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 12100 %{ 12101 match(Set cr (CmpN src (LoadN mem))); 12102 12103 format %{ "cmpl $mem, $src\t# compressed ptr" %} 12104 ins_encode %{ 12105 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 12106 %} 12107 ins_pipe(ialu_cr_reg_mem); 12108 %} 12109 12110 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 12111 match(Set cr (CmpN op1 op2)); 12112 12113 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 12114 ins_encode %{ 12115 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 12116 %} 12117 ins_pipe(ialu_cr_reg_imm); 12118 %} 12119 12120 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 12121 %{ 12122 match(Set cr (CmpN src (LoadNKlass mem))); 12123 12124 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 12125 ins_encode %{ 12126 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 12127 %} 12128 ins_pipe(ialu_cr_reg_mem); 12129 %} 12130 12131 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 12132 match(Set cr (CmpN src zero)); 12133 12134 format %{ "testl $src, $src\t# compressed ptr" %} 12135 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 12136 ins_pipe(ialu_cr_reg_imm); 12137 %} 12138 12139 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 12140 %{ 12141 predicate(Universe::narrow_oop_base() != NULL); 12142 match(Set cr (CmpN (LoadN mem) zero)); 12143 12144 ins_cost(500); // XXX 12145 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 12146 ins_encode %{ 12147 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 12148 %} 12149 ins_pipe(ialu_cr_reg_mem); 12150 %} 12151 12152 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 12153 %{ 12154 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 12155 match(Set cr (CmpN (LoadN mem) zero)); 12156 12157 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 12158 ins_encode %{ 12159 __ cmpl(r12, $mem$$Address); 12160 %} 12161 ins_pipe(ialu_cr_reg_mem); 12162 %} 12163 12164 // Yanked all unsigned pointer compare operations. 12165 // Pointer compares are done with CmpP which is already unsigned. 12166 12167 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 12168 %{ 12169 match(Set cr (CmpL op1 op2)); 12170 12171 format %{ "cmpq $op1, $op2" %} 12172 opcode(0x3B); /* Opcode 3B /r */ 12173 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12174 ins_pipe(ialu_cr_reg_reg); 12175 %} 12176 12177 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 12178 %{ 12179 match(Set cr (CmpL op1 op2)); 12180 12181 format %{ "cmpq $op1, $op2" %} 12182 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12183 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12184 ins_pipe(ialu_cr_reg_imm); 12185 %} 12186 12187 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 12188 %{ 12189 match(Set cr (CmpL op1 (LoadL op2))); 12190 12191 format %{ "cmpq $op1, $op2" %} 12192 opcode(0x3B); /* Opcode 3B /r */ 12193 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12194 ins_pipe(ialu_cr_reg_mem); 12195 %} 12196 12197 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12198 %{ 12199 match(Set cr (CmpL src zero)); 12200 12201 format %{ "testq $src, $src" %} 12202 opcode(0x85); 12203 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12204 ins_pipe(ialu_cr_reg_imm); 12205 %} 12206 12207 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12208 %{ 12209 match(Set cr (CmpL (AndL src con) zero)); 12210 12211 format %{ "testq $src, $con\t# long" %} 12212 opcode(0xF7, 0x00); 12213 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 12214 ins_pipe(ialu_cr_reg_imm); 12215 %} 12216 12217 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12218 %{ 12219 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12220 12221 format %{ "testq $src, $mem" %} 12222 opcode(0x85); 12223 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12224 ins_pipe(ialu_cr_reg_mem); 12225 %} 12226 12227 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12228 %{ 12229 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12230 12231 format %{ "testq $src, $mem" %} 12232 opcode(0x85); 12233 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12234 ins_pipe(ialu_cr_reg_mem); 12235 %} 12236 12237 // Manifest a CmpL result in an integer register. Very painful. 12238 // This is the test to avoid. 12239 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12240 %{ 12241 match(Set dst (CmpL3 src1 src2)); 12242 effect(KILL flags); 12243 12244 ins_cost(275); // XXX 12245 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12246 "movl $dst, -1\n\t" 12247 "jl,s done\n\t" 12248 "setne $dst\n\t" 12249 "movzbl $dst, $dst\n\t" 12250 "done:" %} 12251 ins_encode(cmpl3_flag(src1, src2, dst)); 12252 ins_pipe(pipe_slow); 12253 %} 12254 12255 // Unsigned long compare Instructions; really, same as signed long except they 12256 // produce an rFlagsRegU instead of rFlagsReg. 12257 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12258 %{ 12259 match(Set cr (CmpUL op1 op2)); 12260 12261 format %{ "cmpq $op1, $op2\t# unsigned" %} 12262 opcode(0x3B); /* Opcode 3B /r */ 12263 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12264 ins_pipe(ialu_cr_reg_reg); 12265 %} 12266 12267 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12268 %{ 12269 match(Set cr (CmpUL op1 op2)); 12270 12271 format %{ "cmpq $op1, $op2\t# unsigned" %} 12272 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12273 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12274 ins_pipe(ialu_cr_reg_imm); 12275 %} 12276 12277 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12278 %{ 12279 match(Set cr (CmpUL op1 (LoadL op2))); 12280 12281 format %{ "cmpq $op1, $op2\t# unsigned" %} 12282 opcode(0x3B); /* Opcode 3B /r */ 12283 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12284 ins_pipe(ialu_cr_reg_mem); 12285 %} 12286 12287 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12288 %{ 12289 match(Set cr (CmpUL src zero)); 12290 12291 format %{ "testq $src, $src\t# unsigned" %} 12292 opcode(0x85); 12293 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12294 ins_pipe(ialu_cr_reg_imm); 12295 %} 12296 12297 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12298 %{ 12299 match(Set cr (CmpI (LoadB mem) imm)); 12300 12301 ins_cost(125); 12302 format %{ "cmpb $mem, $imm" %} 12303 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12304 ins_pipe(ialu_cr_reg_mem); 12305 %} 12306 12307 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 12308 %{ 12309 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12310 12311 ins_cost(125); 12312 format %{ "testb $mem, $imm\t# ubyte" %} 12313 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12314 ins_pipe(ialu_cr_reg_mem); 12315 %} 12316 12317 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 12318 %{ 12319 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12320 12321 ins_cost(125); 12322 format %{ "testb $mem, $imm\t# byte" %} 12323 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12324 ins_pipe(ialu_cr_reg_mem); 12325 %} 12326 12327 //----------Max and Min-------------------------------------------------------- 12328 // Min Instructions 12329 12330 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12331 %{ 12332 effect(USE_DEF dst, USE src, USE cr); 12333 12334 format %{ "cmovlgt $dst, $src\t# min" %} 12335 opcode(0x0F, 0x4F); 12336 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12337 ins_pipe(pipe_cmov_reg); 12338 %} 12339 12340 12341 instruct minI_rReg(rRegI dst, rRegI src) 12342 %{ 12343 match(Set dst (MinI dst src)); 12344 12345 ins_cost(200); 12346 expand %{ 12347 rFlagsReg cr; 12348 compI_rReg(cr, dst, src); 12349 cmovI_reg_g(dst, src, cr); 12350 %} 12351 %} 12352 12353 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12354 %{ 12355 effect(USE_DEF dst, USE src, USE cr); 12356 12357 format %{ "cmovllt $dst, $src\t# max" %} 12358 opcode(0x0F, 0x4C); 12359 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12360 ins_pipe(pipe_cmov_reg); 12361 %} 12362 12363 12364 instruct maxI_rReg(rRegI dst, rRegI src) 12365 %{ 12366 match(Set dst (MaxI dst src)); 12367 12368 ins_cost(200); 12369 expand %{ 12370 rFlagsReg cr; 12371 compI_rReg(cr, dst, src); 12372 cmovI_reg_l(dst, src, cr); 12373 %} 12374 %} 12375 12376 // ============================================================================ 12377 // Branch Instructions 12378 12379 // Jump Direct - Label defines a relative address from JMP+1 12380 instruct jmpDir(label labl) 12381 %{ 12382 match(Goto); 12383 effect(USE labl); 12384 12385 ins_cost(300); 12386 format %{ "jmp $labl" %} 12387 size(5); 12388 ins_encode %{ 12389 Label* L = $labl$$label; 12390 __ jmp(*L, false); // Always long jump 12391 %} 12392 ins_pipe(pipe_jmp); 12393 %} 12394 12395 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12396 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12397 %{ 12398 match(If cop cr); 12399 effect(USE labl); 12400 12401 ins_cost(300); 12402 format %{ "j$cop $labl" %} 12403 size(6); 12404 ins_encode %{ 12405 Label* L = $labl$$label; 12406 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12407 %} 12408 ins_pipe(pipe_jcc); 12409 %} 12410 12411 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12412 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12413 %{ 12414 predicate(!n->has_vector_mask_set()); 12415 match(CountedLoopEnd cop cr); 12416 effect(USE labl); 12417 12418 ins_cost(300); 12419 format %{ "j$cop $labl\t# loop end" %} 12420 size(6); 12421 ins_encode %{ 12422 Label* L = $labl$$label; 12423 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12424 %} 12425 ins_pipe(pipe_jcc); 12426 %} 12427 12428 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12429 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12430 predicate(!n->has_vector_mask_set()); 12431 match(CountedLoopEnd cop cmp); 12432 effect(USE labl); 12433 12434 ins_cost(300); 12435 format %{ "j$cop,u $labl\t# loop end" %} 12436 size(6); 12437 ins_encode %{ 12438 Label* L = $labl$$label; 12439 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12440 %} 12441 ins_pipe(pipe_jcc); 12442 %} 12443 12444 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12445 predicate(!n->has_vector_mask_set()); 12446 match(CountedLoopEnd cop cmp); 12447 effect(USE labl); 12448 12449 ins_cost(200); 12450 format %{ "j$cop,u $labl\t# loop end" %} 12451 size(6); 12452 ins_encode %{ 12453 Label* L = $labl$$label; 12454 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12455 %} 12456 ins_pipe(pipe_jcc); 12457 %} 12458 12459 // mask version 12460 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12461 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12462 %{ 12463 predicate(n->has_vector_mask_set()); 12464 match(CountedLoopEnd cop cr); 12465 effect(USE labl); 12466 12467 ins_cost(400); 12468 format %{ "j$cop $labl\t# loop end\n\t" 12469 "restorevectmask \t# vector mask restore for loops" %} 12470 size(10); 12471 ins_encode %{ 12472 Label* L = $labl$$label; 12473 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12474 __ restorevectmask(); 12475 %} 12476 ins_pipe(pipe_jcc); 12477 %} 12478 12479 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12480 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12481 predicate(n->has_vector_mask_set()); 12482 match(CountedLoopEnd cop cmp); 12483 effect(USE labl); 12484 12485 ins_cost(400); 12486 format %{ "j$cop,u $labl\t# loop end\n\t" 12487 "restorevectmask \t# vector mask restore for loops" %} 12488 size(10); 12489 ins_encode %{ 12490 Label* L = $labl$$label; 12491 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12492 __ restorevectmask(); 12493 %} 12494 ins_pipe(pipe_jcc); 12495 %} 12496 12497 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12498 predicate(n->has_vector_mask_set()); 12499 match(CountedLoopEnd cop cmp); 12500 effect(USE labl); 12501 12502 ins_cost(300); 12503 format %{ "j$cop,u $labl\t# loop end\n\t" 12504 "restorevectmask \t# vector mask restore for loops" %} 12505 size(10); 12506 ins_encode %{ 12507 Label* L = $labl$$label; 12508 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12509 __ restorevectmask(); 12510 %} 12511 ins_pipe(pipe_jcc); 12512 %} 12513 12514 // Jump Direct Conditional - using unsigned comparison 12515 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12516 match(If cop cmp); 12517 effect(USE labl); 12518 12519 ins_cost(300); 12520 format %{ "j$cop,u $labl" %} 12521 size(6); 12522 ins_encode %{ 12523 Label* L = $labl$$label; 12524 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12525 %} 12526 ins_pipe(pipe_jcc); 12527 %} 12528 12529 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12530 match(If cop cmp); 12531 effect(USE labl); 12532 12533 ins_cost(200); 12534 format %{ "j$cop,u $labl" %} 12535 size(6); 12536 ins_encode %{ 12537 Label* L = $labl$$label; 12538 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12539 %} 12540 ins_pipe(pipe_jcc); 12541 %} 12542 12543 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12544 match(If cop cmp); 12545 effect(USE labl); 12546 12547 ins_cost(200); 12548 format %{ $$template 12549 if ($cop$$cmpcode == Assembler::notEqual) { 12550 $$emit$$"jp,u $labl\n\t" 12551 $$emit$$"j$cop,u $labl" 12552 } else { 12553 $$emit$$"jp,u done\n\t" 12554 $$emit$$"j$cop,u $labl\n\t" 12555 $$emit$$"done:" 12556 } 12557 %} 12558 ins_encode %{ 12559 Label* l = $labl$$label; 12560 if ($cop$$cmpcode == Assembler::notEqual) { 12561 __ jcc(Assembler::parity, *l, false); 12562 __ jcc(Assembler::notEqual, *l, false); 12563 } else if ($cop$$cmpcode == Assembler::equal) { 12564 Label done; 12565 __ jccb(Assembler::parity, done); 12566 __ jcc(Assembler::equal, *l, false); 12567 __ bind(done); 12568 } else { 12569 ShouldNotReachHere(); 12570 } 12571 %} 12572 ins_pipe(pipe_jcc); 12573 %} 12574 12575 // ============================================================================ 12576 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12577 // superklass array for an instance of the superklass. Set a hidden 12578 // internal cache on a hit (cache is checked with exposed code in 12579 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12580 // encoding ALSO sets flags. 12581 12582 instruct partialSubtypeCheck(rdi_RegP result, 12583 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12584 rFlagsReg cr) 12585 %{ 12586 match(Set result (PartialSubtypeCheck sub super)); 12587 effect(KILL rcx, KILL cr); 12588 12589 ins_cost(1100); // slightly larger than the next version 12590 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12591 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12592 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12593 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12594 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12595 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12596 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12597 "miss:\t" %} 12598 12599 opcode(0x1); // Force a XOR of RDI 12600 ins_encode(enc_PartialSubtypeCheck()); 12601 ins_pipe(pipe_slow); 12602 %} 12603 12604 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12605 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12606 immP0 zero, 12607 rdi_RegP result) 12608 %{ 12609 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12610 effect(KILL rcx, KILL result); 12611 12612 ins_cost(1000); 12613 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12614 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12615 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12616 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12617 "jne,s miss\t\t# Missed: flags nz\n\t" 12618 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12619 "miss:\t" %} 12620 12621 opcode(0x0); // No need to XOR RDI 12622 ins_encode(enc_PartialSubtypeCheck()); 12623 ins_pipe(pipe_slow); 12624 %} 12625 12626 // ============================================================================ 12627 // Branch Instructions -- short offset versions 12628 // 12629 // These instructions are used to replace jumps of a long offset (the default 12630 // match) with jumps of a shorter offset. These instructions are all tagged 12631 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12632 // match rules in general matching. Instead, the ADLC generates a conversion 12633 // method in the MachNode which can be used to do in-place replacement of the 12634 // long variant with the shorter variant. The compiler will determine if a 12635 // branch can be taken by the is_short_branch_offset() predicate in the machine 12636 // specific code section of the file. 12637 12638 // Jump Direct - Label defines a relative address from JMP+1 12639 instruct jmpDir_short(label labl) %{ 12640 match(Goto); 12641 effect(USE labl); 12642 12643 ins_cost(300); 12644 format %{ "jmp,s $labl" %} 12645 size(2); 12646 ins_encode %{ 12647 Label* L = $labl$$label; 12648 __ jmpb(*L); 12649 %} 12650 ins_pipe(pipe_jmp); 12651 ins_short_branch(1); 12652 %} 12653 12654 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12655 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12656 match(If cop cr); 12657 effect(USE labl); 12658 12659 ins_cost(300); 12660 format %{ "j$cop,s $labl" %} 12661 size(2); 12662 ins_encode %{ 12663 Label* L = $labl$$label; 12664 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12665 %} 12666 ins_pipe(pipe_jcc); 12667 ins_short_branch(1); 12668 %} 12669 12670 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12671 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12672 match(CountedLoopEnd cop cr); 12673 effect(USE labl); 12674 12675 ins_cost(300); 12676 format %{ "j$cop,s $labl\t# loop end" %} 12677 size(2); 12678 ins_encode %{ 12679 Label* L = $labl$$label; 12680 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12681 %} 12682 ins_pipe(pipe_jcc); 12683 ins_short_branch(1); 12684 %} 12685 12686 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12687 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12688 match(CountedLoopEnd cop cmp); 12689 effect(USE labl); 12690 12691 ins_cost(300); 12692 format %{ "j$cop,us $labl\t# loop end" %} 12693 size(2); 12694 ins_encode %{ 12695 Label* L = $labl$$label; 12696 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12697 %} 12698 ins_pipe(pipe_jcc); 12699 ins_short_branch(1); 12700 %} 12701 12702 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12703 match(CountedLoopEnd cop cmp); 12704 effect(USE labl); 12705 12706 ins_cost(300); 12707 format %{ "j$cop,us $labl\t# loop end" %} 12708 size(2); 12709 ins_encode %{ 12710 Label* L = $labl$$label; 12711 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12712 %} 12713 ins_pipe(pipe_jcc); 12714 ins_short_branch(1); 12715 %} 12716 12717 // Jump Direct Conditional - using unsigned comparison 12718 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12719 match(If cop cmp); 12720 effect(USE labl); 12721 12722 ins_cost(300); 12723 format %{ "j$cop,us $labl" %} 12724 size(2); 12725 ins_encode %{ 12726 Label* L = $labl$$label; 12727 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12728 %} 12729 ins_pipe(pipe_jcc); 12730 ins_short_branch(1); 12731 %} 12732 12733 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12734 match(If cop cmp); 12735 effect(USE labl); 12736 12737 ins_cost(300); 12738 format %{ "j$cop,us $labl" %} 12739 size(2); 12740 ins_encode %{ 12741 Label* L = $labl$$label; 12742 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12743 %} 12744 ins_pipe(pipe_jcc); 12745 ins_short_branch(1); 12746 %} 12747 12748 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12749 match(If cop cmp); 12750 effect(USE labl); 12751 12752 ins_cost(300); 12753 format %{ $$template 12754 if ($cop$$cmpcode == Assembler::notEqual) { 12755 $$emit$$"jp,u,s $labl\n\t" 12756 $$emit$$"j$cop,u,s $labl" 12757 } else { 12758 $$emit$$"jp,u,s done\n\t" 12759 $$emit$$"j$cop,u,s $labl\n\t" 12760 $$emit$$"done:" 12761 } 12762 %} 12763 size(4); 12764 ins_encode %{ 12765 Label* l = $labl$$label; 12766 if ($cop$$cmpcode == Assembler::notEqual) { 12767 __ jccb(Assembler::parity, *l); 12768 __ jccb(Assembler::notEqual, *l); 12769 } else if ($cop$$cmpcode == Assembler::equal) { 12770 Label done; 12771 __ jccb(Assembler::parity, done); 12772 __ jccb(Assembler::equal, *l); 12773 __ bind(done); 12774 } else { 12775 ShouldNotReachHere(); 12776 } 12777 %} 12778 ins_pipe(pipe_jcc); 12779 ins_short_branch(1); 12780 %} 12781 12782 // ============================================================================ 12783 // inlined locking and unlocking 12784 12785 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12786 predicate(Compile::current()->use_rtm()); 12787 match(Set cr (FastLock object box)); 12788 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12789 ins_cost(300); 12790 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12791 ins_encode %{ 12792 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12793 $scr$$Register, $cx1$$Register, $cx2$$Register, 12794 _counters, _rtm_counters, _stack_rtm_counters, 12795 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12796 true, ra_->C->profile_rtm()); 12797 %} 12798 ins_pipe(pipe_slow); 12799 %} 12800 12801 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12802 predicate(!Compile::current()->use_rtm()); 12803 match(Set cr (FastLock object box)); 12804 effect(TEMP tmp, TEMP scr, USE_KILL box); 12805 ins_cost(300); 12806 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12807 ins_encode %{ 12808 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12809 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12810 %} 12811 ins_pipe(pipe_slow); 12812 %} 12813 12814 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12815 match(Set cr (FastUnlock object box)); 12816 effect(TEMP tmp, USE_KILL box); 12817 ins_cost(300); 12818 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12819 ins_encode %{ 12820 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12821 %} 12822 ins_pipe(pipe_slow); 12823 %} 12824 12825 12826 // ============================================================================ 12827 // Safepoint Instructions 12828 instruct safePoint_poll(rFlagsReg cr) 12829 %{ 12830 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12831 match(SafePoint); 12832 effect(KILL cr); 12833 12834 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12835 "# Safepoint: poll for GC" %} 12836 ins_cost(125); 12837 ins_encode %{ 12838 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12839 __ testl(rax, addr); 12840 %} 12841 ins_pipe(ialu_reg_mem); 12842 %} 12843 12844 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12845 %{ 12846 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12847 match(SafePoint poll); 12848 effect(KILL cr, USE poll); 12849 12850 format %{ "testl rax, [$poll]\t" 12851 "# Safepoint: poll for GC" %} 12852 ins_cost(125); 12853 ins_encode %{ 12854 __ relocate(relocInfo::poll_type); 12855 __ testl(rax, Address($poll$$Register, 0)); 12856 %} 12857 ins_pipe(ialu_reg_mem); 12858 %} 12859 12860 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12861 %{ 12862 predicate(SafepointMechanism::uses_thread_local_poll()); 12863 match(SafePoint poll); 12864 effect(KILL cr, USE poll); 12865 12866 format %{ "testl rax, [$poll]\t" 12867 "# Safepoint: poll for GC" %} 12868 ins_cost(125); 12869 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12870 ins_encode %{ 12871 __ relocate(relocInfo::poll_type); 12872 address pre_pc = __ pc(); 12873 __ testl(rax, Address($poll$$Register, 0)); 12874 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12875 %} 12876 ins_pipe(ialu_reg_mem); 12877 %} 12878 12879 // ============================================================================ 12880 // Procedure Call/Return Instructions 12881 // Call Java Static Instruction 12882 // Note: If this code changes, the corresponding ret_addr_offset() and 12883 // compute_padding() functions will have to be adjusted. 12884 instruct CallStaticJavaDirect(method meth) %{ 12885 match(CallStaticJava); 12886 effect(USE meth); 12887 12888 ins_cost(300); 12889 format %{ "call,static " %} 12890 opcode(0xE8); /* E8 cd */ 12891 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12892 ins_pipe(pipe_slow); 12893 ins_alignment(4); 12894 %} 12895 12896 // Call Java Dynamic Instruction 12897 // Note: If this code changes, the corresponding ret_addr_offset() and 12898 // compute_padding() functions will have to be adjusted. 12899 instruct CallDynamicJavaDirect(method meth) 12900 %{ 12901 match(CallDynamicJava); 12902 effect(USE meth); 12903 12904 ins_cost(300); 12905 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12906 "call,dynamic " %} 12907 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12908 ins_pipe(pipe_slow); 12909 ins_alignment(4); 12910 %} 12911 12912 // Call Runtime Instruction 12913 instruct CallRuntimeDirect(method meth) 12914 %{ 12915 match(CallRuntime); 12916 effect(USE meth); 12917 12918 ins_cost(300); 12919 format %{ "call,runtime " %} 12920 ins_encode(clear_avx, Java_To_Runtime(meth)); 12921 ins_pipe(pipe_slow); 12922 %} 12923 12924 // Call runtime without safepoint 12925 instruct CallLeafDirect(method meth) 12926 %{ 12927 match(CallLeaf); 12928 effect(USE meth); 12929 12930 ins_cost(300); 12931 format %{ "call_leaf,runtime " %} 12932 ins_encode(clear_avx, Java_To_Runtime(meth)); 12933 ins_pipe(pipe_slow); 12934 %} 12935 12936 // Call runtime without safepoint 12937 // entry point is null, target holds the address to call 12938 instruct CallLeafNoFPInDirect(rRegP target) 12939 %{ 12940 predicate(n->as_Call()->entry_point() == NULL); 12941 match(CallLeafNoFP target); 12942 12943 ins_cost(300); 12944 format %{ "call_leaf_nofp,runtime indirect " %} 12945 ins_encode %{ 12946 __ call($target$$Register); 12947 %} 12948 12949 ins_pipe(pipe_slow); 12950 %} 12951 12952 instruct CallLeafNoFPDirect(method meth) 12953 %{ 12954 predicate(n->as_Call()->entry_point() != NULL); 12955 match(CallLeafNoFP); 12956 effect(USE meth); 12957 12958 ins_cost(300); 12959 format %{ "call_leaf_nofp,runtime " %} 12960 ins_encode(clear_avx, Java_To_Runtime(meth)); 12961 ins_pipe(pipe_slow); 12962 %} 12963 12964 // Return Instruction 12965 // Remove the return address & jump to it. 12966 // Notice: We always emit a nop after a ret to make sure there is room 12967 // for safepoint patching 12968 instruct Ret() 12969 %{ 12970 match(Return); 12971 12972 format %{ "ret" %} 12973 opcode(0xC3); 12974 ins_encode(OpcP); 12975 ins_pipe(pipe_jmp); 12976 %} 12977 12978 // Tail Call; Jump from runtime stub to Java code. 12979 // Also known as an 'interprocedural jump'. 12980 // Target of jump will eventually return to caller. 12981 // TailJump below removes the return address. 12982 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12983 %{ 12984 match(TailCall jump_target method_oop); 12985 12986 ins_cost(300); 12987 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12988 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12989 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12990 ins_pipe(pipe_jmp); 12991 %} 12992 12993 // Tail Jump; remove the return address; jump to target. 12994 // TailCall above leaves the return address around. 12995 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12996 %{ 12997 match(TailJump jump_target ex_oop); 12998 12999 ins_cost(300); 13000 format %{ "popq rdx\t# pop return address\n\t" 13001 "jmp $jump_target" %} 13002 opcode(0xFF, 0x4); /* Opcode FF /4 */ 13003 ins_encode(Opcode(0x5a), // popq rdx 13004 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 13005 ins_pipe(pipe_jmp); 13006 %} 13007 13008 // Create exception oop: created by stack-crawling runtime code. 13009 // Created exception is now available to this handler, and is setup 13010 // just prior to jumping to this handler. No code emitted. 13011 instruct CreateException(rax_RegP ex_oop) 13012 %{ 13013 match(Set ex_oop (CreateEx)); 13014 13015 size(0); 13016 // use the following format syntax 13017 format %{ "# exception oop is in rax; no code emitted" %} 13018 ins_encode(); 13019 ins_pipe(empty); 13020 %} 13021 13022 // Rethrow exception: 13023 // The exception oop will come in the first argument position. 13024 // Then JUMP (not call) to the rethrow stub code. 13025 instruct RethrowException() 13026 %{ 13027 match(Rethrow); 13028 13029 // use the following format syntax 13030 format %{ "jmp rethrow_stub" %} 13031 ins_encode(enc_rethrow); 13032 ins_pipe(pipe_jmp); 13033 %} 13034 13035 // ============================================================================ 13036 // This name is KNOWN by the ADLC and cannot be changed. 13037 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 13038 // for this guy. 13039 instruct tlsLoadP(r15_RegP dst) %{ 13040 match(Set dst (ThreadLocal)); 13041 effect(DEF dst); 13042 13043 size(0); 13044 format %{ "# TLS is in R15" %} 13045 ins_encode( /*empty encoding*/ ); 13046 ins_pipe(ialu_reg_reg); 13047 %} 13048 13049 13050 //----------PEEPHOLE RULES----------------------------------------------------- 13051 // These must follow all instruction definitions as they use the names 13052 // defined in the instructions definitions. 13053 // 13054 // peepmatch ( root_instr_name [preceding_instruction]* ); 13055 // 13056 // peepconstraint %{ 13057 // (instruction_number.operand_name relational_op instruction_number.operand_name 13058 // [, ...] ); 13059 // // instruction numbers are zero-based using left to right order in peepmatch 13060 // 13061 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13062 // // provide an instruction_number.operand_name for each operand that appears 13063 // // in the replacement instruction's match rule 13064 // 13065 // ---------VM FLAGS--------------------------------------------------------- 13066 // 13067 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13068 // 13069 // Each peephole rule is given an identifying number starting with zero and 13070 // increasing by one in the order seen by the parser. An individual peephole 13071 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13072 // on the command-line. 13073 // 13074 // ---------CURRENT LIMITATIONS---------------------------------------------- 13075 // 13076 // Only match adjacent instructions in same basic block 13077 // Only equality constraints 13078 // Only constraints between operands, not (0.dest_reg == RAX_enc) 13079 // Only one replacement instruction 13080 // 13081 // ---------EXAMPLE---------------------------------------------------------- 13082 // 13083 // // pertinent parts of existing instructions in architecture description 13084 // instruct movI(rRegI dst, rRegI src) 13085 // %{ 13086 // match(Set dst (CopyI src)); 13087 // %} 13088 // 13089 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 13090 // %{ 13091 // match(Set dst (AddI dst src)); 13092 // effect(KILL cr); 13093 // %} 13094 // 13095 // // Change (inc mov) to lea 13096 // peephole %{ 13097 // // increment preceeded by register-register move 13098 // peepmatch ( incI_rReg movI ); 13099 // // require that the destination register of the increment 13100 // // match the destination register of the move 13101 // peepconstraint ( 0.dst == 1.dst ); 13102 // // construct a replacement instruction that sets 13103 // // the destination to ( move's source register + one ) 13104 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 13105 // %} 13106 // 13107 13108 // Implementation no longer uses movX instructions since 13109 // machine-independent system no longer uses CopyX nodes. 13110 // 13111 // peephole 13112 // %{ 13113 // peepmatch (incI_rReg movI); 13114 // peepconstraint (0.dst == 1.dst); 13115 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13116 // %} 13117 13118 // peephole 13119 // %{ 13120 // peepmatch (decI_rReg movI); 13121 // peepconstraint (0.dst == 1.dst); 13122 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13123 // %} 13124 13125 // peephole 13126 // %{ 13127 // peepmatch (addI_rReg_imm movI); 13128 // peepconstraint (0.dst == 1.dst); 13129 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13130 // %} 13131 13132 // peephole 13133 // %{ 13134 // peepmatch (incL_rReg movL); 13135 // peepconstraint (0.dst == 1.dst); 13136 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13137 // %} 13138 13139 // peephole 13140 // %{ 13141 // peepmatch (decL_rReg movL); 13142 // peepconstraint (0.dst == 1.dst); 13143 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13144 // %} 13145 13146 // peephole 13147 // %{ 13148 // peepmatch (addL_rReg_imm movL); 13149 // peepconstraint (0.dst == 1.dst); 13150 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13151 // %} 13152 13153 // peephole 13154 // %{ 13155 // peepmatch (addP_rReg_imm movP); 13156 // peepconstraint (0.dst == 1.dst); 13157 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13158 // %} 13159 13160 // // Change load of spilled value to only a spill 13161 // instruct storeI(memory mem, rRegI src) 13162 // %{ 13163 // match(Set mem (StoreI mem src)); 13164 // %} 13165 // 13166 // instruct loadI(rRegI dst, memory mem) 13167 // %{ 13168 // match(Set dst (LoadI mem)); 13169 // %} 13170 // 13171 13172 peephole 13173 %{ 13174 peepmatch (loadI storeI); 13175 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13176 peepreplace (storeI(1.mem 1.mem 1.src)); 13177 %} 13178 13179 peephole 13180 %{ 13181 peepmatch (loadL storeL); 13182 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13183 peepreplace (storeL(1.mem 1.mem 1.src)); 13184 %} 13185 13186 //----------SMARTSPILL RULES--------------------------------------------------- 13187 // These must follow all instruction definitions as they use the names 13188 // defined in the instructions definitions.