1 // 2 // Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer/long registers 173 reg_class all_reg(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all int registers 191 reg_class all_int_reg(RAX 192 RDX, 193 RBP, 194 RDI, 195 RSI, 196 RCX, 197 RBX, 198 R8, 199 R9, 200 R10, 201 R11, 202 R12, 203 R13, 204 R14); 205 206 // Class for all pointer registers 207 reg_class any_reg %{ 208 return _ANY_REG_mask; 209 %} 210 211 // Class for all pointer registers (excluding RSP) 212 reg_class ptr_reg %{ 213 return _PTR_REG_mask; 214 %} 215 216 // Class for all pointer registers (excluding RSP and RBP) 217 reg_class ptr_reg_no_rbp %{ 218 return _PTR_REG_NO_RBP_mask; 219 %} 220 221 // Class for all pointer registers (excluding RAX and RSP) 222 reg_class ptr_no_rax_reg %{ 223 return _PTR_NO_RAX_REG_mask; 224 %} 225 226 // Class for all pointer registers (excluding RAX, RBX, and RSP) 227 reg_class ptr_no_rax_rbx_reg %{ 228 return _PTR_NO_RAX_RBX_REG_mask; 229 %} 230 231 // Class for all long registers (excluding RSP) 232 reg_class long_reg %{ 233 return _LONG_REG_mask; 234 %} 235 236 // Class for all long registers (excluding RAX, RDX and RSP) 237 reg_class long_no_rax_rdx_reg %{ 238 return _LONG_NO_RAX_RDX_REG_mask; 239 %} 240 241 // Class for all long registers (excluding RCX and RSP) 242 reg_class long_no_rcx_reg %{ 243 return _LONG_NO_RCX_REG_mask; 244 %} 245 246 // Class for all int registers (excluding RSP) 247 reg_class int_reg %{ 248 return _INT_REG_mask; 249 %} 250 251 // Class for all int registers (excluding RAX, RDX, and RSP) 252 reg_class int_no_rax_rdx_reg %{ 253 return _INT_NO_RAX_RDX_REG_mask; 254 %} 255 256 // Class for all int registers (excluding RCX and RSP) 257 reg_class int_no_rcx_reg %{ 258 return _INT_NO_RCX_REG_mask; 259 %} 260 261 // Singleton class for RAX pointer register 262 reg_class ptr_rax_reg(RAX, RAX_H); 263 264 // Singleton class for RBX pointer register 265 reg_class ptr_rbx_reg(RBX, RBX_H); 266 267 // Singleton class for RSI pointer register 268 reg_class ptr_rsi_reg(RSI, RSI_H); 269 270 // Singleton class for RDI pointer register 271 reg_class ptr_rdi_reg(RDI, RDI_H); 272 273 // Singleton class for stack pointer 274 reg_class ptr_rsp_reg(RSP, RSP_H); 275 276 // Singleton class for TLS pointer 277 reg_class ptr_r15_reg(R15, R15_H); 278 279 // Singleton class for RAX long register 280 reg_class long_rax_reg(RAX, RAX_H); 281 282 // Singleton class for RCX long register 283 reg_class long_rcx_reg(RCX, RCX_H); 284 285 // Singleton class for RDX long register 286 reg_class long_rdx_reg(RDX, RDX_H); 287 288 // Singleton class for RAX int register 289 reg_class int_rax_reg(RAX); 290 291 // Singleton class for RBX int register 292 reg_class int_rbx_reg(RBX); 293 294 // Singleton class for RCX int register 295 reg_class int_rcx_reg(RCX); 296 297 // Singleton class for RCX int register 298 reg_class int_rdx_reg(RDX); 299 300 // Singleton class for RCX int register 301 reg_class int_rdi_reg(RDI); 302 303 // Singleton class for instruction pointer 304 // reg_class ip_reg(RIP); 305 306 %} 307 308 //----------SOURCE BLOCK------------------------------------------------------- 309 // This is a block of C++ code which provides values, functions, and 310 // definitions necessary in the rest of the architecture description 311 source_hpp %{ 312 313 extern RegMask _ANY_REG_mask; 314 extern RegMask _PTR_REG_mask; 315 extern RegMask _PTR_REG_NO_RBP_mask; 316 extern RegMask _PTR_NO_RAX_REG_mask; 317 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 318 extern RegMask _LONG_REG_mask; 319 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 320 extern RegMask _LONG_NO_RCX_REG_mask; 321 extern RegMask _INT_REG_mask; 322 extern RegMask _INT_NO_RAX_RDX_REG_mask; 323 extern RegMask _INT_NO_RCX_REG_mask; 324 325 extern RegMask _STACK_OR_PTR_REG_mask; 326 extern RegMask _STACK_OR_LONG_REG_mask; 327 extern RegMask _STACK_OR_INT_REG_mask; 328 329 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 330 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 331 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 332 333 %} 334 335 source %{ 336 #define RELOC_IMM64 Assembler::imm_operand 337 #define RELOC_DISP32 Assembler::disp32_operand 338 339 #define __ _masm. 340 341 RegMask _ANY_REG_mask; 342 RegMask _PTR_REG_mask; 343 RegMask _PTR_REG_NO_RBP_mask; 344 RegMask _PTR_NO_RAX_REG_mask; 345 RegMask _PTR_NO_RAX_RBX_REG_mask; 346 RegMask _LONG_REG_mask; 347 RegMask _LONG_NO_RAX_RDX_REG_mask; 348 RegMask _LONG_NO_RCX_REG_mask; 349 RegMask _INT_REG_mask; 350 RegMask _INT_NO_RAX_RDX_REG_mask; 351 RegMask _INT_NO_RCX_REG_mask; 352 RegMask _STACK_OR_PTR_REG_mask; 353 RegMask _STACK_OR_LONG_REG_mask; 354 RegMask _STACK_OR_INT_REG_mask; 355 356 static bool need_r12_heapbase() { 357 return UseCompressedOops || UseCompressedClassPointers; 358 } 359 360 void reg_mask_init() { 361 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 362 // We derive a number of subsets from it. 363 _ANY_REG_mask = _ALL_REG_mask; 364 365 if (PreserveFramePointer) { 366 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 367 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 368 } 369 if (need_r12_heapbase()) { 370 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 371 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 372 } 373 374 _PTR_REG_mask = _ANY_REG_mask; 375 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 376 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 377 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 378 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 379 380 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 381 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 382 383 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 384 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 385 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 386 387 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 388 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 389 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 390 391 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 392 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 393 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 394 395 _LONG_REG_mask = _PTR_REG_mask; 396 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 397 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 398 399 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 400 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 401 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 402 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 403 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 404 405 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 406 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 407 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 408 409 _INT_REG_mask = _ALL_INT_REG_mask; 410 if (PreserveFramePointer) { 411 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 412 } 413 if (need_r12_heapbase()) { 414 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 415 } 416 417 _STACK_OR_INT_REG_mask = _INT_REG_mask; 418 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 419 420 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 421 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 422 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 423 424 _INT_NO_RCX_REG_mask = _INT_REG_mask; 425 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 426 } 427 428 static bool generate_vzeroupper(Compile* C) { 429 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 430 } 431 432 static int clear_avx_size() { 433 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 434 } 435 436 // !!!!! Special hack to get all types of calls to specify the byte offset 437 // from the start of the call to the point where the return address 438 // will point. 439 int MachCallStaticJavaNode::ret_addr_offset() 440 { 441 int offset = 5; // 5 bytes from start of call to where return address points 442 offset += clear_avx_size(); 443 return offset; 444 } 445 446 int MachCallDynamicJavaNode::ret_addr_offset() 447 { 448 int offset = 15; // 15 bytes from start of call to where return address points 449 offset += clear_avx_size(); 450 return offset; 451 } 452 453 int MachCallRuntimeNode::ret_addr_offset() { 454 int offset = 13; // movq r10,#addr; callq (r10) 455 offset += clear_avx_size(); 456 return offset; 457 } 458 459 // Indicate if the safepoint node needs the polling page as an input, 460 // it does if the polling page is more than disp32 away. 461 bool SafePointNode::needs_polling_address_input() 462 { 463 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 464 } 465 466 // 467 // Compute padding required for nodes which need alignment 468 // 469 470 // The address of the call instruction needs to be 4-byte aligned to 471 // ensure that it does not span a cache line so that it can be patched. 472 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 473 { 474 current_offset += clear_avx_size(); // skip vzeroupper 475 current_offset += 1; // skip call opcode byte 476 return align_up(current_offset, alignment_required()) - current_offset; 477 } 478 479 // The address of the call instruction needs to be 4-byte aligned to 480 // ensure that it does not span a cache line so that it can be patched. 481 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 482 { 483 current_offset += clear_avx_size(); // skip vzeroupper 484 current_offset += 11; // skip movq instruction + call opcode byte 485 return align_up(current_offset, alignment_required()) - current_offset; 486 } 487 488 // EMIT_RM() 489 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 490 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 491 cbuf.insts()->emit_int8(c); 492 } 493 494 // EMIT_CC() 495 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 496 unsigned char c = (unsigned char) (f1 | f2); 497 cbuf.insts()->emit_int8(c); 498 } 499 500 // EMIT_OPCODE() 501 void emit_opcode(CodeBuffer &cbuf, int code) { 502 cbuf.insts()->emit_int8((unsigned char) code); 503 } 504 505 // EMIT_OPCODE() w/ relocation information 506 void emit_opcode(CodeBuffer &cbuf, 507 int code, relocInfo::relocType reloc, int offset, int format) 508 { 509 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 510 emit_opcode(cbuf, code); 511 } 512 513 // EMIT_D8() 514 void emit_d8(CodeBuffer &cbuf, int d8) { 515 cbuf.insts()->emit_int8((unsigned char) d8); 516 } 517 518 // EMIT_D16() 519 void emit_d16(CodeBuffer &cbuf, int d16) { 520 cbuf.insts()->emit_int16(d16); 521 } 522 523 // EMIT_D32() 524 void emit_d32(CodeBuffer &cbuf, int d32) { 525 cbuf.insts()->emit_int32(d32); 526 } 527 528 // EMIT_D64() 529 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 530 cbuf.insts()->emit_int64(d64); 531 } 532 533 // emit 32 bit value and construct relocation entry from relocInfo::relocType 534 void emit_d32_reloc(CodeBuffer& cbuf, 535 int d32, 536 relocInfo::relocType reloc, 537 int format) 538 { 539 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 540 cbuf.relocate(cbuf.insts_mark(), reloc, format); 541 cbuf.insts()->emit_int32(d32); 542 } 543 544 // emit 32 bit value and construct relocation entry from RelocationHolder 545 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 546 #ifdef ASSERT 547 if (rspec.reloc()->type() == relocInfo::oop_type && 548 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 549 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 550 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)), "cannot embed broken oops in code"); 551 } 552 #endif 553 cbuf.relocate(cbuf.insts_mark(), rspec, format); 554 cbuf.insts()->emit_int32(d32); 555 } 556 557 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 558 address next_ip = cbuf.insts_end() + 4; 559 emit_d32_reloc(cbuf, (int) (addr - next_ip), 560 external_word_Relocation::spec(addr), 561 RELOC_DISP32); 562 } 563 564 565 // emit 64 bit value and construct relocation entry from relocInfo::relocType 566 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 567 cbuf.relocate(cbuf.insts_mark(), reloc, format); 568 cbuf.insts()->emit_int64(d64); 569 } 570 571 // emit 64 bit value and construct relocation entry from RelocationHolder 572 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 573 #ifdef ASSERT 574 if (rspec.reloc()->type() == relocInfo::oop_type && 575 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 576 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 577 assert(oopDesc::is_oop(cast_to_oop(d64)), "cannot embed broken oops in code"); 578 } 579 #endif 580 cbuf.relocate(cbuf.insts_mark(), rspec, format); 581 cbuf.insts()->emit_int64(d64); 582 } 583 584 // Access stack slot for load or store 585 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 586 { 587 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 588 if (-0x80 <= disp && disp < 0x80) { 589 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 590 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 591 emit_d8(cbuf, disp); // Displacement // R/M byte 592 } else { 593 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 594 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 595 emit_d32(cbuf, disp); // Displacement // R/M byte 596 } 597 } 598 599 // rRegI ereg, memory mem) %{ // emit_reg_mem 600 void encode_RegMem(CodeBuffer &cbuf, 601 int reg, 602 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 603 { 604 assert(disp_reloc == relocInfo::none, "cannot have disp"); 605 int regenc = reg & 7; 606 int baseenc = base & 7; 607 int indexenc = index & 7; 608 609 // There is no index & no scale, use form without SIB byte 610 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 611 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 612 if (disp == 0 && base != RBP_enc && base != R13_enc) { 613 emit_rm(cbuf, 0x0, regenc, baseenc); // * 614 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 615 // If 8-bit displacement, mode 0x1 616 emit_rm(cbuf, 0x1, regenc, baseenc); // * 617 emit_d8(cbuf, disp); 618 } else { 619 // If 32-bit displacement 620 if (base == -1) { // Special flag for absolute address 621 emit_rm(cbuf, 0x0, regenc, 0x5); // * 622 if (disp_reloc != relocInfo::none) { 623 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 624 } else { 625 emit_d32(cbuf, disp); 626 } 627 } else { 628 // Normal base + offset 629 emit_rm(cbuf, 0x2, regenc, baseenc); // * 630 if (disp_reloc != relocInfo::none) { 631 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 632 } else { 633 emit_d32(cbuf, disp); 634 } 635 } 636 } 637 } else { 638 // Else, encode with the SIB byte 639 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 640 if (disp == 0 && base != RBP_enc && base != R13_enc) { 641 // If no displacement 642 emit_rm(cbuf, 0x0, regenc, 0x4); // * 643 emit_rm(cbuf, scale, indexenc, baseenc); 644 } else { 645 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 646 // If 8-bit displacement, mode 0x1 647 emit_rm(cbuf, 0x1, regenc, 0x4); // * 648 emit_rm(cbuf, scale, indexenc, baseenc); 649 emit_d8(cbuf, disp); 650 } else { 651 // If 32-bit displacement 652 if (base == 0x04 ) { 653 emit_rm(cbuf, 0x2, regenc, 0x4); 654 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 655 } else { 656 emit_rm(cbuf, 0x2, regenc, 0x4); 657 emit_rm(cbuf, scale, indexenc, baseenc); // * 658 } 659 if (disp_reloc != relocInfo::none) { 660 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 661 } else { 662 emit_d32(cbuf, disp); 663 } 664 } 665 } 666 } 667 } 668 669 // This could be in MacroAssembler but it's fairly C2 specific 670 void emit_cmpfp_fixup(MacroAssembler& _masm) { 671 Label exit; 672 __ jccb(Assembler::noParity, exit); 673 __ pushf(); 674 // 675 // comiss/ucomiss instructions set ZF,PF,CF flags and 676 // zero OF,AF,SF for NaN values. 677 // Fixup flags by zeroing ZF,PF so that compare of NaN 678 // values returns 'less than' result (CF is set). 679 // Leave the rest of flags unchanged. 680 // 681 // 7 6 5 4 3 2 1 0 682 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 683 // 0 0 1 0 1 0 1 1 (0x2B) 684 // 685 __ andq(Address(rsp, 0), 0xffffff2b); 686 __ popf(); 687 __ bind(exit); 688 } 689 690 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 691 Label done; 692 __ movl(dst, -1); 693 __ jcc(Assembler::parity, done); 694 __ jcc(Assembler::below, done); 695 __ setb(Assembler::notEqual, dst); 696 __ movzbl(dst, dst); 697 __ bind(done); 698 } 699 700 // Math.min() # Math.max() 701 // -------------------------- 702 // ucomis[s/d] # 703 // ja -> b # a 704 // jp -> NaN # NaN 705 // jb -> a # b 706 // je # 707 // |-jz -> a | b # a & b 708 // | -> a # 709 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst, 710 XMMRegister a, XMMRegister b, 711 XMMRegister xmmt, Register rt, 712 bool min, bool single) { 713 714 Label nan, zero, below, above, done; 715 716 if (single) 717 __ ucomiss(a, b); 718 else 719 __ ucomisd(a, b); 720 721 if (dst->encoding() != (min ? b : a)->encoding()) 722 __ jccb(Assembler::above, above); // CF=0 & ZF=0 723 else 724 __ jccb(Assembler::above, done); 725 726 __ jccb(Assembler::parity, nan); // PF=1 727 __ jccb(Assembler::below, below); // CF=1 728 729 // equal 730 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 731 if (single) { 732 __ ucomiss(a, xmmt); 733 __ jccb(Assembler::equal, zero); 734 735 __ movflt(dst, a); 736 __ jmp(done); 737 } 738 else { 739 __ ucomisd(a, xmmt); 740 __ jccb(Assembler::equal, zero); 741 742 __ movdbl(dst, a); 743 __ jmp(done); 744 } 745 746 __ bind(zero); 747 if (min) 748 __ vpor(dst, a, b, Assembler::AVX_128bit); 749 else 750 __ vpand(dst, a, b, Assembler::AVX_128bit); 751 752 __ jmp(done); 753 754 __ bind(above); 755 if (single) 756 __ movflt(dst, min ? b : a); 757 else 758 __ movdbl(dst, min ? b : a); 759 760 __ jmp(done); 761 762 __ bind(nan); 763 if (single) { 764 __ movl(rt, 0x7fc00000); // Float.NaN 765 __ movdl(dst, rt); 766 } 767 else { 768 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 769 __ movdq(dst, rt); 770 } 771 __ jmp(done); 772 773 __ bind(below); 774 if (single) 775 __ movflt(dst, min ? a : b); 776 else 777 __ movdbl(dst, min ? a : b); 778 779 __ bind(done); 780 } 781 782 //============================================================================= 783 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 784 785 int Compile::ConstantTable::calculate_table_base_offset() const { 786 return 0; // absolute addressing, no offset 787 } 788 789 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 790 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 791 ShouldNotReachHere(); 792 } 793 794 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 795 // Empty encoding 796 } 797 798 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 799 return 0; 800 } 801 802 #ifndef PRODUCT 803 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 804 st->print("# MachConstantBaseNode (empty encoding)"); 805 } 806 #endif 807 808 809 //============================================================================= 810 #ifndef PRODUCT 811 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 812 Compile* C = ra_->C; 813 814 int framesize = C->frame_size_in_bytes(); 815 int bangsize = C->bang_size_in_bytes(); 816 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 817 // Remove wordSize for return addr which is already pushed. 818 framesize -= wordSize; 819 820 if (C->need_stack_bang(bangsize)) { 821 framesize -= wordSize; 822 st->print("# stack bang (%d bytes)", bangsize); 823 st->print("\n\t"); 824 st->print("pushq rbp\t# Save rbp"); 825 if (PreserveFramePointer) { 826 st->print("\n\t"); 827 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 828 } 829 if (framesize) { 830 st->print("\n\t"); 831 st->print("subq rsp, #%d\t# Create frame",framesize); 832 } 833 } else { 834 st->print("subq rsp, #%d\t# Create frame",framesize); 835 st->print("\n\t"); 836 framesize -= wordSize; 837 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 838 if (PreserveFramePointer) { 839 st->print("\n\t"); 840 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 841 if (framesize > 0) { 842 st->print("\n\t"); 843 st->print("addq rbp, #%d", framesize); 844 } 845 } 846 } 847 848 if (VerifyStackAtCalls) { 849 st->print("\n\t"); 850 framesize -= wordSize; 851 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 852 #ifdef ASSERT 853 st->print("\n\t"); 854 st->print("# stack alignment check"); 855 #endif 856 } 857 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 858 st->print("\n\t"); 859 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t"); 860 st->print("\n\t"); 861 st->print("je fast_entry\t"); 862 st->print("\n\t"); 863 st->print("call #nmethod_entry_barrier_stub\t"); 864 st->print("\n\tfast_entry:"); 865 } 866 st->cr(); 867 } 868 #endif 869 870 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 871 Compile* C = ra_->C; 872 MacroAssembler _masm(&cbuf); 873 874 int framesize = C->frame_size_in_bytes(); 875 int bangsize = C->bang_size_in_bytes(); 876 877 if (C->clinit_barrier_on_entry()) { 878 assert(C->method()->holder()->is_being_initialized(), "sanity"); 879 Label L_skip_barrier; 880 Register klass = rscratch1; 881 882 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 883 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 884 885 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 886 887 __ bind(L_skip_barrier); 888 } 889 890 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != NULL); 891 892 C->set_frame_complete(cbuf.insts_size()); 893 894 if (C->has_mach_constant_base_node()) { 895 // NOTE: We set the table base offset here because users might be 896 // emitted before MachConstantBaseNode. 897 Compile::ConstantTable& constant_table = C->constant_table(); 898 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 899 } 900 } 901 902 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 903 { 904 return MachNode::size(ra_); // too many variables; just compute it 905 // the hard way 906 } 907 908 int MachPrologNode::reloc() const 909 { 910 return 0; // a large enough number 911 } 912 913 //============================================================================= 914 #ifndef PRODUCT 915 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 916 { 917 Compile* C = ra_->C; 918 if (generate_vzeroupper(C)) { 919 st->print("vzeroupper"); 920 st->cr(); st->print("\t"); 921 } 922 923 int framesize = C->frame_size_in_bytes(); 924 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 925 // Remove word for return adr already pushed 926 // and RBP 927 framesize -= 2*wordSize; 928 929 if (framesize) { 930 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 931 st->print("\t"); 932 } 933 934 st->print_cr("popq rbp"); 935 if (do_polling() && C->is_method_compilation()) { 936 st->print("\t"); 937 if (SafepointMechanism::uses_thread_local_poll()) { 938 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 939 "testl rax, [rscratch1]\t" 940 "# Safepoint: poll for GC"); 941 } else if (Assembler::is_polling_page_far()) { 942 st->print_cr("movq rscratch1, #polling_page_address\n\t" 943 "testl rax, [rscratch1]\t" 944 "# Safepoint: poll for GC"); 945 } else { 946 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 947 "# Safepoint: poll for GC"); 948 } 949 } 950 } 951 #endif 952 953 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 954 { 955 Compile* C = ra_->C; 956 MacroAssembler _masm(&cbuf); 957 958 if (generate_vzeroupper(C)) { 959 // Clear upper bits of YMM registers when current compiled code uses 960 // wide vectors to avoid AVX <-> SSE transition penalty during call. 961 __ vzeroupper(); 962 } 963 964 int framesize = C->frame_size_in_bytes(); 965 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 966 // Remove word for return adr already pushed 967 // and RBP 968 framesize -= 2*wordSize; 969 970 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 971 972 if (framesize) { 973 emit_opcode(cbuf, Assembler::REX_W); 974 if (framesize < 0x80) { 975 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 976 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 977 emit_d8(cbuf, framesize); 978 } else { 979 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 980 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 981 emit_d32(cbuf, framesize); 982 } 983 } 984 985 // popq rbp 986 emit_opcode(cbuf, 0x58 | RBP_enc); 987 988 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 989 __ reserved_stack_check(); 990 } 991 992 if (do_polling() && C->is_method_compilation()) { 993 MacroAssembler _masm(&cbuf); 994 if (SafepointMechanism::uses_thread_local_poll()) { 995 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 996 __ relocate(relocInfo::poll_return_type); 997 __ testl(rax, Address(rscratch1, 0)); 998 } else { 999 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1000 if (Assembler::is_polling_page_far()) { 1001 __ lea(rscratch1, polling_page); 1002 __ relocate(relocInfo::poll_return_type); 1003 __ testl(rax, Address(rscratch1, 0)); 1004 } else { 1005 __ testl(rax, polling_page); 1006 } 1007 } 1008 } 1009 } 1010 1011 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1012 { 1013 return MachNode::size(ra_); // too many variables; just compute it 1014 // the hard way 1015 } 1016 1017 int MachEpilogNode::reloc() const 1018 { 1019 return 2; // a large enough number 1020 } 1021 1022 const Pipeline* MachEpilogNode::pipeline() const 1023 { 1024 return MachNode::pipeline_class(); 1025 } 1026 1027 int MachEpilogNode::safepoint_offset() const 1028 { 1029 return 0; 1030 } 1031 1032 //============================================================================= 1033 1034 enum RC { 1035 rc_bad, 1036 rc_int, 1037 rc_float, 1038 rc_stack 1039 }; 1040 1041 static enum RC rc_class(OptoReg::Name reg) 1042 { 1043 if( !OptoReg::is_valid(reg) ) return rc_bad; 1044 1045 if (OptoReg::is_stack(reg)) return rc_stack; 1046 1047 VMReg r = OptoReg::as_VMReg(reg); 1048 1049 if (r->is_Register()) return rc_int; 1050 1051 assert(r->is_XMMRegister(), "must be"); 1052 return rc_float; 1053 } 1054 1055 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1056 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1057 int src_hi, int dst_hi, uint ireg, outputStream* st); 1058 1059 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1060 int stack_offset, int reg, uint ireg, outputStream* st); 1061 1062 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1063 int dst_offset, uint ireg, outputStream* st) { 1064 if (cbuf) { 1065 MacroAssembler _masm(cbuf); 1066 switch (ireg) { 1067 case Op_VecS: 1068 __ movq(Address(rsp, -8), rax); 1069 __ movl(rax, Address(rsp, src_offset)); 1070 __ movl(Address(rsp, dst_offset), rax); 1071 __ movq(rax, Address(rsp, -8)); 1072 break; 1073 case Op_VecD: 1074 __ pushq(Address(rsp, src_offset)); 1075 __ popq (Address(rsp, dst_offset)); 1076 break; 1077 case Op_VecX: 1078 __ pushq(Address(rsp, src_offset)); 1079 __ popq (Address(rsp, dst_offset)); 1080 __ pushq(Address(rsp, src_offset+8)); 1081 __ popq (Address(rsp, dst_offset+8)); 1082 break; 1083 case Op_VecY: 1084 __ vmovdqu(Address(rsp, -32), xmm0); 1085 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1086 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1087 __ vmovdqu(xmm0, Address(rsp, -32)); 1088 break; 1089 case Op_VecZ: 1090 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1091 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1092 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1093 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1094 break; 1095 default: 1096 ShouldNotReachHere(); 1097 } 1098 #ifndef PRODUCT 1099 } else { 1100 switch (ireg) { 1101 case Op_VecS: 1102 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1103 "movl rax, [rsp + #%d]\n\t" 1104 "movl [rsp + #%d], rax\n\t" 1105 "movq rax, [rsp - #8]", 1106 src_offset, dst_offset); 1107 break; 1108 case Op_VecD: 1109 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1110 "popq [rsp + #%d]", 1111 src_offset, dst_offset); 1112 break; 1113 case Op_VecX: 1114 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1115 "popq [rsp + #%d]\n\t" 1116 "pushq [rsp + #%d]\n\t" 1117 "popq [rsp + #%d]", 1118 src_offset, dst_offset, src_offset+8, dst_offset+8); 1119 break; 1120 case Op_VecY: 1121 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1122 "vmovdqu xmm0, [rsp + #%d]\n\t" 1123 "vmovdqu [rsp + #%d], xmm0\n\t" 1124 "vmovdqu xmm0, [rsp - #32]", 1125 src_offset, dst_offset); 1126 break; 1127 case Op_VecZ: 1128 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1129 "vmovdqu xmm0, [rsp + #%d]\n\t" 1130 "vmovdqu [rsp + #%d], xmm0\n\t" 1131 "vmovdqu xmm0, [rsp - #64]", 1132 src_offset, dst_offset); 1133 break; 1134 default: 1135 ShouldNotReachHere(); 1136 } 1137 #endif 1138 } 1139 } 1140 1141 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1142 PhaseRegAlloc* ra_, 1143 bool do_size, 1144 outputStream* st) const { 1145 assert(cbuf != NULL || st != NULL, "sanity"); 1146 // Get registers to move 1147 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1148 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1149 OptoReg::Name dst_second = ra_->get_reg_second(this); 1150 OptoReg::Name dst_first = ra_->get_reg_first(this); 1151 1152 enum RC src_second_rc = rc_class(src_second); 1153 enum RC src_first_rc = rc_class(src_first); 1154 enum RC dst_second_rc = rc_class(dst_second); 1155 enum RC dst_first_rc = rc_class(dst_first); 1156 1157 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1158 "must move at least 1 register" ); 1159 1160 if (src_first == dst_first && src_second == dst_second) { 1161 // Self copy, no move 1162 return 0; 1163 } 1164 if (bottom_type()->isa_vect() != NULL) { 1165 uint ireg = ideal_reg(); 1166 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1167 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1168 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1169 // mem -> mem 1170 int src_offset = ra_->reg2offset(src_first); 1171 int dst_offset = ra_->reg2offset(dst_first); 1172 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1173 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1174 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1175 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1176 int stack_offset = ra_->reg2offset(dst_first); 1177 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1178 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1179 int stack_offset = ra_->reg2offset(src_first); 1180 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1181 } else { 1182 ShouldNotReachHere(); 1183 } 1184 return 0; 1185 } 1186 if (src_first_rc == rc_stack) { 1187 // mem -> 1188 if (dst_first_rc == rc_stack) { 1189 // mem -> mem 1190 assert(src_second != dst_first, "overlap"); 1191 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1192 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1193 // 64-bit 1194 int src_offset = ra_->reg2offset(src_first); 1195 int dst_offset = ra_->reg2offset(dst_first); 1196 if (cbuf) { 1197 MacroAssembler _masm(cbuf); 1198 __ pushq(Address(rsp, src_offset)); 1199 __ popq (Address(rsp, dst_offset)); 1200 #ifndef PRODUCT 1201 } else { 1202 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1203 "popq [rsp + #%d]", 1204 src_offset, dst_offset); 1205 #endif 1206 } 1207 } else { 1208 // 32-bit 1209 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1210 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1211 // No pushl/popl, so: 1212 int src_offset = ra_->reg2offset(src_first); 1213 int dst_offset = ra_->reg2offset(dst_first); 1214 if (cbuf) { 1215 MacroAssembler _masm(cbuf); 1216 __ movq(Address(rsp, -8), rax); 1217 __ movl(rax, Address(rsp, src_offset)); 1218 __ movl(Address(rsp, dst_offset), rax); 1219 __ movq(rax, Address(rsp, -8)); 1220 #ifndef PRODUCT 1221 } else { 1222 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1223 "movl rax, [rsp + #%d]\n\t" 1224 "movl [rsp + #%d], rax\n\t" 1225 "movq rax, [rsp - #8]", 1226 src_offset, dst_offset); 1227 #endif 1228 } 1229 } 1230 return 0; 1231 } else if (dst_first_rc == rc_int) { 1232 // mem -> gpr 1233 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1234 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1235 // 64-bit 1236 int offset = ra_->reg2offset(src_first); 1237 if (cbuf) { 1238 MacroAssembler _masm(cbuf); 1239 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1240 #ifndef PRODUCT 1241 } else { 1242 st->print("movq %s, [rsp + #%d]\t# spill", 1243 Matcher::regName[dst_first], 1244 offset); 1245 #endif 1246 } 1247 } else { 1248 // 32-bit 1249 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1250 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1251 int offset = ra_->reg2offset(src_first); 1252 if (cbuf) { 1253 MacroAssembler _masm(cbuf); 1254 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1255 #ifndef PRODUCT 1256 } else { 1257 st->print("movl %s, [rsp + #%d]\t# spill", 1258 Matcher::regName[dst_first], 1259 offset); 1260 #endif 1261 } 1262 } 1263 return 0; 1264 } else if (dst_first_rc == rc_float) { 1265 // mem-> xmm 1266 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1267 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1268 // 64-bit 1269 int offset = ra_->reg2offset(src_first); 1270 if (cbuf) { 1271 MacroAssembler _masm(cbuf); 1272 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1273 #ifndef PRODUCT 1274 } else { 1275 st->print("%s %s, [rsp + #%d]\t# spill", 1276 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1277 Matcher::regName[dst_first], 1278 offset); 1279 #endif 1280 } 1281 } else { 1282 // 32-bit 1283 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1284 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1285 int offset = ra_->reg2offset(src_first); 1286 if (cbuf) { 1287 MacroAssembler _masm(cbuf); 1288 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1289 #ifndef PRODUCT 1290 } else { 1291 st->print("movss %s, [rsp + #%d]\t# spill", 1292 Matcher::regName[dst_first], 1293 offset); 1294 #endif 1295 } 1296 } 1297 return 0; 1298 } 1299 } else if (src_first_rc == rc_int) { 1300 // gpr -> 1301 if (dst_first_rc == rc_stack) { 1302 // gpr -> mem 1303 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1304 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1305 // 64-bit 1306 int offset = ra_->reg2offset(dst_first); 1307 if (cbuf) { 1308 MacroAssembler _masm(cbuf); 1309 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1310 #ifndef PRODUCT 1311 } else { 1312 st->print("movq [rsp + #%d], %s\t# spill", 1313 offset, 1314 Matcher::regName[src_first]); 1315 #endif 1316 } 1317 } else { 1318 // 32-bit 1319 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1320 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1321 int offset = ra_->reg2offset(dst_first); 1322 if (cbuf) { 1323 MacroAssembler _masm(cbuf); 1324 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1325 #ifndef PRODUCT 1326 } else { 1327 st->print("movl [rsp + #%d], %s\t# spill", 1328 offset, 1329 Matcher::regName[src_first]); 1330 #endif 1331 } 1332 } 1333 return 0; 1334 } else if (dst_first_rc == rc_int) { 1335 // gpr -> gpr 1336 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1337 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1338 // 64-bit 1339 if (cbuf) { 1340 MacroAssembler _masm(cbuf); 1341 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1342 as_Register(Matcher::_regEncode[src_first])); 1343 #ifndef PRODUCT 1344 } else { 1345 st->print("movq %s, %s\t# spill", 1346 Matcher::regName[dst_first], 1347 Matcher::regName[src_first]); 1348 #endif 1349 } 1350 return 0; 1351 } else { 1352 // 32-bit 1353 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1354 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1355 if (cbuf) { 1356 MacroAssembler _masm(cbuf); 1357 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1358 as_Register(Matcher::_regEncode[src_first])); 1359 #ifndef PRODUCT 1360 } else { 1361 st->print("movl %s, %s\t# spill", 1362 Matcher::regName[dst_first], 1363 Matcher::regName[src_first]); 1364 #endif 1365 } 1366 return 0; 1367 } 1368 } else if (dst_first_rc == rc_float) { 1369 // gpr -> xmm 1370 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1371 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1372 // 64-bit 1373 if (cbuf) { 1374 MacroAssembler _masm(cbuf); 1375 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1376 #ifndef PRODUCT 1377 } else { 1378 st->print("movdq %s, %s\t# spill", 1379 Matcher::regName[dst_first], 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 if (cbuf) { 1388 MacroAssembler _masm(cbuf); 1389 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1390 #ifndef PRODUCT 1391 } else { 1392 st->print("movdl %s, %s\t# spill", 1393 Matcher::regName[dst_first], 1394 Matcher::regName[src_first]); 1395 #endif 1396 } 1397 } 1398 return 0; 1399 } 1400 } else if (src_first_rc == rc_float) { 1401 // xmm -> 1402 if (dst_first_rc == rc_stack) { 1403 // xmm -> mem 1404 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1405 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1406 // 64-bit 1407 int offset = ra_->reg2offset(dst_first); 1408 if (cbuf) { 1409 MacroAssembler _masm(cbuf); 1410 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1411 #ifndef PRODUCT 1412 } else { 1413 st->print("movsd [rsp + #%d], %s\t# spill", 1414 offset, 1415 Matcher::regName[src_first]); 1416 #endif 1417 } 1418 } else { 1419 // 32-bit 1420 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1421 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1422 int offset = ra_->reg2offset(dst_first); 1423 if (cbuf) { 1424 MacroAssembler _masm(cbuf); 1425 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1426 #ifndef PRODUCT 1427 } else { 1428 st->print("movss [rsp + #%d], %s\t# spill", 1429 offset, 1430 Matcher::regName[src_first]); 1431 #endif 1432 } 1433 } 1434 return 0; 1435 } else if (dst_first_rc == rc_int) { 1436 // xmm -> gpr 1437 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1438 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1439 // 64-bit 1440 if (cbuf) { 1441 MacroAssembler _masm(cbuf); 1442 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1443 #ifndef PRODUCT 1444 } else { 1445 st->print("movdq %s, %s\t# spill", 1446 Matcher::regName[dst_first], 1447 Matcher::regName[src_first]); 1448 #endif 1449 } 1450 } else { 1451 // 32-bit 1452 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1453 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1454 if (cbuf) { 1455 MacroAssembler _masm(cbuf); 1456 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1457 #ifndef PRODUCT 1458 } else { 1459 st->print("movdl %s, %s\t# spill", 1460 Matcher::regName[dst_first], 1461 Matcher::regName[src_first]); 1462 #endif 1463 } 1464 } 1465 return 0; 1466 } else if (dst_first_rc == rc_float) { 1467 // xmm -> xmm 1468 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1469 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1470 // 64-bit 1471 if (cbuf) { 1472 MacroAssembler _masm(cbuf); 1473 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1474 #ifndef PRODUCT 1475 } else { 1476 st->print("%s %s, %s\t# spill", 1477 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1478 Matcher::regName[dst_first], 1479 Matcher::regName[src_first]); 1480 #endif 1481 } 1482 } else { 1483 // 32-bit 1484 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1485 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1486 if (cbuf) { 1487 MacroAssembler _masm(cbuf); 1488 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1489 #ifndef PRODUCT 1490 } else { 1491 st->print("%s %s, %s\t# spill", 1492 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1493 Matcher::regName[dst_first], 1494 Matcher::regName[src_first]); 1495 #endif 1496 } 1497 } 1498 return 0; 1499 } 1500 } 1501 1502 assert(0," foo "); 1503 Unimplemented(); 1504 return 0; 1505 } 1506 1507 #ifndef PRODUCT 1508 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1509 implementation(NULL, ra_, false, st); 1510 } 1511 #endif 1512 1513 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1514 implementation(&cbuf, ra_, false, NULL); 1515 } 1516 1517 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1518 return MachNode::size(ra_); 1519 } 1520 1521 //============================================================================= 1522 #ifndef PRODUCT 1523 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1524 { 1525 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1526 int reg = ra_->get_reg_first(this); 1527 st->print("leaq %s, [rsp + #%d]\t# box lock", 1528 Matcher::regName[reg], offset); 1529 } 1530 #endif 1531 1532 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1533 { 1534 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1535 int reg = ra_->get_encode(this); 1536 if (offset >= 0x80) { 1537 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1538 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1539 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1540 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1541 emit_d32(cbuf, offset); 1542 } else { 1543 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1544 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1545 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1546 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1547 emit_d8(cbuf, offset); 1548 } 1549 } 1550 1551 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1552 { 1553 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1554 return (offset < 0x80) ? 5 : 8; // REX 1555 } 1556 1557 //============================================================================= 1558 #ifndef PRODUCT 1559 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1560 { 1561 if (UseCompressedClassPointers) { 1562 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1563 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1564 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1565 } else { 1566 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1567 "# Inline cache check"); 1568 } 1569 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1570 st->print_cr("\tnop\t# nops to align entry point"); 1571 } 1572 #endif 1573 1574 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1575 { 1576 MacroAssembler masm(&cbuf); 1577 uint insts_size = cbuf.insts_size(); 1578 if (UseCompressedClassPointers) { 1579 masm.load_klass(rscratch1, j_rarg0); 1580 masm.cmpptr(rax, rscratch1); 1581 } else { 1582 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1583 } 1584 1585 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1586 1587 /* WARNING these NOPs are critical so that verified entry point is properly 1588 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1589 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1590 if (OptoBreakpoint) { 1591 // Leave space for int3 1592 nops_cnt -= 1; 1593 } 1594 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1595 if (nops_cnt > 0) 1596 masm.nop(nops_cnt); 1597 } 1598 1599 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1600 { 1601 return MachNode::size(ra_); // too many variables; just compute it 1602 // the hard way 1603 } 1604 1605 1606 //============================================================================= 1607 1608 int Matcher::regnum_to_fpu_offset(int regnum) 1609 { 1610 return regnum - 32; // The FP registers are in the second chunk 1611 } 1612 1613 // This is UltraSparc specific, true just means we have fast l2f conversion 1614 const bool Matcher::convL2FSupported(void) { 1615 return true; 1616 } 1617 1618 // Is this branch offset short enough that a short branch can be used? 1619 // 1620 // NOTE: If the platform does not provide any short branch variants, then 1621 // this method should return false for offset 0. 1622 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1623 // The passed offset is relative to address of the branch. 1624 // On 86 a branch displacement is calculated relative to address 1625 // of a next instruction. 1626 offset -= br_size; 1627 1628 // the short version of jmpConUCF2 contains multiple branches, 1629 // making the reach slightly less 1630 if (rule == jmpConUCF2_rule) 1631 return (-126 <= offset && offset <= 125); 1632 return (-128 <= offset && offset <= 127); 1633 } 1634 1635 const bool Matcher::isSimpleConstant64(jlong value) { 1636 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1637 //return value == (int) value; // Cf. storeImmL and immL32. 1638 1639 // Probably always true, even if a temp register is required. 1640 return true; 1641 } 1642 1643 // The ecx parameter to rep stosq for the ClearArray node is in words. 1644 const bool Matcher::init_array_count_is_in_bytes = false; 1645 1646 // No additional cost for CMOVL. 1647 const int Matcher::long_cmove_cost() { return 0; } 1648 1649 // No CMOVF/CMOVD with SSE2 1650 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1651 1652 // Does the CPU require late expand (see block.cpp for description of late expand)? 1653 const bool Matcher::require_postalloc_expand = false; 1654 1655 // Do we need to mask the count passed to shift instructions or does 1656 // the cpu only look at the lower 5/6 bits anyway? 1657 const bool Matcher::need_masked_shift_count = false; 1658 1659 bool Matcher::narrow_oop_use_complex_address() { 1660 assert(UseCompressedOops, "only for compressed oops code"); 1661 return (LogMinObjAlignmentInBytes <= 3); 1662 } 1663 1664 bool Matcher::narrow_klass_use_complex_address() { 1665 assert(UseCompressedClassPointers, "only for compressed klass code"); 1666 return (LogKlassAlignmentInBytes <= 3); 1667 } 1668 1669 bool Matcher::const_oop_prefer_decode() { 1670 // Prefer ConN+DecodeN over ConP. 1671 return true; 1672 } 1673 1674 bool Matcher::const_klass_prefer_decode() { 1675 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1676 // or condisider the following: 1677 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1678 //return Universe::narrow_klass_base() == NULL; 1679 return true; 1680 } 1681 1682 // Is it better to copy float constants, or load them directly from 1683 // memory? Intel can load a float constant from a direct address, 1684 // requiring no extra registers. Most RISCs will have to materialize 1685 // an address into a register first, so they would do better to copy 1686 // the constant from stack. 1687 const bool Matcher::rematerialize_float_constants = true; // XXX 1688 1689 // If CPU can load and store mis-aligned doubles directly then no 1690 // fixup is needed. Else we split the double into 2 integer pieces 1691 // and move it piece-by-piece. Only happens when passing doubles into 1692 // C code as the Java calling convention forces doubles to be aligned. 1693 const bool Matcher::misaligned_doubles_ok = true; 1694 1695 // No-op on amd64 1696 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1697 1698 // Advertise here if the CPU requires explicit rounding operations to 1699 // implement the UseStrictFP mode. 1700 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1701 1702 // Are floats conerted to double when stored to stack during deoptimization? 1703 // On x64 it is stored without convertion so we can use normal access. 1704 bool Matcher::float_in_double() { return false; } 1705 1706 // Do ints take an entire long register or just half? 1707 const bool Matcher::int_in_long = true; 1708 1709 // Return whether or not this register is ever used as an argument. 1710 // This function is used on startup to build the trampoline stubs in 1711 // generateOptoStub. Registers not mentioned will be killed by the VM 1712 // call in the trampoline, and arguments in those registers not be 1713 // available to the callee. 1714 bool Matcher::can_be_java_arg(int reg) 1715 { 1716 return 1717 reg == RDI_num || reg == RDI_H_num || 1718 reg == RSI_num || reg == RSI_H_num || 1719 reg == RDX_num || reg == RDX_H_num || 1720 reg == RCX_num || reg == RCX_H_num || 1721 reg == R8_num || reg == R8_H_num || 1722 reg == R9_num || reg == R9_H_num || 1723 reg == R12_num || reg == R12_H_num || 1724 reg == XMM0_num || reg == XMM0b_num || 1725 reg == XMM1_num || reg == XMM1b_num || 1726 reg == XMM2_num || reg == XMM2b_num || 1727 reg == XMM3_num || reg == XMM3b_num || 1728 reg == XMM4_num || reg == XMM4b_num || 1729 reg == XMM5_num || reg == XMM5b_num || 1730 reg == XMM6_num || reg == XMM6b_num || 1731 reg == XMM7_num || reg == XMM7b_num; 1732 } 1733 1734 bool Matcher::is_spillable_arg(int reg) 1735 { 1736 return can_be_java_arg(reg); 1737 } 1738 1739 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1740 // In 64 bit mode a code which use multiply when 1741 // devisor is constant is faster than hardware 1742 // DIV instruction (it uses MulHiL). 1743 return false; 1744 } 1745 1746 // Register for DIVI projection of divmodI 1747 RegMask Matcher::divI_proj_mask() { 1748 return INT_RAX_REG_mask(); 1749 } 1750 1751 // Register for MODI projection of divmodI 1752 RegMask Matcher::modI_proj_mask() { 1753 return INT_RDX_REG_mask(); 1754 } 1755 1756 // Register for DIVL projection of divmodL 1757 RegMask Matcher::divL_proj_mask() { 1758 return LONG_RAX_REG_mask(); 1759 } 1760 1761 // Register for MODL projection of divmodL 1762 RegMask Matcher::modL_proj_mask() { 1763 return LONG_RDX_REG_mask(); 1764 } 1765 1766 // Register for saving SP into on method handle invokes. Not used on x86_64. 1767 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1768 return NO_REG_mask(); 1769 } 1770 1771 %} 1772 1773 //----------ENCODING BLOCK----------------------------------------------------- 1774 // This block specifies the encoding classes used by the compiler to 1775 // output byte streams. Encoding classes are parameterized macros 1776 // used by Machine Instruction Nodes in order to generate the bit 1777 // encoding of the instruction. Operands specify their base encoding 1778 // interface with the interface keyword. There are currently 1779 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1780 // COND_INTER. REG_INTER causes an operand to generate a function 1781 // which returns its register number when queried. CONST_INTER causes 1782 // an operand to generate a function which returns the value of the 1783 // constant when queried. MEMORY_INTER causes an operand to generate 1784 // four functions which return the Base Register, the Index Register, 1785 // the Scale Value, and the Offset Value of the operand when queried. 1786 // COND_INTER causes an operand to generate six functions which return 1787 // the encoding code (ie - encoding bits for the instruction) 1788 // associated with each basic boolean condition for a conditional 1789 // instruction. 1790 // 1791 // Instructions specify two basic values for encoding. Again, a 1792 // function is available to check if the constant displacement is an 1793 // oop. They use the ins_encode keyword to specify their encoding 1794 // classes (which must be a sequence of enc_class names, and their 1795 // parameters, specified in the encoding block), and they use the 1796 // opcode keyword to specify, in order, their primary, secondary, and 1797 // tertiary opcode. Only the opcode sections which a particular 1798 // instruction needs for encoding need to be specified. 1799 encode %{ 1800 // Build emit functions for each basic byte or larger field in the 1801 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1802 // from C++ code in the enc_class source block. Emit functions will 1803 // live in the main source block for now. In future, we can 1804 // generalize this by adding a syntax that specifies the sizes of 1805 // fields in an order, so that the adlc can build the emit functions 1806 // automagically 1807 1808 // Emit primary opcode 1809 enc_class OpcP 1810 %{ 1811 emit_opcode(cbuf, $primary); 1812 %} 1813 1814 // Emit secondary opcode 1815 enc_class OpcS 1816 %{ 1817 emit_opcode(cbuf, $secondary); 1818 %} 1819 1820 // Emit tertiary opcode 1821 enc_class OpcT 1822 %{ 1823 emit_opcode(cbuf, $tertiary); 1824 %} 1825 1826 // Emit opcode directly 1827 enc_class Opcode(immI d8) 1828 %{ 1829 emit_opcode(cbuf, $d8$$constant); 1830 %} 1831 1832 // Emit size prefix 1833 enc_class SizePrefix 1834 %{ 1835 emit_opcode(cbuf, 0x66); 1836 %} 1837 1838 enc_class reg(rRegI reg) 1839 %{ 1840 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1841 %} 1842 1843 enc_class reg_reg(rRegI dst, rRegI src) 1844 %{ 1845 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1846 %} 1847 1848 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1849 %{ 1850 emit_opcode(cbuf, $opcode$$constant); 1851 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1852 %} 1853 1854 enc_class cdql_enc(no_rax_rdx_RegI div) 1855 %{ 1856 // Full implementation of Java idiv and irem; checks for 1857 // special case as described in JVM spec., p.243 & p.271. 1858 // 1859 // normal case special case 1860 // 1861 // input : rax: dividend min_int 1862 // reg: divisor -1 1863 // 1864 // output: rax: quotient (= rax idiv reg) min_int 1865 // rdx: remainder (= rax irem reg) 0 1866 // 1867 // Code sequnce: 1868 // 1869 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1870 // 5: 75 07/08 jne e <normal> 1871 // 7: 33 d2 xor %edx,%edx 1872 // [div >= 8 -> offset + 1] 1873 // [REX_B] 1874 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1875 // c: 74 03/04 je 11 <done> 1876 // 000000000000000e <normal>: 1877 // e: 99 cltd 1878 // [div >= 8 -> offset + 1] 1879 // [REX_B] 1880 // f: f7 f9 idiv $div 1881 // 0000000000000011 <done>: 1882 1883 // cmp $0x80000000,%eax 1884 emit_opcode(cbuf, 0x3d); 1885 emit_d8(cbuf, 0x00); 1886 emit_d8(cbuf, 0x00); 1887 emit_d8(cbuf, 0x00); 1888 emit_d8(cbuf, 0x80); 1889 1890 // jne e <normal> 1891 emit_opcode(cbuf, 0x75); 1892 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1893 1894 // xor %edx,%edx 1895 emit_opcode(cbuf, 0x33); 1896 emit_d8(cbuf, 0xD2); 1897 1898 // cmp $0xffffffffffffffff,%ecx 1899 if ($div$$reg >= 8) { 1900 emit_opcode(cbuf, Assembler::REX_B); 1901 } 1902 emit_opcode(cbuf, 0x83); 1903 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1904 emit_d8(cbuf, 0xFF); 1905 1906 // je 11 <done> 1907 emit_opcode(cbuf, 0x74); 1908 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1909 1910 // <normal> 1911 // cltd 1912 emit_opcode(cbuf, 0x99); 1913 1914 // idivl (note: must be emitted by the user of this rule) 1915 // <done> 1916 %} 1917 1918 enc_class cdqq_enc(no_rax_rdx_RegL div) 1919 %{ 1920 // Full implementation of Java ldiv and lrem; checks for 1921 // special case as described in JVM spec., p.243 & p.271. 1922 // 1923 // normal case special case 1924 // 1925 // input : rax: dividend min_long 1926 // reg: divisor -1 1927 // 1928 // output: rax: quotient (= rax idiv reg) min_long 1929 // rdx: remainder (= rax irem reg) 0 1930 // 1931 // Code sequnce: 1932 // 1933 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1934 // 7: 00 00 80 1935 // a: 48 39 d0 cmp %rdx,%rax 1936 // d: 75 08 jne 17 <normal> 1937 // f: 33 d2 xor %edx,%edx 1938 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1939 // 15: 74 05 je 1c <done> 1940 // 0000000000000017 <normal>: 1941 // 17: 48 99 cqto 1942 // 19: 48 f7 f9 idiv $div 1943 // 000000000000001c <done>: 1944 1945 // mov $0x8000000000000000,%rdx 1946 emit_opcode(cbuf, Assembler::REX_W); 1947 emit_opcode(cbuf, 0xBA); 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, 0x00); 1954 emit_d8(cbuf, 0x00); 1955 emit_d8(cbuf, 0x80); 1956 1957 // cmp %rdx,%rax 1958 emit_opcode(cbuf, Assembler::REX_W); 1959 emit_opcode(cbuf, 0x39); 1960 emit_d8(cbuf, 0xD0); 1961 1962 // jne 17 <normal> 1963 emit_opcode(cbuf, 0x75); 1964 emit_d8(cbuf, 0x08); 1965 1966 // xor %edx,%edx 1967 emit_opcode(cbuf, 0x33); 1968 emit_d8(cbuf, 0xD2); 1969 1970 // cmp $0xffffffffffffffff,$div 1971 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1972 emit_opcode(cbuf, 0x83); 1973 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1974 emit_d8(cbuf, 0xFF); 1975 1976 // je 1e <done> 1977 emit_opcode(cbuf, 0x74); 1978 emit_d8(cbuf, 0x05); 1979 1980 // <normal> 1981 // cqto 1982 emit_opcode(cbuf, Assembler::REX_W); 1983 emit_opcode(cbuf, 0x99); 1984 1985 // idivq (note: must be emitted by the user of this rule) 1986 // <done> 1987 %} 1988 1989 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1990 enc_class OpcSE(immI imm) 1991 %{ 1992 // Emit primary opcode and set sign-extend bit 1993 // Check for 8-bit immediate, and set sign extend bit in opcode 1994 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1995 emit_opcode(cbuf, $primary | 0x02); 1996 } else { 1997 // 32-bit immediate 1998 emit_opcode(cbuf, $primary); 1999 } 2000 %} 2001 2002 enc_class OpcSErm(rRegI dst, immI imm) 2003 %{ 2004 // OpcSEr/m 2005 int dstenc = $dst$$reg; 2006 if (dstenc >= 8) { 2007 emit_opcode(cbuf, Assembler::REX_B); 2008 dstenc -= 8; 2009 } 2010 // Emit primary opcode and set sign-extend bit 2011 // Check for 8-bit immediate, and set sign extend bit in opcode 2012 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2013 emit_opcode(cbuf, $primary | 0x02); 2014 } else { 2015 // 32-bit immediate 2016 emit_opcode(cbuf, $primary); 2017 } 2018 // Emit r/m byte with secondary opcode, after primary opcode. 2019 emit_rm(cbuf, 0x3, $secondary, dstenc); 2020 %} 2021 2022 enc_class OpcSErm_wide(rRegL dst, immI imm) 2023 %{ 2024 // OpcSEr/m 2025 int dstenc = $dst$$reg; 2026 if (dstenc < 8) { 2027 emit_opcode(cbuf, Assembler::REX_W); 2028 } else { 2029 emit_opcode(cbuf, Assembler::REX_WB); 2030 dstenc -= 8; 2031 } 2032 // Emit primary opcode and set sign-extend bit 2033 // Check for 8-bit immediate, and set sign extend bit in opcode 2034 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2035 emit_opcode(cbuf, $primary | 0x02); 2036 } else { 2037 // 32-bit immediate 2038 emit_opcode(cbuf, $primary); 2039 } 2040 // Emit r/m byte with secondary opcode, after primary opcode. 2041 emit_rm(cbuf, 0x3, $secondary, dstenc); 2042 %} 2043 2044 enc_class Con8or32(immI imm) 2045 %{ 2046 // Check for 8-bit immediate, and set sign extend bit in opcode 2047 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2048 $$$emit8$imm$$constant; 2049 } else { 2050 // 32-bit immediate 2051 $$$emit32$imm$$constant; 2052 } 2053 %} 2054 2055 enc_class opc2_reg(rRegI dst) 2056 %{ 2057 // BSWAP 2058 emit_cc(cbuf, $secondary, $dst$$reg); 2059 %} 2060 2061 enc_class opc3_reg(rRegI dst) 2062 %{ 2063 // BSWAP 2064 emit_cc(cbuf, $tertiary, $dst$$reg); 2065 %} 2066 2067 enc_class reg_opc(rRegI div) 2068 %{ 2069 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2070 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2071 %} 2072 2073 enc_class enc_cmov(cmpOp cop) 2074 %{ 2075 // CMOV 2076 $$$emit8$primary; 2077 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2078 %} 2079 2080 enc_class enc_PartialSubtypeCheck() 2081 %{ 2082 Register Rrdi = as_Register(RDI_enc); // result register 2083 Register Rrax = as_Register(RAX_enc); // super class 2084 Register Rrcx = as_Register(RCX_enc); // killed 2085 Register Rrsi = as_Register(RSI_enc); // sub class 2086 Label miss; 2087 const bool set_cond_codes = true; 2088 2089 MacroAssembler _masm(&cbuf); 2090 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2091 NULL, &miss, 2092 /*set_cond_codes:*/ true); 2093 if ($primary) { 2094 __ xorptr(Rrdi, Rrdi); 2095 } 2096 __ bind(miss); 2097 %} 2098 2099 enc_class clear_avx %{ 2100 debug_only(int off0 = cbuf.insts_size()); 2101 if (generate_vzeroupper(Compile::current())) { 2102 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2103 // Clear upper bits of YMM registers when current compiled code uses 2104 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2105 MacroAssembler _masm(&cbuf); 2106 __ vzeroupper(); 2107 } 2108 debug_only(int off1 = cbuf.insts_size()); 2109 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2110 %} 2111 2112 enc_class Java_To_Runtime(method meth) %{ 2113 // No relocation needed 2114 MacroAssembler _masm(&cbuf); 2115 __ mov64(r10, (int64_t) $meth$$method); 2116 __ call(r10); 2117 %} 2118 2119 enc_class Java_To_Interpreter(method meth) 2120 %{ 2121 // CALL Java_To_Interpreter 2122 // This is the instruction starting address for relocation info. 2123 cbuf.set_insts_mark(); 2124 $$$emit8$primary; 2125 // CALL directly to the runtime 2126 emit_d32_reloc(cbuf, 2127 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2128 runtime_call_Relocation::spec(), 2129 RELOC_DISP32); 2130 %} 2131 2132 enc_class Java_Static_Call(method meth) 2133 %{ 2134 // JAVA STATIC CALL 2135 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2136 // determine who we intended to call. 2137 cbuf.set_insts_mark(); 2138 $$$emit8$primary; 2139 2140 if (!_method) { 2141 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2142 runtime_call_Relocation::spec(), 2143 RELOC_DISP32); 2144 } else { 2145 int method_index = resolved_method_index(cbuf); 2146 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2147 : static_call_Relocation::spec(method_index); 2148 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2149 rspec, RELOC_DISP32); 2150 // Emit stubs for static call. 2151 address mark = cbuf.insts_mark(); 2152 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2153 if (stub == NULL) { 2154 ciEnv::current()->record_failure("CodeCache is full"); 2155 return; 2156 } 2157 #if INCLUDE_AOT 2158 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2159 #endif 2160 } 2161 %} 2162 2163 enc_class Java_Dynamic_Call(method meth) %{ 2164 MacroAssembler _masm(&cbuf); 2165 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2166 %} 2167 2168 enc_class Java_Compiled_Call(method meth) 2169 %{ 2170 // JAVA COMPILED CALL 2171 int disp = in_bytes(Method:: from_compiled_offset()); 2172 2173 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2174 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2175 2176 // callq *disp(%rax) 2177 cbuf.set_insts_mark(); 2178 $$$emit8$primary; 2179 if (disp < 0x80) { 2180 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2181 emit_d8(cbuf, disp); // Displacement 2182 } else { 2183 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2184 emit_d32(cbuf, disp); // Displacement 2185 } 2186 %} 2187 2188 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2189 %{ 2190 // SAL, SAR, SHR 2191 int dstenc = $dst$$reg; 2192 if (dstenc >= 8) { 2193 emit_opcode(cbuf, Assembler::REX_B); 2194 dstenc -= 8; 2195 } 2196 $$$emit8$primary; 2197 emit_rm(cbuf, 0x3, $secondary, dstenc); 2198 $$$emit8$shift$$constant; 2199 %} 2200 2201 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2202 %{ 2203 // SAL, SAR, SHR 2204 int dstenc = $dst$$reg; 2205 if (dstenc < 8) { 2206 emit_opcode(cbuf, Assembler::REX_W); 2207 } else { 2208 emit_opcode(cbuf, Assembler::REX_WB); 2209 dstenc -= 8; 2210 } 2211 $$$emit8$primary; 2212 emit_rm(cbuf, 0x3, $secondary, dstenc); 2213 $$$emit8$shift$$constant; 2214 %} 2215 2216 enc_class load_immI(rRegI dst, immI src) 2217 %{ 2218 int dstenc = $dst$$reg; 2219 if (dstenc >= 8) { 2220 emit_opcode(cbuf, Assembler::REX_B); 2221 dstenc -= 8; 2222 } 2223 emit_opcode(cbuf, 0xB8 | dstenc); 2224 $$$emit32$src$$constant; 2225 %} 2226 2227 enc_class load_immL(rRegL dst, immL src) 2228 %{ 2229 int dstenc = $dst$$reg; 2230 if (dstenc < 8) { 2231 emit_opcode(cbuf, Assembler::REX_W); 2232 } else { 2233 emit_opcode(cbuf, Assembler::REX_WB); 2234 dstenc -= 8; 2235 } 2236 emit_opcode(cbuf, 0xB8 | dstenc); 2237 emit_d64(cbuf, $src$$constant); 2238 %} 2239 2240 enc_class load_immUL32(rRegL dst, immUL32 src) 2241 %{ 2242 // same as load_immI, but this time we care about zeroes in the high word 2243 int dstenc = $dst$$reg; 2244 if (dstenc >= 8) { 2245 emit_opcode(cbuf, Assembler::REX_B); 2246 dstenc -= 8; 2247 } 2248 emit_opcode(cbuf, 0xB8 | dstenc); 2249 $$$emit32$src$$constant; 2250 %} 2251 2252 enc_class load_immL32(rRegL dst, immL32 src) 2253 %{ 2254 int dstenc = $dst$$reg; 2255 if (dstenc < 8) { 2256 emit_opcode(cbuf, Assembler::REX_W); 2257 } else { 2258 emit_opcode(cbuf, Assembler::REX_WB); 2259 dstenc -= 8; 2260 } 2261 emit_opcode(cbuf, 0xC7); 2262 emit_rm(cbuf, 0x03, 0x00, dstenc); 2263 $$$emit32$src$$constant; 2264 %} 2265 2266 enc_class load_immP31(rRegP dst, immP32 src) 2267 %{ 2268 // same as load_immI, but this time we care about zeroes in the high word 2269 int dstenc = $dst$$reg; 2270 if (dstenc >= 8) { 2271 emit_opcode(cbuf, Assembler::REX_B); 2272 dstenc -= 8; 2273 } 2274 emit_opcode(cbuf, 0xB8 | dstenc); 2275 $$$emit32$src$$constant; 2276 %} 2277 2278 enc_class load_immP(rRegP dst, immP src) 2279 %{ 2280 int dstenc = $dst$$reg; 2281 if (dstenc < 8) { 2282 emit_opcode(cbuf, Assembler::REX_W); 2283 } else { 2284 emit_opcode(cbuf, Assembler::REX_WB); 2285 dstenc -= 8; 2286 } 2287 emit_opcode(cbuf, 0xB8 | dstenc); 2288 // This next line should be generated from ADLC 2289 if ($src->constant_reloc() != relocInfo::none) { 2290 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2291 } else { 2292 emit_d64(cbuf, $src$$constant); 2293 } 2294 %} 2295 2296 enc_class Con32(immI src) 2297 %{ 2298 // Output immediate 2299 $$$emit32$src$$constant; 2300 %} 2301 2302 enc_class Con32F_as_bits(immF src) 2303 %{ 2304 // Output Float immediate bits 2305 jfloat jf = $src$$constant; 2306 jint jf_as_bits = jint_cast(jf); 2307 emit_d32(cbuf, jf_as_bits); 2308 %} 2309 2310 enc_class Con16(immI src) 2311 %{ 2312 // Output immediate 2313 $$$emit16$src$$constant; 2314 %} 2315 2316 // How is this different from Con32??? XXX 2317 enc_class Con_d32(immI src) 2318 %{ 2319 emit_d32(cbuf,$src$$constant); 2320 %} 2321 2322 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2323 // Output immediate memory reference 2324 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2325 emit_d32(cbuf, 0x00); 2326 %} 2327 2328 enc_class lock_prefix() 2329 %{ 2330 emit_opcode(cbuf, 0xF0); // lock 2331 %} 2332 2333 enc_class REX_mem(memory mem) 2334 %{ 2335 if ($mem$$base >= 8) { 2336 if ($mem$$index < 8) { 2337 emit_opcode(cbuf, Assembler::REX_B); 2338 } else { 2339 emit_opcode(cbuf, Assembler::REX_XB); 2340 } 2341 } else { 2342 if ($mem$$index >= 8) { 2343 emit_opcode(cbuf, Assembler::REX_X); 2344 } 2345 } 2346 %} 2347 2348 enc_class REX_mem_wide(memory mem) 2349 %{ 2350 if ($mem$$base >= 8) { 2351 if ($mem$$index < 8) { 2352 emit_opcode(cbuf, Assembler::REX_WB); 2353 } else { 2354 emit_opcode(cbuf, Assembler::REX_WXB); 2355 } 2356 } else { 2357 if ($mem$$index < 8) { 2358 emit_opcode(cbuf, Assembler::REX_W); 2359 } else { 2360 emit_opcode(cbuf, Assembler::REX_WX); 2361 } 2362 } 2363 %} 2364 2365 // for byte regs 2366 enc_class REX_breg(rRegI reg) 2367 %{ 2368 if ($reg$$reg >= 4) { 2369 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2370 } 2371 %} 2372 2373 // for byte regs 2374 enc_class REX_reg_breg(rRegI dst, rRegI src) 2375 %{ 2376 if ($dst$$reg < 8) { 2377 if ($src$$reg >= 4) { 2378 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2379 } 2380 } else { 2381 if ($src$$reg < 8) { 2382 emit_opcode(cbuf, Assembler::REX_R); 2383 } else { 2384 emit_opcode(cbuf, Assembler::REX_RB); 2385 } 2386 } 2387 %} 2388 2389 // for byte regs 2390 enc_class REX_breg_mem(rRegI reg, memory mem) 2391 %{ 2392 if ($reg$$reg < 8) { 2393 if ($mem$$base < 8) { 2394 if ($mem$$index >= 8) { 2395 emit_opcode(cbuf, Assembler::REX_X); 2396 } else if ($reg$$reg >= 4) { 2397 emit_opcode(cbuf, Assembler::REX); 2398 } 2399 } else { 2400 if ($mem$$index < 8) { 2401 emit_opcode(cbuf, Assembler::REX_B); 2402 } else { 2403 emit_opcode(cbuf, Assembler::REX_XB); 2404 } 2405 } 2406 } else { 2407 if ($mem$$base < 8) { 2408 if ($mem$$index < 8) { 2409 emit_opcode(cbuf, Assembler::REX_R); 2410 } else { 2411 emit_opcode(cbuf, Assembler::REX_RX); 2412 } 2413 } else { 2414 if ($mem$$index < 8) { 2415 emit_opcode(cbuf, Assembler::REX_RB); 2416 } else { 2417 emit_opcode(cbuf, Assembler::REX_RXB); 2418 } 2419 } 2420 } 2421 %} 2422 2423 enc_class REX_reg(rRegI reg) 2424 %{ 2425 if ($reg$$reg >= 8) { 2426 emit_opcode(cbuf, Assembler::REX_B); 2427 } 2428 %} 2429 2430 enc_class REX_reg_wide(rRegI reg) 2431 %{ 2432 if ($reg$$reg < 8) { 2433 emit_opcode(cbuf, Assembler::REX_W); 2434 } else { 2435 emit_opcode(cbuf, Assembler::REX_WB); 2436 } 2437 %} 2438 2439 enc_class REX_reg_reg(rRegI dst, rRegI src) 2440 %{ 2441 if ($dst$$reg < 8) { 2442 if ($src$$reg >= 8) { 2443 emit_opcode(cbuf, Assembler::REX_B); 2444 } 2445 } else { 2446 if ($src$$reg < 8) { 2447 emit_opcode(cbuf, Assembler::REX_R); 2448 } else { 2449 emit_opcode(cbuf, Assembler::REX_RB); 2450 } 2451 } 2452 %} 2453 2454 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2455 %{ 2456 if ($dst$$reg < 8) { 2457 if ($src$$reg < 8) { 2458 emit_opcode(cbuf, Assembler::REX_W); 2459 } else { 2460 emit_opcode(cbuf, Assembler::REX_WB); 2461 } 2462 } else { 2463 if ($src$$reg < 8) { 2464 emit_opcode(cbuf, Assembler::REX_WR); 2465 } else { 2466 emit_opcode(cbuf, Assembler::REX_WRB); 2467 } 2468 } 2469 %} 2470 2471 enc_class REX_reg_mem(rRegI reg, memory mem) 2472 %{ 2473 if ($reg$$reg < 8) { 2474 if ($mem$$base < 8) { 2475 if ($mem$$index >= 8) { 2476 emit_opcode(cbuf, Assembler::REX_X); 2477 } 2478 } else { 2479 if ($mem$$index < 8) { 2480 emit_opcode(cbuf, Assembler::REX_B); 2481 } else { 2482 emit_opcode(cbuf, Assembler::REX_XB); 2483 } 2484 } 2485 } else { 2486 if ($mem$$base < 8) { 2487 if ($mem$$index < 8) { 2488 emit_opcode(cbuf, Assembler::REX_R); 2489 } else { 2490 emit_opcode(cbuf, Assembler::REX_RX); 2491 } 2492 } else { 2493 if ($mem$$index < 8) { 2494 emit_opcode(cbuf, Assembler::REX_RB); 2495 } else { 2496 emit_opcode(cbuf, Assembler::REX_RXB); 2497 } 2498 } 2499 } 2500 %} 2501 2502 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2503 %{ 2504 if ($reg$$reg < 8) { 2505 if ($mem$$base < 8) { 2506 if ($mem$$index < 8) { 2507 emit_opcode(cbuf, Assembler::REX_W); 2508 } else { 2509 emit_opcode(cbuf, Assembler::REX_WX); 2510 } 2511 } else { 2512 if ($mem$$index < 8) { 2513 emit_opcode(cbuf, Assembler::REX_WB); 2514 } else { 2515 emit_opcode(cbuf, Assembler::REX_WXB); 2516 } 2517 } 2518 } else { 2519 if ($mem$$base < 8) { 2520 if ($mem$$index < 8) { 2521 emit_opcode(cbuf, Assembler::REX_WR); 2522 } else { 2523 emit_opcode(cbuf, Assembler::REX_WRX); 2524 } 2525 } else { 2526 if ($mem$$index < 8) { 2527 emit_opcode(cbuf, Assembler::REX_WRB); 2528 } else { 2529 emit_opcode(cbuf, Assembler::REX_WRXB); 2530 } 2531 } 2532 } 2533 %} 2534 2535 enc_class reg_mem(rRegI ereg, memory mem) 2536 %{ 2537 // High registers handle in encode_RegMem 2538 int reg = $ereg$$reg; 2539 int base = $mem$$base; 2540 int index = $mem$$index; 2541 int scale = $mem$$scale; 2542 int disp = $mem$$disp; 2543 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2544 2545 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2546 %} 2547 2548 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2549 %{ 2550 int rm_byte_opcode = $rm_opcode$$constant; 2551 2552 // High registers handle in encode_RegMem 2553 int base = $mem$$base; 2554 int index = $mem$$index; 2555 int scale = $mem$$scale; 2556 int displace = $mem$$disp; 2557 2558 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2559 // working with static 2560 // globals 2561 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2562 disp_reloc); 2563 %} 2564 2565 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2566 %{ 2567 int reg_encoding = $dst$$reg; 2568 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2569 int index = 0x04; // 0x04 indicates no index 2570 int scale = 0x00; // 0x00 indicates no scale 2571 int displace = $src1$$constant; // 0x00 indicates no displacement 2572 relocInfo::relocType disp_reloc = relocInfo::none; 2573 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2574 disp_reloc); 2575 %} 2576 2577 enc_class neg_reg(rRegI dst) 2578 %{ 2579 int dstenc = $dst$$reg; 2580 if (dstenc >= 8) { 2581 emit_opcode(cbuf, Assembler::REX_B); 2582 dstenc -= 8; 2583 } 2584 // NEG $dst 2585 emit_opcode(cbuf, 0xF7); 2586 emit_rm(cbuf, 0x3, 0x03, dstenc); 2587 %} 2588 2589 enc_class neg_reg_wide(rRegI dst) 2590 %{ 2591 int dstenc = $dst$$reg; 2592 if (dstenc < 8) { 2593 emit_opcode(cbuf, Assembler::REX_W); 2594 } else { 2595 emit_opcode(cbuf, Assembler::REX_WB); 2596 dstenc -= 8; 2597 } 2598 // NEG $dst 2599 emit_opcode(cbuf, 0xF7); 2600 emit_rm(cbuf, 0x3, 0x03, dstenc); 2601 %} 2602 2603 enc_class setLT_reg(rRegI dst) 2604 %{ 2605 int dstenc = $dst$$reg; 2606 if (dstenc >= 8) { 2607 emit_opcode(cbuf, Assembler::REX_B); 2608 dstenc -= 8; 2609 } else if (dstenc >= 4) { 2610 emit_opcode(cbuf, Assembler::REX); 2611 } 2612 // SETLT $dst 2613 emit_opcode(cbuf, 0x0F); 2614 emit_opcode(cbuf, 0x9C); 2615 emit_rm(cbuf, 0x3, 0x0, dstenc); 2616 %} 2617 2618 enc_class setNZ_reg(rRegI dst) 2619 %{ 2620 int dstenc = $dst$$reg; 2621 if (dstenc >= 8) { 2622 emit_opcode(cbuf, Assembler::REX_B); 2623 dstenc -= 8; 2624 } else if (dstenc >= 4) { 2625 emit_opcode(cbuf, Assembler::REX); 2626 } 2627 // SETNZ $dst 2628 emit_opcode(cbuf, 0x0F); 2629 emit_opcode(cbuf, 0x95); 2630 emit_rm(cbuf, 0x3, 0x0, dstenc); 2631 %} 2632 2633 2634 // Compare the lonogs and set -1, 0, or 1 into dst 2635 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2636 %{ 2637 int src1enc = $src1$$reg; 2638 int src2enc = $src2$$reg; 2639 int dstenc = $dst$$reg; 2640 2641 // cmpq $src1, $src2 2642 if (src1enc < 8) { 2643 if (src2enc < 8) { 2644 emit_opcode(cbuf, Assembler::REX_W); 2645 } else { 2646 emit_opcode(cbuf, Assembler::REX_WB); 2647 } 2648 } else { 2649 if (src2enc < 8) { 2650 emit_opcode(cbuf, Assembler::REX_WR); 2651 } else { 2652 emit_opcode(cbuf, Assembler::REX_WRB); 2653 } 2654 } 2655 emit_opcode(cbuf, 0x3B); 2656 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2657 2658 // movl $dst, -1 2659 if (dstenc >= 8) { 2660 emit_opcode(cbuf, Assembler::REX_B); 2661 } 2662 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2663 emit_d32(cbuf, -1); 2664 2665 // jl,s done 2666 emit_opcode(cbuf, 0x7C); 2667 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2668 2669 // setne $dst 2670 if (dstenc >= 4) { 2671 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2672 } 2673 emit_opcode(cbuf, 0x0F); 2674 emit_opcode(cbuf, 0x95); 2675 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2676 2677 // movzbl $dst, $dst 2678 if (dstenc >= 4) { 2679 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2680 } 2681 emit_opcode(cbuf, 0x0F); 2682 emit_opcode(cbuf, 0xB6); 2683 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2684 %} 2685 2686 enc_class Push_ResultXD(regD dst) %{ 2687 MacroAssembler _masm(&cbuf); 2688 __ fstp_d(Address(rsp, 0)); 2689 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2690 __ addptr(rsp, 8); 2691 %} 2692 2693 enc_class Push_SrcXD(regD src) %{ 2694 MacroAssembler _masm(&cbuf); 2695 __ subptr(rsp, 8); 2696 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2697 __ fld_d(Address(rsp, 0)); 2698 %} 2699 2700 2701 enc_class enc_rethrow() 2702 %{ 2703 cbuf.set_insts_mark(); 2704 emit_opcode(cbuf, 0xE9); // jmp entry 2705 emit_d32_reloc(cbuf, 2706 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2707 runtime_call_Relocation::spec(), 2708 RELOC_DISP32); 2709 %} 2710 2711 %} 2712 2713 2714 2715 //----------FRAME-------------------------------------------------------------- 2716 // Definition of frame structure and management information. 2717 // 2718 // S T A C K L A Y O U T Allocators stack-slot number 2719 // | (to get allocators register number 2720 // G Owned by | | v add OptoReg::stack0()) 2721 // r CALLER | | 2722 // o | +--------+ pad to even-align allocators stack-slot 2723 // w V | pad0 | numbers; owned by CALLER 2724 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2725 // h ^ | in | 5 2726 // | | args | 4 Holes in incoming args owned by SELF 2727 // | | | | 3 2728 // | | +--------+ 2729 // V | | old out| Empty on Intel, window on Sparc 2730 // | old |preserve| Must be even aligned. 2731 // | SP-+--------+----> Matcher::_old_SP, even aligned 2732 // | | in | 3 area for Intel ret address 2733 // Owned by |preserve| Empty on Sparc. 2734 // SELF +--------+ 2735 // | | pad2 | 2 pad to align old SP 2736 // | +--------+ 1 2737 // | | locks | 0 2738 // | +--------+----> OptoReg::stack0(), even aligned 2739 // | | pad1 | 11 pad to align new SP 2740 // | +--------+ 2741 // | | | 10 2742 // | | spills | 9 spills 2743 // V | | 8 (pad0 slot for callee) 2744 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2745 // ^ | out | 7 2746 // | | args | 6 Holes in outgoing args owned by CALLEE 2747 // Owned by +--------+ 2748 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2749 // | new |preserve| Must be even-aligned. 2750 // | SP-+--------+----> Matcher::_new_SP, even aligned 2751 // | | | 2752 // 2753 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2754 // known from SELF's arguments and the Java calling convention. 2755 // Region 6-7 is determined per call site. 2756 // Note 2: If the calling convention leaves holes in the incoming argument 2757 // area, those holes are owned by SELF. Holes in the outgoing area 2758 // are owned by the CALLEE. Holes should not be nessecary in the 2759 // incoming area, as the Java calling convention is completely under 2760 // the control of the AD file. Doubles can be sorted and packed to 2761 // avoid holes. Holes in the outgoing arguments may be nessecary for 2762 // varargs C calling conventions. 2763 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2764 // even aligned with pad0 as needed. 2765 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2766 // region 6-11 is even aligned; it may be padded out more so that 2767 // the region from SP to FP meets the minimum stack alignment. 2768 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2769 // alignment. Region 11, pad1, may be dynamically extended so that 2770 // SP meets the minimum alignment. 2771 2772 frame 2773 %{ 2774 // What direction does stack grow in (assumed to be same for C & Java) 2775 stack_direction(TOWARDS_LOW); 2776 2777 // These three registers define part of the calling convention 2778 // between compiled code and the interpreter. 2779 inline_cache_reg(RAX); // Inline Cache Register 2780 interpreter_method_oop_reg(RBX); // Method Oop Register when 2781 // calling interpreter 2782 2783 // Optional: name the operand used by cisc-spilling to access 2784 // [stack_pointer + offset] 2785 cisc_spilling_operand_name(indOffset32); 2786 2787 // Number of stack slots consumed by locking an object 2788 sync_stack_slots(2); 2789 2790 // Compiled code's Frame Pointer 2791 frame_pointer(RSP); 2792 2793 // Interpreter stores its frame pointer in a register which is 2794 // stored to the stack by I2CAdaptors. 2795 // I2CAdaptors convert from interpreted java to compiled java. 2796 interpreter_frame_pointer(RBP); 2797 2798 // Stack alignment requirement 2799 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2800 2801 // Number of stack slots between incoming argument block and the start of 2802 // a new frame. The PROLOG must add this many slots to the stack. The 2803 // EPILOG must remove this many slots. amd64 needs two slots for 2804 // return address. 2805 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2806 2807 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2808 // for calls to C. Supports the var-args backing area for register parms. 2809 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2810 2811 // The after-PROLOG location of the return address. Location of 2812 // return address specifies a type (REG or STACK) and a number 2813 // representing the register number (i.e. - use a register name) or 2814 // stack slot. 2815 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2816 // Otherwise, it is above the locks and verification slot and alignment word 2817 return_addr(STACK - 2 + 2818 align_up((Compile::current()->in_preserve_stack_slots() + 2819 Compile::current()->fixed_slots()), 2820 stack_alignment_in_slots())); 2821 2822 // Body of function which returns an integer array locating 2823 // arguments either in registers or in stack slots. Passed an array 2824 // of ideal registers called "sig" and a "length" count. Stack-slot 2825 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2826 // arguments for a CALLEE. Incoming stack arguments are 2827 // automatically biased by the preserve_stack_slots field above. 2828 2829 calling_convention 2830 %{ 2831 // No difference between ingoing/outgoing just pass false 2832 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2833 %} 2834 2835 c_calling_convention 2836 %{ 2837 // This is obviously always outgoing 2838 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2839 %} 2840 2841 // Location of compiled Java return values. Same as C for now. 2842 return_value 2843 %{ 2844 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2845 "only return normal values"); 2846 2847 static const int lo[Op_RegL + 1] = { 2848 0, 2849 0, 2850 RAX_num, // Op_RegN 2851 RAX_num, // Op_RegI 2852 RAX_num, // Op_RegP 2853 XMM0_num, // Op_RegF 2854 XMM0_num, // Op_RegD 2855 RAX_num // Op_RegL 2856 }; 2857 static const int hi[Op_RegL + 1] = { 2858 0, 2859 0, 2860 OptoReg::Bad, // Op_RegN 2861 OptoReg::Bad, // Op_RegI 2862 RAX_H_num, // Op_RegP 2863 OptoReg::Bad, // Op_RegF 2864 XMM0b_num, // Op_RegD 2865 RAX_H_num // Op_RegL 2866 }; 2867 // Excluded flags and vector registers. 2868 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2869 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2870 %} 2871 %} 2872 2873 //----------ATTRIBUTES--------------------------------------------------------- 2874 //----------Operand Attributes------------------------------------------------- 2875 op_attrib op_cost(0); // Required cost attribute 2876 2877 //----------Instruction Attributes--------------------------------------------- 2878 ins_attrib ins_cost(100); // Required cost attribute 2879 ins_attrib ins_size(8); // Required size attribute (in bits) 2880 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2881 // a non-matching short branch variant 2882 // of some long branch? 2883 ins_attrib ins_alignment(1); // Required alignment attribute (must 2884 // be a power of 2) specifies the 2885 // alignment that some part of the 2886 // instruction (not necessarily the 2887 // start) requires. If > 1, a 2888 // compute_padding() function must be 2889 // provided for the instruction 2890 2891 //----------OPERANDS----------------------------------------------------------- 2892 // Operand definitions must precede instruction definitions for correct parsing 2893 // in the ADLC because operands constitute user defined types which are used in 2894 // instruction definitions. 2895 2896 //----------Simple Operands---------------------------------------------------- 2897 // Immediate Operands 2898 // Integer Immediate 2899 operand immI() 2900 %{ 2901 match(ConI); 2902 2903 op_cost(10); 2904 format %{ %} 2905 interface(CONST_INTER); 2906 %} 2907 2908 // Constant for test vs zero 2909 operand immI0() 2910 %{ 2911 predicate(n->get_int() == 0); 2912 match(ConI); 2913 2914 op_cost(0); 2915 format %{ %} 2916 interface(CONST_INTER); 2917 %} 2918 2919 // Constant for increment 2920 operand immI1() 2921 %{ 2922 predicate(n->get_int() == 1); 2923 match(ConI); 2924 2925 op_cost(0); 2926 format %{ %} 2927 interface(CONST_INTER); 2928 %} 2929 2930 // Constant for decrement 2931 operand immI_M1() 2932 %{ 2933 predicate(n->get_int() == -1); 2934 match(ConI); 2935 2936 op_cost(0); 2937 format %{ %} 2938 interface(CONST_INTER); 2939 %} 2940 2941 // Valid scale values for addressing modes 2942 operand immI2() 2943 %{ 2944 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2945 match(ConI); 2946 2947 format %{ %} 2948 interface(CONST_INTER); 2949 %} 2950 2951 operand immI8() 2952 %{ 2953 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2954 match(ConI); 2955 2956 op_cost(5); 2957 format %{ %} 2958 interface(CONST_INTER); 2959 %} 2960 2961 operand immU8() 2962 %{ 2963 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2964 match(ConI); 2965 2966 op_cost(5); 2967 format %{ %} 2968 interface(CONST_INTER); 2969 %} 2970 2971 operand immI16() 2972 %{ 2973 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2974 match(ConI); 2975 2976 op_cost(10); 2977 format %{ %} 2978 interface(CONST_INTER); 2979 %} 2980 2981 // Int Immediate non-negative 2982 operand immU31() 2983 %{ 2984 predicate(n->get_int() >= 0); 2985 match(ConI); 2986 2987 op_cost(0); 2988 format %{ %} 2989 interface(CONST_INTER); 2990 %} 2991 2992 // Constant for long shifts 2993 operand immI_32() 2994 %{ 2995 predicate( n->get_int() == 32 ); 2996 match(ConI); 2997 2998 op_cost(0); 2999 format %{ %} 3000 interface(CONST_INTER); 3001 %} 3002 3003 // Constant for long shifts 3004 operand immI_64() 3005 %{ 3006 predicate( n->get_int() == 64 ); 3007 match(ConI); 3008 3009 op_cost(0); 3010 format %{ %} 3011 interface(CONST_INTER); 3012 %} 3013 3014 // Pointer Immediate 3015 operand immP() 3016 %{ 3017 match(ConP); 3018 3019 op_cost(10); 3020 format %{ %} 3021 interface(CONST_INTER); 3022 %} 3023 3024 // NULL Pointer Immediate 3025 operand immP0() 3026 %{ 3027 predicate(n->get_ptr() == 0); 3028 match(ConP); 3029 3030 op_cost(5); 3031 format %{ %} 3032 interface(CONST_INTER); 3033 %} 3034 3035 // Pointer Immediate 3036 operand immN() %{ 3037 match(ConN); 3038 3039 op_cost(10); 3040 format %{ %} 3041 interface(CONST_INTER); 3042 %} 3043 3044 operand immNKlass() %{ 3045 match(ConNKlass); 3046 3047 op_cost(10); 3048 format %{ %} 3049 interface(CONST_INTER); 3050 %} 3051 3052 // NULL Pointer Immediate 3053 operand immN0() %{ 3054 predicate(n->get_narrowcon() == 0); 3055 match(ConN); 3056 3057 op_cost(5); 3058 format %{ %} 3059 interface(CONST_INTER); 3060 %} 3061 3062 operand immP31() 3063 %{ 3064 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3065 && (n->get_ptr() >> 31) == 0); 3066 match(ConP); 3067 3068 op_cost(5); 3069 format %{ %} 3070 interface(CONST_INTER); 3071 %} 3072 3073 3074 // Long Immediate 3075 operand immL() 3076 %{ 3077 match(ConL); 3078 3079 op_cost(20); 3080 format %{ %} 3081 interface(CONST_INTER); 3082 %} 3083 3084 // Long Immediate 8-bit 3085 operand immL8() 3086 %{ 3087 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3088 match(ConL); 3089 3090 op_cost(5); 3091 format %{ %} 3092 interface(CONST_INTER); 3093 %} 3094 3095 // Long Immediate 32-bit unsigned 3096 operand immUL32() 3097 %{ 3098 predicate(n->get_long() == (unsigned int) (n->get_long())); 3099 match(ConL); 3100 3101 op_cost(10); 3102 format %{ %} 3103 interface(CONST_INTER); 3104 %} 3105 3106 // Long Immediate 32-bit signed 3107 operand immL32() 3108 %{ 3109 predicate(n->get_long() == (int) (n->get_long())); 3110 match(ConL); 3111 3112 op_cost(15); 3113 format %{ %} 3114 interface(CONST_INTER); 3115 %} 3116 3117 // Long Immediate zero 3118 operand immL0() 3119 %{ 3120 predicate(n->get_long() == 0L); 3121 match(ConL); 3122 3123 op_cost(10); 3124 format %{ %} 3125 interface(CONST_INTER); 3126 %} 3127 3128 // Constant for increment 3129 operand immL1() 3130 %{ 3131 predicate(n->get_long() == 1); 3132 match(ConL); 3133 3134 format %{ %} 3135 interface(CONST_INTER); 3136 %} 3137 3138 // Constant for decrement 3139 operand immL_M1() 3140 %{ 3141 predicate(n->get_long() == -1); 3142 match(ConL); 3143 3144 format %{ %} 3145 interface(CONST_INTER); 3146 %} 3147 3148 // Long Immediate: the value 10 3149 operand immL10() 3150 %{ 3151 predicate(n->get_long() == 10); 3152 match(ConL); 3153 3154 format %{ %} 3155 interface(CONST_INTER); 3156 %} 3157 3158 // Long immediate from 0 to 127. 3159 // Used for a shorter form of long mul by 10. 3160 operand immL_127() 3161 %{ 3162 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3163 match(ConL); 3164 3165 op_cost(10); 3166 format %{ %} 3167 interface(CONST_INTER); 3168 %} 3169 3170 // Long Immediate: low 32-bit mask 3171 operand immL_32bits() 3172 %{ 3173 predicate(n->get_long() == 0xFFFFFFFFL); 3174 match(ConL); 3175 op_cost(20); 3176 3177 format %{ %} 3178 interface(CONST_INTER); 3179 %} 3180 3181 // Float Immediate zero 3182 operand immF0() 3183 %{ 3184 predicate(jint_cast(n->getf()) == 0); 3185 match(ConF); 3186 3187 op_cost(5); 3188 format %{ %} 3189 interface(CONST_INTER); 3190 %} 3191 3192 // Float Immediate 3193 operand immF() 3194 %{ 3195 match(ConF); 3196 3197 op_cost(15); 3198 format %{ %} 3199 interface(CONST_INTER); 3200 %} 3201 3202 // Double Immediate zero 3203 operand immD0() 3204 %{ 3205 predicate(jlong_cast(n->getd()) == 0); 3206 match(ConD); 3207 3208 op_cost(5); 3209 format %{ %} 3210 interface(CONST_INTER); 3211 %} 3212 3213 // Double Immediate 3214 operand immD() 3215 %{ 3216 match(ConD); 3217 3218 op_cost(15); 3219 format %{ %} 3220 interface(CONST_INTER); 3221 %} 3222 3223 // Immediates for special shifts (sign extend) 3224 3225 // Constants for increment 3226 operand immI_16() 3227 %{ 3228 predicate(n->get_int() == 16); 3229 match(ConI); 3230 3231 format %{ %} 3232 interface(CONST_INTER); 3233 %} 3234 3235 operand immI_24() 3236 %{ 3237 predicate(n->get_int() == 24); 3238 match(ConI); 3239 3240 format %{ %} 3241 interface(CONST_INTER); 3242 %} 3243 3244 // Constant for byte-wide masking 3245 operand immI_255() 3246 %{ 3247 predicate(n->get_int() == 255); 3248 match(ConI); 3249 3250 format %{ %} 3251 interface(CONST_INTER); 3252 %} 3253 3254 // Constant for short-wide masking 3255 operand immI_65535() 3256 %{ 3257 predicate(n->get_int() == 65535); 3258 match(ConI); 3259 3260 format %{ %} 3261 interface(CONST_INTER); 3262 %} 3263 3264 // Constant for byte-wide masking 3265 operand immL_255() 3266 %{ 3267 predicate(n->get_long() == 255); 3268 match(ConL); 3269 3270 format %{ %} 3271 interface(CONST_INTER); 3272 %} 3273 3274 // Constant for short-wide masking 3275 operand immL_65535() 3276 %{ 3277 predicate(n->get_long() == 65535); 3278 match(ConL); 3279 3280 format %{ %} 3281 interface(CONST_INTER); 3282 %} 3283 3284 // Register Operands 3285 // Integer Register 3286 operand rRegI() 3287 %{ 3288 constraint(ALLOC_IN_RC(int_reg)); 3289 match(RegI); 3290 3291 match(rax_RegI); 3292 match(rbx_RegI); 3293 match(rcx_RegI); 3294 match(rdx_RegI); 3295 match(rdi_RegI); 3296 3297 format %{ %} 3298 interface(REG_INTER); 3299 %} 3300 3301 // Special Registers 3302 operand rax_RegI() 3303 %{ 3304 constraint(ALLOC_IN_RC(int_rax_reg)); 3305 match(RegI); 3306 match(rRegI); 3307 3308 format %{ "RAX" %} 3309 interface(REG_INTER); 3310 %} 3311 3312 // Special Registers 3313 operand rbx_RegI() 3314 %{ 3315 constraint(ALLOC_IN_RC(int_rbx_reg)); 3316 match(RegI); 3317 match(rRegI); 3318 3319 format %{ "RBX" %} 3320 interface(REG_INTER); 3321 %} 3322 3323 operand rcx_RegI() 3324 %{ 3325 constraint(ALLOC_IN_RC(int_rcx_reg)); 3326 match(RegI); 3327 match(rRegI); 3328 3329 format %{ "RCX" %} 3330 interface(REG_INTER); 3331 %} 3332 3333 operand rdx_RegI() 3334 %{ 3335 constraint(ALLOC_IN_RC(int_rdx_reg)); 3336 match(RegI); 3337 match(rRegI); 3338 3339 format %{ "RDX" %} 3340 interface(REG_INTER); 3341 %} 3342 3343 operand rdi_RegI() 3344 %{ 3345 constraint(ALLOC_IN_RC(int_rdi_reg)); 3346 match(RegI); 3347 match(rRegI); 3348 3349 format %{ "RDI" %} 3350 interface(REG_INTER); 3351 %} 3352 3353 operand no_rcx_RegI() 3354 %{ 3355 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3356 match(RegI); 3357 match(rax_RegI); 3358 match(rbx_RegI); 3359 match(rdx_RegI); 3360 match(rdi_RegI); 3361 3362 format %{ %} 3363 interface(REG_INTER); 3364 %} 3365 3366 operand no_rax_rdx_RegI() 3367 %{ 3368 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3369 match(RegI); 3370 match(rbx_RegI); 3371 match(rcx_RegI); 3372 match(rdi_RegI); 3373 3374 format %{ %} 3375 interface(REG_INTER); 3376 %} 3377 3378 // Pointer Register 3379 operand any_RegP() 3380 %{ 3381 constraint(ALLOC_IN_RC(any_reg)); 3382 match(RegP); 3383 match(rax_RegP); 3384 match(rbx_RegP); 3385 match(rdi_RegP); 3386 match(rsi_RegP); 3387 match(rbp_RegP); 3388 match(r15_RegP); 3389 match(rRegP); 3390 3391 format %{ %} 3392 interface(REG_INTER); 3393 %} 3394 3395 operand rRegP() 3396 %{ 3397 constraint(ALLOC_IN_RC(ptr_reg)); 3398 match(RegP); 3399 match(rax_RegP); 3400 match(rbx_RegP); 3401 match(rdi_RegP); 3402 match(rsi_RegP); 3403 match(rbp_RegP); // See Q&A below about 3404 match(r15_RegP); // r15_RegP and rbp_RegP. 3405 3406 format %{ %} 3407 interface(REG_INTER); 3408 %} 3409 3410 operand rRegN() %{ 3411 constraint(ALLOC_IN_RC(int_reg)); 3412 match(RegN); 3413 3414 format %{ %} 3415 interface(REG_INTER); 3416 %} 3417 3418 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3419 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3420 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3421 // The output of an instruction is controlled by the allocator, which respects 3422 // register class masks, not match rules. Unless an instruction mentions 3423 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3424 // by the allocator as an input. 3425 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3426 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3427 // result, RBP is not included in the output of the instruction either. 3428 3429 operand no_rax_RegP() 3430 %{ 3431 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3432 match(RegP); 3433 match(rbx_RegP); 3434 match(rsi_RegP); 3435 match(rdi_RegP); 3436 3437 format %{ %} 3438 interface(REG_INTER); 3439 %} 3440 3441 // This operand is not allowed to use RBP even if 3442 // RBP is not used to hold the frame pointer. 3443 operand no_rbp_RegP() 3444 %{ 3445 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3446 match(RegP); 3447 match(rbx_RegP); 3448 match(rsi_RegP); 3449 match(rdi_RegP); 3450 3451 format %{ %} 3452 interface(REG_INTER); 3453 %} 3454 3455 operand no_rax_rbx_RegP() 3456 %{ 3457 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3458 match(RegP); 3459 match(rsi_RegP); 3460 match(rdi_RegP); 3461 3462 format %{ %} 3463 interface(REG_INTER); 3464 %} 3465 3466 // Special Registers 3467 // Return a pointer value 3468 operand rax_RegP() 3469 %{ 3470 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3471 match(RegP); 3472 match(rRegP); 3473 3474 format %{ %} 3475 interface(REG_INTER); 3476 %} 3477 3478 // Special Registers 3479 // Return a compressed pointer value 3480 operand rax_RegN() 3481 %{ 3482 constraint(ALLOC_IN_RC(int_rax_reg)); 3483 match(RegN); 3484 match(rRegN); 3485 3486 format %{ %} 3487 interface(REG_INTER); 3488 %} 3489 3490 // Used in AtomicAdd 3491 operand rbx_RegP() 3492 %{ 3493 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3494 match(RegP); 3495 match(rRegP); 3496 3497 format %{ %} 3498 interface(REG_INTER); 3499 %} 3500 3501 operand rsi_RegP() 3502 %{ 3503 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3504 match(RegP); 3505 match(rRegP); 3506 3507 format %{ %} 3508 interface(REG_INTER); 3509 %} 3510 3511 // Used in rep stosq 3512 operand rdi_RegP() 3513 %{ 3514 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3515 match(RegP); 3516 match(rRegP); 3517 3518 format %{ %} 3519 interface(REG_INTER); 3520 %} 3521 3522 operand r15_RegP() 3523 %{ 3524 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3525 match(RegP); 3526 match(rRegP); 3527 3528 format %{ %} 3529 interface(REG_INTER); 3530 %} 3531 3532 operand rRegL() 3533 %{ 3534 constraint(ALLOC_IN_RC(long_reg)); 3535 match(RegL); 3536 match(rax_RegL); 3537 match(rdx_RegL); 3538 3539 format %{ %} 3540 interface(REG_INTER); 3541 %} 3542 3543 // Special Registers 3544 operand no_rax_rdx_RegL() 3545 %{ 3546 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3547 match(RegL); 3548 match(rRegL); 3549 3550 format %{ %} 3551 interface(REG_INTER); 3552 %} 3553 3554 operand no_rax_RegL() 3555 %{ 3556 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3557 match(RegL); 3558 match(rRegL); 3559 match(rdx_RegL); 3560 3561 format %{ %} 3562 interface(REG_INTER); 3563 %} 3564 3565 operand no_rcx_RegL() 3566 %{ 3567 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3568 match(RegL); 3569 match(rRegL); 3570 3571 format %{ %} 3572 interface(REG_INTER); 3573 %} 3574 3575 operand rax_RegL() 3576 %{ 3577 constraint(ALLOC_IN_RC(long_rax_reg)); 3578 match(RegL); 3579 match(rRegL); 3580 3581 format %{ "RAX" %} 3582 interface(REG_INTER); 3583 %} 3584 3585 operand rcx_RegL() 3586 %{ 3587 constraint(ALLOC_IN_RC(long_rcx_reg)); 3588 match(RegL); 3589 match(rRegL); 3590 3591 format %{ %} 3592 interface(REG_INTER); 3593 %} 3594 3595 operand rdx_RegL() 3596 %{ 3597 constraint(ALLOC_IN_RC(long_rdx_reg)); 3598 match(RegL); 3599 match(rRegL); 3600 3601 format %{ %} 3602 interface(REG_INTER); 3603 %} 3604 3605 // Flags register, used as output of compare instructions 3606 operand rFlagsReg() 3607 %{ 3608 constraint(ALLOC_IN_RC(int_flags)); 3609 match(RegFlags); 3610 3611 format %{ "RFLAGS" %} 3612 interface(REG_INTER); 3613 %} 3614 3615 // Flags register, used as output of FLOATING POINT compare instructions 3616 operand rFlagsRegU() 3617 %{ 3618 constraint(ALLOC_IN_RC(int_flags)); 3619 match(RegFlags); 3620 3621 format %{ "RFLAGS_U" %} 3622 interface(REG_INTER); 3623 %} 3624 3625 operand rFlagsRegUCF() %{ 3626 constraint(ALLOC_IN_RC(int_flags)); 3627 match(RegFlags); 3628 predicate(false); 3629 3630 format %{ "RFLAGS_U_CF" %} 3631 interface(REG_INTER); 3632 %} 3633 3634 // Float register operands 3635 operand regF() %{ 3636 constraint(ALLOC_IN_RC(float_reg)); 3637 match(RegF); 3638 3639 format %{ %} 3640 interface(REG_INTER); 3641 %} 3642 3643 // Float register operands 3644 operand legRegF() %{ 3645 constraint(ALLOC_IN_RC(float_reg_legacy)); 3646 match(RegF); 3647 3648 format %{ %} 3649 interface(REG_INTER); 3650 %} 3651 3652 // Float register operands 3653 operand vlRegF() %{ 3654 constraint(ALLOC_IN_RC(float_reg_vl)); 3655 match(RegF); 3656 3657 format %{ %} 3658 interface(REG_INTER); 3659 %} 3660 3661 // Double register operands 3662 operand regD() %{ 3663 constraint(ALLOC_IN_RC(double_reg)); 3664 match(RegD); 3665 3666 format %{ %} 3667 interface(REG_INTER); 3668 %} 3669 3670 // Double register operands 3671 operand legRegD() %{ 3672 constraint(ALLOC_IN_RC(double_reg_legacy)); 3673 match(RegD); 3674 3675 format %{ %} 3676 interface(REG_INTER); 3677 %} 3678 3679 // Double register operands 3680 operand vlRegD() %{ 3681 constraint(ALLOC_IN_RC(double_reg_vl)); 3682 match(RegD); 3683 3684 format %{ %} 3685 interface(REG_INTER); 3686 %} 3687 3688 // Vectors 3689 operand vecS() %{ 3690 constraint(ALLOC_IN_RC(vectors_reg_vlbwdq)); 3691 match(VecS); 3692 3693 format %{ %} 3694 interface(REG_INTER); 3695 %} 3696 3697 // Vectors 3698 operand legVecS() %{ 3699 constraint(ALLOC_IN_RC(vectors_reg_legacy)); 3700 match(VecS); 3701 3702 format %{ %} 3703 interface(REG_INTER); 3704 %} 3705 3706 operand vecD() %{ 3707 constraint(ALLOC_IN_RC(vectord_reg_vlbwdq)); 3708 match(VecD); 3709 3710 format %{ %} 3711 interface(REG_INTER); 3712 %} 3713 3714 operand legVecD() %{ 3715 constraint(ALLOC_IN_RC(vectord_reg_legacy)); 3716 match(VecD); 3717 3718 format %{ %} 3719 interface(REG_INTER); 3720 %} 3721 3722 operand vecX() %{ 3723 constraint(ALLOC_IN_RC(vectorx_reg_vlbwdq)); 3724 match(VecX); 3725 3726 format %{ %} 3727 interface(REG_INTER); 3728 %} 3729 3730 operand legVecX() %{ 3731 constraint(ALLOC_IN_RC(vectorx_reg_legacy)); 3732 match(VecX); 3733 3734 format %{ %} 3735 interface(REG_INTER); 3736 %} 3737 3738 operand vecY() %{ 3739 constraint(ALLOC_IN_RC(vectory_reg_vlbwdq)); 3740 match(VecY); 3741 3742 format %{ %} 3743 interface(REG_INTER); 3744 %} 3745 3746 operand legVecY() %{ 3747 constraint(ALLOC_IN_RC(vectory_reg_legacy)); 3748 match(VecY); 3749 3750 format %{ %} 3751 interface(REG_INTER); 3752 %} 3753 3754 //----------Memory Operands---------------------------------------------------- 3755 // Direct Memory Operand 3756 // operand direct(immP addr) 3757 // %{ 3758 // match(addr); 3759 3760 // format %{ "[$addr]" %} 3761 // interface(MEMORY_INTER) %{ 3762 // base(0xFFFFFFFF); 3763 // index(0x4); 3764 // scale(0x0); 3765 // disp($addr); 3766 // %} 3767 // %} 3768 3769 // Indirect Memory Operand 3770 operand indirect(any_RegP reg) 3771 %{ 3772 constraint(ALLOC_IN_RC(ptr_reg)); 3773 match(reg); 3774 3775 format %{ "[$reg]" %} 3776 interface(MEMORY_INTER) %{ 3777 base($reg); 3778 index(0x4); 3779 scale(0x0); 3780 disp(0x0); 3781 %} 3782 %} 3783 3784 // Indirect Memory Plus Short Offset Operand 3785 operand indOffset8(any_RegP reg, immL8 off) 3786 %{ 3787 constraint(ALLOC_IN_RC(ptr_reg)); 3788 match(AddP reg off); 3789 3790 format %{ "[$reg + $off (8-bit)]" %} 3791 interface(MEMORY_INTER) %{ 3792 base($reg); 3793 index(0x4); 3794 scale(0x0); 3795 disp($off); 3796 %} 3797 %} 3798 3799 // Indirect Memory Plus Long Offset Operand 3800 operand indOffset32(any_RegP reg, immL32 off) 3801 %{ 3802 constraint(ALLOC_IN_RC(ptr_reg)); 3803 match(AddP reg off); 3804 3805 format %{ "[$reg + $off (32-bit)]" %} 3806 interface(MEMORY_INTER) %{ 3807 base($reg); 3808 index(0x4); 3809 scale(0x0); 3810 disp($off); 3811 %} 3812 %} 3813 3814 // Indirect Memory Plus Index Register Plus Offset Operand 3815 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3816 %{ 3817 constraint(ALLOC_IN_RC(ptr_reg)); 3818 match(AddP (AddP reg lreg) off); 3819 3820 op_cost(10); 3821 format %{"[$reg + $off + $lreg]" %} 3822 interface(MEMORY_INTER) %{ 3823 base($reg); 3824 index($lreg); 3825 scale(0x0); 3826 disp($off); 3827 %} 3828 %} 3829 3830 // Indirect Memory Plus Index Register Plus Offset Operand 3831 operand indIndex(any_RegP reg, rRegL lreg) 3832 %{ 3833 constraint(ALLOC_IN_RC(ptr_reg)); 3834 match(AddP reg lreg); 3835 3836 op_cost(10); 3837 format %{"[$reg + $lreg]" %} 3838 interface(MEMORY_INTER) %{ 3839 base($reg); 3840 index($lreg); 3841 scale(0x0); 3842 disp(0x0); 3843 %} 3844 %} 3845 3846 // Indirect Memory Times Scale Plus Index Register 3847 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3848 %{ 3849 constraint(ALLOC_IN_RC(ptr_reg)); 3850 match(AddP reg (LShiftL lreg scale)); 3851 3852 op_cost(10); 3853 format %{"[$reg + $lreg << $scale]" %} 3854 interface(MEMORY_INTER) %{ 3855 base($reg); 3856 index($lreg); 3857 scale($scale); 3858 disp(0x0); 3859 %} 3860 %} 3861 3862 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3863 %{ 3864 constraint(ALLOC_IN_RC(ptr_reg)); 3865 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3866 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3867 3868 op_cost(10); 3869 format %{"[$reg + pos $idx << $scale]" %} 3870 interface(MEMORY_INTER) %{ 3871 base($reg); 3872 index($idx); 3873 scale($scale); 3874 disp(0x0); 3875 %} 3876 %} 3877 3878 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3879 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3880 %{ 3881 constraint(ALLOC_IN_RC(ptr_reg)); 3882 match(AddP (AddP reg (LShiftL lreg scale)) off); 3883 3884 op_cost(10); 3885 format %{"[$reg + $off + $lreg << $scale]" %} 3886 interface(MEMORY_INTER) %{ 3887 base($reg); 3888 index($lreg); 3889 scale($scale); 3890 disp($off); 3891 %} 3892 %} 3893 3894 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3895 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3896 %{ 3897 constraint(ALLOC_IN_RC(ptr_reg)); 3898 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3899 match(AddP (AddP reg (ConvI2L idx)) off); 3900 3901 op_cost(10); 3902 format %{"[$reg + $off + $idx]" %} 3903 interface(MEMORY_INTER) %{ 3904 base($reg); 3905 index($idx); 3906 scale(0x0); 3907 disp($off); 3908 %} 3909 %} 3910 3911 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3912 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3913 %{ 3914 constraint(ALLOC_IN_RC(ptr_reg)); 3915 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3916 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3917 3918 op_cost(10); 3919 format %{"[$reg + $off + $idx << $scale]" %} 3920 interface(MEMORY_INTER) %{ 3921 base($reg); 3922 index($idx); 3923 scale($scale); 3924 disp($off); 3925 %} 3926 %} 3927 3928 // Indirect Narrow Oop Plus Offset Operand 3929 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3930 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3931 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3932 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3933 constraint(ALLOC_IN_RC(ptr_reg)); 3934 match(AddP (DecodeN reg) off); 3935 3936 op_cost(10); 3937 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3938 interface(MEMORY_INTER) %{ 3939 base(0xc); // R12 3940 index($reg); 3941 scale(0x3); 3942 disp($off); 3943 %} 3944 %} 3945 3946 // Indirect Memory Operand 3947 operand indirectNarrow(rRegN reg) 3948 %{ 3949 predicate(Universe::narrow_oop_shift() == 0); 3950 constraint(ALLOC_IN_RC(ptr_reg)); 3951 match(DecodeN reg); 3952 3953 format %{ "[$reg]" %} 3954 interface(MEMORY_INTER) %{ 3955 base($reg); 3956 index(0x4); 3957 scale(0x0); 3958 disp(0x0); 3959 %} 3960 %} 3961 3962 // Indirect Memory Plus Short Offset Operand 3963 operand indOffset8Narrow(rRegN reg, immL8 off) 3964 %{ 3965 predicate(Universe::narrow_oop_shift() == 0); 3966 constraint(ALLOC_IN_RC(ptr_reg)); 3967 match(AddP (DecodeN reg) off); 3968 3969 format %{ "[$reg + $off (8-bit)]" %} 3970 interface(MEMORY_INTER) %{ 3971 base($reg); 3972 index(0x4); 3973 scale(0x0); 3974 disp($off); 3975 %} 3976 %} 3977 3978 // Indirect Memory Plus Long Offset Operand 3979 operand indOffset32Narrow(rRegN reg, immL32 off) 3980 %{ 3981 predicate(Universe::narrow_oop_shift() == 0); 3982 constraint(ALLOC_IN_RC(ptr_reg)); 3983 match(AddP (DecodeN reg) off); 3984 3985 format %{ "[$reg + $off (32-bit)]" %} 3986 interface(MEMORY_INTER) %{ 3987 base($reg); 3988 index(0x4); 3989 scale(0x0); 3990 disp($off); 3991 %} 3992 %} 3993 3994 // Indirect Memory Plus Index Register Plus Offset Operand 3995 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3996 %{ 3997 predicate(Universe::narrow_oop_shift() == 0); 3998 constraint(ALLOC_IN_RC(ptr_reg)); 3999 match(AddP (AddP (DecodeN reg) lreg) off); 4000 4001 op_cost(10); 4002 format %{"[$reg + $off + $lreg]" %} 4003 interface(MEMORY_INTER) %{ 4004 base($reg); 4005 index($lreg); 4006 scale(0x0); 4007 disp($off); 4008 %} 4009 %} 4010 4011 // Indirect Memory Plus Index Register Plus Offset Operand 4012 operand indIndexNarrow(rRegN reg, rRegL lreg) 4013 %{ 4014 predicate(Universe::narrow_oop_shift() == 0); 4015 constraint(ALLOC_IN_RC(ptr_reg)); 4016 match(AddP (DecodeN reg) lreg); 4017 4018 op_cost(10); 4019 format %{"[$reg + $lreg]" %} 4020 interface(MEMORY_INTER) %{ 4021 base($reg); 4022 index($lreg); 4023 scale(0x0); 4024 disp(0x0); 4025 %} 4026 %} 4027 4028 // Indirect Memory Times Scale Plus Index Register 4029 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4030 %{ 4031 predicate(Universe::narrow_oop_shift() == 0); 4032 constraint(ALLOC_IN_RC(ptr_reg)); 4033 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4034 4035 op_cost(10); 4036 format %{"[$reg + $lreg << $scale]" %} 4037 interface(MEMORY_INTER) %{ 4038 base($reg); 4039 index($lreg); 4040 scale($scale); 4041 disp(0x0); 4042 %} 4043 %} 4044 4045 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4046 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4047 %{ 4048 predicate(Universe::narrow_oop_shift() == 0); 4049 constraint(ALLOC_IN_RC(ptr_reg)); 4050 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4051 4052 op_cost(10); 4053 format %{"[$reg + $off + $lreg << $scale]" %} 4054 interface(MEMORY_INTER) %{ 4055 base($reg); 4056 index($lreg); 4057 scale($scale); 4058 disp($off); 4059 %} 4060 %} 4061 4062 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4063 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4064 %{ 4065 constraint(ALLOC_IN_RC(ptr_reg)); 4066 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4067 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4068 4069 op_cost(10); 4070 format %{"[$reg + $off + $idx]" %} 4071 interface(MEMORY_INTER) %{ 4072 base($reg); 4073 index($idx); 4074 scale(0x0); 4075 disp($off); 4076 %} 4077 %} 4078 4079 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4080 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4081 %{ 4082 constraint(ALLOC_IN_RC(ptr_reg)); 4083 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4084 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4085 4086 op_cost(10); 4087 format %{"[$reg + $off + $idx << $scale]" %} 4088 interface(MEMORY_INTER) %{ 4089 base($reg); 4090 index($idx); 4091 scale($scale); 4092 disp($off); 4093 %} 4094 %} 4095 4096 //----------Special Memory Operands-------------------------------------------- 4097 // Stack Slot Operand - This operand is used for loading and storing temporary 4098 // values on the stack where a match requires a value to 4099 // flow through memory. 4100 operand stackSlotP(sRegP reg) 4101 %{ 4102 constraint(ALLOC_IN_RC(stack_slots)); 4103 // No match rule because this operand is only generated in matching 4104 4105 format %{ "[$reg]" %} 4106 interface(MEMORY_INTER) %{ 4107 base(0x4); // RSP 4108 index(0x4); // No Index 4109 scale(0x0); // No Scale 4110 disp($reg); // Stack Offset 4111 %} 4112 %} 4113 4114 operand stackSlotI(sRegI reg) 4115 %{ 4116 constraint(ALLOC_IN_RC(stack_slots)); 4117 // No match rule because this operand is only generated in matching 4118 4119 format %{ "[$reg]" %} 4120 interface(MEMORY_INTER) %{ 4121 base(0x4); // RSP 4122 index(0x4); // No Index 4123 scale(0x0); // No Scale 4124 disp($reg); // Stack Offset 4125 %} 4126 %} 4127 4128 operand stackSlotF(sRegF reg) 4129 %{ 4130 constraint(ALLOC_IN_RC(stack_slots)); 4131 // No match rule because this operand is only generated in matching 4132 4133 format %{ "[$reg]" %} 4134 interface(MEMORY_INTER) %{ 4135 base(0x4); // RSP 4136 index(0x4); // No Index 4137 scale(0x0); // No Scale 4138 disp($reg); // Stack Offset 4139 %} 4140 %} 4141 4142 operand stackSlotD(sRegD reg) 4143 %{ 4144 constraint(ALLOC_IN_RC(stack_slots)); 4145 // No match rule because this operand is only generated in matching 4146 4147 format %{ "[$reg]" %} 4148 interface(MEMORY_INTER) %{ 4149 base(0x4); // RSP 4150 index(0x4); // No Index 4151 scale(0x0); // No Scale 4152 disp($reg); // Stack Offset 4153 %} 4154 %} 4155 operand stackSlotL(sRegL reg) 4156 %{ 4157 constraint(ALLOC_IN_RC(stack_slots)); 4158 // No match rule because this operand is only generated in matching 4159 4160 format %{ "[$reg]" %} 4161 interface(MEMORY_INTER) %{ 4162 base(0x4); // RSP 4163 index(0x4); // No Index 4164 scale(0x0); // No Scale 4165 disp($reg); // Stack Offset 4166 %} 4167 %} 4168 4169 //----------Conditional Branch Operands---------------------------------------- 4170 // Comparison Op - This is the operation of the comparison, and is limited to 4171 // the following set of codes: 4172 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4173 // 4174 // Other attributes of the comparison, such as unsignedness, are specified 4175 // by the comparison instruction that sets a condition code flags register. 4176 // That result is represented by a flags operand whose subtype is appropriate 4177 // to the unsignedness (etc.) of the comparison. 4178 // 4179 // Later, the instruction which matches both the Comparison Op (a Bool) and 4180 // the flags (produced by the Cmp) specifies the coding of the comparison op 4181 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4182 4183 // Comparision Code 4184 operand cmpOp() 4185 %{ 4186 match(Bool); 4187 4188 format %{ "" %} 4189 interface(COND_INTER) %{ 4190 equal(0x4, "e"); 4191 not_equal(0x5, "ne"); 4192 less(0xC, "l"); 4193 greater_equal(0xD, "ge"); 4194 less_equal(0xE, "le"); 4195 greater(0xF, "g"); 4196 overflow(0x0, "o"); 4197 no_overflow(0x1, "no"); 4198 %} 4199 %} 4200 4201 // Comparison Code, unsigned compare. Used by FP also, with 4202 // C2 (unordered) turned into GT or LT already. The other bits 4203 // C0 and C3 are turned into Carry & Zero flags. 4204 operand cmpOpU() 4205 %{ 4206 match(Bool); 4207 4208 format %{ "" %} 4209 interface(COND_INTER) %{ 4210 equal(0x4, "e"); 4211 not_equal(0x5, "ne"); 4212 less(0x2, "b"); 4213 greater_equal(0x3, "nb"); 4214 less_equal(0x6, "be"); 4215 greater(0x7, "nbe"); 4216 overflow(0x0, "o"); 4217 no_overflow(0x1, "no"); 4218 %} 4219 %} 4220 4221 4222 // Floating comparisons that don't require any fixup for the unordered case 4223 operand cmpOpUCF() %{ 4224 match(Bool); 4225 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4226 n->as_Bool()->_test._test == BoolTest::ge || 4227 n->as_Bool()->_test._test == BoolTest::le || 4228 n->as_Bool()->_test._test == BoolTest::gt); 4229 format %{ "" %} 4230 interface(COND_INTER) %{ 4231 equal(0x4, "e"); 4232 not_equal(0x5, "ne"); 4233 less(0x2, "b"); 4234 greater_equal(0x3, "nb"); 4235 less_equal(0x6, "be"); 4236 greater(0x7, "nbe"); 4237 overflow(0x0, "o"); 4238 no_overflow(0x1, "no"); 4239 %} 4240 %} 4241 4242 4243 // Floating comparisons that can be fixed up with extra conditional jumps 4244 operand cmpOpUCF2() %{ 4245 match(Bool); 4246 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4247 n->as_Bool()->_test._test == BoolTest::eq); 4248 format %{ "" %} 4249 interface(COND_INTER) %{ 4250 equal(0x4, "e"); 4251 not_equal(0x5, "ne"); 4252 less(0x2, "b"); 4253 greater_equal(0x3, "nb"); 4254 less_equal(0x6, "be"); 4255 greater(0x7, "nbe"); 4256 overflow(0x0, "o"); 4257 no_overflow(0x1, "no"); 4258 %} 4259 %} 4260 4261 // Operands for bound floating pointer register arguments 4262 operand rxmm0() %{ 4263 constraint(ALLOC_IN_RC(xmm0_reg)); 4264 match(VecX); 4265 format%{%} 4266 interface(REG_INTER); 4267 %} 4268 operand rxmm1() %{ 4269 constraint(ALLOC_IN_RC(xmm1_reg)); 4270 match(VecX); 4271 format%{%} 4272 interface(REG_INTER); 4273 %} 4274 operand rxmm2() %{ 4275 constraint(ALLOC_IN_RC(xmm2_reg)); 4276 match(VecX); 4277 format%{%} 4278 interface(REG_INTER); 4279 %} 4280 operand rxmm3() %{ 4281 constraint(ALLOC_IN_RC(xmm3_reg)); 4282 match(VecX); 4283 format%{%} 4284 interface(REG_INTER); 4285 %} 4286 operand rxmm4() %{ 4287 constraint(ALLOC_IN_RC(xmm4_reg)); 4288 match(VecX); 4289 format%{%} 4290 interface(REG_INTER); 4291 %} 4292 operand rxmm5() %{ 4293 constraint(ALLOC_IN_RC(xmm5_reg)); 4294 match(VecX); 4295 format%{%} 4296 interface(REG_INTER); 4297 %} 4298 operand rxmm6() %{ 4299 constraint(ALLOC_IN_RC(xmm6_reg)); 4300 match(VecX); 4301 format%{%} 4302 interface(REG_INTER); 4303 %} 4304 operand rxmm7() %{ 4305 constraint(ALLOC_IN_RC(xmm7_reg)); 4306 match(VecX); 4307 format%{%} 4308 interface(REG_INTER); 4309 %} 4310 operand rxmm8() %{ 4311 constraint(ALLOC_IN_RC(xmm8_reg)); 4312 match(VecX); 4313 format%{%} 4314 interface(REG_INTER); 4315 %} 4316 operand rxmm9() %{ 4317 constraint(ALLOC_IN_RC(xmm9_reg)); 4318 match(VecX); 4319 format%{%} 4320 interface(REG_INTER); 4321 %} 4322 operand rxmm10() %{ 4323 constraint(ALLOC_IN_RC(xmm10_reg)); 4324 match(VecX); 4325 format%{%} 4326 interface(REG_INTER); 4327 %} 4328 operand rxmm11() %{ 4329 constraint(ALLOC_IN_RC(xmm11_reg)); 4330 match(VecX); 4331 format%{%} 4332 interface(REG_INTER); 4333 %} 4334 operand rxmm12() %{ 4335 constraint(ALLOC_IN_RC(xmm12_reg)); 4336 match(VecX); 4337 format%{%} 4338 interface(REG_INTER); 4339 %} 4340 operand rxmm13() %{ 4341 constraint(ALLOC_IN_RC(xmm13_reg)); 4342 match(VecX); 4343 format%{%} 4344 interface(REG_INTER); 4345 %} 4346 operand rxmm14() %{ 4347 constraint(ALLOC_IN_RC(xmm14_reg)); 4348 match(VecX); 4349 format%{%} 4350 interface(REG_INTER); 4351 %} 4352 operand rxmm15() %{ 4353 constraint(ALLOC_IN_RC(xmm15_reg)); 4354 match(VecX); 4355 format%{%} 4356 interface(REG_INTER); 4357 %} 4358 operand rxmm16() %{ 4359 constraint(ALLOC_IN_RC(xmm16_reg)); 4360 match(VecX); 4361 format%{%} 4362 interface(REG_INTER); 4363 %} 4364 operand rxmm17() %{ 4365 constraint(ALLOC_IN_RC(xmm17_reg)); 4366 match(VecX); 4367 format%{%} 4368 interface(REG_INTER); 4369 %} 4370 operand rxmm18() %{ 4371 constraint(ALLOC_IN_RC(xmm18_reg)); 4372 match(VecX); 4373 format%{%} 4374 interface(REG_INTER); 4375 %} 4376 operand rxmm19() %{ 4377 constraint(ALLOC_IN_RC(xmm19_reg)); 4378 match(VecX); 4379 format%{%} 4380 interface(REG_INTER); 4381 %} 4382 operand rxmm20() %{ 4383 constraint(ALLOC_IN_RC(xmm20_reg)); 4384 match(VecX); 4385 format%{%} 4386 interface(REG_INTER); 4387 %} 4388 operand rxmm21() %{ 4389 constraint(ALLOC_IN_RC(xmm21_reg)); 4390 match(VecX); 4391 format%{%} 4392 interface(REG_INTER); 4393 %} 4394 operand rxmm22() %{ 4395 constraint(ALLOC_IN_RC(xmm22_reg)); 4396 match(VecX); 4397 format%{%} 4398 interface(REG_INTER); 4399 %} 4400 operand rxmm23() %{ 4401 constraint(ALLOC_IN_RC(xmm23_reg)); 4402 match(VecX); 4403 format%{%} 4404 interface(REG_INTER); 4405 %} 4406 operand rxmm24() %{ 4407 constraint(ALLOC_IN_RC(xmm24_reg)); 4408 match(VecX); 4409 format%{%} 4410 interface(REG_INTER); 4411 %} 4412 operand rxmm25() %{ 4413 constraint(ALLOC_IN_RC(xmm25_reg)); 4414 match(VecX); 4415 format%{%} 4416 interface(REG_INTER); 4417 %} 4418 operand rxmm26() %{ 4419 constraint(ALLOC_IN_RC(xmm26_reg)); 4420 match(VecX); 4421 format%{%} 4422 interface(REG_INTER); 4423 %} 4424 operand rxmm27() %{ 4425 constraint(ALLOC_IN_RC(xmm27_reg)); 4426 match(VecX); 4427 format%{%} 4428 interface(REG_INTER); 4429 %} 4430 operand rxmm28() %{ 4431 constraint(ALLOC_IN_RC(xmm28_reg)); 4432 match(VecX); 4433 format%{%} 4434 interface(REG_INTER); 4435 %} 4436 operand rxmm29() %{ 4437 constraint(ALLOC_IN_RC(xmm29_reg)); 4438 match(VecX); 4439 format%{%} 4440 interface(REG_INTER); 4441 %} 4442 operand rxmm30() %{ 4443 constraint(ALLOC_IN_RC(xmm30_reg)); 4444 match(VecX); 4445 format%{%} 4446 interface(REG_INTER); 4447 %} 4448 operand rxmm31() %{ 4449 constraint(ALLOC_IN_RC(xmm31_reg)); 4450 match(VecX); 4451 format%{%} 4452 interface(REG_INTER); 4453 %} 4454 4455 //----------OPERAND CLASSES---------------------------------------------------- 4456 // Operand Classes are groups of operands that are used as to simplify 4457 // instruction definitions by not requiring the AD writer to specify separate 4458 // instructions for every form of operand when the instruction accepts 4459 // multiple operand types with the same basic encoding and format. The classic 4460 // case of this is memory operands. 4461 4462 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4463 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4464 indCompressedOopOffset, 4465 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4466 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4467 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4468 4469 //----------PIPELINE----------------------------------------------------------- 4470 // Rules which define the behavior of the target architectures pipeline. 4471 pipeline %{ 4472 4473 //----------ATTRIBUTES--------------------------------------------------------- 4474 attributes %{ 4475 variable_size_instructions; // Fixed size instructions 4476 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4477 instruction_unit_size = 1; // An instruction is 1 bytes long 4478 instruction_fetch_unit_size = 16; // The processor fetches one line 4479 instruction_fetch_units = 1; // of 16 bytes 4480 4481 // List of nop instructions 4482 nops( MachNop ); 4483 %} 4484 4485 //----------RESOURCES---------------------------------------------------------- 4486 // Resources are the functional units available to the machine 4487 4488 // Generic P2/P3 pipeline 4489 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4490 // 3 instructions decoded per cycle. 4491 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4492 // 3 ALU op, only ALU0 handles mul instructions. 4493 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4494 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4495 BR, FPU, 4496 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4497 4498 //----------PIPELINE DESCRIPTION----------------------------------------------- 4499 // Pipeline Description specifies the stages in the machine's pipeline 4500 4501 // Generic P2/P3 pipeline 4502 pipe_desc(S0, S1, S2, S3, S4, S5); 4503 4504 //----------PIPELINE CLASSES--------------------------------------------------- 4505 // Pipeline Classes describe the stages in which input and output are 4506 // referenced by the hardware pipeline. 4507 4508 // Naming convention: ialu or fpu 4509 // Then: _reg 4510 // Then: _reg if there is a 2nd register 4511 // Then: _long if it's a pair of instructions implementing a long 4512 // Then: _fat if it requires the big decoder 4513 // Or: _mem if it requires the big decoder and a memory unit. 4514 4515 // Integer ALU reg operation 4516 pipe_class ialu_reg(rRegI dst) 4517 %{ 4518 single_instruction; 4519 dst : S4(write); 4520 dst : S3(read); 4521 DECODE : S0; // any decoder 4522 ALU : S3; // any alu 4523 %} 4524 4525 // Long ALU reg operation 4526 pipe_class ialu_reg_long(rRegL dst) 4527 %{ 4528 instruction_count(2); 4529 dst : S4(write); 4530 dst : S3(read); 4531 DECODE : S0(2); // any 2 decoders 4532 ALU : S3(2); // both alus 4533 %} 4534 4535 // Integer ALU reg operation using big decoder 4536 pipe_class ialu_reg_fat(rRegI dst) 4537 %{ 4538 single_instruction; 4539 dst : S4(write); 4540 dst : S3(read); 4541 D0 : S0; // big decoder only 4542 ALU : S3; // any alu 4543 %} 4544 4545 // Long ALU reg operation using big decoder 4546 pipe_class ialu_reg_long_fat(rRegL dst) 4547 %{ 4548 instruction_count(2); 4549 dst : S4(write); 4550 dst : S3(read); 4551 D0 : S0(2); // big decoder only; twice 4552 ALU : S3(2); // any 2 alus 4553 %} 4554 4555 // Integer ALU reg-reg operation 4556 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4557 %{ 4558 single_instruction; 4559 dst : S4(write); 4560 src : S3(read); 4561 DECODE : S0; // any decoder 4562 ALU : S3; // any alu 4563 %} 4564 4565 // Long ALU reg-reg operation 4566 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4567 %{ 4568 instruction_count(2); 4569 dst : S4(write); 4570 src : S3(read); 4571 DECODE : S0(2); // any 2 decoders 4572 ALU : S3(2); // both alus 4573 %} 4574 4575 // Integer ALU reg-reg operation 4576 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4577 %{ 4578 single_instruction; 4579 dst : S4(write); 4580 src : S3(read); 4581 D0 : S0; // big decoder only 4582 ALU : S3; // any alu 4583 %} 4584 4585 // Long ALU reg-reg operation 4586 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4587 %{ 4588 instruction_count(2); 4589 dst : S4(write); 4590 src : S3(read); 4591 D0 : S0(2); // big decoder only; twice 4592 ALU : S3(2); // both alus 4593 %} 4594 4595 // Integer ALU reg-mem operation 4596 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4597 %{ 4598 single_instruction; 4599 dst : S5(write); 4600 mem : S3(read); 4601 D0 : S0; // big decoder only 4602 ALU : S4; // any alu 4603 MEM : S3; // any mem 4604 %} 4605 4606 // Integer mem operation (prefetch) 4607 pipe_class ialu_mem(memory mem) 4608 %{ 4609 single_instruction; 4610 mem : S3(read); 4611 D0 : S0; // big decoder only 4612 MEM : S3; // any mem 4613 %} 4614 4615 // Integer Store to Memory 4616 pipe_class ialu_mem_reg(memory mem, rRegI src) 4617 %{ 4618 single_instruction; 4619 mem : S3(read); 4620 src : S5(read); 4621 D0 : S0; // big decoder only 4622 ALU : S4; // any alu 4623 MEM : S3; 4624 %} 4625 4626 // // Long Store to Memory 4627 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4628 // %{ 4629 // instruction_count(2); 4630 // mem : S3(read); 4631 // src : S5(read); 4632 // D0 : S0(2); // big decoder only; twice 4633 // ALU : S4(2); // any 2 alus 4634 // MEM : S3(2); // Both mems 4635 // %} 4636 4637 // Integer Store to Memory 4638 pipe_class ialu_mem_imm(memory mem) 4639 %{ 4640 single_instruction; 4641 mem : S3(read); 4642 D0 : S0; // big decoder only 4643 ALU : S4; // any alu 4644 MEM : S3; 4645 %} 4646 4647 // Integer ALU0 reg-reg operation 4648 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4649 %{ 4650 single_instruction; 4651 dst : S4(write); 4652 src : S3(read); 4653 D0 : S0; // Big decoder only 4654 ALU0 : S3; // only alu0 4655 %} 4656 4657 // Integer ALU0 reg-mem operation 4658 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4659 %{ 4660 single_instruction; 4661 dst : S5(write); 4662 mem : S3(read); 4663 D0 : S0; // big decoder only 4664 ALU0 : S4; // ALU0 only 4665 MEM : S3; // any mem 4666 %} 4667 4668 // Integer ALU reg-reg operation 4669 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4670 %{ 4671 single_instruction; 4672 cr : S4(write); 4673 src1 : S3(read); 4674 src2 : S3(read); 4675 DECODE : S0; // any decoder 4676 ALU : S3; // any alu 4677 %} 4678 4679 // Integer ALU reg-imm operation 4680 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4681 %{ 4682 single_instruction; 4683 cr : S4(write); 4684 src1 : S3(read); 4685 DECODE : S0; // any decoder 4686 ALU : S3; // any alu 4687 %} 4688 4689 // Integer ALU reg-mem operation 4690 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4691 %{ 4692 single_instruction; 4693 cr : S4(write); 4694 src1 : S3(read); 4695 src2 : S3(read); 4696 D0 : S0; // big decoder only 4697 ALU : S4; // any alu 4698 MEM : S3; 4699 %} 4700 4701 // Conditional move reg-reg 4702 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4703 %{ 4704 instruction_count(4); 4705 y : S4(read); 4706 q : S3(read); 4707 p : S3(read); 4708 DECODE : S0(4); // any decoder 4709 %} 4710 4711 // Conditional move reg-reg 4712 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4713 %{ 4714 single_instruction; 4715 dst : S4(write); 4716 src : S3(read); 4717 cr : S3(read); 4718 DECODE : S0; // any decoder 4719 %} 4720 4721 // Conditional move reg-mem 4722 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4723 %{ 4724 single_instruction; 4725 dst : S4(write); 4726 src : S3(read); 4727 cr : S3(read); 4728 DECODE : S0; // any decoder 4729 MEM : S3; 4730 %} 4731 4732 // Conditional move reg-reg long 4733 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4734 %{ 4735 single_instruction; 4736 dst : S4(write); 4737 src : S3(read); 4738 cr : S3(read); 4739 DECODE : S0(2); // any 2 decoders 4740 %} 4741 4742 // XXX 4743 // // Conditional move double reg-reg 4744 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4745 // %{ 4746 // single_instruction; 4747 // dst : S4(write); 4748 // src : S3(read); 4749 // cr : S3(read); 4750 // DECODE : S0; // any decoder 4751 // %} 4752 4753 // Float reg-reg operation 4754 pipe_class fpu_reg(regD dst) 4755 %{ 4756 instruction_count(2); 4757 dst : S3(read); 4758 DECODE : S0(2); // any 2 decoders 4759 FPU : S3; 4760 %} 4761 4762 // Float reg-reg operation 4763 pipe_class fpu_reg_reg(regD dst, regD src) 4764 %{ 4765 instruction_count(2); 4766 dst : S4(write); 4767 src : S3(read); 4768 DECODE : S0(2); // any 2 decoders 4769 FPU : S3; 4770 %} 4771 4772 // Float reg-reg operation 4773 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4774 %{ 4775 instruction_count(3); 4776 dst : S4(write); 4777 src1 : S3(read); 4778 src2 : S3(read); 4779 DECODE : S0(3); // any 3 decoders 4780 FPU : S3(2); 4781 %} 4782 4783 // Float reg-reg operation 4784 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4785 %{ 4786 instruction_count(4); 4787 dst : S4(write); 4788 src1 : S3(read); 4789 src2 : S3(read); 4790 src3 : S3(read); 4791 DECODE : S0(4); // any 3 decoders 4792 FPU : S3(2); 4793 %} 4794 4795 // Float reg-reg operation 4796 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4797 %{ 4798 instruction_count(4); 4799 dst : S4(write); 4800 src1 : S3(read); 4801 src2 : S3(read); 4802 src3 : S3(read); 4803 DECODE : S1(3); // any 3 decoders 4804 D0 : S0; // Big decoder only 4805 FPU : S3(2); 4806 MEM : S3; 4807 %} 4808 4809 // Float reg-mem operation 4810 pipe_class fpu_reg_mem(regD dst, memory mem) 4811 %{ 4812 instruction_count(2); 4813 dst : S5(write); 4814 mem : S3(read); 4815 D0 : S0; // big decoder only 4816 DECODE : S1; // any decoder for FPU POP 4817 FPU : S4; 4818 MEM : S3; // any mem 4819 %} 4820 4821 // Float reg-mem operation 4822 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4823 %{ 4824 instruction_count(3); 4825 dst : S5(write); 4826 src1 : S3(read); 4827 mem : S3(read); 4828 D0 : S0; // big decoder only 4829 DECODE : S1(2); // any decoder for FPU POP 4830 FPU : S4; 4831 MEM : S3; // any mem 4832 %} 4833 4834 // Float mem-reg operation 4835 pipe_class fpu_mem_reg(memory mem, regD src) 4836 %{ 4837 instruction_count(2); 4838 src : S5(read); 4839 mem : S3(read); 4840 DECODE : S0; // any decoder for FPU PUSH 4841 D0 : S1; // big decoder only 4842 FPU : S4; 4843 MEM : S3; // any mem 4844 %} 4845 4846 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4847 %{ 4848 instruction_count(3); 4849 src1 : S3(read); 4850 src2 : S3(read); 4851 mem : S3(read); 4852 DECODE : S0(2); // any decoder for FPU PUSH 4853 D0 : S1; // big decoder only 4854 FPU : S4; 4855 MEM : S3; // any mem 4856 %} 4857 4858 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4859 %{ 4860 instruction_count(3); 4861 src1 : S3(read); 4862 src2 : S3(read); 4863 mem : S4(read); 4864 DECODE : S0; // any decoder for FPU PUSH 4865 D0 : S0(2); // big decoder only 4866 FPU : S4; 4867 MEM : S3(2); // any mem 4868 %} 4869 4870 pipe_class fpu_mem_mem(memory dst, memory src1) 4871 %{ 4872 instruction_count(2); 4873 src1 : S3(read); 4874 dst : S4(read); 4875 D0 : S0(2); // big decoder only 4876 MEM : S3(2); // any mem 4877 %} 4878 4879 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4880 %{ 4881 instruction_count(3); 4882 src1 : S3(read); 4883 src2 : S3(read); 4884 dst : S4(read); 4885 D0 : S0(3); // big decoder only 4886 FPU : S4; 4887 MEM : S3(3); // any mem 4888 %} 4889 4890 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4891 %{ 4892 instruction_count(3); 4893 src1 : S4(read); 4894 mem : S4(read); 4895 DECODE : S0; // any decoder for FPU PUSH 4896 D0 : S0(2); // big decoder only 4897 FPU : S4; 4898 MEM : S3(2); // any mem 4899 %} 4900 4901 // Float load constant 4902 pipe_class fpu_reg_con(regD dst) 4903 %{ 4904 instruction_count(2); 4905 dst : S5(write); 4906 D0 : S0; // big decoder only for the load 4907 DECODE : S1; // any decoder for FPU POP 4908 FPU : S4; 4909 MEM : S3; // any mem 4910 %} 4911 4912 // Float load constant 4913 pipe_class fpu_reg_reg_con(regD dst, regD src) 4914 %{ 4915 instruction_count(3); 4916 dst : S5(write); 4917 src : S3(read); 4918 D0 : S0; // big decoder only for the load 4919 DECODE : S1(2); // any decoder for FPU POP 4920 FPU : S4; 4921 MEM : S3; // any mem 4922 %} 4923 4924 // UnConditional branch 4925 pipe_class pipe_jmp(label labl) 4926 %{ 4927 single_instruction; 4928 BR : S3; 4929 %} 4930 4931 // Conditional branch 4932 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4933 %{ 4934 single_instruction; 4935 cr : S1(read); 4936 BR : S3; 4937 %} 4938 4939 // Allocation idiom 4940 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4941 %{ 4942 instruction_count(1); force_serialization; 4943 fixed_latency(6); 4944 heap_ptr : S3(read); 4945 DECODE : S0(3); 4946 D0 : S2; 4947 MEM : S3; 4948 ALU : S3(2); 4949 dst : S5(write); 4950 BR : S5; 4951 %} 4952 4953 // Generic big/slow expanded idiom 4954 pipe_class pipe_slow() 4955 %{ 4956 instruction_count(10); multiple_bundles; force_serialization; 4957 fixed_latency(100); 4958 D0 : S0(2); 4959 MEM : S3(2); 4960 %} 4961 4962 // The real do-nothing guy 4963 pipe_class empty() 4964 %{ 4965 instruction_count(0); 4966 %} 4967 4968 // Define the class for the Nop node 4969 define 4970 %{ 4971 MachNop = empty; 4972 %} 4973 4974 %} 4975 4976 //----------INSTRUCTIONS------------------------------------------------------- 4977 // 4978 // match -- States which machine-independent subtree may be replaced 4979 // by this instruction. 4980 // ins_cost -- The estimated cost of this instruction is used by instruction 4981 // selection to identify a minimum cost tree of machine 4982 // instructions that matches a tree of machine-independent 4983 // instructions. 4984 // format -- A string providing the disassembly for this instruction. 4985 // The value of an instruction's operand may be inserted 4986 // by referring to it with a '$' prefix. 4987 // opcode -- Three instruction opcodes may be provided. These are referred 4988 // to within an encode class as $primary, $secondary, and $tertiary 4989 // rrspectively. The primary opcode is commonly used to 4990 // indicate the type of machine instruction, while secondary 4991 // and tertiary are often used for prefix options or addressing 4992 // modes. 4993 // ins_encode -- A list of encode classes with parameters. The encode class 4994 // name must have been defined in an 'enc_class' specification 4995 // in the encode section of the architecture description. 4996 4997 4998 //----------Load/Store/Move Instructions--------------------------------------- 4999 //----------Load Instructions-------------------------------------------------- 5000 5001 // Load Byte (8 bit signed) 5002 instruct loadB(rRegI dst, memory mem) 5003 %{ 5004 match(Set dst (LoadB mem)); 5005 5006 ins_cost(125); 5007 format %{ "movsbl $dst, $mem\t# byte" %} 5008 5009 ins_encode %{ 5010 __ movsbl($dst$$Register, $mem$$Address); 5011 %} 5012 5013 ins_pipe(ialu_reg_mem); 5014 %} 5015 5016 // Load Byte (8 bit signed) into Long Register 5017 instruct loadB2L(rRegL dst, memory mem) 5018 %{ 5019 match(Set dst (ConvI2L (LoadB mem))); 5020 5021 ins_cost(125); 5022 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5023 5024 ins_encode %{ 5025 __ movsbq($dst$$Register, $mem$$Address); 5026 %} 5027 5028 ins_pipe(ialu_reg_mem); 5029 %} 5030 5031 // Load Unsigned Byte (8 bit UNsigned) 5032 instruct loadUB(rRegI dst, memory mem) 5033 %{ 5034 match(Set dst (LoadUB mem)); 5035 5036 ins_cost(125); 5037 format %{ "movzbl $dst, $mem\t# ubyte" %} 5038 5039 ins_encode %{ 5040 __ movzbl($dst$$Register, $mem$$Address); 5041 %} 5042 5043 ins_pipe(ialu_reg_mem); 5044 %} 5045 5046 // Load Unsigned Byte (8 bit UNsigned) into Long Register 5047 instruct loadUB2L(rRegL dst, memory mem) 5048 %{ 5049 match(Set dst (ConvI2L (LoadUB mem))); 5050 5051 ins_cost(125); 5052 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5053 5054 ins_encode %{ 5055 __ movzbq($dst$$Register, $mem$$Address); 5056 %} 5057 5058 ins_pipe(ialu_reg_mem); 5059 %} 5060 5061 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 5062 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5063 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5064 effect(KILL cr); 5065 5066 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 5067 "andl $dst, right_n_bits($mask, 8)" %} 5068 ins_encode %{ 5069 Register Rdst = $dst$$Register; 5070 __ movzbq(Rdst, $mem$$Address); 5071 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 5072 %} 5073 ins_pipe(ialu_reg_mem); 5074 %} 5075 5076 // Load Short (16 bit signed) 5077 instruct loadS(rRegI dst, memory mem) 5078 %{ 5079 match(Set dst (LoadS mem)); 5080 5081 ins_cost(125); 5082 format %{ "movswl $dst, $mem\t# short" %} 5083 5084 ins_encode %{ 5085 __ movswl($dst$$Register, $mem$$Address); 5086 %} 5087 5088 ins_pipe(ialu_reg_mem); 5089 %} 5090 5091 // Load Short (16 bit signed) to Byte (8 bit signed) 5092 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5093 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5094 5095 ins_cost(125); 5096 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5097 ins_encode %{ 5098 __ movsbl($dst$$Register, $mem$$Address); 5099 %} 5100 ins_pipe(ialu_reg_mem); 5101 %} 5102 5103 // Load Short (16 bit signed) into Long Register 5104 instruct loadS2L(rRegL dst, memory mem) 5105 %{ 5106 match(Set dst (ConvI2L (LoadS mem))); 5107 5108 ins_cost(125); 5109 format %{ "movswq $dst, $mem\t# short -> long" %} 5110 5111 ins_encode %{ 5112 __ movswq($dst$$Register, $mem$$Address); 5113 %} 5114 5115 ins_pipe(ialu_reg_mem); 5116 %} 5117 5118 // Load Unsigned Short/Char (16 bit UNsigned) 5119 instruct loadUS(rRegI dst, memory mem) 5120 %{ 5121 match(Set dst (LoadUS mem)); 5122 5123 ins_cost(125); 5124 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5125 5126 ins_encode %{ 5127 __ movzwl($dst$$Register, $mem$$Address); 5128 %} 5129 5130 ins_pipe(ialu_reg_mem); 5131 %} 5132 5133 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5134 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5135 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5136 5137 ins_cost(125); 5138 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5139 ins_encode %{ 5140 __ movsbl($dst$$Register, $mem$$Address); 5141 %} 5142 ins_pipe(ialu_reg_mem); 5143 %} 5144 5145 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5146 instruct loadUS2L(rRegL dst, memory mem) 5147 %{ 5148 match(Set dst (ConvI2L (LoadUS mem))); 5149 5150 ins_cost(125); 5151 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5152 5153 ins_encode %{ 5154 __ movzwq($dst$$Register, $mem$$Address); 5155 %} 5156 5157 ins_pipe(ialu_reg_mem); 5158 %} 5159 5160 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5161 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5162 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5163 5164 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5165 ins_encode %{ 5166 __ movzbq($dst$$Register, $mem$$Address); 5167 %} 5168 ins_pipe(ialu_reg_mem); 5169 %} 5170 5171 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5172 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5173 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5174 effect(KILL cr); 5175 5176 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5177 "andl $dst, right_n_bits($mask, 16)" %} 5178 ins_encode %{ 5179 Register Rdst = $dst$$Register; 5180 __ movzwq(Rdst, $mem$$Address); 5181 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5182 %} 5183 ins_pipe(ialu_reg_mem); 5184 %} 5185 5186 // Load Integer 5187 instruct loadI(rRegI dst, memory mem) 5188 %{ 5189 match(Set dst (LoadI mem)); 5190 5191 ins_cost(125); 5192 format %{ "movl $dst, $mem\t# int" %} 5193 5194 ins_encode %{ 5195 __ movl($dst$$Register, $mem$$Address); 5196 %} 5197 5198 ins_pipe(ialu_reg_mem); 5199 %} 5200 5201 // Load Integer (32 bit signed) to Byte (8 bit signed) 5202 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5203 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5204 5205 ins_cost(125); 5206 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5207 ins_encode %{ 5208 __ movsbl($dst$$Register, $mem$$Address); 5209 %} 5210 ins_pipe(ialu_reg_mem); 5211 %} 5212 5213 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5214 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5215 match(Set dst (AndI (LoadI mem) mask)); 5216 5217 ins_cost(125); 5218 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5219 ins_encode %{ 5220 __ movzbl($dst$$Register, $mem$$Address); 5221 %} 5222 ins_pipe(ialu_reg_mem); 5223 %} 5224 5225 // Load Integer (32 bit signed) to Short (16 bit signed) 5226 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5227 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5228 5229 ins_cost(125); 5230 format %{ "movswl $dst, $mem\t# int -> short" %} 5231 ins_encode %{ 5232 __ movswl($dst$$Register, $mem$$Address); 5233 %} 5234 ins_pipe(ialu_reg_mem); 5235 %} 5236 5237 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5238 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5239 match(Set dst (AndI (LoadI mem) mask)); 5240 5241 ins_cost(125); 5242 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5243 ins_encode %{ 5244 __ movzwl($dst$$Register, $mem$$Address); 5245 %} 5246 ins_pipe(ialu_reg_mem); 5247 %} 5248 5249 // Load Integer into Long Register 5250 instruct loadI2L(rRegL dst, memory mem) 5251 %{ 5252 match(Set dst (ConvI2L (LoadI mem))); 5253 5254 ins_cost(125); 5255 format %{ "movslq $dst, $mem\t# int -> long" %} 5256 5257 ins_encode %{ 5258 __ movslq($dst$$Register, $mem$$Address); 5259 %} 5260 5261 ins_pipe(ialu_reg_mem); 5262 %} 5263 5264 // Load Integer with mask 0xFF into Long Register 5265 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5266 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5267 5268 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5269 ins_encode %{ 5270 __ movzbq($dst$$Register, $mem$$Address); 5271 %} 5272 ins_pipe(ialu_reg_mem); 5273 %} 5274 5275 // Load Integer with mask 0xFFFF into Long Register 5276 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5277 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5278 5279 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5280 ins_encode %{ 5281 __ movzwq($dst$$Register, $mem$$Address); 5282 %} 5283 ins_pipe(ialu_reg_mem); 5284 %} 5285 5286 // Load Integer with a 31-bit mask into Long Register 5287 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5288 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5289 effect(KILL cr); 5290 5291 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5292 "andl $dst, $mask" %} 5293 ins_encode %{ 5294 Register Rdst = $dst$$Register; 5295 __ movl(Rdst, $mem$$Address); 5296 __ andl(Rdst, $mask$$constant); 5297 %} 5298 ins_pipe(ialu_reg_mem); 5299 %} 5300 5301 // Load Unsigned Integer into Long Register 5302 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5303 %{ 5304 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5305 5306 ins_cost(125); 5307 format %{ "movl $dst, $mem\t# uint -> long" %} 5308 5309 ins_encode %{ 5310 __ movl($dst$$Register, $mem$$Address); 5311 %} 5312 5313 ins_pipe(ialu_reg_mem); 5314 %} 5315 5316 // Load Long 5317 instruct loadL(rRegL dst, memory mem) 5318 %{ 5319 match(Set dst (LoadL mem)); 5320 5321 ins_cost(125); 5322 format %{ "movq $dst, $mem\t# long" %} 5323 5324 ins_encode %{ 5325 __ movq($dst$$Register, $mem$$Address); 5326 %} 5327 5328 ins_pipe(ialu_reg_mem); // XXX 5329 %} 5330 5331 // Load Range 5332 instruct loadRange(rRegI dst, memory mem) 5333 %{ 5334 match(Set dst (LoadRange mem)); 5335 5336 ins_cost(125); // XXX 5337 format %{ "movl $dst, $mem\t# range" %} 5338 opcode(0x8B); 5339 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5340 ins_pipe(ialu_reg_mem); 5341 %} 5342 5343 // Load Pointer 5344 instruct loadP(rRegP dst, memory mem) 5345 %{ 5346 match(Set dst (LoadP mem)); 5347 5348 ins_cost(125); // XXX 5349 format %{ "movq $dst, $mem\t# ptr" %} 5350 opcode(0x8B); 5351 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5352 ins_pipe(ialu_reg_mem); // XXX 5353 %} 5354 5355 // Load Compressed Pointer 5356 instruct loadN(rRegN dst, memory mem) 5357 %{ 5358 match(Set dst (LoadN mem)); 5359 5360 ins_cost(125); // XXX 5361 format %{ "movl $dst, $mem\t# compressed ptr" %} 5362 ins_encode %{ 5363 __ movl($dst$$Register, $mem$$Address); 5364 %} 5365 ins_pipe(ialu_reg_mem); // XXX 5366 %} 5367 5368 5369 // Load Klass Pointer 5370 instruct loadKlass(rRegP dst, memory mem) 5371 %{ 5372 match(Set dst (LoadKlass mem)); 5373 5374 ins_cost(125); // XXX 5375 format %{ "movq $dst, $mem\t# class" %} 5376 opcode(0x8B); 5377 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5378 ins_pipe(ialu_reg_mem); // XXX 5379 %} 5380 5381 // Load narrow Klass Pointer 5382 instruct loadNKlass(rRegN dst, memory mem) 5383 %{ 5384 match(Set dst (LoadNKlass mem)); 5385 5386 ins_cost(125); // XXX 5387 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5388 ins_encode %{ 5389 __ movl($dst$$Register, $mem$$Address); 5390 %} 5391 ins_pipe(ialu_reg_mem); // XXX 5392 %} 5393 5394 // Load Float 5395 instruct loadF(regF dst, memory mem) 5396 %{ 5397 match(Set dst (LoadF mem)); 5398 5399 ins_cost(145); // XXX 5400 format %{ "movss $dst, $mem\t# float" %} 5401 ins_encode %{ 5402 __ movflt($dst$$XMMRegister, $mem$$Address); 5403 %} 5404 ins_pipe(pipe_slow); // XXX 5405 %} 5406 5407 // Load Float 5408 instruct MoveF2VL(vlRegF dst, regF src) %{ 5409 match(Set dst src); 5410 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5411 ins_encode %{ 5412 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5413 %} 5414 ins_pipe( fpu_reg_reg ); 5415 %} 5416 5417 // Load Float 5418 instruct MoveF2LEG(legRegF dst, regF src) %{ 5419 match(Set dst src); 5420 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5421 ins_encode %{ 5422 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5423 %} 5424 ins_pipe( fpu_reg_reg ); 5425 %} 5426 5427 // Load Float 5428 instruct MoveVL2F(regF dst, vlRegF src) %{ 5429 match(Set dst src); 5430 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5431 ins_encode %{ 5432 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5433 %} 5434 ins_pipe( fpu_reg_reg ); 5435 %} 5436 5437 // Load Float 5438 instruct MoveLEG2F(regF dst, legRegF src) %{ 5439 match(Set dst src); 5440 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5441 ins_encode %{ 5442 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5443 %} 5444 ins_pipe( fpu_reg_reg ); 5445 %} 5446 5447 // Load Double 5448 instruct loadD_partial(regD dst, memory mem) 5449 %{ 5450 predicate(!UseXmmLoadAndClearUpper); 5451 match(Set dst (LoadD mem)); 5452 5453 ins_cost(145); // XXX 5454 format %{ "movlpd $dst, $mem\t# double" %} 5455 ins_encode %{ 5456 __ movdbl($dst$$XMMRegister, $mem$$Address); 5457 %} 5458 ins_pipe(pipe_slow); // XXX 5459 %} 5460 5461 instruct loadD(regD dst, memory mem) 5462 %{ 5463 predicate(UseXmmLoadAndClearUpper); 5464 match(Set dst (LoadD mem)); 5465 5466 ins_cost(145); // XXX 5467 format %{ "movsd $dst, $mem\t# double" %} 5468 ins_encode %{ 5469 __ movdbl($dst$$XMMRegister, $mem$$Address); 5470 %} 5471 ins_pipe(pipe_slow); // XXX 5472 %} 5473 5474 // Load Double 5475 instruct MoveD2VL(vlRegD dst, regD src) %{ 5476 match(Set dst src); 5477 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5478 ins_encode %{ 5479 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5480 %} 5481 ins_pipe( fpu_reg_reg ); 5482 %} 5483 5484 // Load Double 5485 instruct MoveD2LEG(legRegD dst, regD src) %{ 5486 match(Set dst src); 5487 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5488 ins_encode %{ 5489 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5490 %} 5491 ins_pipe( fpu_reg_reg ); 5492 %} 5493 5494 // Load Double 5495 instruct MoveVL2D(regD dst, vlRegD src) %{ 5496 match(Set dst src); 5497 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5498 ins_encode %{ 5499 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5500 %} 5501 ins_pipe( fpu_reg_reg ); 5502 %} 5503 5504 // Load Double 5505 instruct MoveLEG2D(regD dst, legRegD src) %{ 5506 match(Set dst src); 5507 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5508 ins_encode %{ 5509 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5510 %} 5511 ins_pipe( fpu_reg_reg ); 5512 %} 5513 5514 // Following pseudo code describes the algorithm for max[FD]: 5515 // Min algorithm is on similar lines 5516 // btmp = (b < +0.0) ? a : b 5517 // atmp = (b < +0.0) ? b : a 5518 // Tmp = Max_Float(atmp , btmp) 5519 // Res = (atmp == NaN) ? atmp : Tmp 5520 5521 // max = java.lang.Math.max(float a, float b) 5522 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5523 predicate(UseAVX > 0 && !n->is_reduction()); 5524 match(Set dst (MaxF a b)); 5525 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5526 format %{ 5527 "blendvps $btmp,$b,$a,$b \n\t" 5528 "blendvps $atmp,$a,$b,$b \n\t" 5529 "vmaxss $tmp,$atmp,$btmp \n\t" 5530 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5531 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5532 %} 5533 ins_encode %{ 5534 int vector_len = Assembler::AVX_128bit; 5535 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5536 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5537 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5538 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5539 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5540 %} 5541 ins_pipe( pipe_slow ); 5542 %} 5543 5544 instruct maxF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{ 5545 predicate(UseAVX > 0 && n->is_reduction()); 5546 match(Set dst (MaxF a b)); 5547 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5548 5549 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 5550 ins_encode %{ 5551 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5552 false /*min*/, true /*single*/); 5553 %} 5554 ins_pipe( pipe_slow ); 5555 %} 5556 5557 // max = java.lang.Math.max(double a, double b) 5558 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5559 predicate(UseAVX > 0 && !n->is_reduction()); 5560 match(Set dst (MaxD a b)); 5561 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 5562 format %{ 5563 "blendvpd $btmp,$b,$a,$b \n\t" 5564 "blendvpd $atmp,$a,$b,$b \n\t" 5565 "vmaxsd $tmp,$atmp,$btmp \n\t" 5566 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5567 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5568 %} 5569 ins_encode %{ 5570 int vector_len = Assembler::AVX_128bit; 5571 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5572 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5573 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5574 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5575 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5576 %} 5577 ins_pipe( pipe_slow ); 5578 %} 5579 5580 instruct maxD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{ 5581 predicate(UseAVX > 0 && n->is_reduction()); 5582 match(Set dst (MaxD a b)); 5583 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5584 5585 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 5586 ins_encode %{ 5587 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5588 false /*min*/, false /*single*/); 5589 %} 5590 ins_pipe( pipe_slow ); 5591 %} 5592 5593 // min = java.lang.Math.min(float a, float b) 5594 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5595 predicate(UseAVX > 0 && !n->is_reduction()); 5596 match(Set dst (MinF a b)); 5597 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5598 format %{ 5599 "blendvps $atmp,$a,$b,$a \n\t" 5600 "blendvps $btmp,$b,$a,$a \n\t" 5601 "vminss $tmp,$atmp,$btmp \n\t" 5602 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5603 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5604 %} 5605 ins_encode %{ 5606 int vector_len = Assembler::AVX_128bit; 5607 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5608 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5609 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5610 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5611 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5612 %} 5613 ins_pipe( pipe_slow ); 5614 %} 5615 5616 instruct minF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{ 5617 predicate(UseAVX > 0 && n->is_reduction()); 5618 match(Set dst (MinF a b)); 5619 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5620 5621 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 5622 ins_encode %{ 5623 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5624 true /*min*/, true /*single*/); 5625 %} 5626 ins_pipe( pipe_slow ); 5627 %} 5628 5629 // min = java.lang.Math.min(double a, double b) 5630 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5631 predicate(UseAVX > 0 && !n->is_reduction()); 5632 match(Set dst (MinD a b)); 5633 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5634 format %{ 5635 "blendvpd $atmp,$a,$b,$a \n\t" 5636 "blendvpd $btmp,$b,$a,$a \n\t" 5637 "vminsd $tmp,$atmp,$btmp \n\t" 5638 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5639 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5640 %} 5641 ins_encode %{ 5642 int vector_len = Assembler::AVX_128bit; 5643 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5644 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5645 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5646 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5647 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5648 %} 5649 ins_pipe( pipe_slow ); 5650 %} 5651 5652 instruct minD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{ 5653 predicate(UseAVX > 0 && n->is_reduction()); 5654 match(Set dst (MinD a b)); 5655 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5656 5657 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 5658 ins_encode %{ 5659 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5660 true /*min*/, false /*single*/); 5661 %} 5662 ins_pipe( pipe_slow ); 5663 %} 5664 5665 // Load Effective Address 5666 instruct leaP8(rRegP dst, indOffset8 mem) 5667 %{ 5668 match(Set dst mem); 5669 5670 ins_cost(110); // XXX 5671 format %{ "leaq $dst, $mem\t# ptr 8" %} 5672 opcode(0x8D); 5673 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5674 ins_pipe(ialu_reg_reg_fat); 5675 %} 5676 5677 instruct leaP32(rRegP dst, indOffset32 mem) 5678 %{ 5679 match(Set dst mem); 5680 5681 ins_cost(110); 5682 format %{ "leaq $dst, $mem\t# ptr 32" %} 5683 opcode(0x8D); 5684 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5685 ins_pipe(ialu_reg_reg_fat); 5686 %} 5687 5688 // instruct leaPIdx(rRegP dst, indIndex mem) 5689 // %{ 5690 // match(Set dst mem); 5691 5692 // ins_cost(110); 5693 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5694 // opcode(0x8D); 5695 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5696 // ins_pipe(ialu_reg_reg_fat); 5697 // %} 5698 5699 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5700 %{ 5701 match(Set dst mem); 5702 5703 ins_cost(110); 5704 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5705 opcode(0x8D); 5706 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5707 ins_pipe(ialu_reg_reg_fat); 5708 %} 5709 5710 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5711 %{ 5712 match(Set dst mem); 5713 5714 ins_cost(110); 5715 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5716 opcode(0x8D); 5717 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5718 ins_pipe(ialu_reg_reg_fat); 5719 %} 5720 5721 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5722 %{ 5723 match(Set dst mem); 5724 5725 ins_cost(110); 5726 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5727 opcode(0x8D); 5728 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5729 ins_pipe(ialu_reg_reg_fat); 5730 %} 5731 5732 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5733 %{ 5734 match(Set dst mem); 5735 5736 ins_cost(110); 5737 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5738 opcode(0x8D); 5739 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5740 ins_pipe(ialu_reg_reg_fat); 5741 %} 5742 5743 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5744 %{ 5745 match(Set dst mem); 5746 5747 ins_cost(110); 5748 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5749 opcode(0x8D); 5750 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5751 ins_pipe(ialu_reg_reg_fat); 5752 %} 5753 5754 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5755 %{ 5756 match(Set dst mem); 5757 5758 ins_cost(110); 5759 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5760 opcode(0x8D); 5761 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5762 ins_pipe(ialu_reg_reg_fat); 5763 %} 5764 5765 // Load Effective Address which uses Narrow (32-bits) oop 5766 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5767 %{ 5768 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5769 match(Set dst mem); 5770 5771 ins_cost(110); 5772 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5773 opcode(0x8D); 5774 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5775 ins_pipe(ialu_reg_reg_fat); 5776 %} 5777 5778 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5779 %{ 5780 predicate(Universe::narrow_oop_shift() == 0); 5781 match(Set dst mem); 5782 5783 ins_cost(110); // XXX 5784 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5785 opcode(0x8D); 5786 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5787 ins_pipe(ialu_reg_reg_fat); 5788 %} 5789 5790 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5791 %{ 5792 predicate(Universe::narrow_oop_shift() == 0); 5793 match(Set dst mem); 5794 5795 ins_cost(110); 5796 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5797 opcode(0x8D); 5798 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5799 ins_pipe(ialu_reg_reg_fat); 5800 %} 5801 5802 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5803 %{ 5804 predicate(Universe::narrow_oop_shift() == 0); 5805 match(Set dst mem); 5806 5807 ins_cost(110); 5808 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5809 opcode(0x8D); 5810 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5811 ins_pipe(ialu_reg_reg_fat); 5812 %} 5813 5814 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5815 %{ 5816 predicate(Universe::narrow_oop_shift() == 0); 5817 match(Set dst mem); 5818 5819 ins_cost(110); 5820 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5821 opcode(0x8D); 5822 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5823 ins_pipe(ialu_reg_reg_fat); 5824 %} 5825 5826 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5827 %{ 5828 predicate(Universe::narrow_oop_shift() == 0); 5829 match(Set dst mem); 5830 5831 ins_cost(110); 5832 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5833 opcode(0x8D); 5834 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5835 ins_pipe(ialu_reg_reg_fat); 5836 %} 5837 5838 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5839 %{ 5840 predicate(Universe::narrow_oop_shift() == 0); 5841 match(Set dst mem); 5842 5843 ins_cost(110); 5844 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5845 opcode(0x8D); 5846 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5847 ins_pipe(ialu_reg_reg_fat); 5848 %} 5849 5850 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5851 %{ 5852 predicate(Universe::narrow_oop_shift() == 0); 5853 match(Set dst mem); 5854 5855 ins_cost(110); 5856 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5857 opcode(0x8D); 5858 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5859 ins_pipe(ialu_reg_reg_fat); 5860 %} 5861 5862 instruct loadConI(rRegI dst, immI src) 5863 %{ 5864 match(Set dst src); 5865 5866 format %{ "movl $dst, $src\t# int" %} 5867 ins_encode(load_immI(dst, src)); 5868 ins_pipe(ialu_reg_fat); // XXX 5869 %} 5870 5871 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5872 %{ 5873 match(Set dst src); 5874 effect(KILL cr); 5875 5876 ins_cost(50); 5877 format %{ "xorl $dst, $dst\t# int" %} 5878 opcode(0x33); /* + rd */ 5879 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5880 ins_pipe(ialu_reg); 5881 %} 5882 5883 instruct loadConL(rRegL dst, immL src) 5884 %{ 5885 match(Set dst src); 5886 5887 ins_cost(150); 5888 format %{ "movq $dst, $src\t# long" %} 5889 ins_encode(load_immL(dst, src)); 5890 ins_pipe(ialu_reg); 5891 %} 5892 5893 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5894 %{ 5895 match(Set dst src); 5896 effect(KILL cr); 5897 5898 ins_cost(50); 5899 format %{ "xorl $dst, $dst\t# long" %} 5900 opcode(0x33); /* + rd */ 5901 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5902 ins_pipe(ialu_reg); // XXX 5903 %} 5904 5905 instruct loadConUL32(rRegL dst, immUL32 src) 5906 %{ 5907 match(Set dst src); 5908 5909 ins_cost(60); 5910 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5911 ins_encode(load_immUL32(dst, src)); 5912 ins_pipe(ialu_reg); 5913 %} 5914 5915 instruct loadConL32(rRegL dst, immL32 src) 5916 %{ 5917 match(Set dst src); 5918 5919 ins_cost(70); 5920 format %{ "movq $dst, $src\t# long (32-bit)" %} 5921 ins_encode(load_immL32(dst, src)); 5922 ins_pipe(ialu_reg); 5923 %} 5924 5925 instruct loadConP(rRegP dst, immP con) %{ 5926 match(Set dst con); 5927 5928 format %{ "movq $dst, $con\t# ptr" %} 5929 ins_encode(load_immP(dst, con)); 5930 ins_pipe(ialu_reg_fat); // XXX 5931 %} 5932 5933 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5934 %{ 5935 match(Set dst src); 5936 effect(KILL cr); 5937 5938 ins_cost(50); 5939 format %{ "xorl $dst, $dst\t# ptr" %} 5940 opcode(0x33); /* + rd */ 5941 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5942 ins_pipe(ialu_reg); 5943 %} 5944 5945 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5946 %{ 5947 match(Set dst src); 5948 effect(KILL cr); 5949 5950 ins_cost(60); 5951 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5952 ins_encode(load_immP31(dst, src)); 5953 ins_pipe(ialu_reg); 5954 %} 5955 5956 instruct loadConF(regF dst, immF con) %{ 5957 match(Set dst con); 5958 ins_cost(125); 5959 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5960 ins_encode %{ 5961 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5962 %} 5963 ins_pipe(pipe_slow); 5964 %} 5965 5966 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5967 match(Set dst src); 5968 effect(KILL cr); 5969 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5970 ins_encode %{ 5971 __ xorq($dst$$Register, $dst$$Register); 5972 %} 5973 ins_pipe(ialu_reg); 5974 %} 5975 5976 instruct loadConN(rRegN dst, immN src) %{ 5977 match(Set dst src); 5978 5979 ins_cost(125); 5980 format %{ "movl $dst, $src\t# compressed ptr" %} 5981 ins_encode %{ 5982 address con = (address)$src$$constant; 5983 if (con == NULL) { 5984 ShouldNotReachHere(); 5985 } else { 5986 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5987 } 5988 %} 5989 ins_pipe(ialu_reg_fat); // XXX 5990 %} 5991 5992 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5993 match(Set dst src); 5994 5995 ins_cost(125); 5996 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5997 ins_encode %{ 5998 address con = (address)$src$$constant; 5999 if (con == NULL) { 6000 ShouldNotReachHere(); 6001 } else { 6002 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 6003 } 6004 %} 6005 ins_pipe(ialu_reg_fat); // XXX 6006 %} 6007 6008 instruct loadConF0(regF dst, immF0 src) 6009 %{ 6010 match(Set dst src); 6011 ins_cost(100); 6012 6013 format %{ "xorps $dst, $dst\t# float 0.0" %} 6014 ins_encode %{ 6015 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 6016 %} 6017 ins_pipe(pipe_slow); 6018 %} 6019 6020 // Use the same format since predicate() can not be used here. 6021 instruct loadConD(regD dst, immD con) %{ 6022 match(Set dst con); 6023 ins_cost(125); 6024 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 6025 ins_encode %{ 6026 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 6027 %} 6028 ins_pipe(pipe_slow); 6029 %} 6030 6031 instruct loadConD0(regD dst, immD0 src) 6032 %{ 6033 match(Set dst src); 6034 ins_cost(100); 6035 6036 format %{ "xorpd $dst, $dst\t# double 0.0" %} 6037 ins_encode %{ 6038 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 6039 %} 6040 ins_pipe(pipe_slow); 6041 %} 6042 6043 instruct loadSSI(rRegI dst, stackSlotI src) 6044 %{ 6045 match(Set dst src); 6046 6047 ins_cost(125); 6048 format %{ "movl $dst, $src\t# int stk" %} 6049 opcode(0x8B); 6050 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6051 ins_pipe(ialu_reg_mem); 6052 %} 6053 6054 instruct loadSSL(rRegL dst, stackSlotL src) 6055 %{ 6056 match(Set dst src); 6057 6058 ins_cost(125); 6059 format %{ "movq $dst, $src\t# long stk" %} 6060 opcode(0x8B); 6061 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6062 ins_pipe(ialu_reg_mem); 6063 %} 6064 6065 instruct loadSSP(rRegP dst, stackSlotP src) 6066 %{ 6067 match(Set dst src); 6068 6069 ins_cost(125); 6070 format %{ "movq $dst, $src\t# ptr stk" %} 6071 opcode(0x8B); 6072 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6073 ins_pipe(ialu_reg_mem); 6074 %} 6075 6076 instruct loadSSF(regF dst, stackSlotF src) 6077 %{ 6078 match(Set dst src); 6079 6080 ins_cost(125); 6081 format %{ "movss $dst, $src\t# float stk" %} 6082 ins_encode %{ 6083 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 6084 %} 6085 ins_pipe(pipe_slow); // XXX 6086 %} 6087 6088 // Use the same format since predicate() can not be used here. 6089 instruct loadSSD(regD dst, stackSlotD src) 6090 %{ 6091 match(Set dst src); 6092 6093 ins_cost(125); 6094 format %{ "movsd $dst, $src\t# double stk" %} 6095 ins_encode %{ 6096 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 6097 %} 6098 ins_pipe(pipe_slow); // XXX 6099 %} 6100 6101 // Prefetch instructions for allocation. 6102 // Must be safe to execute with invalid address (cannot fault). 6103 6104 instruct prefetchAlloc( memory mem ) %{ 6105 predicate(AllocatePrefetchInstr==3); 6106 match(PrefetchAllocation mem); 6107 ins_cost(125); 6108 6109 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 6110 ins_encode %{ 6111 __ prefetchw($mem$$Address); 6112 %} 6113 ins_pipe(ialu_mem); 6114 %} 6115 6116 instruct prefetchAllocNTA( memory mem ) %{ 6117 predicate(AllocatePrefetchInstr==0); 6118 match(PrefetchAllocation mem); 6119 ins_cost(125); 6120 6121 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 6122 ins_encode %{ 6123 __ prefetchnta($mem$$Address); 6124 %} 6125 ins_pipe(ialu_mem); 6126 %} 6127 6128 instruct prefetchAllocT0( memory mem ) %{ 6129 predicate(AllocatePrefetchInstr==1); 6130 match(PrefetchAllocation mem); 6131 ins_cost(125); 6132 6133 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 6134 ins_encode %{ 6135 __ prefetcht0($mem$$Address); 6136 %} 6137 ins_pipe(ialu_mem); 6138 %} 6139 6140 instruct prefetchAllocT2( memory mem ) %{ 6141 predicate(AllocatePrefetchInstr==2); 6142 match(PrefetchAllocation mem); 6143 ins_cost(125); 6144 6145 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 6146 ins_encode %{ 6147 __ prefetcht2($mem$$Address); 6148 %} 6149 ins_pipe(ialu_mem); 6150 %} 6151 6152 //----------Store Instructions------------------------------------------------- 6153 6154 // Store Byte 6155 instruct storeB(memory mem, rRegI src) 6156 %{ 6157 match(Set mem (StoreB mem src)); 6158 6159 ins_cost(125); // XXX 6160 format %{ "movb $mem, $src\t# byte" %} 6161 opcode(0x88); 6162 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6163 ins_pipe(ialu_mem_reg); 6164 %} 6165 6166 // Store Char/Short 6167 instruct storeC(memory mem, rRegI src) 6168 %{ 6169 match(Set mem (StoreC mem src)); 6170 6171 ins_cost(125); // XXX 6172 format %{ "movw $mem, $src\t# char/short" %} 6173 opcode(0x89); 6174 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6175 ins_pipe(ialu_mem_reg); 6176 %} 6177 6178 // Store Integer 6179 instruct storeI(memory mem, rRegI src) 6180 %{ 6181 match(Set mem (StoreI mem src)); 6182 6183 ins_cost(125); // XXX 6184 format %{ "movl $mem, $src\t# int" %} 6185 opcode(0x89); 6186 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6187 ins_pipe(ialu_mem_reg); 6188 %} 6189 6190 // Store Long 6191 instruct storeL(memory mem, rRegL src) 6192 %{ 6193 match(Set mem (StoreL mem src)); 6194 6195 ins_cost(125); // XXX 6196 format %{ "movq $mem, $src\t# long" %} 6197 opcode(0x89); 6198 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6199 ins_pipe(ialu_mem_reg); // XXX 6200 %} 6201 6202 // Store Pointer 6203 instruct storeP(memory mem, any_RegP src) 6204 %{ 6205 match(Set mem (StoreP mem src)); 6206 6207 ins_cost(125); // XXX 6208 format %{ "movq $mem, $src\t# ptr" %} 6209 opcode(0x89); 6210 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6211 ins_pipe(ialu_mem_reg); 6212 %} 6213 6214 instruct storeImmP0(memory mem, immP0 zero) 6215 %{ 6216 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6217 match(Set mem (StoreP mem zero)); 6218 6219 ins_cost(125); // XXX 6220 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6221 ins_encode %{ 6222 __ movq($mem$$Address, r12); 6223 %} 6224 ins_pipe(ialu_mem_reg); 6225 %} 6226 6227 // Store NULL Pointer, mark word, or other simple pointer constant. 6228 instruct storeImmP(memory mem, immP31 src) 6229 %{ 6230 match(Set mem (StoreP mem src)); 6231 6232 ins_cost(150); // XXX 6233 format %{ "movq $mem, $src\t# ptr" %} 6234 opcode(0xC7); /* C7 /0 */ 6235 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6236 ins_pipe(ialu_mem_imm); 6237 %} 6238 6239 // Store Compressed Pointer 6240 instruct storeN(memory mem, rRegN src) 6241 %{ 6242 match(Set mem (StoreN mem src)); 6243 6244 ins_cost(125); // XXX 6245 format %{ "movl $mem, $src\t# compressed ptr" %} 6246 ins_encode %{ 6247 __ movl($mem$$Address, $src$$Register); 6248 %} 6249 ins_pipe(ialu_mem_reg); 6250 %} 6251 6252 instruct storeNKlass(memory mem, rRegN src) 6253 %{ 6254 match(Set mem (StoreNKlass mem src)); 6255 6256 ins_cost(125); // XXX 6257 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6258 ins_encode %{ 6259 __ movl($mem$$Address, $src$$Register); 6260 %} 6261 ins_pipe(ialu_mem_reg); 6262 %} 6263 6264 instruct storeImmN0(memory mem, immN0 zero) 6265 %{ 6266 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 6267 match(Set mem (StoreN mem zero)); 6268 6269 ins_cost(125); // XXX 6270 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6271 ins_encode %{ 6272 __ movl($mem$$Address, r12); 6273 %} 6274 ins_pipe(ialu_mem_reg); 6275 %} 6276 6277 instruct storeImmN(memory mem, immN src) 6278 %{ 6279 match(Set mem (StoreN mem src)); 6280 6281 ins_cost(150); // XXX 6282 format %{ "movl $mem, $src\t# compressed ptr" %} 6283 ins_encode %{ 6284 address con = (address)$src$$constant; 6285 if (con == NULL) { 6286 __ movl($mem$$Address, (int32_t)0); 6287 } else { 6288 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6289 } 6290 %} 6291 ins_pipe(ialu_mem_imm); 6292 %} 6293 6294 instruct storeImmNKlass(memory mem, immNKlass src) 6295 %{ 6296 match(Set mem (StoreNKlass mem src)); 6297 6298 ins_cost(150); // XXX 6299 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6300 ins_encode %{ 6301 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6302 %} 6303 ins_pipe(ialu_mem_imm); 6304 %} 6305 6306 // Store Integer Immediate 6307 instruct storeImmI0(memory mem, immI0 zero) 6308 %{ 6309 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6310 match(Set mem (StoreI mem zero)); 6311 6312 ins_cost(125); // XXX 6313 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6314 ins_encode %{ 6315 __ movl($mem$$Address, r12); 6316 %} 6317 ins_pipe(ialu_mem_reg); 6318 %} 6319 6320 instruct storeImmI(memory mem, immI src) 6321 %{ 6322 match(Set mem (StoreI mem src)); 6323 6324 ins_cost(150); 6325 format %{ "movl $mem, $src\t# int" %} 6326 opcode(0xC7); /* C7 /0 */ 6327 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6328 ins_pipe(ialu_mem_imm); 6329 %} 6330 6331 // Store Long Immediate 6332 instruct storeImmL0(memory mem, immL0 zero) 6333 %{ 6334 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6335 match(Set mem (StoreL mem zero)); 6336 6337 ins_cost(125); // XXX 6338 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6339 ins_encode %{ 6340 __ movq($mem$$Address, r12); 6341 %} 6342 ins_pipe(ialu_mem_reg); 6343 %} 6344 6345 instruct storeImmL(memory mem, immL32 src) 6346 %{ 6347 match(Set mem (StoreL mem src)); 6348 6349 ins_cost(150); 6350 format %{ "movq $mem, $src\t# long" %} 6351 opcode(0xC7); /* C7 /0 */ 6352 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6353 ins_pipe(ialu_mem_imm); 6354 %} 6355 6356 // Store Short/Char Immediate 6357 instruct storeImmC0(memory mem, immI0 zero) 6358 %{ 6359 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6360 match(Set mem (StoreC mem zero)); 6361 6362 ins_cost(125); // XXX 6363 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6364 ins_encode %{ 6365 __ movw($mem$$Address, r12); 6366 %} 6367 ins_pipe(ialu_mem_reg); 6368 %} 6369 6370 instruct storeImmI16(memory mem, immI16 src) 6371 %{ 6372 predicate(UseStoreImmI16); 6373 match(Set mem (StoreC mem src)); 6374 6375 ins_cost(150); 6376 format %{ "movw $mem, $src\t# short/char" %} 6377 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6378 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6379 ins_pipe(ialu_mem_imm); 6380 %} 6381 6382 // Store Byte Immediate 6383 instruct storeImmB0(memory mem, immI0 zero) 6384 %{ 6385 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6386 match(Set mem (StoreB mem zero)); 6387 6388 ins_cost(125); // XXX 6389 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6390 ins_encode %{ 6391 __ movb($mem$$Address, r12); 6392 %} 6393 ins_pipe(ialu_mem_reg); 6394 %} 6395 6396 instruct storeImmB(memory mem, immI8 src) 6397 %{ 6398 match(Set mem (StoreB mem src)); 6399 6400 ins_cost(150); // XXX 6401 format %{ "movb $mem, $src\t# byte" %} 6402 opcode(0xC6); /* C6 /0 */ 6403 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6404 ins_pipe(ialu_mem_imm); 6405 %} 6406 6407 // Store CMS card-mark Immediate 6408 instruct storeImmCM0_reg(memory mem, immI0 zero) 6409 %{ 6410 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6411 match(Set mem (StoreCM mem zero)); 6412 6413 ins_cost(125); // XXX 6414 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6415 ins_encode %{ 6416 __ movb($mem$$Address, r12); 6417 %} 6418 ins_pipe(ialu_mem_reg); 6419 %} 6420 6421 instruct storeImmCM0(memory mem, immI0 src) 6422 %{ 6423 match(Set mem (StoreCM mem src)); 6424 6425 ins_cost(150); // XXX 6426 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6427 opcode(0xC6); /* C6 /0 */ 6428 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6429 ins_pipe(ialu_mem_imm); 6430 %} 6431 6432 // Store Float 6433 instruct storeF(memory mem, regF src) 6434 %{ 6435 match(Set mem (StoreF mem src)); 6436 6437 ins_cost(95); // XXX 6438 format %{ "movss $mem, $src\t# float" %} 6439 ins_encode %{ 6440 __ movflt($mem$$Address, $src$$XMMRegister); 6441 %} 6442 ins_pipe(pipe_slow); // XXX 6443 %} 6444 6445 // Store immediate Float value (it is faster than store from XMM register) 6446 instruct storeF0(memory mem, immF0 zero) 6447 %{ 6448 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6449 match(Set mem (StoreF mem zero)); 6450 6451 ins_cost(25); // XXX 6452 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6453 ins_encode %{ 6454 __ movl($mem$$Address, r12); 6455 %} 6456 ins_pipe(ialu_mem_reg); 6457 %} 6458 6459 instruct storeF_imm(memory mem, immF src) 6460 %{ 6461 match(Set mem (StoreF mem src)); 6462 6463 ins_cost(50); 6464 format %{ "movl $mem, $src\t# float" %} 6465 opcode(0xC7); /* C7 /0 */ 6466 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6467 ins_pipe(ialu_mem_imm); 6468 %} 6469 6470 // Store Double 6471 instruct storeD(memory mem, regD src) 6472 %{ 6473 match(Set mem (StoreD mem src)); 6474 6475 ins_cost(95); // XXX 6476 format %{ "movsd $mem, $src\t# double" %} 6477 ins_encode %{ 6478 __ movdbl($mem$$Address, $src$$XMMRegister); 6479 %} 6480 ins_pipe(pipe_slow); // XXX 6481 %} 6482 6483 // Store immediate double 0.0 (it is faster than store from XMM register) 6484 instruct storeD0_imm(memory mem, immD0 src) 6485 %{ 6486 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6487 match(Set mem (StoreD mem src)); 6488 6489 ins_cost(50); 6490 format %{ "movq $mem, $src\t# double 0." %} 6491 opcode(0xC7); /* C7 /0 */ 6492 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6493 ins_pipe(ialu_mem_imm); 6494 %} 6495 6496 instruct storeD0(memory mem, immD0 zero) 6497 %{ 6498 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6499 match(Set mem (StoreD mem zero)); 6500 6501 ins_cost(25); // XXX 6502 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6503 ins_encode %{ 6504 __ movq($mem$$Address, r12); 6505 %} 6506 ins_pipe(ialu_mem_reg); 6507 %} 6508 6509 instruct storeSSI(stackSlotI dst, rRegI src) 6510 %{ 6511 match(Set dst src); 6512 6513 ins_cost(100); 6514 format %{ "movl $dst, $src\t# int stk" %} 6515 opcode(0x89); 6516 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6517 ins_pipe( ialu_mem_reg ); 6518 %} 6519 6520 instruct storeSSL(stackSlotL dst, rRegL src) 6521 %{ 6522 match(Set dst src); 6523 6524 ins_cost(100); 6525 format %{ "movq $dst, $src\t# long stk" %} 6526 opcode(0x89); 6527 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6528 ins_pipe(ialu_mem_reg); 6529 %} 6530 6531 instruct storeSSP(stackSlotP dst, rRegP src) 6532 %{ 6533 match(Set dst src); 6534 6535 ins_cost(100); 6536 format %{ "movq $dst, $src\t# ptr stk" %} 6537 opcode(0x89); 6538 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6539 ins_pipe(ialu_mem_reg); 6540 %} 6541 6542 instruct storeSSF(stackSlotF dst, regF src) 6543 %{ 6544 match(Set dst src); 6545 6546 ins_cost(95); // XXX 6547 format %{ "movss $dst, $src\t# float stk" %} 6548 ins_encode %{ 6549 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6550 %} 6551 ins_pipe(pipe_slow); // XXX 6552 %} 6553 6554 instruct storeSSD(stackSlotD dst, regD src) 6555 %{ 6556 match(Set dst src); 6557 6558 ins_cost(95); // XXX 6559 format %{ "movsd $dst, $src\t# double stk" %} 6560 ins_encode %{ 6561 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6562 %} 6563 ins_pipe(pipe_slow); // XXX 6564 %} 6565 6566 //----------BSWAP Instructions------------------------------------------------- 6567 instruct bytes_reverse_int(rRegI dst) %{ 6568 match(Set dst (ReverseBytesI dst)); 6569 6570 format %{ "bswapl $dst" %} 6571 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6572 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6573 ins_pipe( ialu_reg ); 6574 %} 6575 6576 instruct bytes_reverse_long(rRegL dst) %{ 6577 match(Set dst (ReverseBytesL dst)); 6578 6579 format %{ "bswapq $dst" %} 6580 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6581 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6582 ins_pipe( ialu_reg); 6583 %} 6584 6585 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6586 match(Set dst (ReverseBytesUS dst)); 6587 effect(KILL cr); 6588 6589 format %{ "bswapl $dst\n\t" 6590 "shrl $dst,16\n\t" %} 6591 ins_encode %{ 6592 __ bswapl($dst$$Register); 6593 __ shrl($dst$$Register, 16); 6594 %} 6595 ins_pipe( ialu_reg ); 6596 %} 6597 6598 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6599 match(Set dst (ReverseBytesS dst)); 6600 effect(KILL cr); 6601 6602 format %{ "bswapl $dst\n\t" 6603 "sar $dst,16\n\t" %} 6604 ins_encode %{ 6605 __ bswapl($dst$$Register); 6606 __ sarl($dst$$Register, 16); 6607 %} 6608 ins_pipe( ialu_reg ); 6609 %} 6610 6611 //---------- Zeros Count Instructions ------------------------------------------ 6612 6613 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6614 predicate(UseCountLeadingZerosInstruction); 6615 match(Set dst (CountLeadingZerosI src)); 6616 effect(KILL cr); 6617 6618 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6619 ins_encode %{ 6620 __ lzcntl($dst$$Register, $src$$Register); 6621 %} 6622 ins_pipe(ialu_reg); 6623 %} 6624 6625 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6626 predicate(!UseCountLeadingZerosInstruction); 6627 match(Set dst (CountLeadingZerosI src)); 6628 effect(KILL cr); 6629 6630 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6631 "jnz skip\n\t" 6632 "movl $dst, -1\n" 6633 "skip:\n\t" 6634 "negl $dst\n\t" 6635 "addl $dst, 31" %} 6636 ins_encode %{ 6637 Register Rdst = $dst$$Register; 6638 Register Rsrc = $src$$Register; 6639 Label skip; 6640 __ bsrl(Rdst, Rsrc); 6641 __ jccb(Assembler::notZero, skip); 6642 __ movl(Rdst, -1); 6643 __ bind(skip); 6644 __ negl(Rdst); 6645 __ addl(Rdst, BitsPerInt - 1); 6646 %} 6647 ins_pipe(ialu_reg); 6648 %} 6649 6650 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6651 predicate(UseCountLeadingZerosInstruction); 6652 match(Set dst (CountLeadingZerosL src)); 6653 effect(KILL cr); 6654 6655 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6656 ins_encode %{ 6657 __ lzcntq($dst$$Register, $src$$Register); 6658 %} 6659 ins_pipe(ialu_reg); 6660 %} 6661 6662 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6663 predicate(!UseCountLeadingZerosInstruction); 6664 match(Set dst (CountLeadingZerosL src)); 6665 effect(KILL cr); 6666 6667 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6668 "jnz skip\n\t" 6669 "movl $dst, -1\n" 6670 "skip:\n\t" 6671 "negl $dst\n\t" 6672 "addl $dst, 63" %} 6673 ins_encode %{ 6674 Register Rdst = $dst$$Register; 6675 Register Rsrc = $src$$Register; 6676 Label skip; 6677 __ bsrq(Rdst, Rsrc); 6678 __ jccb(Assembler::notZero, skip); 6679 __ movl(Rdst, -1); 6680 __ bind(skip); 6681 __ negl(Rdst); 6682 __ addl(Rdst, BitsPerLong - 1); 6683 %} 6684 ins_pipe(ialu_reg); 6685 %} 6686 6687 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6688 predicate(UseCountTrailingZerosInstruction); 6689 match(Set dst (CountTrailingZerosI src)); 6690 effect(KILL cr); 6691 6692 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6693 ins_encode %{ 6694 __ tzcntl($dst$$Register, $src$$Register); 6695 %} 6696 ins_pipe(ialu_reg); 6697 %} 6698 6699 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6700 predicate(!UseCountTrailingZerosInstruction); 6701 match(Set dst (CountTrailingZerosI src)); 6702 effect(KILL cr); 6703 6704 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6705 "jnz done\n\t" 6706 "movl $dst, 32\n" 6707 "done:" %} 6708 ins_encode %{ 6709 Register Rdst = $dst$$Register; 6710 Label done; 6711 __ bsfl(Rdst, $src$$Register); 6712 __ jccb(Assembler::notZero, done); 6713 __ movl(Rdst, BitsPerInt); 6714 __ bind(done); 6715 %} 6716 ins_pipe(ialu_reg); 6717 %} 6718 6719 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6720 predicate(UseCountTrailingZerosInstruction); 6721 match(Set dst (CountTrailingZerosL src)); 6722 effect(KILL cr); 6723 6724 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6725 ins_encode %{ 6726 __ tzcntq($dst$$Register, $src$$Register); 6727 %} 6728 ins_pipe(ialu_reg); 6729 %} 6730 6731 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6732 predicate(!UseCountTrailingZerosInstruction); 6733 match(Set dst (CountTrailingZerosL src)); 6734 effect(KILL cr); 6735 6736 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6737 "jnz done\n\t" 6738 "movl $dst, 64\n" 6739 "done:" %} 6740 ins_encode %{ 6741 Register Rdst = $dst$$Register; 6742 Label done; 6743 __ bsfq(Rdst, $src$$Register); 6744 __ jccb(Assembler::notZero, done); 6745 __ movl(Rdst, BitsPerLong); 6746 __ bind(done); 6747 %} 6748 ins_pipe(ialu_reg); 6749 %} 6750 6751 6752 //---------- Population Count Instructions ------------------------------------- 6753 6754 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6755 predicate(UsePopCountInstruction); 6756 match(Set dst (PopCountI src)); 6757 effect(KILL cr); 6758 6759 format %{ "popcnt $dst, $src" %} 6760 ins_encode %{ 6761 __ popcntl($dst$$Register, $src$$Register); 6762 %} 6763 ins_pipe(ialu_reg); 6764 %} 6765 6766 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6767 predicate(UsePopCountInstruction); 6768 match(Set dst (PopCountI (LoadI mem))); 6769 effect(KILL cr); 6770 6771 format %{ "popcnt $dst, $mem" %} 6772 ins_encode %{ 6773 __ popcntl($dst$$Register, $mem$$Address); 6774 %} 6775 ins_pipe(ialu_reg); 6776 %} 6777 6778 // Note: Long.bitCount(long) returns an int. 6779 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6780 predicate(UsePopCountInstruction); 6781 match(Set dst (PopCountL src)); 6782 effect(KILL cr); 6783 6784 format %{ "popcnt $dst, $src" %} 6785 ins_encode %{ 6786 __ popcntq($dst$$Register, $src$$Register); 6787 %} 6788 ins_pipe(ialu_reg); 6789 %} 6790 6791 // Note: Long.bitCount(long) returns an int. 6792 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6793 predicate(UsePopCountInstruction); 6794 match(Set dst (PopCountL (LoadL mem))); 6795 effect(KILL cr); 6796 6797 format %{ "popcnt $dst, $mem" %} 6798 ins_encode %{ 6799 __ popcntq($dst$$Register, $mem$$Address); 6800 %} 6801 ins_pipe(ialu_reg); 6802 %} 6803 6804 6805 //----------MemBar Instructions----------------------------------------------- 6806 // Memory barrier flavors 6807 6808 instruct membar_acquire() 6809 %{ 6810 match(MemBarAcquire); 6811 match(LoadFence); 6812 ins_cost(0); 6813 6814 size(0); 6815 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6816 ins_encode(); 6817 ins_pipe(empty); 6818 %} 6819 6820 instruct membar_acquire_lock() 6821 %{ 6822 match(MemBarAcquireLock); 6823 ins_cost(0); 6824 6825 size(0); 6826 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6827 ins_encode(); 6828 ins_pipe(empty); 6829 %} 6830 6831 instruct membar_release() 6832 %{ 6833 match(MemBarRelease); 6834 match(StoreFence); 6835 ins_cost(0); 6836 6837 size(0); 6838 format %{ "MEMBAR-release ! (empty encoding)" %} 6839 ins_encode(); 6840 ins_pipe(empty); 6841 %} 6842 6843 instruct membar_release_lock() 6844 %{ 6845 match(MemBarReleaseLock); 6846 ins_cost(0); 6847 6848 size(0); 6849 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6850 ins_encode(); 6851 ins_pipe(empty); 6852 %} 6853 6854 instruct membar_volatile(rFlagsReg cr) %{ 6855 match(MemBarVolatile); 6856 effect(KILL cr); 6857 ins_cost(400); 6858 6859 format %{ 6860 $$template 6861 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6862 %} 6863 ins_encode %{ 6864 __ membar(Assembler::StoreLoad); 6865 %} 6866 ins_pipe(pipe_slow); 6867 %} 6868 6869 instruct unnecessary_membar_volatile() 6870 %{ 6871 match(MemBarVolatile); 6872 predicate(Matcher::post_store_load_barrier(n)); 6873 ins_cost(0); 6874 6875 size(0); 6876 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6877 ins_encode(); 6878 ins_pipe(empty); 6879 %} 6880 6881 instruct membar_storestore() %{ 6882 match(MemBarStoreStore); 6883 ins_cost(0); 6884 6885 size(0); 6886 format %{ "MEMBAR-storestore (empty encoding)" %} 6887 ins_encode( ); 6888 ins_pipe(empty); 6889 %} 6890 6891 //----------Move Instructions-------------------------------------------------- 6892 6893 instruct castX2P(rRegP dst, rRegL src) 6894 %{ 6895 match(Set dst (CastX2P src)); 6896 6897 format %{ "movq $dst, $src\t# long->ptr" %} 6898 ins_encode %{ 6899 if ($dst$$reg != $src$$reg) { 6900 __ movptr($dst$$Register, $src$$Register); 6901 } 6902 %} 6903 ins_pipe(ialu_reg_reg); // XXX 6904 %} 6905 6906 instruct castP2X(rRegL dst, rRegP src) 6907 %{ 6908 match(Set dst (CastP2X src)); 6909 6910 format %{ "movq $dst, $src\t# ptr -> long" %} 6911 ins_encode %{ 6912 if ($dst$$reg != $src$$reg) { 6913 __ movptr($dst$$Register, $src$$Register); 6914 } 6915 %} 6916 ins_pipe(ialu_reg_reg); // XXX 6917 %} 6918 6919 // Convert oop into int for vectors alignment masking 6920 instruct convP2I(rRegI dst, rRegP src) 6921 %{ 6922 match(Set dst (ConvL2I (CastP2X src))); 6923 6924 format %{ "movl $dst, $src\t# ptr -> int" %} 6925 ins_encode %{ 6926 __ movl($dst$$Register, $src$$Register); 6927 %} 6928 ins_pipe(ialu_reg_reg); // XXX 6929 %} 6930 6931 // Convert compressed oop into int for vectors alignment masking 6932 // in case of 32bit oops (heap < 4Gb). 6933 instruct convN2I(rRegI dst, rRegN src) 6934 %{ 6935 predicate(Universe::narrow_oop_shift() == 0); 6936 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6937 6938 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6939 ins_encode %{ 6940 __ movl($dst$$Register, $src$$Register); 6941 %} 6942 ins_pipe(ialu_reg_reg); // XXX 6943 %} 6944 6945 // Convert oop pointer into compressed form 6946 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6947 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6948 match(Set dst (EncodeP src)); 6949 effect(KILL cr); 6950 format %{ "encode_heap_oop $dst,$src" %} 6951 ins_encode %{ 6952 Register s = $src$$Register; 6953 Register d = $dst$$Register; 6954 if (s != d) { 6955 __ movq(d, s); 6956 } 6957 __ encode_heap_oop(d); 6958 %} 6959 ins_pipe(ialu_reg_long); 6960 %} 6961 6962 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6963 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6964 match(Set dst (EncodeP src)); 6965 effect(KILL cr); 6966 format %{ "encode_heap_oop_not_null $dst,$src" %} 6967 ins_encode %{ 6968 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6969 %} 6970 ins_pipe(ialu_reg_long); 6971 %} 6972 6973 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6974 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6975 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6976 match(Set dst (DecodeN src)); 6977 effect(KILL cr); 6978 format %{ "decode_heap_oop $dst,$src" %} 6979 ins_encode %{ 6980 Register s = $src$$Register; 6981 Register d = $dst$$Register; 6982 if (s != d) { 6983 __ movq(d, s); 6984 } 6985 __ decode_heap_oop(d); 6986 %} 6987 ins_pipe(ialu_reg_long); 6988 %} 6989 6990 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6991 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6992 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6993 match(Set dst (DecodeN src)); 6994 effect(KILL cr); 6995 format %{ "decode_heap_oop_not_null $dst,$src" %} 6996 ins_encode %{ 6997 Register s = $src$$Register; 6998 Register d = $dst$$Register; 6999 if (s != d) { 7000 __ decode_heap_oop_not_null(d, s); 7001 } else { 7002 __ decode_heap_oop_not_null(d); 7003 } 7004 %} 7005 ins_pipe(ialu_reg_long); 7006 %} 7007 7008 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7009 match(Set dst (EncodePKlass src)); 7010 effect(KILL cr); 7011 format %{ "encode_klass_not_null $dst,$src" %} 7012 ins_encode %{ 7013 __ encode_klass_not_null($dst$$Register, $src$$Register); 7014 %} 7015 ins_pipe(ialu_reg_long); 7016 %} 7017 7018 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7019 match(Set dst (DecodeNKlass src)); 7020 effect(KILL cr); 7021 format %{ "decode_klass_not_null $dst,$src" %} 7022 ins_encode %{ 7023 Register s = $src$$Register; 7024 Register d = $dst$$Register; 7025 if (s != d) { 7026 __ decode_klass_not_null(d, s); 7027 } else { 7028 __ decode_klass_not_null(d); 7029 } 7030 %} 7031 ins_pipe(ialu_reg_long); 7032 %} 7033 7034 7035 //----------Conditional Move--------------------------------------------------- 7036 // Jump 7037 // dummy instruction for generating temp registers 7038 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7039 match(Jump (LShiftL switch_val shift)); 7040 ins_cost(350); 7041 predicate(false); 7042 effect(TEMP dest); 7043 7044 format %{ "leaq $dest, [$constantaddress]\n\t" 7045 "jmp [$dest + $switch_val << $shift]\n\t" %} 7046 ins_encode %{ 7047 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7048 // to do that and the compiler is using that register as one it can allocate. 7049 // So we build it all by hand. 7050 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 7051 // ArrayAddress dispatch(table, index); 7052 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 7053 __ lea($dest$$Register, $constantaddress); 7054 __ jmp(dispatch); 7055 %} 7056 ins_pipe(pipe_jmp); 7057 %} 7058 7059 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7060 match(Jump (AddL (LShiftL switch_val shift) offset)); 7061 ins_cost(350); 7062 effect(TEMP dest); 7063 7064 format %{ "leaq $dest, [$constantaddress]\n\t" 7065 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7066 ins_encode %{ 7067 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7068 // to do that and the compiler is using that register as one it can allocate. 7069 // So we build it all by hand. 7070 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7071 // ArrayAddress dispatch(table, index); 7072 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7073 __ lea($dest$$Register, $constantaddress); 7074 __ jmp(dispatch); 7075 %} 7076 ins_pipe(pipe_jmp); 7077 %} 7078 7079 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7080 match(Jump switch_val); 7081 ins_cost(350); 7082 effect(TEMP dest); 7083 7084 format %{ "leaq $dest, [$constantaddress]\n\t" 7085 "jmp [$dest + $switch_val]\n\t" %} 7086 ins_encode %{ 7087 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7088 // to do that and the compiler is using that register as one it can allocate. 7089 // So we build it all by hand. 7090 // Address index(noreg, switch_reg, Address::times_1); 7091 // ArrayAddress dispatch(table, index); 7092 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 7093 __ lea($dest$$Register, $constantaddress); 7094 __ jmp(dispatch); 7095 %} 7096 ins_pipe(pipe_jmp); 7097 %} 7098 7099 // Conditional move 7100 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 7101 %{ 7102 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7103 7104 ins_cost(200); // XXX 7105 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7106 opcode(0x0F, 0x40); 7107 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7108 ins_pipe(pipe_cmov_reg); 7109 %} 7110 7111 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 7112 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7113 7114 ins_cost(200); // XXX 7115 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7116 opcode(0x0F, 0x40); 7117 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7118 ins_pipe(pipe_cmov_reg); 7119 %} 7120 7121 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 7122 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7123 ins_cost(200); 7124 expand %{ 7125 cmovI_regU(cop, cr, dst, src); 7126 %} 7127 %} 7128 7129 // Conditional move 7130 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7131 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7132 7133 ins_cost(250); // XXX 7134 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7135 opcode(0x0F, 0x40); 7136 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7137 ins_pipe(pipe_cmov_mem); 7138 %} 7139 7140 // Conditional move 7141 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7142 %{ 7143 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7144 7145 ins_cost(250); // XXX 7146 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7147 opcode(0x0F, 0x40); 7148 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7149 ins_pipe(pipe_cmov_mem); 7150 %} 7151 7152 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7153 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7154 ins_cost(250); 7155 expand %{ 7156 cmovI_memU(cop, cr, dst, src); 7157 %} 7158 %} 7159 7160 // Conditional move 7161 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7162 %{ 7163 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7164 7165 ins_cost(200); // XXX 7166 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7167 opcode(0x0F, 0x40); 7168 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7169 ins_pipe(pipe_cmov_reg); 7170 %} 7171 7172 // Conditional move 7173 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7174 %{ 7175 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7176 7177 ins_cost(200); // XXX 7178 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7179 opcode(0x0F, 0x40); 7180 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7181 ins_pipe(pipe_cmov_reg); 7182 %} 7183 7184 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7185 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7186 ins_cost(200); 7187 expand %{ 7188 cmovN_regU(cop, cr, dst, src); 7189 %} 7190 %} 7191 7192 // Conditional move 7193 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7194 %{ 7195 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7196 7197 ins_cost(200); // XXX 7198 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7199 opcode(0x0F, 0x40); 7200 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7201 ins_pipe(pipe_cmov_reg); // XXX 7202 %} 7203 7204 // Conditional move 7205 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7206 %{ 7207 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7208 7209 ins_cost(200); // XXX 7210 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7211 opcode(0x0F, 0x40); 7212 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7213 ins_pipe(pipe_cmov_reg); // XXX 7214 %} 7215 7216 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7217 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7218 ins_cost(200); 7219 expand %{ 7220 cmovP_regU(cop, cr, dst, src); 7221 %} 7222 %} 7223 7224 // DISABLED: Requires the ADLC to emit a bottom_type call that 7225 // correctly meets the two pointer arguments; one is an incoming 7226 // register but the other is a memory operand. ALSO appears to 7227 // be buggy with implicit null checks. 7228 // 7229 //// Conditional move 7230 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7231 //%{ 7232 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7233 // ins_cost(250); 7234 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7235 // opcode(0x0F,0x40); 7236 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7237 // ins_pipe( pipe_cmov_mem ); 7238 //%} 7239 // 7240 //// Conditional move 7241 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7242 //%{ 7243 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7244 // ins_cost(250); 7245 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7246 // opcode(0x0F,0x40); 7247 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7248 // ins_pipe( pipe_cmov_mem ); 7249 //%} 7250 7251 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7252 %{ 7253 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7254 7255 ins_cost(200); // XXX 7256 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7257 opcode(0x0F, 0x40); 7258 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7259 ins_pipe(pipe_cmov_reg); // XXX 7260 %} 7261 7262 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7263 %{ 7264 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7265 7266 ins_cost(200); // XXX 7267 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7268 opcode(0x0F, 0x40); 7269 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7270 ins_pipe(pipe_cmov_mem); // XXX 7271 %} 7272 7273 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7274 %{ 7275 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7276 7277 ins_cost(200); // XXX 7278 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7279 opcode(0x0F, 0x40); 7280 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7281 ins_pipe(pipe_cmov_reg); // XXX 7282 %} 7283 7284 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7285 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7286 ins_cost(200); 7287 expand %{ 7288 cmovL_regU(cop, cr, dst, src); 7289 %} 7290 %} 7291 7292 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7293 %{ 7294 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7295 7296 ins_cost(200); // XXX 7297 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7298 opcode(0x0F, 0x40); 7299 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7300 ins_pipe(pipe_cmov_mem); // XXX 7301 %} 7302 7303 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7304 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7305 ins_cost(200); 7306 expand %{ 7307 cmovL_memU(cop, cr, dst, src); 7308 %} 7309 %} 7310 7311 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7312 %{ 7313 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7314 7315 ins_cost(200); // XXX 7316 format %{ "jn$cop skip\t# signed cmove float\n\t" 7317 "movss $dst, $src\n" 7318 "skip:" %} 7319 ins_encode %{ 7320 Label Lskip; 7321 // Invert sense of branch from sense of CMOV 7322 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7323 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7324 __ bind(Lskip); 7325 %} 7326 ins_pipe(pipe_slow); 7327 %} 7328 7329 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7330 // %{ 7331 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL 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(enc_cmovf_mem_branch(cop, dst, src)); 7338 // ins_pipe(pipe_slow); 7339 // %} 7340 7341 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7342 %{ 7343 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7344 7345 ins_cost(200); // XXX 7346 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7347 "movss $dst, $src\n" 7348 "skip:" %} 7349 ins_encode %{ 7350 Label Lskip; 7351 // Invert sense of branch from sense of CMOV 7352 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7353 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7354 __ bind(Lskip); 7355 %} 7356 ins_pipe(pipe_slow); 7357 %} 7358 7359 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7360 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7361 ins_cost(200); 7362 expand %{ 7363 cmovF_regU(cop, cr, dst, src); 7364 %} 7365 %} 7366 7367 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7368 %{ 7369 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7370 7371 ins_cost(200); // XXX 7372 format %{ "jn$cop skip\t# signed cmove double\n\t" 7373 "movsd $dst, $src\n" 7374 "skip:" %} 7375 ins_encode %{ 7376 Label Lskip; 7377 // Invert sense of branch from sense of CMOV 7378 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7379 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7380 __ bind(Lskip); 7381 %} 7382 ins_pipe(pipe_slow); 7383 %} 7384 7385 instruct cmovD_regU(cmpOpU cop, rFlagsRegU 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# unsigned 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_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7404 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7405 ins_cost(200); 7406 expand %{ 7407 cmovD_regU(cop, cr, dst, src); 7408 %} 7409 %} 7410 7411 //----------Arithmetic Instructions-------------------------------------------- 7412 //----------Addition Instructions---------------------------------------------- 7413 7414 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7415 %{ 7416 match(Set dst (AddI dst src)); 7417 effect(KILL cr); 7418 7419 format %{ "addl $dst, $src\t# int" %} 7420 opcode(0x03); 7421 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7422 ins_pipe(ialu_reg_reg); 7423 %} 7424 7425 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7426 %{ 7427 match(Set dst (AddI dst src)); 7428 effect(KILL cr); 7429 7430 format %{ "addl $dst, $src\t# int" %} 7431 opcode(0x81, 0x00); /* /0 id */ 7432 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7433 ins_pipe( ialu_reg ); 7434 %} 7435 7436 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7437 %{ 7438 match(Set dst (AddI dst (LoadI src))); 7439 effect(KILL cr); 7440 7441 ins_cost(125); // XXX 7442 format %{ "addl $dst, $src\t# int" %} 7443 opcode(0x03); 7444 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7445 ins_pipe(ialu_reg_mem); 7446 %} 7447 7448 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7449 %{ 7450 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7451 effect(KILL cr); 7452 7453 ins_cost(150); // XXX 7454 format %{ "addl $dst, $src\t# int" %} 7455 opcode(0x01); /* Opcode 01 /r */ 7456 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7457 ins_pipe(ialu_mem_reg); 7458 %} 7459 7460 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7461 %{ 7462 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7463 effect(KILL cr); 7464 7465 ins_cost(125); // XXX 7466 format %{ "addl $dst, $src\t# int" %} 7467 opcode(0x81); /* Opcode 81 /0 id */ 7468 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7469 ins_pipe(ialu_mem_imm); 7470 %} 7471 7472 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7473 %{ 7474 predicate(UseIncDec); 7475 match(Set dst (AddI dst src)); 7476 effect(KILL cr); 7477 7478 format %{ "incl $dst\t# int" %} 7479 opcode(0xFF, 0x00); // FF /0 7480 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7481 ins_pipe(ialu_reg); 7482 %} 7483 7484 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7485 %{ 7486 predicate(UseIncDec); 7487 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7488 effect(KILL cr); 7489 7490 ins_cost(125); // XXX 7491 format %{ "incl $dst\t# int" %} 7492 opcode(0xFF); /* Opcode FF /0 */ 7493 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7494 ins_pipe(ialu_mem_imm); 7495 %} 7496 7497 // XXX why does that use AddI 7498 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7499 %{ 7500 predicate(UseIncDec); 7501 match(Set dst (AddI dst src)); 7502 effect(KILL cr); 7503 7504 format %{ "decl $dst\t# int" %} 7505 opcode(0xFF, 0x01); // FF /1 7506 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7507 ins_pipe(ialu_reg); 7508 %} 7509 7510 // XXX why does that use AddI 7511 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7512 %{ 7513 predicate(UseIncDec); 7514 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7515 effect(KILL cr); 7516 7517 ins_cost(125); // XXX 7518 format %{ "decl $dst\t# int" %} 7519 opcode(0xFF); /* Opcode FF /1 */ 7520 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7521 ins_pipe(ialu_mem_imm); 7522 %} 7523 7524 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7525 %{ 7526 match(Set dst (AddI src0 src1)); 7527 7528 ins_cost(110); 7529 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7530 opcode(0x8D); /* 0x8D /r */ 7531 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7532 ins_pipe(ialu_reg_reg); 7533 %} 7534 7535 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7536 %{ 7537 match(Set dst (AddL dst src)); 7538 effect(KILL cr); 7539 7540 format %{ "addq $dst, $src\t# long" %} 7541 opcode(0x03); 7542 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7543 ins_pipe(ialu_reg_reg); 7544 %} 7545 7546 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7547 %{ 7548 match(Set dst (AddL dst src)); 7549 effect(KILL cr); 7550 7551 format %{ "addq $dst, $src\t# long" %} 7552 opcode(0x81, 0x00); /* /0 id */ 7553 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7554 ins_pipe( ialu_reg ); 7555 %} 7556 7557 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7558 %{ 7559 match(Set dst (AddL dst (LoadL src))); 7560 effect(KILL cr); 7561 7562 ins_cost(125); // XXX 7563 format %{ "addq $dst, $src\t# long" %} 7564 opcode(0x03); 7565 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7566 ins_pipe(ialu_reg_mem); 7567 %} 7568 7569 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7570 %{ 7571 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7572 effect(KILL cr); 7573 7574 ins_cost(150); // XXX 7575 format %{ "addq $dst, $src\t# long" %} 7576 opcode(0x01); /* Opcode 01 /r */ 7577 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7578 ins_pipe(ialu_mem_reg); 7579 %} 7580 7581 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7582 %{ 7583 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7584 effect(KILL cr); 7585 7586 ins_cost(125); // XXX 7587 format %{ "addq $dst, $src\t# long" %} 7588 opcode(0x81); /* Opcode 81 /0 id */ 7589 ins_encode(REX_mem_wide(dst), 7590 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7591 ins_pipe(ialu_mem_imm); 7592 %} 7593 7594 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7595 %{ 7596 predicate(UseIncDec); 7597 match(Set dst (AddL dst src)); 7598 effect(KILL cr); 7599 7600 format %{ "incq $dst\t# long" %} 7601 opcode(0xFF, 0x00); // FF /0 7602 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7603 ins_pipe(ialu_reg); 7604 %} 7605 7606 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7607 %{ 7608 predicate(UseIncDec); 7609 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7610 effect(KILL cr); 7611 7612 ins_cost(125); // XXX 7613 format %{ "incq $dst\t# long" %} 7614 opcode(0xFF); /* Opcode FF /0 */ 7615 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7616 ins_pipe(ialu_mem_imm); 7617 %} 7618 7619 // XXX why does that use AddL 7620 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7621 %{ 7622 predicate(UseIncDec); 7623 match(Set dst (AddL dst src)); 7624 effect(KILL cr); 7625 7626 format %{ "decq $dst\t# long" %} 7627 opcode(0xFF, 0x01); // FF /1 7628 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7629 ins_pipe(ialu_reg); 7630 %} 7631 7632 // XXX why does that use AddL 7633 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7634 %{ 7635 predicate(UseIncDec); 7636 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7637 effect(KILL cr); 7638 7639 ins_cost(125); // XXX 7640 format %{ "decq $dst\t# long" %} 7641 opcode(0xFF); /* Opcode FF /1 */ 7642 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7643 ins_pipe(ialu_mem_imm); 7644 %} 7645 7646 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7647 %{ 7648 match(Set dst (AddL src0 src1)); 7649 7650 ins_cost(110); 7651 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7652 opcode(0x8D); /* 0x8D /r */ 7653 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7654 ins_pipe(ialu_reg_reg); 7655 %} 7656 7657 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7658 %{ 7659 match(Set dst (AddP dst src)); 7660 effect(KILL cr); 7661 7662 format %{ "addq $dst, $src\t# ptr" %} 7663 opcode(0x03); 7664 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7665 ins_pipe(ialu_reg_reg); 7666 %} 7667 7668 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7669 %{ 7670 match(Set dst (AddP dst src)); 7671 effect(KILL cr); 7672 7673 format %{ "addq $dst, $src\t# ptr" %} 7674 opcode(0x81, 0x00); /* /0 id */ 7675 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7676 ins_pipe( ialu_reg ); 7677 %} 7678 7679 // XXX addP mem ops ???? 7680 7681 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7682 %{ 7683 match(Set dst (AddP src0 src1)); 7684 7685 ins_cost(110); 7686 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7687 opcode(0x8D); /* 0x8D /r */ 7688 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7689 ins_pipe(ialu_reg_reg); 7690 %} 7691 7692 instruct checkCastPP(rRegP dst) 7693 %{ 7694 match(Set dst (CheckCastPP dst)); 7695 7696 size(0); 7697 format %{ "# checkcastPP of $dst" %} 7698 ins_encode(/* empty encoding */); 7699 ins_pipe(empty); 7700 %} 7701 7702 instruct castPP(rRegP dst) 7703 %{ 7704 match(Set dst (CastPP dst)); 7705 7706 size(0); 7707 format %{ "# castPP of $dst" %} 7708 ins_encode(/* empty encoding */); 7709 ins_pipe(empty); 7710 %} 7711 7712 instruct castII(rRegI dst) 7713 %{ 7714 match(Set dst (CastII dst)); 7715 7716 size(0); 7717 format %{ "# castII of $dst" %} 7718 ins_encode(/* empty encoding */); 7719 ins_cost(0); 7720 ins_pipe(empty); 7721 %} 7722 7723 // LoadP-locked same as a regular LoadP when used with compare-swap 7724 instruct loadPLocked(rRegP dst, memory mem) 7725 %{ 7726 match(Set dst (LoadPLocked mem)); 7727 7728 ins_cost(125); // XXX 7729 format %{ "movq $dst, $mem\t# ptr locked" %} 7730 opcode(0x8B); 7731 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7732 ins_pipe(ialu_reg_mem); // XXX 7733 %} 7734 7735 // Conditional-store of the updated heap-top. 7736 // Used during allocation of the shared heap. 7737 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7738 7739 instruct storePConditional(memory heap_top_ptr, 7740 rax_RegP oldval, rRegP newval, 7741 rFlagsReg cr) 7742 %{ 7743 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7744 7745 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7746 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7747 opcode(0x0F, 0xB1); 7748 ins_encode(lock_prefix, 7749 REX_reg_mem_wide(newval, heap_top_ptr), 7750 OpcP, OpcS, 7751 reg_mem(newval, heap_top_ptr)); 7752 ins_pipe(pipe_cmpxchg); 7753 %} 7754 7755 // Conditional-store of an int value. 7756 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7757 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7758 %{ 7759 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7760 effect(KILL oldval); 7761 7762 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7763 opcode(0x0F, 0xB1); 7764 ins_encode(lock_prefix, 7765 REX_reg_mem(newval, mem), 7766 OpcP, OpcS, 7767 reg_mem(newval, mem)); 7768 ins_pipe(pipe_cmpxchg); 7769 %} 7770 7771 // Conditional-store of a long value. 7772 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7773 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7774 %{ 7775 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7776 effect(KILL oldval); 7777 7778 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7779 opcode(0x0F, 0xB1); 7780 ins_encode(lock_prefix, 7781 REX_reg_mem_wide(newval, mem), 7782 OpcP, OpcS, 7783 reg_mem(newval, mem)); 7784 ins_pipe(pipe_cmpxchg); 7785 %} 7786 7787 7788 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7789 instruct compareAndSwapP(rRegI res, 7790 memory mem_ptr, 7791 rax_RegP oldval, rRegP newval, 7792 rFlagsReg cr) 7793 %{ 7794 predicate(VM_Version::supports_cx8()); 7795 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7796 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7797 effect(KILL cr, KILL oldval); 7798 7799 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7800 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7801 "sete $res\n\t" 7802 "movzbl $res, $res" %} 7803 opcode(0x0F, 0xB1); 7804 ins_encode(lock_prefix, 7805 REX_reg_mem_wide(newval, mem_ptr), 7806 OpcP, OpcS, 7807 reg_mem(newval, mem_ptr), 7808 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7809 REX_reg_breg(res, res), // movzbl 7810 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7811 ins_pipe( pipe_cmpxchg ); 7812 %} 7813 7814 instruct compareAndSwapL(rRegI res, 7815 memory mem_ptr, 7816 rax_RegL oldval, rRegL newval, 7817 rFlagsReg cr) 7818 %{ 7819 predicate(VM_Version::supports_cx8()); 7820 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7821 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7822 effect(KILL cr, KILL oldval); 7823 7824 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7825 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7826 "sete $res\n\t" 7827 "movzbl $res, $res" %} 7828 opcode(0x0F, 0xB1); 7829 ins_encode(lock_prefix, 7830 REX_reg_mem_wide(newval, mem_ptr), 7831 OpcP, OpcS, 7832 reg_mem(newval, mem_ptr), 7833 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7834 REX_reg_breg(res, res), // movzbl 7835 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7836 ins_pipe( pipe_cmpxchg ); 7837 %} 7838 7839 instruct compareAndSwapI(rRegI res, 7840 memory mem_ptr, 7841 rax_RegI oldval, rRegI newval, 7842 rFlagsReg cr) 7843 %{ 7844 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7845 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7846 effect(KILL cr, KILL oldval); 7847 7848 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7849 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7850 "sete $res\n\t" 7851 "movzbl $res, $res" %} 7852 opcode(0x0F, 0xB1); 7853 ins_encode(lock_prefix, 7854 REX_reg_mem(newval, mem_ptr), 7855 OpcP, OpcS, 7856 reg_mem(newval, mem_ptr), 7857 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7858 REX_reg_breg(res, res), // movzbl 7859 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7860 ins_pipe( pipe_cmpxchg ); 7861 %} 7862 7863 instruct compareAndSwapB(rRegI res, 7864 memory mem_ptr, 7865 rax_RegI oldval, rRegI newval, 7866 rFlagsReg cr) 7867 %{ 7868 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7869 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7870 effect(KILL cr, KILL oldval); 7871 7872 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7873 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7874 "sete $res\n\t" 7875 "movzbl $res, $res" %} 7876 opcode(0x0F, 0xB0); 7877 ins_encode(lock_prefix, 7878 REX_breg_mem(newval, mem_ptr), 7879 OpcP, OpcS, 7880 reg_mem(newval, mem_ptr), 7881 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7882 REX_reg_breg(res, res), // movzbl 7883 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7884 ins_pipe( pipe_cmpxchg ); 7885 %} 7886 7887 instruct compareAndSwapS(rRegI res, 7888 memory mem_ptr, 7889 rax_RegI oldval, rRegI newval, 7890 rFlagsReg cr) 7891 %{ 7892 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7893 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7894 effect(KILL cr, KILL oldval); 7895 7896 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7897 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7898 "sete $res\n\t" 7899 "movzbl $res, $res" %} 7900 opcode(0x0F, 0xB1); 7901 ins_encode(lock_prefix, 7902 SizePrefix, 7903 REX_reg_mem(newval, mem_ptr), 7904 OpcP, OpcS, 7905 reg_mem(newval, mem_ptr), 7906 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7907 REX_reg_breg(res, res), // movzbl 7908 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7909 ins_pipe( pipe_cmpxchg ); 7910 %} 7911 7912 instruct compareAndSwapN(rRegI res, 7913 memory mem_ptr, 7914 rax_RegN oldval, rRegN newval, 7915 rFlagsReg cr) %{ 7916 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7917 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7918 effect(KILL cr, KILL oldval); 7919 7920 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7921 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7922 "sete $res\n\t" 7923 "movzbl $res, $res" %} 7924 opcode(0x0F, 0xB1); 7925 ins_encode(lock_prefix, 7926 REX_reg_mem(newval, mem_ptr), 7927 OpcP, OpcS, 7928 reg_mem(newval, mem_ptr), 7929 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7930 REX_reg_breg(res, res), // movzbl 7931 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7932 ins_pipe( pipe_cmpxchg ); 7933 %} 7934 7935 instruct compareAndExchangeB( 7936 memory mem_ptr, 7937 rax_RegI oldval, rRegI newval, 7938 rFlagsReg cr) 7939 %{ 7940 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7941 effect(KILL cr); 7942 7943 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7944 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7945 opcode(0x0F, 0xB0); 7946 ins_encode(lock_prefix, 7947 REX_breg_mem(newval, mem_ptr), 7948 OpcP, OpcS, 7949 reg_mem(newval, mem_ptr) // lock cmpxchg 7950 ); 7951 ins_pipe( pipe_cmpxchg ); 7952 %} 7953 7954 instruct compareAndExchangeS( 7955 memory mem_ptr, 7956 rax_RegI oldval, rRegI newval, 7957 rFlagsReg cr) 7958 %{ 7959 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7960 effect(KILL cr); 7961 7962 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7963 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7964 opcode(0x0F, 0xB1); 7965 ins_encode(lock_prefix, 7966 SizePrefix, 7967 REX_reg_mem(newval, mem_ptr), 7968 OpcP, OpcS, 7969 reg_mem(newval, mem_ptr) // lock cmpxchg 7970 ); 7971 ins_pipe( pipe_cmpxchg ); 7972 %} 7973 7974 instruct compareAndExchangeI( 7975 memory mem_ptr, 7976 rax_RegI oldval, rRegI newval, 7977 rFlagsReg cr) 7978 %{ 7979 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7980 effect(KILL cr); 7981 7982 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7983 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7984 opcode(0x0F, 0xB1); 7985 ins_encode(lock_prefix, 7986 REX_reg_mem(newval, mem_ptr), 7987 OpcP, OpcS, 7988 reg_mem(newval, mem_ptr) // lock cmpxchg 7989 ); 7990 ins_pipe( pipe_cmpxchg ); 7991 %} 7992 7993 instruct compareAndExchangeL( 7994 memory mem_ptr, 7995 rax_RegL oldval, rRegL newval, 7996 rFlagsReg cr) 7997 %{ 7998 predicate(VM_Version::supports_cx8()); 7999 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 8000 effect(KILL cr); 8001 8002 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8003 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8004 opcode(0x0F, 0xB1); 8005 ins_encode(lock_prefix, 8006 REX_reg_mem_wide(newval, mem_ptr), 8007 OpcP, OpcS, 8008 reg_mem(newval, mem_ptr) // lock cmpxchg 8009 ); 8010 ins_pipe( pipe_cmpxchg ); 8011 %} 8012 8013 instruct compareAndExchangeN( 8014 memory mem_ptr, 8015 rax_RegN oldval, rRegN newval, 8016 rFlagsReg cr) %{ 8017 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 8018 effect(KILL cr); 8019 8020 format %{ "cmpxchgl $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(newval, mem_ptr), 8025 OpcP, OpcS, 8026 reg_mem(newval, mem_ptr) // lock cmpxchg 8027 ); 8028 ins_pipe( pipe_cmpxchg ); 8029 %} 8030 8031 instruct compareAndExchangeP( 8032 memory mem_ptr, 8033 rax_RegP oldval, rRegP newval, 8034 rFlagsReg cr) 8035 %{ 8036 predicate(VM_Version::supports_cx8()); 8037 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 8038 effect(KILL cr); 8039 8040 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8041 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8042 opcode(0x0F, 0xB1); 8043 ins_encode(lock_prefix, 8044 REX_reg_mem_wide(newval, mem_ptr), 8045 OpcP, OpcS, 8046 reg_mem(newval, mem_ptr) // lock cmpxchg 8047 ); 8048 ins_pipe( pipe_cmpxchg ); 8049 %} 8050 8051 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8052 predicate(n->as_LoadStore()->result_not_used()); 8053 match(Set dummy (GetAndAddB mem add)); 8054 effect(KILL cr); 8055 format %{ "ADDB [$mem],$add" %} 8056 ins_encode %{ 8057 __ lock(); 8058 __ addb($mem$$Address, $add$$constant); 8059 %} 8060 ins_pipe( pipe_cmpxchg ); 8061 %} 8062 8063 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 8064 match(Set newval (GetAndAddB mem newval)); 8065 effect(KILL cr); 8066 format %{ "XADDB [$mem],$newval" %} 8067 ins_encode %{ 8068 __ lock(); 8069 __ xaddb($mem$$Address, $newval$$Register); 8070 %} 8071 ins_pipe( pipe_cmpxchg ); 8072 %} 8073 8074 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8075 predicate(n->as_LoadStore()->result_not_used()); 8076 match(Set dummy (GetAndAddS mem add)); 8077 effect(KILL cr); 8078 format %{ "ADDW [$mem],$add" %} 8079 ins_encode %{ 8080 __ lock(); 8081 __ addw($mem$$Address, $add$$constant); 8082 %} 8083 ins_pipe( pipe_cmpxchg ); 8084 %} 8085 8086 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 8087 match(Set newval (GetAndAddS mem newval)); 8088 effect(KILL cr); 8089 format %{ "XADDW [$mem],$newval" %} 8090 ins_encode %{ 8091 __ lock(); 8092 __ xaddw($mem$$Address, $newval$$Register); 8093 %} 8094 ins_pipe( pipe_cmpxchg ); 8095 %} 8096 8097 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8098 predicate(n->as_LoadStore()->result_not_used()); 8099 match(Set dummy (GetAndAddI mem add)); 8100 effect(KILL cr); 8101 format %{ "ADDL [$mem],$add" %} 8102 ins_encode %{ 8103 __ lock(); 8104 __ addl($mem$$Address, $add$$constant); 8105 %} 8106 ins_pipe( pipe_cmpxchg ); 8107 %} 8108 8109 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 8110 match(Set newval (GetAndAddI mem newval)); 8111 effect(KILL cr); 8112 format %{ "XADDL [$mem],$newval" %} 8113 ins_encode %{ 8114 __ lock(); 8115 __ xaddl($mem$$Address, $newval$$Register); 8116 %} 8117 ins_pipe( pipe_cmpxchg ); 8118 %} 8119 8120 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8121 predicate(n->as_LoadStore()->result_not_used()); 8122 match(Set dummy (GetAndAddL mem add)); 8123 effect(KILL cr); 8124 format %{ "ADDQ [$mem],$add" %} 8125 ins_encode %{ 8126 __ lock(); 8127 __ addq($mem$$Address, $add$$constant); 8128 %} 8129 ins_pipe( pipe_cmpxchg ); 8130 %} 8131 8132 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 8133 match(Set newval (GetAndAddL mem newval)); 8134 effect(KILL cr); 8135 format %{ "XADDQ [$mem],$newval" %} 8136 ins_encode %{ 8137 __ lock(); 8138 __ xaddq($mem$$Address, $newval$$Register); 8139 %} 8140 ins_pipe( pipe_cmpxchg ); 8141 %} 8142 8143 instruct xchgB( memory mem, rRegI newval) %{ 8144 match(Set newval (GetAndSetB mem newval)); 8145 format %{ "XCHGB $newval,[$mem]" %} 8146 ins_encode %{ 8147 __ xchgb($newval$$Register, $mem$$Address); 8148 %} 8149 ins_pipe( pipe_cmpxchg ); 8150 %} 8151 8152 instruct xchgS( memory mem, rRegI newval) %{ 8153 match(Set newval (GetAndSetS mem newval)); 8154 format %{ "XCHGW $newval,[$mem]" %} 8155 ins_encode %{ 8156 __ xchgw($newval$$Register, $mem$$Address); 8157 %} 8158 ins_pipe( pipe_cmpxchg ); 8159 %} 8160 8161 instruct xchgI( memory mem, rRegI newval) %{ 8162 match(Set newval (GetAndSetI mem newval)); 8163 format %{ "XCHGL $newval,[$mem]" %} 8164 ins_encode %{ 8165 __ xchgl($newval$$Register, $mem$$Address); 8166 %} 8167 ins_pipe( pipe_cmpxchg ); 8168 %} 8169 8170 instruct xchgL( memory mem, rRegL newval) %{ 8171 match(Set newval (GetAndSetL mem newval)); 8172 format %{ "XCHGL $newval,[$mem]" %} 8173 ins_encode %{ 8174 __ xchgq($newval$$Register, $mem$$Address); 8175 %} 8176 ins_pipe( pipe_cmpxchg ); 8177 %} 8178 8179 instruct xchgP( memory mem, rRegP newval) %{ 8180 match(Set newval (GetAndSetP mem newval)); 8181 format %{ "XCHGQ $newval,[$mem]" %} 8182 ins_encode %{ 8183 __ xchgq($newval$$Register, $mem$$Address); 8184 %} 8185 ins_pipe( pipe_cmpxchg ); 8186 %} 8187 8188 instruct xchgN( memory mem, rRegN newval) %{ 8189 match(Set newval (GetAndSetN mem newval)); 8190 format %{ "XCHGL $newval,$mem]" %} 8191 ins_encode %{ 8192 __ xchgl($newval$$Register, $mem$$Address); 8193 %} 8194 ins_pipe( pipe_cmpxchg ); 8195 %} 8196 8197 //----------Subtraction Instructions------------------------------------------- 8198 8199 // Integer Subtraction Instructions 8200 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8201 %{ 8202 match(Set dst (SubI dst src)); 8203 effect(KILL cr); 8204 8205 format %{ "subl $dst, $src\t# int" %} 8206 opcode(0x2B); 8207 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8208 ins_pipe(ialu_reg_reg); 8209 %} 8210 8211 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8212 %{ 8213 match(Set dst (SubI dst src)); 8214 effect(KILL cr); 8215 8216 format %{ "subl $dst, $src\t# int" %} 8217 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8218 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8219 ins_pipe(ialu_reg); 8220 %} 8221 8222 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8223 %{ 8224 match(Set dst (SubI dst (LoadI src))); 8225 effect(KILL cr); 8226 8227 ins_cost(125); 8228 format %{ "subl $dst, $src\t# int" %} 8229 opcode(0x2B); 8230 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8231 ins_pipe(ialu_reg_mem); 8232 %} 8233 8234 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8235 %{ 8236 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8237 effect(KILL cr); 8238 8239 ins_cost(150); 8240 format %{ "subl $dst, $src\t# int" %} 8241 opcode(0x29); /* Opcode 29 /r */ 8242 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8243 ins_pipe(ialu_mem_reg); 8244 %} 8245 8246 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8247 %{ 8248 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8249 effect(KILL cr); 8250 8251 ins_cost(125); // XXX 8252 format %{ "subl $dst, $src\t# int" %} 8253 opcode(0x81); /* Opcode 81 /5 id */ 8254 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8255 ins_pipe(ialu_mem_imm); 8256 %} 8257 8258 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8259 %{ 8260 match(Set dst (SubL dst src)); 8261 effect(KILL cr); 8262 8263 format %{ "subq $dst, $src\t# long" %} 8264 opcode(0x2B); 8265 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8266 ins_pipe(ialu_reg_reg); 8267 %} 8268 8269 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8270 %{ 8271 match(Set dst (SubL dst src)); 8272 effect(KILL cr); 8273 8274 format %{ "subq $dst, $src\t# long" %} 8275 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8276 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8277 ins_pipe(ialu_reg); 8278 %} 8279 8280 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8281 %{ 8282 match(Set dst (SubL dst (LoadL src))); 8283 effect(KILL cr); 8284 8285 ins_cost(125); 8286 format %{ "subq $dst, $src\t# long" %} 8287 opcode(0x2B); 8288 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8289 ins_pipe(ialu_reg_mem); 8290 %} 8291 8292 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8293 %{ 8294 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8295 effect(KILL cr); 8296 8297 ins_cost(150); 8298 format %{ "subq $dst, $src\t# long" %} 8299 opcode(0x29); /* Opcode 29 /r */ 8300 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8301 ins_pipe(ialu_mem_reg); 8302 %} 8303 8304 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8305 %{ 8306 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8307 effect(KILL cr); 8308 8309 ins_cost(125); // XXX 8310 format %{ "subq $dst, $src\t# long" %} 8311 opcode(0x81); /* Opcode 81 /5 id */ 8312 ins_encode(REX_mem_wide(dst), 8313 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8314 ins_pipe(ialu_mem_imm); 8315 %} 8316 8317 // Subtract from a pointer 8318 // XXX hmpf??? 8319 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8320 %{ 8321 match(Set dst (AddP dst (SubI zero src))); 8322 effect(KILL cr); 8323 8324 format %{ "subq $dst, $src\t# ptr - int" %} 8325 opcode(0x2B); 8326 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8327 ins_pipe(ialu_reg_reg); 8328 %} 8329 8330 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8331 %{ 8332 match(Set dst (SubI zero dst)); 8333 effect(KILL cr); 8334 8335 format %{ "negl $dst\t# int" %} 8336 opcode(0xF7, 0x03); // Opcode F7 /3 8337 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8338 ins_pipe(ialu_reg); 8339 %} 8340 8341 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8342 %{ 8343 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8344 effect(KILL cr); 8345 8346 format %{ "negl $dst\t# int" %} 8347 opcode(0xF7, 0x03); // Opcode F7 /3 8348 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8349 ins_pipe(ialu_reg); 8350 %} 8351 8352 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8353 %{ 8354 match(Set dst (SubL zero dst)); 8355 effect(KILL cr); 8356 8357 format %{ "negq $dst\t# long" %} 8358 opcode(0xF7, 0x03); // Opcode F7 /3 8359 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8360 ins_pipe(ialu_reg); 8361 %} 8362 8363 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8364 %{ 8365 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8366 effect(KILL cr); 8367 8368 format %{ "negq $dst\t# long" %} 8369 opcode(0xF7, 0x03); // Opcode F7 /3 8370 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8371 ins_pipe(ialu_reg); 8372 %} 8373 8374 //----------Multiplication/Division Instructions------------------------------- 8375 // Integer Multiplication Instructions 8376 // Multiply Register 8377 8378 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8379 %{ 8380 match(Set dst (MulI dst src)); 8381 effect(KILL cr); 8382 8383 ins_cost(300); 8384 format %{ "imull $dst, $src\t# int" %} 8385 opcode(0x0F, 0xAF); 8386 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8387 ins_pipe(ialu_reg_reg_alu0); 8388 %} 8389 8390 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8391 %{ 8392 match(Set dst (MulI src imm)); 8393 effect(KILL cr); 8394 8395 ins_cost(300); 8396 format %{ "imull $dst, $src, $imm\t# int" %} 8397 opcode(0x69); /* 69 /r id */ 8398 ins_encode(REX_reg_reg(dst, src), 8399 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8400 ins_pipe(ialu_reg_reg_alu0); 8401 %} 8402 8403 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8404 %{ 8405 match(Set dst (MulI dst (LoadI src))); 8406 effect(KILL cr); 8407 8408 ins_cost(350); 8409 format %{ "imull $dst, $src\t# int" %} 8410 opcode(0x0F, 0xAF); 8411 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8412 ins_pipe(ialu_reg_mem_alu0); 8413 %} 8414 8415 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8416 %{ 8417 match(Set dst (MulI (LoadI src) imm)); 8418 effect(KILL cr); 8419 8420 ins_cost(300); 8421 format %{ "imull $dst, $src, $imm\t# int" %} 8422 opcode(0x69); /* 69 /r id */ 8423 ins_encode(REX_reg_mem(dst, src), 8424 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8425 ins_pipe(ialu_reg_mem_alu0); 8426 %} 8427 8428 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8429 %{ 8430 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8431 effect(KILL cr, KILL src2); 8432 8433 expand %{ mulI_rReg(dst, src1, cr); 8434 mulI_rReg(src2, src3, cr); 8435 addI_rReg(dst, src2, cr); %} 8436 %} 8437 8438 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8439 %{ 8440 match(Set dst (MulL dst src)); 8441 effect(KILL cr); 8442 8443 ins_cost(300); 8444 format %{ "imulq $dst, $src\t# long" %} 8445 opcode(0x0F, 0xAF); 8446 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8447 ins_pipe(ialu_reg_reg_alu0); 8448 %} 8449 8450 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8451 %{ 8452 match(Set dst (MulL src imm)); 8453 effect(KILL cr); 8454 8455 ins_cost(300); 8456 format %{ "imulq $dst, $src, $imm\t# long" %} 8457 opcode(0x69); /* 69 /r id */ 8458 ins_encode(REX_reg_reg_wide(dst, src), 8459 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8460 ins_pipe(ialu_reg_reg_alu0); 8461 %} 8462 8463 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8464 %{ 8465 match(Set dst (MulL dst (LoadL src))); 8466 effect(KILL cr); 8467 8468 ins_cost(350); 8469 format %{ "imulq $dst, $src\t# long" %} 8470 opcode(0x0F, 0xAF); 8471 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8472 ins_pipe(ialu_reg_mem_alu0); 8473 %} 8474 8475 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8476 %{ 8477 match(Set dst (MulL (LoadL src) imm)); 8478 effect(KILL cr); 8479 8480 ins_cost(300); 8481 format %{ "imulq $dst, $src, $imm\t# long" %} 8482 opcode(0x69); /* 69 /r id */ 8483 ins_encode(REX_reg_mem_wide(dst, src), 8484 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8485 ins_pipe(ialu_reg_mem_alu0); 8486 %} 8487 8488 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8489 %{ 8490 match(Set dst (MulHiL src rax)); 8491 effect(USE_KILL rax, KILL cr); 8492 8493 ins_cost(300); 8494 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8495 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8496 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8497 ins_pipe(ialu_reg_reg_alu0); 8498 %} 8499 8500 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8501 rFlagsReg cr) 8502 %{ 8503 match(Set rax (DivI rax div)); 8504 effect(KILL rdx, KILL cr); 8505 8506 ins_cost(30*100+10*100); // XXX 8507 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8508 "jne,s normal\n\t" 8509 "xorl rdx, rdx\n\t" 8510 "cmpl $div, -1\n\t" 8511 "je,s done\n" 8512 "normal: cdql\n\t" 8513 "idivl $div\n" 8514 "done:" %} 8515 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8516 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8517 ins_pipe(ialu_reg_reg_alu0); 8518 %} 8519 8520 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8521 rFlagsReg cr) 8522 %{ 8523 match(Set rax (DivL rax div)); 8524 effect(KILL rdx, KILL cr); 8525 8526 ins_cost(30*100+10*100); // XXX 8527 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8528 "cmpq rax, rdx\n\t" 8529 "jne,s normal\n\t" 8530 "xorl rdx, rdx\n\t" 8531 "cmpq $div, -1\n\t" 8532 "je,s done\n" 8533 "normal: cdqq\n\t" 8534 "idivq $div\n" 8535 "done:" %} 8536 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8537 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8538 ins_pipe(ialu_reg_reg_alu0); 8539 %} 8540 8541 // Integer DIVMOD with Register, both quotient and mod results 8542 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8543 rFlagsReg cr) 8544 %{ 8545 match(DivModI rax div); 8546 effect(KILL cr); 8547 8548 ins_cost(30*100+10*100); // XXX 8549 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8550 "jne,s normal\n\t" 8551 "xorl rdx, rdx\n\t" 8552 "cmpl $div, -1\n\t" 8553 "je,s done\n" 8554 "normal: cdql\n\t" 8555 "idivl $div\n" 8556 "done:" %} 8557 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8558 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8559 ins_pipe(pipe_slow); 8560 %} 8561 8562 // Long DIVMOD with Register, both quotient and mod results 8563 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8564 rFlagsReg cr) 8565 %{ 8566 match(DivModL rax div); 8567 effect(KILL cr); 8568 8569 ins_cost(30*100+10*100); // XXX 8570 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8571 "cmpq rax, rdx\n\t" 8572 "jne,s normal\n\t" 8573 "xorl rdx, rdx\n\t" 8574 "cmpq $div, -1\n\t" 8575 "je,s done\n" 8576 "normal: cdqq\n\t" 8577 "idivq $div\n" 8578 "done:" %} 8579 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8580 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8581 ins_pipe(pipe_slow); 8582 %} 8583 8584 //----------- DivL-By-Constant-Expansions-------------------------------------- 8585 // DivI cases are handled by the compiler 8586 8587 // Magic constant, reciprocal of 10 8588 instruct loadConL_0x6666666666666667(rRegL dst) 8589 %{ 8590 effect(DEF dst); 8591 8592 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8593 ins_encode(load_immL(dst, 0x6666666666666667)); 8594 ins_pipe(ialu_reg); 8595 %} 8596 8597 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8598 %{ 8599 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8600 8601 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8602 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8603 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8604 ins_pipe(ialu_reg_reg_alu0); 8605 %} 8606 8607 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8608 %{ 8609 effect(USE_DEF dst, KILL cr); 8610 8611 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8612 opcode(0xC1, 0x7); /* C1 /7 ib */ 8613 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8614 ins_pipe(ialu_reg); 8615 %} 8616 8617 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8618 %{ 8619 effect(USE_DEF dst, KILL cr); 8620 8621 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8622 opcode(0xC1, 0x7); /* C1 /7 ib */ 8623 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8624 ins_pipe(ialu_reg); 8625 %} 8626 8627 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8628 %{ 8629 match(Set dst (DivL src div)); 8630 8631 ins_cost((5+8)*100); 8632 expand %{ 8633 rax_RegL rax; // Killed temp 8634 rFlagsReg cr; // Killed 8635 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8636 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8637 sarL_rReg_63(src, cr); // sarq src, 63 8638 sarL_rReg_2(dst, cr); // sarq rdx, 2 8639 subL_rReg(dst, src, cr); // subl rdx, src 8640 %} 8641 %} 8642 8643 //----------------------------------------------------------------------------- 8644 8645 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8646 rFlagsReg cr) 8647 %{ 8648 match(Set rdx (ModI rax div)); 8649 effect(KILL rax, KILL cr); 8650 8651 ins_cost(300); // XXX 8652 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8653 "jne,s normal\n\t" 8654 "xorl rdx, rdx\n\t" 8655 "cmpl $div, -1\n\t" 8656 "je,s done\n" 8657 "normal: cdql\n\t" 8658 "idivl $div\n" 8659 "done:" %} 8660 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8661 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8662 ins_pipe(ialu_reg_reg_alu0); 8663 %} 8664 8665 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8666 rFlagsReg cr) 8667 %{ 8668 match(Set rdx (ModL rax div)); 8669 effect(KILL rax, KILL cr); 8670 8671 ins_cost(300); // XXX 8672 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8673 "cmpq rax, rdx\n\t" 8674 "jne,s normal\n\t" 8675 "xorl rdx, rdx\n\t" 8676 "cmpq $div, -1\n\t" 8677 "je,s done\n" 8678 "normal: cdqq\n\t" 8679 "idivq $div\n" 8680 "done:" %} 8681 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8682 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8683 ins_pipe(ialu_reg_reg_alu0); 8684 %} 8685 8686 // Integer Shift Instructions 8687 // Shift Left by one 8688 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8689 %{ 8690 match(Set dst (LShiftI dst shift)); 8691 effect(KILL cr); 8692 8693 format %{ "sall $dst, $shift" %} 8694 opcode(0xD1, 0x4); /* D1 /4 */ 8695 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8696 ins_pipe(ialu_reg); 8697 %} 8698 8699 // Shift Left by one 8700 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8701 %{ 8702 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8703 effect(KILL cr); 8704 8705 format %{ "sall $dst, $shift\t" %} 8706 opcode(0xD1, 0x4); /* D1 /4 */ 8707 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8708 ins_pipe(ialu_mem_imm); 8709 %} 8710 8711 // Shift Left by 8-bit immediate 8712 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8713 %{ 8714 match(Set dst (LShiftI dst shift)); 8715 effect(KILL cr); 8716 8717 format %{ "sall $dst, $shift" %} 8718 opcode(0xC1, 0x4); /* C1 /4 ib */ 8719 ins_encode(reg_opc_imm(dst, shift)); 8720 ins_pipe(ialu_reg); 8721 %} 8722 8723 // Shift Left by 8-bit immediate 8724 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8725 %{ 8726 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8727 effect(KILL cr); 8728 8729 format %{ "sall $dst, $shift" %} 8730 opcode(0xC1, 0x4); /* C1 /4 ib */ 8731 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8732 ins_pipe(ialu_mem_imm); 8733 %} 8734 8735 // Shift Left by variable 8736 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8737 %{ 8738 match(Set dst (LShiftI dst shift)); 8739 effect(KILL cr); 8740 8741 format %{ "sall $dst, $shift" %} 8742 opcode(0xD3, 0x4); /* D3 /4 */ 8743 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8744 ins_pipe(ialu_reg_reg); 8745 %} 8746 8747 // Shift Left by variable 8748 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8749 %{ 8750 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8751 effect(KILL cr); 8752 8753 format %{ "sall $dst, $shift" %} 8754 opcode(0xD3, 0x4); /* D3 /4 */ 8755 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8756 ins_pipe(ialu_mem_reg); 8757 %} 8758 8759 // Arithmetic shift right by one 8760 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8761 %{ 8762 match(Set dst (RShiftI dst shift)); 8763 effect(KILL cr); 8764 8765 format %{ "sarl $dst, $shift" %} 8766 opcode(0xD1, 0x7); /* D1 /7 */ 8767 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8768 ins_pipe(ialu_reg); 8769 %} 8770 8771 // Arithmetic shift right by one 8772 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8773 %{ 8774 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8775 effect(KILL cr); 8776 8777 format %{ "sarl $dst, $shift" %} 8778 opcode(0xD1, 0x7); /* D1 /7 */ 8779 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8780 ins_pipe(ialu_mem_imm); 8781 %} 8782 8783 // Arithmetic Shift Right by 8-bit immediate 8784 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8785 %{ 8786 match(Set dst (RShiftI dst shift)); 8787 effect(KILL cr); 8788 8789 format %{ "sarl $dst, $shift" %} 8790 opcode(0xC1, 0x7); /* C1 /7 ib */ 8791 ins_encode(reg_opc_imm(dst, shift)); 8792 ins_pipe(ialu_mem_imm); 8793 %} 8794 8795 // Arithmetic Shift Right by 8-bit immediate 8796 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8797 %{ 8798 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8799 effect(KILL cr); 8800 8801 format %{ "sarl $dst, $shift" %} 8802 opcode(0xC1, 0x7); /* C1 /7 ib */ 8803 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8804 ins_pipe(ialu_mem_imm); 8805 %} 8806 8807 // Arithmetic Shift Right by variable 8808 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8809 %{ 8810 match(Set dst (RShiftI dst shift)); 8811 effect(KILL cr); 8812 8813 format %{ "sarl $dst, $shift" %} 8814 opcode(0xD3, 0x7); /* D3 /7 */ 8815 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8816 ins_pipe(ialu_reg_reg); 8817 %} 8818 8819 // Arithmetic Shift Right by variable 8820 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8821 %{ 8822 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8823 effect(KILL cr); 8824 8825 format %{ "sarl $dst, $shift" %} 8826 opcode(0xD3, 0x7); /* D3 /7 */ 8827 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8828 ins_pipe(ialu_mem_reg); 8829 %} 8830 8831 // Logical shift right by one 8832 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8833 %{ 8834 match(Set dst (URShiftI dst shift)); 8835 effect(KILL cr); 8836 8837 format %{ "shrl $dst, $shift" %} 8838 opcode(0xD1, 0x5); /* D1 /5 */ 8839 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8840 ins_pipe(ialu_reg); 8841 %} 8842 8843 // Logical shift right by one 8844 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8845 %{ 8846 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8847 effect(KILL cr); 8848 8849 format %{ "shrl $dst, $shift" %} 8850 opcode(0xD1, 0x5); /* D1 /5 */ 8851 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8852 ins_pipe(ialu_mem_imm); 8853 %} 8854 8855 // Logical Shift Right by 8-bit immediate 8856 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8857 %{ 8858 match(Set dst (URShiftI dst shift)); 8859 effect(KILL cr); 8860 8861 format %{ "shrl $dst, $shift" %} 8862 opcode(0xC1, 0x5); /* C1 /5 ib */ 8863 ins_encode(reg_opc_imm(dst, shift)); 8864 ins_pipe(ialu_reg); 8865 %} 8866 8867 // Logical Shift Right by 8-bit immediate 8868 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8869 %{ 8870 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8871 effect(KILL cr); 8872 8873 format %{ "shrl $dst, $shift" %} 8874 opcode(0xC1, 0x5); /* C1 /5 ib */ 8875 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8876 ins_pipe(ialu_mem_imm); 8877 %} 8878 8879 // Logical Shift Right by variable 8880 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8881 %{ 8882 match(Set dst (URShiftI dst shift)); 8883 effect(KILL cr); 8884 8885 format %{ "shrl $dst, $shift" %} 8886 opcode(0xD3, 0x5); /* D3 /5 */ 8887 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8888 ins_pipe(ialu_reg_reg); 8889 %} 8890 8891 // Logical Shift Right by variable 8892 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8893 %{ 8894 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8895 effect(KILL cr); 8896 8897 format %{ "shrl $dst, $shift" %} 8898 opcode(0xD3, 0x5); /* D3 /5 */ 8899 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8900 ins_pipe(ialu_mem_reg); 8901 %} 8902 8903 // Long Shift Instructions 8904 // Shift Left by one 8905 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8906 %{ 8907 match(Set dst (LShiftL dst shift)); 8908 effect(KILL cr); 8909 8910 format %{ "salq $dst, $shift" %} 8911 opcode(0xD1, 0x4); /* D1 /4 */ 8912 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8913 ins_pipe(ialu_reg); 8914 %} 8915 8916 // Shift Left by one 8917 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8918 %{ 8919 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8920 effect(KILL cr); 8921 8922 format %{ "salq $dst, $shift" %} 8923 opcode(0xD1, 0x4); /* D1 /4 */ 8924 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8925 ins_pipe(ialu_mem_imm); 8926 %} 8927 8928 // Shift Left by 8-bit immediate 8929 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8930 %{ 8931 match(Set dst (LShiftL dst shift)); 8932 effect(KILL cr); 8933 8934 format %{ "salq $dst, $shift" %} 8935 opcode(0xC1, 0x4); /* C1 /4 ib */ 8936 ins_encode(reg_opc_imm_wide(dst, shift)); 8937 ins_pipe(ialu_reg); 8938 %} 8939 8940 // Shift Left by 8-bit immediate 8941 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8942 %{ 8943 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8944 effect(KILL cr); 8945 8946 format %{ "salq $dst, $shift" %} 8947 opcode(0xC1, 0x4); /* C1 /4 ib */ 8948 ins_encode(REX_mem_wide(dst), OpcP, 8949 RM_opc_mem(secondary, dst), Con8or32(shift)); 8950 ins_pipe(ialu_mem_imm); 8951 %} 8952 8953 // Shift Left by variable 8954 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8955 %{ 8956 match(Set dst (LShiftL dst shift)); 8957 effect(KILL cr); 8958 8959 format %{ "salq $dst, $shift" %} 8960 opcode(0xD3, 0x4); /* D3 /4 */ 8961 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8962 ins_pipe(ialu_reg_reg); 8963 %} 8964 8965 // Shift Left by variable 8966 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8967 %{ 8968 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8969 effect(KILL cr); 8970 8971 format %{ "salq $dst, $shift" %} 8972 opcode(0xD3, 0x4); /* D3 /4 */ 8973 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8974 ins_pipe(ialu_mem_reg); 8975 %} 8976 8977 // Arithmetic shift right by one 8978 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8979 %{ 8980 match(Set dst (RShiftL dst shift)); 8981 effect(KILL cr); 8982 8983 format %{ "sarq $dst, $shift" %} 8984 opcode(0xD1, 0x7); /* D1 /7 */ 8985 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8986 ins_pipe(ialu_reg); 8987 %} 8988 8989 // Arithmetic shift right by one 8990 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8991 %{ 8992 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8993 effect(KILL cr); 8994 8995 format %{ "sarq $dst, $shift" %} 8996 opcode(0xD1, 0x7); /* D1 /7 */ 8997 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8998 ins_pipe(ialu_mem_imm); 8999 %} 9000 9001 // Arithmetic Shift Right by 8-bit immediate 9002 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9003 %{ 9004 match(Set dst (RShiftL dst shift)); 9005 effect(KILL cr); 9006 9007 format %{ "sarq $dst, $shift" %} 9008 opcode(0xC1, 0x7); /* C1 /7 ib */ 9009 ins_encode(reg_opc_imm_wide(dst, shift)); 9010 ins_pipe(ialu_mem_imm); 9011 %} 9012 9013 // Arithmetic Shift Right by 8-bit immediate 9014 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9015 %{ 9016 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9017 effect(KILL cr); 9018 9019 format %{ "sarq $dst, $shift" %} 9020 opcode(0xC1, 0x7); /* C1 /7 ib */ 9021 ins_encode(REX_mem_wide(dst), OpcP, 9022 RM_opc_mem(secondary, dst), Con8or32(shift)); 9023 ins_pipe(ialu_mem_imm); 9024 %} 9025 9026 // Arithmetic Shift Right by variable 9027 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9028 %{ 9029 match(Set dst (RShiftL dst shift)); 9030 effect(KILL cr); 9031 9032 format %{ "sarq $dst, $shift" %} 9033 opcode(0xD3, 0x7); /* D3 /7 */ 9034 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9035 ins_pipe(ialu_reg_reg); 9036 %} 9037 9038 // Arithmetic Shift Right by variable 9039 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9040 %{ 9041 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9042 effect(KILL cr); 9043 9044 format %{ "sarq $dst, $shift" %} 9045 opcode(0xD3, 0x7); /* D3 /7 */ 9046 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9047 ins_pipe(ialu_mem_reg); 9048 %} 9049 9050 // Logical shift right by one 9051 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9052 %{ 9053 match(Set dst (URShiftL dst shift)); 9054 effect(KILL cr); 9055 9056 format %{ "shrq $dst, $shift" %} 9057 opcode(0xD1, 0x5); /* D1 /5 */ 9058 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 9059 ins_pipe(ialu_reg); 9060 %} 9061 9062 // Logical shift right by one 9063 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9064 %{ 9065 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9066 effect(KILL cr); 9067 9068 format %{ "shrq $dst, $shift" %} 9069 opcode(0xD1, 0x5); /* D1 /5 */ 9070 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9071 ins_pipe(ialu_mem_imm); 9072 %} 9073 9074 // Logical Shift Right by 8-bit immediate 9075 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9076 %{ 9077 match(Set dst (URShiftL dst shift)); 9078 effect(KILL cr); 9079 9080 format %{ "shrq $dst, $shift" %} 9081 opcode(0xC1, 0x5); /* C1 /5 ib */ 9082 ins_encode(reg_opc_imm_wide(dst, shift)); 9083 ins_pipe(ialu_reg); 9084 %} 9085 9086 9087 // Logical Shift Right by 8-bit immediate 9088 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9089 %{ 9090 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9091 effect(KILL cr); 9092 9093 format %{ "shrq $dst, $shift" %} 9094 opcode(0xC1, 0x5); /* C1 /5 ib */ 9095 ins_encode(REX_mem_wide(dst), OpcP, 9096 RM_opc_mem(secondary, dst), Con8or32(shift)); 9097 ins_pipe(ialu_mem_imm); 9098 %} 9099 9100 // Logical Shift Right by variable 9101 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9102 %{ 9103 match(Set dst (URShiftL dst shift)); 9104 effect(KILL cr); 9105 9106 format %{ "shrq $dst, $shift" %} 9107 opcode(0xD3, 0x5); /* D3 /5 */ 9108 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9109 ins_pipe(ialu_reg_reg); 9110 %} 9111 9112 // Logical Shift Right by variable 9113 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9114 %{ 9115 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9116 effect(KILL cr); 9117 9118 format %{ "shrq $dst, $shift" %} 9119 opcode(0xD3, 0x5); /* D3 /5 */ 9120 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9121 ins_pipe(ialu_mem_reg); 9122 %} 9123 9124 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9125 // This idiom is used by the compiler for the i2b bytecode. 9126 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9127 %{ 9128 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9129 9130 format %{ "movsbl $dst, $src\t# i2b" %} 9131 opcode(0x0F, 0xBE); 9132 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9133 ins_pipe(ialu_reg_reg); 9134 %} 9135 9136 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9137 // This idiom is used by the compiler the i2s bytecode. 9138 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9139 %{ 9140 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9141 9142 format %{ "movswl $dst, $src\t# i2s" %} 9143 opcode(0x0F, 0xBF); 9144 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9145 ins_pipe(ialu_reg_reg); 9146 %} 9147 9148 // ROL/ROR instructions 9149 9150 // ROL expand 9151 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9152 effect(KILL cr, USE_DEF dst); 9153 9154 format %{ "roll $dst" %} 9155 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9156 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9157 ins_pipe(ialu_reg); 9158 %} 9159 9160 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9161 effect(USE_DEF dst, USE shift, KILL cr); 9162 9163 format %{ "roll $dst, $shift" %} 9164 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9165 ins_encode( reg_opc_imm(dst, shift) ); 9166 ins_pipe(ialu_reg); 9167 %} 9168 9169 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9170 %{ 9171 effect(USE_DEF dst, USE shift, KILL cr); 9172 9173 format %{ "roll $dst, $shift" %} 9174 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9175 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9176 ins_pipe(ialu_reg_reg); 9177 %} 9178 // end of ROL expand 9179 9180 // Rotate Left by one 9181 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9182 %{ 9183 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9184 9185 expand %{ 9186 rolI_rReg_imm1(dst, cr); 9187 %} 9188 %} 9189 9190 // Rotate Left by 8-bit immediate 9191 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9192 %{ 9193 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9194 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9195 9196 expand %{ 9197 rolI_rReg_imm8(dst, lshift, cr); 9198 %} 9199 %} 9200 9201 // Rotate Left by variable 9202 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9203 %{ 9204 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9205 9206 expand %{ 9207 rolI_rReg_CL(dst, shift, cr); 9208 %} 9209 %} 9210 9211 // Rotate Left by variable 9212 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9213 %{ 9214 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9215 9216 expand %{ 9217 rolI_rReg_CL(dst, shift, cr); 9218 %} 9219 %} 9220 9221 // ROR expand 9222 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9223 %{ 9224 effect(USE_DEF dst, KILL cr); 9225 9226 format %{ "rorl $dst" %} 9227 opcode(0xD1, 0x1); /* D1 /1 */ 9228 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9229 ins_pipe(ialu_reg); 9230 %} 9231 9232 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9233 %{ 9234 effect(USE_DEF dst, USE shift, KILL cr); 9235 9236 format %{ "rorl $dst, $shift" %} 9237 opcode(0xC1, 0x1); /* C1 /1 ib */ 9238 ins_encode(reg_opc_imm(dst, shift)); 9239 ins_pipe(ialu_reg); 9240 %} 9241 9242 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9243 %{ 9244 effect(USE_DEF dst, USE shift, KILL cr); 9245 9246 format %{ "rorl $dst, $shift" %} 9247 opcode(0xD3, 0x1); /* D3 /1 */ 9248 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9249 ins_pipe(ialu_reg_reg); 9250 %} 9251 // end of ROR expand 9252 9253 // Rotate Right by one 9254 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9255 %{ 9256 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9257 9258 expand %{ 9259 rorI_rReg_imm1(dst, cr); 9260 %} 9261 %} 9262 9263 // Rotate Right by 8-bit immediate 9264 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9265 %{ 9266 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9267 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9268 9269 expand %{ 9270 rorI_rReg_imm8(dst, rshift, cr); 9271 %} 9272 %} 9273 9274 // Rotate Right by variable 9275 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9276 %{ 9277 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9278 9279 expand %{ 9280 rorI_rReg_CL(dst, shift, cr); 9281 %} 9282 %} 9283 9284 // Rotate Right by variable 9285 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9286 %{ 9287 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9288 9289 expand %{ 9290 rorI_rReg_CL(dst, shift, cr); 9291 %} 9292 %} 9293 9294 // for long rotate 9295 // ROL expand 9296 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9297 effect(USE_DEF dst, KILL cr); 9298 9299 format %{ "rolq $dst" %} 9300 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9301 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9302 ins_pipe(ialu_reg); 9303 %} 9304 9305 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9306 effect(USE_DEF dst, USE shift, KILL cr); 9307 9308 format %{ "rolq $dst, $shift" %} 9309 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9310 ins_encode( reg_opc_imm_wide(dst, shift) ); 9311 ins_pipe(ialu_reg); 9312 %} 9313 9314 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9315 %{ 9316 effect(USE_DEF dst, USE shift, KILL cr); 9317 9318 format %{ "rolq $dst, $shift" %} 9319 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9320 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9321 ins_pipe(ialu_reg_reg); 9322 %} 9323 // end of ROL expand 9324 9325 // Rotate Left by one 9326 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9327 %{ 9328 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9329 9330 expand %{ 9331 rolL_rReg_imm1(dst, cr); 9332 %} 9333 %} 9334 9335 // Rotate Left by 8-bit immediate 9336 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9337 %{ 9338 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9339 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9340 9341 expand %{ 9342 rolL_rReg_imm8(dst, lshift, cr); 9343 %} 9344 %} 9345 9346 // Rotate Left by variable 9347 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9348 %{ 9349 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9350 9351 expand %{ 9352 rolL_rReg_CL(dst, shift, cr); 9353 %} 9354 %} 9355 9356 // Rotate Left by variable 9357 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9358 %{ 9359 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9360 9361 expand %{ 9362 rolL_rReg_CL(dst, shift, cr); 9363 %} 9364 %} 9365 9366 // ROR expand 9367 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9368 %{ 9369 effect(USE_DEF dst, KILL cr); 9370 9371 format %{ "rorq $dst" %} 9372 opcode(0xD1, 0x1); /* D1 /1 */ 9373 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9374 ins_pipe(ialu_reg); 9375 %} 9376 9377 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9378 %{ 9379 effect(USE_DEF dst, USE shift, KILL cr); 9380 9381 format %{ "rorq $dst, $shift" %} 9382 opcode(0xC1, 0x1); /* C1 /1 ib */ 9383 ins_encode(reg_opc_imm_wide(dst, shift)); 9384 ins_pipe(ialu_reg); 9385 %} 9386 9387 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9388 %{ 9389 effect(USE_DEF dst, USE shift, KILL cr); 9390 9391 format %{ "rorq $dst, $shift" %} 9392 opcode(0xD3, 0x1); /* D3 /1 */ 9393 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9394 ins_pipe(ialu_reg_reg); 9395 %} 9396 // end of ROR expand 9397 9398 // Rotate Right by one 9399 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9400 %{ 9401 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9402 9403 expand %{ 9404 rorL_rReg_imm1(dst, cr); 9405 %} 9406 %} 9407 9408 // Rotate Right by 8-bit immediate 9409 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9410 %{ 9411 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9412 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9413 9414 expand %{ 9415 rorL_rReg_imm8(dst, rshift, cr); 9416 %} 9417 %} 9418 9419 // Rotate Right by variable 9420 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9421 %{ 9422 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9423 9424 expand %{ 9425 rorL_rReg_CL(dst, shift, cr); 9426 %} 9427 %} 9428 9429 // Rotate Right by variable 9430 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9431 %{ 9432 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9433 9434 expand %{ 9435 rorL_rReg_CL(dst, shift, cr); 9436 %} 9437 %} 9438 9439 // Logical Instructions 9440 9441 // Integer Logical Instructions 9442 9443 // And Instructions 9444 // And Register with Register 9445 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9446 %{ 9447 match(Set dst (AndI dst src)); 9448 effect(KILL cr); 9449 9450 format %{ "andl $dst, $src\t# int" %} 9451 opcode(0x23); 9452 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9453 ins_pipe(ialu_reg_reg); 9454 %} 9455 9456 // And Register with Immediate 255 9457 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9458 %{ 9459 match(Set dst (AndI dst src)); 9460 9461 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9462 opcode(0x0F, 0xB6); 9463 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9464 ins_pipe(ialu_reg); 9465 %} 9466 9467 // And Register with Immediate 255 and promote to long 9468 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9469 %{ 9470 match(Set dst (ConvI2L (AndI src mask))); 9471 9472 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9473 opcode(0x0F, 0xB6); 9474 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9475 ins_pipe(ialu_reg); 9476 %} 9477 9478 // And Register with Immediate 65535 9479 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9480 %{ 9481 match(Set dst (AndI dst src)); 9482 9483 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9484 opcode(0x0F, 0xB7); 9485 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9486 ins_pipe(ialu_reg); 9487 %} 9488 9489 // And Register with Immediate 65535 and promote to long 9490 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9491 %{ 9492 match(Set dst (ConvI2L (AndI src mask))); 9493 9494 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9495 opcode(0x0F, 0xB7); 9496 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9497 ins_pipe(ialu_reg); 9498 %} 9499 9500 // And Register with Immediate 9501 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9502 %{ 9503 match(Set dst (AndI dst src)); 9504 effect(KILL cr); 9505 9506 format %{ "andl $dst, $src\t# int" %} 9507 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9508 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9509 ins_pipe(ialu_reg); 9510 %} 9511 9512 // And Register with Memory 9513 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9514 %{ 9515 match(Set dst (AndI dst (LoadI src))); 9516 effect(KILL cr); 9517 9518 ins_cost(125); 9519 format %{ "andl $dst, $src\t# int" %} 9520 opcode(0x23); 9521 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9522 ins_pipe(ialu_reg_mem); 9523 %} 9524 9525 // And Memory with Register 9526 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9527 %{ 9528 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9529 effect(KILL cr); 9530 9531 ins_cost(150); 9532 format %{ "andb $dst, $src\t# byte" %} 9533 opcode(0x20); 9534 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9535 ins_pipe(ialu_mem_reg); 9536 %} 9537 9538 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9539 %{ 9540 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9541 effect(KILL cr); 9542 9543 ins_cost(150); 9544 format %{ "andl $dst, $src\t# int" %} 9545 opcode(0x21); /* Opcode 21 /r */ 9546 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9547 ins_pipe(ialu_mem_reg); 9548 %} 9549 9550 // And Memory with Immediate 9551 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9552 %{ 9553 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9554 effect(KILL cr); 9555 9556 ins_cost(125); 9557 format %{ "andl $dst, $src\t# int" %} 9558 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9559 ins_encode(REX_mem(dst), OpcSE(src), 9560 RM_opc_mem(secondary, dst), Con8or32(src)); 9561 ins_pipe(ialu_mem_imm); 9562 %} 9563 9564 // BMI1 instructions 9565 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9566 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9567 predicate(UseBMI1Instructions); 9568 effect(KILL cr); 9569 9570 ins_cost(125); 9571 format %{ "andnl $dst, $src1, $src2" %} 9572 9573 ins_encode %{ 9574 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9575 %} 9576 ins_pipe(ialu_reg_mem); 9577 %} 9578 9579 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9580 match(Set dst (AndI (XorI src1 minus_1) src2)); 9581 predicate(UseBMI1Instructions); 9582 effect(KILL cr); 9583 9584 format %{ "andnl $dst, $src1, $src2" %} 9585 9586 ins_encode %{ 9587 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9588 %} 9589 ins_pipe(ialu_reg); 9590 %} 9591 9592 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9593 match(Set dst (AndI (SubI imm_zero src) src)); 9594 predicate(UseBMI1Instructions); 9595 effect(KILL cr); 9596 9597 format %{ "blsil $dst, $src" %} 9598 9599 ins_encode %{ 9600 __ blsil($dst$$Register, $src$$Register); 9601 %} 9602 ins_pipe(ialu_reg); 9603 %} 9604 9605 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9606 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9607 predicate(UseBMI1Instructions); 9608 effect(KILL cr); 9609 9610 ins_cost(125); 9611 format %{ "blsil $dst, $src" %} 9612 9613 ins_encode %{ 9614 __ blsil($dst$$Register, $src$$Address); 9615 %} 9616 ins_pipe(ialu_reg_mem); 9617 %} 9618 9619 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9620 %{ 9621 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9622 predicate(UseBMI1Instructions); 9623 effect(KILL cr); 9624 9625 ins_cost(125); 9626 format %{ "blsmskl $dst, $src" %} 9627 9628 ins_encode %{ 9629 __ blsmskl($dst$$Register, $src$$Address); 9630 %} 9631 ins_pipe(ialu_reg_mem); 9632 %} 9633 9634 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9635 %{ 9636 match(Set dst (XorI (AddI src minus_1) src)); 9637 predicate(UseBMI1Instructions); 9638 effect(KILL cr); 9639 9640 format %{ "blsmskl $dst, $src" %} 9641 9642 ins_encode %{ 9643 __ blsmskl($dst$$Register, $src$$Register); 9644 %} 9645 9646 ins_pipe(ialu_reg); 9647 %} 9648 9649 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9650 %{ 9651 match(Set dst (AndI (AddI src minus_1) src) ); 9652 predicate(UseBMI1Instructions); 9653 effect(KILL cr); 9654 9655 format %{ "blsrl $dst, $src" %} 9656 9657 ins_encode %{ 9658 __ blsrl($dst$$Register, $src$$Register); 9659 %} 9660 9661 ins_pipe(ialu_reg_mem); 9662 %} 9663 9664 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9665 %{ 9666 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9667 predicate(UseBMI1Instructions); 9668 effect(KILL cr); 9669 9670 ins_cost(125); 9671 format %{ "blsrl $dst, $src" %} 9672 9673 ins_encode %{ 9674 __ blsrl($dst$$Register, $src$$Address); 9675 %} 9676 9677 ins_pipe(ialu_reg); 9678 %} 9679 9680 // Or Instructions 9681 // Or Register with Register 9682 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9683 %{ 9684 match(Set dst (OrI dst src)); 9685 effect(KILL cr); 9686 9687 format %{ "orl $dst, $src\t# int" %} 9688 opcode(0x0B); 9689 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9690 ins_pipe(ialu_reg_reg); 9691 %} 9692 9693 // Or Register with Immediate 9694 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9695 %{ 9696 match(Set dst (OrI dst src)); 9697 effect(KILL cr); 9698 9699 format %{ "orl $dst, $src\t# int" %} 9700 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9701 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9702 ins_pipe(ialu_reg); 9703 %} 9704 9705 // Or Register with Memory 9706 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9707 %{ 9708 match(Set dst (OrI dst (LoadI src))); 9709 effect(KILL cr); 9710 9711 ins_cost(125); 9712 format %{ "orl $dst, $src\t# int" %} 9713 opcode(0x0B); 9714 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9715 ins_pipe(ialu_reg_mem); 9716 %} 9717 9718 // Or Memory with Register 9719 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9720 %{ 9721 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9722 effect(KILL cr); 9723 9724 ins_cost(150); 9725 format %{ "orb $dst, $src\t# byte" %} 9726 opcode(0x08); 9727 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9728 ins_pipe(ialu_mem_reg); 9729 %} 9730 9731 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9732 %{ 9733 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9734 effect(KILL cr); 9735 9736 ins_cost(150); 9737 format %{ "orl $dst, $src\t# int" %} 9738 opcode(0x09); /* Opcode 09 /r */ 9739 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9740 ins_pipe(ialu_mem_reg); 9741 %} 9742 9743 // Or Memory with Immediate 9744 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9745 %{ 9746 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9747 effect(KILL cr); 9748 9749 ins_cost(125); 9750 format %{ "orl $dst, $src\t# int" %} 9751 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9752 ins_encode(REX_mem(dst), OpcSE(src), 9753 RM_opc_mem(secondary, dst), Con8or32(src)); 9754 ins_pipe(ialu_mem_imm); 9755 %} 9756 9757 // Xor Instructions 9758 // Xor Register with Register 9759 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9760 %{ 9761 match(Set dst (XorI dst src)); 9762 effect(KILL cr); 9763 9764 format %{ "xorl $dst, $src\t# int" %} 9765 opcode(0x33); 9766 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9767 ins_pipe(ialu_reg_reg); 9768 %} 9769 9770 // Xor Register with Immediate -1 9771 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9772 match(Set dst (XorI dst imm)); 9773 9774 format %{ "not $dst" %} 9775 ins_encode %{ 9776 __ notl($dst$$Register); 9777 %} 9778 ins_pipe(ialu_reg); 9779 %} 9780 9781 // Xor Register with Immediate 9782 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9783 %{ 9784 match(Set dst (XorI dst src)); 9785 effect(KILL cr); 9786 9787 format %{ "xorl $dst, $src\t# int" %} 9788 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9789 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9790 ins_pipe(ialu_reg); 9791 %} 9792 9793 // Xor Register with Memory 9794 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9795 %{ 9796 match(Set dst (XorI dst (LoadI src))); 9797 effect(KILL cr); 9798 9799 ins_cost(125); 9800 format %{ "xorl $dst, $src\t# int" %} 9801 opcode(0x33); 9802 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9803 ins_pipe(ialu_reg_mem); 9804 %} 9805 9806 // Xor Memory with Register 9807 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9808 %{ 9809 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9810 effect(KILL cr); 9811 9812 ins_cost(150); 9813 format %{ "xorb $dst, $src\t# byte" %} 9814 opcode(0x30); 9815 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9816 ins_pipe(ialu_mem_reg); 9817 %} 9818 9819 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9820 %{ 9821 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9822 effect(KILL cr); 9823 9824 ins_cost(150); 9825 format %{ "xorl $dst, $src\t# int" %} 9826 opcode(0x31); /* Opcode 31 /r */ 9827 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9828 ins_pipe(ialu_mem_reg); 9829 %} 9830 9831 // Xor Memory with Immediate 9832 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9833 %{ 9834 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9835 effect(KILL cr); 9836 9837 ins_cost(125); 9838 format %{ "xorl $dst, $src\t# int" %} 9839 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9840 ins_encode(REX_mem(dst), OpcSE(src), 9841 RM_opc_mem(secondary, dst), Con8or32(src)); 9842 ins_pipe(ialu_mem_imm); 9843 %} 9844 9845 9846 // Long Logical Instructions 9847 9848 // And Instructions 9849 // And Register with Register 9850 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9851 %{ 9852 match(Set dst (AndL dst src)); 9853 effect(KILL cr); 9854 9855 format %{ "andq $dst, $src\t# long" %} 9856 opcode(0x23); 9857 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9858 ins_pipe(ialu_reg_reg); 9859 %} 9860 9861 // And Register with Immediate 255 9862 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9863 %{ 9864 match(Set dst (AndL dst src)); 9865 9866 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9867 opcode(0x0F, 0xB6); 9868 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9869 ins_pipe(ialu_reg); 9870 %} 9871 9872 // And Register with Immediate 65535 9873 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9874 %{ 9875 match(Set dst (AndL dst src)); 9876 9877 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9878 opcode(0x0F, 0xB7); 9879 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9880 ins_pipe(ialu_reg); 9881 %} 9882 9883 // And Register with Immediate 9884 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9885 %{ 9886 match(Set dst (AndL dst src)); 9887 effect(KILL cr); 9888 9889 format %{ "andq $dst, $src\t# long" %} 9890 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9891 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9892 ins_pipe(ialu_reg); 9893 %} 9894 9895 // And Register with Memory 9896 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9897 %{ 9898 match(Set dst (AndL dst (LoadL src))); 9899 effect(KILL cr); 9900 9901 ins_cost(125); 9902 format %{ "andq $dst, $src\t# long" %} 9903 opcode(0x23); 9904 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9905 ins_pipe(ialu_reg_mem); 9906 %} 9907 9908 // And Memory with Register 9909 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9910 %{ 9911 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9912 effect(KILL cr); 9913 9914 ins_cost(150); 9915 format %{ "andq $dst, $src\t# long" %} 9916 opcode(0x21); /* Opcode 21 /r */ 9917 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9918 ins_pipe(ialu_mem_reg); 9919 %} 9920 9921 // And Memory with Immediate 9922 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9923 %{ 9924 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9925 effect(KILL cr); 9926 9927 ins_cost(125); 9928 format %{ "andq $dst, $src\t# long" %} 9929 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9930 ins_encode(REX_mem_wide(dst), OpcSE(src), 9931 RM_opc_mem(secondary, dst), Con8or32(src)); 9932 ins_pipe(ialu_mem_imm); 9933 %} 9934 9935 // BMI1 instructions 9936 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9937 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9938 predicate(UseBMI1Instructions); 9939 effect(KILL cr); 9940 9941 ins_cost(125); 9942 format %{ "andnq $dst, $src1, $src2" %} 9943 9944 ins_encode %{ 9945 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9946 %} 9947 ins_pipe(ialu_reg_mem); 9948 %} 9949 9950 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9951 match(Set dst (AndL (XorL src1 minus_1) src2)); 9952 predicate(UseBMI1Instructions); 9953 effect(KILL cr); 9954 9955 format %{ "andnq $dst, $src1, $src2" %} 9956 9957 ins_encode %{ 9958 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9959 %} 9960 ins_pipe(ialu_reg_mem); 9961 %} 9962 9963 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9964 match(Set dst (AndL (SubL imm_zero src) src)); 9965 predicate(UseBMI1Instructions); 9966 effect(KILL cr); 9967 9968 format %{ "blsiq $dst, $src" %} 9969 9970 ins_encode %{ 9971 __ blsiq($dst$$Register, $src$$Register); 9972 %} 9973 ins_pipe(ialu_reg); 9974 %} 9975 9976 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9977 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9978 predicate(UseBMI1Instructions); 9979 effect(KILL cr); 9980 9981 ins_cost(125); 9982 format %{ "blsiq $dst, $src" %} 9983 9984 ins_encode %{ 9985 __ blsiq($dst$$Register, $src$$Address); 9986 %} 9987 ins_pipe(ialu_reg_mem); 9988 %} 9989 9990 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9991 %{ 9992 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9993 predicate(UseBMI1Instructions); 9994 effect(KILL cr); 9995 9996 ins_cost(125); 9997 format %{ "blsmskq $dst, $src" %} 9998 9999 ins_encode %{ 10000 __ blsmskq($dst$$Register, $src$$Address); 10001 %} 10002 ins_pipe(ialu_reg_mem); 10003 %} 10004 10005 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10006 %{ 10007 match(Set dst (XorL (AddL src minus_1) src)); 10008 predicate(UseBMI1Instructions); 10009 effect(KILL cr); 10010 10011 format %{ "blsmskq $dst, $src" %} 10012 10013 ins_encode %{ 10014 __ blsmskq($dst$$Register, $src$$Register); 10015 %} 10016 10017 ins_pipe(ialu_reg); 10018 %} 10019 10020 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10021 %{ 10022 match(Set dst (AndL (AddL src minus_1) src) ); 10023 predicate(UseBMI1Instructions); 10024 effect(KILL cr); 10025 10026 format %{ "blsrq $dst, $src" %} 10027 10028 ins_encode %{ 10029 __ blsrq($dst$$Register, $src$$Register); 10030 %} 10031 10032 ins_pipe(ialu_reg); 10033 %} 10034 10035 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10036 %{ 10037 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 10038 predicate(UseBMI1Instructions); 10039 effect(KILL cr); 10040 10041 ins_cost(125); 10042 format %{ "blsrq $dst, $src" %} 10043 10044 ins_encode %{ 10045 __ blsrq($dst$$Register, $src$$Address); 10046 %} 10047 10048 ins_pipe(ialu_reg); 10049 %} 10050 10051 // Or Instructions 10052 // Or Register with Register 10053 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10054 %{ 10055 match(Set dst (OrL dst src)); 10056 effect(KILL cr); 10057 10058 format %{ "orq $dst, $src\t# long" %} 10059 opcode(0x0B); 10060 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10061 ins_pipe(ialu_reg_reg); 10062 %} 10063 10064 // Use any_RegP to match R15 (TLS register) without spilling. 10065 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 10066 match(Set dst (OrL dst (CastP2X src))); 10067 effect(KILL cr); 10068 10069 format %{ "orq $dst, $src\t# long" %} 10070 opcode(0x0B); 10071 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10072 ins_pipe(ialu_reg_reg); 10073 %} 10074 10075 10076 // Or Register with Immediate 10077 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10078 %{ 10079 match(Set dst (OrL dst src)); 10080 effect(KILL cr); 10081 10082 format %{ "orq $dst, $src\t# long" %} 10083 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 10084 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10085 ins_pipe(ialu_reg); 10086 %} 10087 10088 // Or Register with Memory 10089 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10090 %{ 10091 match(Set dst (OrL dst (LoadL src))); 10092 effect(KILL cr); 10093 10094 ins_cost(125); 10095 format %{ "orq $dst, $src\t# long" %} 10096 opcode(0x0B); 10097 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10098 ins_pipe(ialu_reg_mem); 10099 %} 10100 10101 // Or Memory with Register 10102 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10103 %{ 10104 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10105 effect(KILL cr); 10106 10107 ins_cost(150); 10108 format %{ "orq $dst, $src\t# long" %} 10109 opcode(0x09); /* Opcode 09 /r */ 10110 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10111 ins_pipe(ialu_mem_reg); 10112 %} 10113 10114 // Or Memory with Immediate 10115 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10116 %{ 10117 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10118 effect(KILL cr); 10119 10120 ins_cost(125); 10121 format %{ "orq $dst, $src\t# long" %} 10122 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 10123 ins_encode(REX_mem_wide(dst), OpcSE(src), 10124 RM_opc_mem(secondary, dst), Con8or32(src)); 10125 ins_pipe(ialu_mem_imm); 10126 %} 10127 10128 // Xor Instructions 10129 // Xor Register with Register 10130 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10131 %{ 10132 match(Set dst (XorL dst src)); 10133 effect(KILL cr); 10134 10135 format %{ "xorq $dst, $src\t# long" %} 10136 opcode(0x33); 10137 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10138 ins_pipe(ialu_reg_reg); 10139 %} 10140 10141 // Xor Register with Immediate -1 10142 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10143 match(Set dst (XorL dst imm)); 10144 10145 format %{ "notq $dst" %} 10146 ins_encode %{ 10147 __ notq($dst$$Register); 10148 %} 10149 ins_pipe(ialu_reg); 10150 %} 10151 10152 // Xor Register with Immediate 10153 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10154 %{ 10155 match(Set dst (XorL dst src)); 10156 effect(KILL cr); 10157 10158 format %{ "xorq $dst, $src\t# long" %} 10159 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10160 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10161 ins_pipe(ialu_reg); 10162 %} 10163 10164 // Xor Register with Memory 10165 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10166 %{ 10167 match(Set dst (XorL dst (LoadL src))); 10168 effect(KILL cr); 10169 10170 ins_cost(125); 10171 format %{ "xorq $dst, $src\t# long" %} 10172 opcode(0x33); 10173 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10174 ins_pipe(ialu_reg_mem); 10175 %} 10176 10177 // Xor Memory with Register 10178 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10179 %{ 10180 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10181 effect(KILL cr); 10182 10183 ins_cost(150); 10184 format %{ "xorq $dst, $src\t# long" %} 10185 opcode(0x31); /* Opcode 31 /r */ 10186 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10187 ins_pipe(ialu_mem_reg); 10188 %} 10189 10190 // Xor Memory with Immediate 10191 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10192 %{ 10193 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10194 effect(KILL cr); 10195 10196 ins_cost(125); 10197 format %{ "xorq $dst, $src\t# long" %} 10198 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10199 ins_encode(REX_mem_wide(dst), OpcSE(src), 10200 RM_opc_mem(secondary, dst), Con8or32(src)); 10201 ins_pipe(ialu_mem_imm); 10202 %} 10203 10204 // Convert Int to Boolean 10205 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10206 %{ 10207 match(Set dst (Conv2B src)); 10208 effect(KILL cr); 10209 10210 format %{ "testl $src, $src\t# ci2b\n\t" 10211 "setnz $dst\n\t" 10212 "movzbl $dst, $dst" %} 10213 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10214 setNZ_reg(dst), 10215 REX_reg_breg(dst, dst), // movzbl 10216 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10217 ins_pipe(pipe_slow); // XXX 10218 %} 10219 10220 // Convert Pointer to Boolean 10221 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10222 %{ 10223 match(Set dst (Conv2B src)); 10224 effect(KILL cr); 10225 10226 format %{ "testq $src, $src\t# cp2b\n\t" 10227 "setnz $dst\n\t" 10228 "movzbl $dst, $dst" %} 10229 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10230 setNZ_reg(dst), 10231 REX_reg_breg(dst, dst), // movzbl 10232 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10233 ins_pipe(pipe_slow); // XXX 10234 %} 10235 10236 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10237 %{ 10238 match(Set dst (CmpLTMask p q)); 10239 effect(KILL cr); 10240 10241 ins_cost(400); 10242 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10243 "setlt $dst\n\t" 10244 "movzbl $dst, $dst\n\t" 10245 "negl $dst" %} 10246 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10247 setLT_reg(dst), 10248 REX_reg_breg(dst, dst), // movzbl 10249 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10250 neg_reg(dst)); 10251 ins_pipe(pipe_slow); 10252 %} 10253 10254 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10255 %{ 10256 match(Set dst (CmpLTMask dst zero)); 10257 effect(KILL cr); 10258 10259 ins_cost(100); 10260 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10261 ins_encode %{ 10262 __ sarl($dst$$Register, 31); 10263 %} 10264 ins_pipe(ialu_reg); 10265 %} 10266 10267 /* Better to save a register than avoid a branch */ 10268 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10269 %{ 10270 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10271 effect(KILL cr); 10272 ins_cost(300); 10273 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10274 "jge done\n\t" 10275 "addl $p,$y\n" 10276 "done: " %} 10277 ins_encode %{ 10278 Register Rp = $p$$Register; 10279 Register Rq = $q$$Register; 10280 Register Ry = $y$$Register; 10281 Label done; 10282 __ subl(Rp, Rq); 10283 __ jccb(Assembler::greaterEqual, done); 10284 __ addl(Rp, Ry); 10285 __ bind(done); 10286 %} 10287 ins_pipe(pipe_cmplt); 10288 %} 10289 10290 /* Better to save a register than avoid a branch */ 10291 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10292 %{ 10293 match(Set y (AndI (CmpLTMask p q) y)); 10294 effect(KILL cr); 10295 10296 ins_cost(300); 10297 10298 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10299 "jlt done\n\t" 10300 "xorl $y, $y\n" 10301 "done: " %} 10302 ins_encode %{ 10303 Register Rp = $p$$Register; 10304 Register Rq = $q$$Register; 10305 Register Ry = $y$$Register; 10306 Label done; 10307 __ cmpl(Rp, Rq); 10308 __ jccb(Assembler::less, done); 10309 __ xorl(Ry, Ry); 10310 __ bind(done); 10311 %} 10312 ins_pipe(pipe_cmplt); 10313 %} 10314 10315 10316 //---------- FP Instructions------------------------------------------------ 10317 10318 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10319 %{ 10320 match(Set cr (CmpF src1 src2)); 10321 10322 ins_cost(145); 10323 format %{ "ucomiss $src1, $src2\n\t" 10324 "jnp,s exit\n\t" 10325 "pushfq\t# saw NaN, set CF\n\t" 10326 "andq [rsp], #0xffffff2b\n\t" 10327 "popfq\n" 10328 "exit:" %} 10329 ins_encode %{ 10330 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10331 emit_cmpfp_fixup(_masm); 10332 %} 10333 ins_pipe(pipe_slow); 10334 %} 10335 10336 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10337 match(Set cr (CmpF src1 src2)); 10338 10339 ins_cost(100); 10340 format %{ "ucomiss $src1, $src2" %} 10341 ins_encode %{ 10342 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10343 %} 10344 ins_pipe(pipe_slow); 10345 %} 10346 10347 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10348 %{ 10349 match(Set cr (CmpF src1 (LoadF src2))); 10350 10351 ins_cost(145); 10352 format %{ "ucomiss $src1, $src2\n\t" 10353 "jnp,s exit\n\t" 10354 "pushfq\t# saw NaN, set CF\n\t" 10355 "andq [rsp], #0xffffff2b\n\t" 10356 "popfq\n" 10357 "exit:" %} 10358 ins_encode %{ 10359 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10360 emit_cmpfp_fixup(_masm); 10361 %} 10362 ins_pipe(pipe_slow); 10363 %} 10364 10365 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10366 match(Set cr (CmpF src1 (LoadF src2))); 10367 10368 ins_cost(100); 10369 format %{ "ucomiss $src1, $src2" %} 10370 ins_encode %{ 10371 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10372 %} 10373 ins_pipe(pipe_slow); 10374 %} 10375 10376 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10377 match(Set cr (CmpF src con)); 10378 10379 ins_cost(145); 10380 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10381 "jnp,s exit\n\t" 10382 "pushfq\t# saw NaN, set CF\n\t" 10383 "andq [rsp], #0xffffff2b\n\t" 10384 "popfq\n" 10385 "exit:" %} 10386 ins_encode %{ 10387 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10388 emit_cmpfp_fixup(_masm); 10389 %} 10390 ins_pipe(pipe_slow); 10391 %} 10392 10393 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10394 match(Set cr (CmpF src con)); 10395 ins_cost(100); 10396 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10397 ins_encode %{ 10398 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10399 %} 10400 ins_pipe(pipe_slow); 10401 %} 10402 10403 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10404 %{ 10405 match(Set cr (CmpD src1 src2)); 10406 10407 ins_cost(145); 10408 format %{ "ucomisd $src1, $src2\n\t" 10409 "jnp,s exit\n\t" 10410 "pushfq\t# saw NaN, set CF\n\t" 10411 "andq [rsp], #0xffffff2b\n\t" 10412 "popfq\n" 10413 "exit:" %} 10414 ins_encode %{ 10415 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10416 emit_cmpfp_fixup(_masm); 10417 %} 10418 ins_pipe(pipe_slow); 10419 %} 10420 10421 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10422 match(Set cr (CmpD src1 src2)); 10423 10424 ins_cost(100); 10425 format %{ "ucomisd $src1, $src2 test" %} 10426 ins_encode %{ 10427 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10428 %} 10429 ins_pipe(pipe_slow); 10430 %} 10431 10432 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10433 %{ 10434 match(Set cr (CmpD src1 (LoadD src2))); 10435 10436 ins_cost(145); 10437 format %{ "ucomisd $src1, $src2\n\t" 10438 "jnp,s exit\n\t" 10439 "pushfq\t# saw NaN, set CF\n\t" 10440 "andq [rsp], #0xffffff2b\n\t" 10441 "popfq\n" 10442 "exit:" %} 10443 ins_encode %{ 10444 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10445 emit_cmpfp_fixup(_masm); 10446 %} 10447 ins_pipe(pipe_slow); 10448 %} 10449 10450 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10451 match(Set cr (CmpD src1 (LoadD src2))); 10452 10453 ins_cost(100); 10454 format %{ "ucomisd $src1, $src2" %} 10455 ins_encode %{ 10456 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10457 %} 10458 ins_pipe(pipe_slow); 10459 %} 10460 10461 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10462 match(Set cr (CmpD src con)); 10463 10464 ins_cost(145); 10465 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10466 "jnp,s exit\n\t" 10467 "pushfq\t# saw NaN, set CF\n\t" 10468 "andq [rsp], #0xffffff2b\n\t" 10469 "popfq\n" 10470 "exit:" %} 10471 ins_encode %{ 10472 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10473 emit_cmpfp_fixup(_masm); 10474 %} 10475 ins_pipe(pipe_slow); 10476 %} 10477 10478 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10479 match(Set cr (CmpD src con)); 10480 ins_cost(100); 10481 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10482 ins_encode %{ 10483 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10484 %} 10485 ins_pipe(pipe_slow); 10486 %} 10487 10488 // Compare into -1,0,1 10489 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10490 %{ 10491 match(Set dst (CmpF3 src1 src2)); 10492 effect(KILL cr); 10493 10494 ins_cost(275); 10495 format %{ "ucomiss $src1, $src2\n\t" 10496 "movl $dst, #-1\n\t" 10497 "jp,s done\n\t" 10498 "jb,s done\n\t" 10499 "setne $dst\n\t" 10500 "movzbl $dst, $dst\n" 10501 "done:" %} 10502 ins_encode %{ 10503 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10504 emit_cmpfp3(_masm, $dst$$Register); 10505 %} 10506 ins_pipe(pipe_slow); 10507 %} 10508 10509 // Compare into -1,0,1 10510 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10511 %{ 10512 match(Set dst (CmpF3 src1 (LoadF src2))); 10513 effect(KILL cr); 10514 10515 ins_cost(275); 10516 format %{ "ucomiss $src1, $src2\n\t" 10517 "movl $dst, #-1\n\t" 10518 "jp,s done\n\t" 10519 "jb,s done\n\t" 10520 "setne $dst\n\t" 10521 "movzbl $dst, $dst\n" 10522 "done:" %} 10523 ins_encode %{ 10524 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10525 emit_cmpfp3(_masm, $dst$$Register); 10526 %} 10527 ins_pipe(pipe_slow); 10528 %} 10529 10530 // Compare into -1,0,1 10531 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10532 match(Set dst (CmpF3 src con)); 10533 effect(KILL cr); 10534 10535 ins_cost(275); 10536 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10537 "movl $dst, #-1\n\t" 10538 "jp,s done\n\t" 10539 "jb,s done\n\t" 10540 "setne $dst\n\t" 10541 "movzbl $dst, $dst\n" 10542 "done:" %} 10543 ins_encode %{ 10544 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10545 emit_cmpfp3(_masm, $dst$$Register); 10546 %} 10547 ins_pipe(pipe_slow); 10548 %} 10549 10550 // Compare into -1,0,1 10551 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10552 %{ 10553 match(Set dst (CmpD3 src1 src2)); 10554 effect(KILL cr); 10555 10556 ins_cost(275); 10557 format %{ "ucomisd $src1, $src2\n\t" 10558 "movl $dst, #-1\n\t" 10559 "jp,s done\n\t" 10560 "jb,s done\n\t" 10561 "setne $dst\n\t" 10562 "movzbl $dst, $dst\n" 10563 "done:" %} 10564 ins_encode %{ 10565 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10566 emit_cmpfp3(_masm, $dst$$Register); 10567 %} 10568 ins_pipe(pipe_slow); 10569 %} 10570 10571 // Compare into -1,0,1 10572 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10573 %{ 10574 match(Set dst (CmpD3 src1 (LoadD src2))); 10575 effect(KILL cr); 10576 10577 ins_cost(275); 10578 format %{ "ucomisd $src1, $src2\n\t" 10579 "movl $dst, #-1\n\t" 10580 "jp,s done\n\t" 10581 "jb,s done\n\t" 10582 "setne $dst\n\t" 10583 "movzbl $dst, $dst\n" 10584 "done:" %} 10585 ins_encode %{ 10586 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10587 emit_cmpfp3(_masm, $dst$$Register); 10588 %} 10589 ins_pipe(pipe_slow); 10590 %} 10591 10592 // Compare into -1,0,1 10593 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10594 match(Set dst (CmpD3 src con)); 10595 effect(KILL cr); 10596 10597 ins_cost(275); 10598 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10599 "movl $dst, #-1\n\t" 10600 "jp,s done\n\t" 10601 "jb,s done\n\t" 10602 "setne $dst\n\t" 10603 "movzbl $dst, $dst\n" 10604 "done:" %} 10605 ins_encode %{ 10606 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10607 emit_cmpfp3(_masm, $dst$$Register); 10608 %} 10609 ins_pipe(pipe_slow); 10610 %} 10611 10612 //----------Arithmetic Conversion Instructions--------------------------------- 10613 10614 instruct roundFloat_nop(regF dst) 10615 %{ 10616 match(Set dst (RoundFloat dst)); 10617 10618 ins_cost(0); 10619 ins_encode(); 10620 ins_pipe(empty); 10621 %} 10622 10623 instruct roundDouble_nop(regD dst) 10624 %{ 10625 match(Set dst (RoundDouble dst)); 10626 10627 ins_cost(0); 10628 ins_encode(); 10629 ins_pipe(empty); 10630 %} 10631 10632 instruct convF2D_reg_reg(regD dst, regF src) 10633 %{ 10634 match(Set dst (ConvF2D src)); 10635 10636 format %{ "cvtss2sd $dst, $src" %} 10637 ins_encode %{ 10638 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10639 %} 10640 ins_pipe(pipe_slow); // XXX 10641 %} 10642 10643 instruct convF2D_reg_mem(regD dst, memory src) 10644 %{ 10645 match(Set dst (ConvF2D (LoadF src))); 10646 10647 format %{ "cvtss2sd $dst, $src" %} 10648 ins_encode %{ 10649 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10650 %} 10651 ins_pipe(pipe_slow); // XXX 10652 %} 10653 10654 instruct convD2F_reg_reg(regF dst, regD src) 10655 %{ 10656 match(Set dst (ConvD2F src)); 10657 10658 format %{ "cvtsd2ss $dst, $src" %} 10659 ins_encode %{ 10660 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10661 %} 10662 ins_pipe(pipe_slow); // XXX 10663 %} 10664 10665 instruct convD2F_reg_mem(regF dst, memory src) 10666 %{ 10667 match(Set dst (ConvD2F (LoadD src))); 10668 10669 format %{ "cvtsd2ss $dst, $src" %} 10670 ins_encode %{ 10671 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10672 %} 10673 ins_pipe(pipe_slow); // XXX 10674 %} 10675 10676 // XXX do mem variants 10677 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10678 %{ 10679 match(Set dst (ConvF2I src)); 10680 effect(KILL cr); 10681 10682 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10683 "cmpl $dst, #0x80000000\n\t" 10684 "jne,s done\n\t" 10685 "subq rsp, #8\n\t" 10686 "movss [rsp], $src\n\t" 10687 "call f2i_fixup\n\t" 10688 "popq $dst\n" 10689 "done: "%} 10690 ins_encode %{ 10691 Label done; 10692 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10693 __ cmpl($dst$$Register, 0x80000000); 10694 __ jccb(Assembler::notEqual, done); 10695 __ subptr(rsp, 8); 10696 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10697 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10698 __ pop($dst$$Register); 10699 __ bind(done); 10700 %} 10701 ins_pipe(pipe_slow); 10702 %} 10703 10704 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10705 %{ 10706 match(Set dst (ConvF2L src)); 10707 effect(KILL cr); 10708 10709 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10710 "cmpq $dst, [0x8000000000000000]\n\t" 10711 "jne,s done\n\t" 10712 "subq rsp, #8\n\t" 10713 "movss [rsp], $src\n\t" 10714 "call f2l_fixup\n\t" 10715 "popq $dst\n" 10716 "done: "%} 10717 ins_encode %{ 10718 Label done; 10719 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10720 __ cmp64($dst$$Register, 10721 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10722 __ jccb(Assembler::notEqual, done); 10723 __ subptr(rsp, 8); 10724 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10725 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10726 __ pop($dst$$Register); 10727 __ bind(done); 10728 %} 10729 ins_pipe(pipe_slow); 10730 %} 10731 10732 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10733 %{ 10734 match(Set dst (ConvD2I src)); 10735 effect(KILL cr); 10736 10737 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10738 "cmpl $dst, #0x80000000\n\t" 10739 "jne,s done\n\t" 10740 "subq rsp, #8\n\t" 10741 "movsd [rsp], $src\n\t" 10742 "call d2i_fixup\n\t" 10743 "popq $dst\n" 10744 "done: "%} 10745 ins_encode %{ 10746 Label done; 10747 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10748 __ cmpl($dst$$Register, 0x80000000); 10749 __ jccb(Assembler::notEqual, done); 10750 __ subptr(rsp, 8); 10751 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10752 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10753 __ pop($dst$$Register); 10754 __ bind(done); 10755 %} 10756 ins_pipe(pipe_slow); 10757 %} 10758 10759 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10760 %{ 10761 match(Set dst (ConvD2L src)); 10762 effect(KILL cr); 10763 10764 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10765 "cmpq $dst, [0x8000000000000000]\n\t" 10766 "jne,s done\n\t" 10767 "subq rsp, #8\n\t" 10768 "movsd [rsp], $src\n\t" 10769 "call d2l_fixup\n\t" 10770 "popq $dst\n" 10771 "done: "%} 10772 ins_encode %{ 10773 Label done; 10774 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10775 __ cmp64($dst$$Register, 10776 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10777 __ jccb(Assembler::notEqual, done); 10778 __ subptr(rsp, 8); 10779 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10780 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10781 __ pop($dst$$Register); 10782 __ bind(done); 10783 %} 10784 ins_pipe(pipe_slow); 10785 %} 10786 10787 instruct convI2F_reg_reg(regF dst, rRegI src) 10788 %{ 10789 predicate(!UseXmmI2F); 10790 match(Set dst (ConvI2F src)); 10791 10792 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10793 ins_encode %{ 10794 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10795 %} 10796 ins_pipe(pipe_slow); // XXX 10797 %} 10798 10799 instruct convI2F_reg_mem(regF dst, memory src) 10800 %{ 10801 match(Set dst (ConvI2F (LoadI src))); 10802 10803 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10804 ins_encode %{ 10805 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10806 %} 10807 ins_pipe(pipe_slow); // XXX 10808 %} 10809 10810 instruct convI2D_reg_reg(regD dst, rRegI src) 10811 %{ 10812 predicate(!UseXmmI2D); 10813 match(Set dst (ConvI2D src)); 10814 10815 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10816 ins_encode %{ 10817 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10818 %} 10819 ins_pipe(pipe_slow); // XXX 10820 %} 10821 10822 instruct convI2D_reg_mem(regD dst, memory src) 10823 %{ 10824 match(Set dst (ConvI2D (LoadI src))); 10825 10826 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10827 ins_encode %{ 10828 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10829 %} 10830 ins_pipe(pipe_slow); // XXX 10831 %} 10832 10833 instruct convXI2F_reg(regF dst, rRegI src) 10834 %{ 10835 predicate(UseXmmI2F); 10836 match(Set dst (ConvI2F src)); 10837 10838 format %{ "movdl $dst, $src\n\t" 10839 "cvtdq2psl $dst, $dst\t# i2f" %} 10840 ins_encode %{ 10841 __ movdl($dst$$XMMRegister, $src$$Register); 10842 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10843 %} 10844 ins_pipe(pipe_slow); // XXX 10845 %} 10846 10847 instruct convXI2D_reg(regD dst, rRegI src) 10848 %{ 10849 predicate(UseXmmI2D); 10850 match(Set dst (ConvI2D src)); 10851 10852 format %{ "movdl $dst, $src\n\t" 10853 "cvtdq2pdl $dst, $dst\t# i2d" %} 10854 ins_encode %{ 10855 __ movdl($dst$$XMMRegister, $src$$Register); 10856 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10857 %} 10858 ins_pipe(pipe_slow); // XXX 10859 %} 10860 10861 instruct convL2F_reg_reg(regF dst, rRegL src) 10862 %{ 10863 match(Set dst (ConvL2F src)); 10864 10865 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10866 ins_encode %{ 10867 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10868 %} 10869 ins_pipe(pipe_slow); // XXX 10870 %} 10871 10872 instruct convL2F_reg_mem(regF dst, memory src) 10873 %{ 10874 match(Set dst (ConvL2F (LoadL src))); 10875 10876 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10877 ins_encode %{ 10878 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10879 %} 10880 ins_pipe(pipe_slow); // XXX 10881 %} 10882 10883 instruct convL2D_reg_reg(regD dst, rRegL src) 10884 %{ 10885 match(Set dst (ConvL2D src)); 10886 10887 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10888 ins_encode %{ 10889 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10890 %} 10891 ins_pipe(pipe_slow); // XXX 10892 %} 10893 10894 instruct convL2D_reg_mem(regD dst, memory src) 10895 %{ 10896 match(Set dst (ConvL2D (LoadL src))); 10897 10898 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10899 ins_encode %{ 10900 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10901 %} 10902 ins_pipe(pipe_slow); // XXX 10903 %} 10904 10905 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10906 %{ 10907 match(Set dst (ConvI2L src)); 10908 10909 ins_cost(125); 10910 format %{ "movslq $dst, $src\t# i2l" %} 10911 ins_encode %{ 10912 __ movslq($dst$$Register, $src$$Register); 10913 %} 10914 ins_pipe(ialu_reg_reg); 10915 %} 10916 10917 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10918 // %{ 10919 // match(Set dst (ConvI2L src)); 10920 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10921 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10922 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10923 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10924 // ((const TypeNode*) n)->type()->is_long()->_lo == 10925 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10926 10927 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10928 // ins_encode(enc_copy(dst, src)); 10929 // // opcode(0x63); // needs REX.W 10930 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10931 // ins_pipe(ialu_reg_reg); 10932 // %} 10933 10934 // Zero-extend convert int to long 10935 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10936 %{ 10937 match(Set dst (AndL (ConvI2L src) mask)); 10938 10939 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10940 ins_encode %{ 10941 if ($dst$$reg != $src$$reg) { 10942 __ movl($dst$$Register, $src$$Register); 10943 } 10944 %} 10945 ins_pipe(ialu_reg_reg); 10946 %} 10947 10948 // Zero-extend convert int to long 10949 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10950 %{ 10951 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10952 10953 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10954 ins_encode %{ 10955 __ movl($dst$$Register, $src$$Address); 10956 %} 10957 ins_pipe(ialu_reg_mem); 10958 %} 10959 10960 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10961 %{ 10962 match(Set dst (AndL src mask)); 10963 10964 format %{ "movl $dst, $src\t# zero-extend long" %} 10965 ins_encode %{ 10966 __ movl($dst$$Register, $src$$Register); 10967 %} 10968 ins_pipe(ialu_reg_reg); 10969 %} 10970 10971 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10972 %{ 10973 match(Set dst (ConvL2I src)); 10974 10975 format %{ "movl $dst, $src\t# l2i" %} 10976 ins_encode %{ 10977 __ movl($dst$$Register, $src$$Register); 10978 %} 10979 ins_pipe(ialu_reg_reg); 10980 %} 10981 10982 10983 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10984 match(Set dst (MoveF2I src)); 10985 effect(DEF dst, USE src); 10986 10987 ins_cost(125); 10988 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10989 ins_encode %{ 10990 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10991 %} 10992 ins_pipe(ialu_reg_mem); 10993 %} 10994 10995 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10996 match(Set dst (MoveI2F src)); 10997 effect(DEF dst, USE src); 10998 10999 ins_cost(125); 11000 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 11001 ins_encode %{ 11002 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 11003 %} 11004 ins_pipe(pipe_slow); 11005 %} 11006 11007 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 11008 match(Set dst (MoveD2L src)); 11009 effect(DEF dst, USE src); 11010 11011 ins_cost(125); 11012 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 11013 ins_encode %{ 11014 __ movq($dst$$Register, Address(rsp, $src$$disp)); 11015 %} 11016 ins_pipe(ialu_reg_mem); 11017 %} 11018 11019 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 11020 predicate(!UseXmmLoadAndClearUpper); 11021 match(Set dst (MoveL2D src)); 11022 effect(DEF dst, USE src); 11023 11024 ins_cost(125); 11025 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 11026 ins_encode %{ 11027 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11028 %} 11029 ins_pipe(pipe_slow); 11030 %} 11031 11032 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 11033 predicate(UseXmmLoadAndClearUpper); 11034 match(Set dst (MoveL2D src)); 11035 effect(DEF dst, USE src); 11036 11037 ins_cost(125); 11038 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 11039 ins_encode %{ 11040 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11041 %} 11042 ins_pipe(pipe_slow); 11043 %} 11044 11045 11046 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 11047 match(Set dst (MoveF2I src)); 11048 effect(DEF dst, USE src); 11049 11050 ins_cost(95); // XXX 11051 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 11052 ins_encode %{ 11053 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 11054 %} 11055 ins_pipe(pipe_slow); 11056 %} 11057 11058 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 11059 match(Set dst (MoveI2F src)); 11060 effect(DEF dst, USE src); 11061 11062 ins_cost(100); 11063 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 11064 ins_encode %{ 11065 __ movl(Address(rsp, $dst$$disp), $src$$Register); 11066 %} 11067 ins_pipe( ialu_mem_reg ); 11068 %} 11069 11070 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 11071 match(Set dst (MoveD2L src)); 11072 effect(DEF dst, USE src); 11073 11074 ins_cost(95); // XXX 11075 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 11076 ins_encode %{ 11077 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 11078 %} 11079 ins_pipe(pipe_slow); 11080 %} 11081 11082 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 11083 match(Set dst (MoveL2D src)); 11084 effect(DEF dst, USE src); 11085 11086 ins_cost(100); 11087 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 11088 ins_encode %{ 11089 __ movq(Address(rsp, $dst$$disp), $src$$Register); 11090 %} 11091 ins_pipe(ialu_mem_reg); 11092 %} 11093 11094 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 11095 match(Set dst (MoveF2I src)); 11096 effect(DEF dst, USE src); 11097 ins_cost(85); 11098 format %{ "movd $dst,$src\t# MoveF2I" %} 11099 ins_encode %{ 11100 __ movdl($dst$$Register, $src$$XMMRegister); 11101 %} 11102 ins_pipe( pipe_slow ); 11103 %} 11104 11105 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 11106 match(Set dst (MoveD2L src)); 11107 effect(DEF dst, USE src); 11108 ins_cost(85); 11109 format %{ "movd $dst,$src\t# MoveD2L" %} 11110 ins_encode %{ 11111 __ movdq($dst$$Register, $src$$XMMRegister); 11112 %} 11113 ins_pipe( pipe_slow ); 11114 %} 11115 11116 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 11117 match(Set dst (MoveI2F src)); 11118 effect(DEF dst, USE src); 11119 ins_cost(100); 11120 format %{ "movd $dst,$src\t# MoveI2F" %} 11121 ins_encode %{ 11122 __ movdl($dst$$XMMRegister, $src$$Register); 11123 %} 11124 ins_pipe( pipe_slow ); 11125 %} 11126 11127 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 11128 match(Set dst (MoveL2D src)); 11129 effect(DEF dst, USE src); 11130 ins_cost(100); 11131 format %{ "movd $dst,$src\t# MoveL2D" %} 11132 ins_encode %{ 11133 __ movdq($dst$$XMMRegister, $src$$Register); 11134 %} 11135 ins_pipe( pipe_slow ); 11136 %} 11137 11138 11139 // ======================================================================= 11140 // fast clearing of an array 11141 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 11142 Universe dummy, rFlagsReg cr) 11143 %{ 11144 predicate(!((ClearArrayNode*)n)->is_large()); 11145 match(Set dummy (ClearArray cnt base)); 11146 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 11147 11148 format %{ $$template 11149 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11150 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11151 $$emit$$"jg LARGE\n\t" 11152 $$emit$$"dec rcx\n\t" 11153 $$emit$$"js DONE\t# Zero length\n\t" 11154 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11155 $$emit$$"dec rcx\n\t" 11156 $$emit$$"jge LOOP\n\t" 11157 $$emit$$"jmp DONE\n\t" 11158 $$emit$$"# LARGE:\n\t" 11159 if (UseFastStosb) { 11160 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11161 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 11162 } else if (UseXMMForObjInit) { 11163 $$emit$$"mov rdi,rax\n\t" 11164 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11165 $$emit$$"jmpq L_zero_64_bytes\n\t" 11166 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11167 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11168 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11169 $$emit$$"add 0x40,rax\n\t" 11170 $$emit$$"# L_zero_64_bytes:\n\t" 11171 $$emit$$"sub 0x8,rcx\n\t" 11172 $$emit$$"jge L_loop\n\t" 11173 $$emit$$"add 0x4,rcx\n\t" 11174 $$emit$$"jl L_tail\n\t" 11175 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11176 $$emit$$"add 0x20,rax\n\t" 11177 $$emit$$"sub 0x4,rcx\n\t" 11178 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11179 $$emit$$"add 0x4,rcx\n\t" 11180 $$emit$$"jle L_end\n\t" 11181 $$emit$$"dec rcx\n\t" 11182 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11183 $$emit$$"vmovq xmm0,(rax)\n\t" 11184 $$emit$$"add 0x8,rax\n\t" 11185 $$emit$$"dec rcx\n\t" 11186 $$emit$$"jge L_sloop\n\t" 11187 $$emit$$"# L_end:\n\t" 11188 } else { 11189 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11190 } 11191 $$emit$$"# DONE" 11192 %} 11193 ins_encode %{ 11194 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11195 $tmp$$XMMRegister, false); 11196 %} 11197 ins_pipe(pipe_slow); 11198 %} 11199 11200 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 11201 Universe dummy, rFlagsReg cr) 11202 %{ 11203 predicate(((ClearArrayNode*)n)->is_large()); 11204 match(Set dummy (ClearArray cnt base)); 11205 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 11206 11207 format %{ $$template 11208 if (UseFastStosb) { 11209 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11210 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11211 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11212 } else if (UseXMMForObjInit) { 11213 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 11214 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11215 $$emit$$"jmpq L_zero_64_bytes\n\t" 11216 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11217 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11218 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11219 $$emit$$"add 0x40,rax\n\t" 11220 $$emit$$"# L_zero_64_bytes:\n\t" 11221 $$emit$$"sub 0x8,rcx\n\t" 11222 $$emit$$"jge L_loop\n\t" 11223 $$emit$$"add 0x4,rcx\n\t" 11224 $$emit$$"jl L_tail\n\t" 11225 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11226 $$emit$$"add 0x20,rax\n\t" 11227 $$emit$$"sub 0x4,rcx\n\t" 11228 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11229 $$emit$$"add 0x4,rcx\n\t" 11230 $$emit$$"jle L_end\n\t" 11231 $$emit$$"dec rcx\n\t" 11232 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11233 $$emit$$"vmovq xmm0,(rax)\n\t" 11234 $$emit$$"add 0x8,rax\n\t" 11235 $$emit$$"dec rcx\n\t" 11236 $$emit$$"jge L_sloop\n\t" 11237 $$emit$$"# L_end:\n\t" 11238 } else { 11239 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11240 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11241 } 11242 %} 11243 ins_encode %{ 11244 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11245 $tmp$$XMMRegister, true); 11246 %} 11247 ins_pipe(pipe_slow); 11248 %} 11249 11250 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11251 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11252 %{ 11253 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11254 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11255 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11256 11257 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11258 ins_encode %{ 11259 __ string_compare($str1$$Register, $str2$$Register, 11260 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11261 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11262 %} 11263 ins_pipe( pipe_slow ); 11264 %} 11265 11266 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11267 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11268 %{ 11269 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11270 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11271 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11272 11273 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11274 ins_encode %{ 11275 __ string_compare($str1$$Register, $str2$$Register, 11276 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11277 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11278 %} 11279 ins_pipe( pipe_slow ); 11280 %} 11281 11282 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11283 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11284 %{ 11285 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11286 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11287 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11288 11289 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11290 ins_encode %{ 11291 __ string_compare($str1$$Register, $str2$$Register, 11292 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11293 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11294 %} 11295 ins_pipe( pipe_slow ); 11296 %} 11297 11298 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11299 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11300 %{ 11301 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11302 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11303 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11304 11305 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11306 ins_encode %{ 11307 __ string_compare($str2$$Register, $str1$$Register, 11308 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11309 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11310 %} 11311 ins_pipe( pipe_slow ); 11312 %} 11313 11314 // fast search of substring with known size. 11315 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11316 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11317 %{ 11318 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11319 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11320 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11321 11322 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11323 ins_encode %{ 11324 int icnt2 = (int)$int_cnt2$$constant; 11325 if (icnt2 >= 16) { 11326 // IndexOf for constant substrings with size >= 16 elements 11327 // which don't need to be loaded through stack. 11328 __ string_indexofC8($str1$$Register, $str2$$Register, 11329 $cnt1$$Register, $cnt2$$Register, 11330 icnt2, $result$$Register, 11331 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11332 } else { 11333 // Small strings are loaded through stack if they cross page boundary. 11334 __ string_indexof($str1$$Register, $str2$$Register, 11335 $cnt1$$Register, $cnt2$$Register, 11336 icnt2, $result$$Register, 11337 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11338 } 11339 %} 11340 ins_pipe( pipe_slow ); 11341 %} 11342 11343 // fast search of substring with known size. 11344 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11345 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11346 %{ 11347 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11348 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11349 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11350 11351 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11352 ins_encode %{ 11353 int icnt2 = (int)$int_cnt2$$constant; 11354 if (icnt2 >= 8) { 11355 // IndexOf for constant substrings with size >= 8 elements 11356 // which don't need to be loaded through stack. 11357 __ string_indexofC8($str1$$Register, $str2$$Register, 11358 $cnt1$$Register, $cnt2$$Register, 11359 icnt2, $result$$Register, 11360 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11361 } else { 11362 // Small strings are loaded through stack if they cross page boundary. 11363 __ string_indexof($str1$$Register, $str2$$Register, 11364 $cnt1$$Register, $cnt2$$Register, 11365 icnt2, $result$$Register, 11366 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11367 } 11368 %} 11369 ins_pipe( pipe_slow ); 11370 %} 11371 11372 // fast search of substring with known size. 11373 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11374 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11375 %{ 11376 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11377 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11378 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11379 11380 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11381 ins_encode %{ 11382 int icnt2 = (int)$int_cnt2$$constant; 11383 if (icnt2 >= 8) { 11384 // IndexOf for constant substrings with size >= 8 elements 11385 // which don't need to be loaded through stack. 11386 __ string_indexofC8($str1$$Register, $str2$$Register, 11387 $cnt1$$Register, $cnt2$$Register, 11388 icnt2, $result$$Register, 11389 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11390 } else { 11391 // Small strings are loaded through stack if they cross page boundary. 11392 __ string_indexof($str1$$Register, $str2$$Register, 11393 $cnt1$$Register, $cnt2$$Register, 11394 icnt2, $result$$Register, 11395 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11396 } 11397 %} 11398 ins_pipe( pipe_slow ); 11399 %} 11400 11401 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11402 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11403 %{ 11404 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11405 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11406 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11407 11408 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11409 ins_encode %{ 11410 __ string_indexof($str1$$Register, $str2$$Register, 11411 $cnt1$$Register, $cnt2$$Register, 11412 (-1), $result$$Register, 11413 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11414 %} 11415 ins_pipe( pipe_slow ); 11416 %} 11417 11418 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11419 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11420 %{ 11421 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11422 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11423 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11424 11425 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11426 ins_encode %{ 11427 __ string_indexof($str1$$Register, $str2$$Register, 11428 $cnt1$$Register, $cnt2$$Register, 11429 (-1), $result$$Register, 11430 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11431 %} 11432 ins_pipe( pipe_slow ); 11433 %} 11434 11435 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11436 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11437 %{ 11438 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11439 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11440 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11441 11442 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11443 ins_encode %{ 11444 __ string_indexof($str1$$Register, $str2$$Register, 11445 $cnt1$$Register, $cnt2$$Register, 11446 (-1), $result$$Register, 11447 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11448 %} 11449 ins_pipe( pipe_slow ); 11450 %} 11451 11452 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11453 rbx_RegI result, legVecS vec1, legVecS vec2, legVecS vec3, rcx_RegI tmp, rFlagsReg cr) 11454 %{ 11455 predicate(UseSSE42Intrinsics); 11456 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11457 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11458 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11459 ins_encode %{ 11460 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11461 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11462 %} 11463 ins_pipe( pipe_slow ); 11464 %} 11465 11466 // fast string equals 11467 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11468 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11469 %{ 11470 match(Set result (StrEquals (Binary str1 str2) cnt)); 11471 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11472 11473 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11474 ins_encode %{ 11475 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11476 $cnt$$Register, $result$$Register, $tmp3$$Register, 11477 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11478 %} 11479 ins_pipe( pipe_slow ); 11480 %} 11481 11482 // fast array equals 11483 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11484 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11485 %{ 11486 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11487 match(Set result (AryEq ary1 ary2)); 11488 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11489 11490 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11491 ins_encode %{ 11492 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11493 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11494 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11495 %} 11496 ins_pipe( pipe_slow ); 11497 %} 11498 11499 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11500 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11501 %{ 11502 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11503 match(Set result (AryEq ary1 ary2)); 11504 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11505 11506 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11507 ins_encode %{ 11508 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11509 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11510 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11511 %} 11512 ins_pipe( pipe_slow ); 11513 %} 11514 11515 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11516 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11517 %{ 11518 match(Set result (HasNegatives ary1 len)); 11519 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11520 11521 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11522 ins_encode %{ 11523 __ has_negatives($ary1$$Register, $len$$Register, 11524 $result$$Register, $tmp3$$Register, 11525 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11526 %} 11527 ins_pipe( pipe_slow ); 11528 %} 11529 11530 // fast char[] to byte[] compression 11531 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11532 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11533 match(Set result (StrCompressedCopy src (Binary dst len))); 11534 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11535 11536 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11537 ins_encode %{ 11538 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11539 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11540 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11541 %} 11542 ins_pipe( pipe_slow ); 11543 %} 11544 11545 // fast byte[] to char[] inflation 11546 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11547 legVecS tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11548 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11549 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11550 11551 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11552 ins_encode %{ 11553 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11554 $tmp1$$XMMRegister, $tmp2$$Register); 11555 %} 11556 ins_pipe( pipe_slow ); 11557 %} 11558 11559 // encode char[] to byte[] in ISO_8859_1 11560 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11561 legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11562 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11563 match(Set result (EncodeISOArray src (Binary dst len))); 11564 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11565 11566 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11567 ins_encode %{ 11568 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11569 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11570 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11571 %} 11572 ins_pipe( pipe_slow ); 11573 %} 11574 11575 //----------Overflow Math Instructions----------------------------------------- 11576 11577 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11578 %{ 11579 match(Set cr (OverflowAddI op1 op2)); 11580 effect(DEF cr, USE_KILL op1, USE op2); 11581 11582 format %{ "addl $op1, $op2\t# overflow check int" %} 11583 11584 ins_encode %{ 11585 __ addl($op1$$Register, $op2$$Register); 11586 %} 11587 ins_pipe(ialu_reg_reg); 11588 %} 11589 11590 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11591 %{ 11592 match(Set cr (OverflowAddI op1 op2)); 11593 effect(DEF cr, USE_KILL op1, USE op2); 11594 11595 format %{ "addl $op1, $op2\t# overflow check int" %} 11596 11597 ins_encode %{ 11598 __ addl($op1$$Register, $op2$$constant); 11599 %} 11600 ins_pipe(ialu_reg_reg); 11601 %} 11602 11603 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11604 %{ 11605 match(Set cr (OverflowAddL op1 op2)); 11606 effect(DEF cr, USE_KILL op1, USE op2); 11607 11608 format %{ "addq $op1, $op2\t# overflow check long" %} 11609 ins_encode %{ 11610 __ addq($op1$$Register, $op2$$Register); 11611 %} 11612 ins_pipe(ialu_reg_reg); 11613 %} 11614 11615 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11616 %{ 11617 match(Set cr (OverflowAddL op1 op2)); 11618 effect(DEF cr, USE_KILL op1, USE op2); 11619 11620 format %{ "addq $op1, $op2\t# overflow check long" %} 11621 ins_encode %{ 11622 __ addq($op1$$Register, $op2$$constant); 11623 %} 11624 ins_pipe(ialu_reg_reg); 11625 %} 11626 11627 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11628 %{ 11629 match(Set cr (OverflowSubI op1 op2)); 11630 11631 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11632 ins_encode %{ 11633 __ cmpl($op1$$Register, $op2$$Register); 11634 %} 11635 ins_pipe(ialu_reg_reg); 11636 %} 11637 11638 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11639 %{ 11640 match(Set cr (OverflowSubI op1 op2)); 11641 11642 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11643 ins_encode %{ 11644 __ cmpl($op1$$Register, $op2$$constant); 11645 %} 11646 ins_pipe(ialu_reg_reg); 11647 %} 11648 11649 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11650 %{ 11651 match(Set cr (OverflowSubL op1 op2)); 11652 11653 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11654 ins_encode %{ 11655 __ cmpq($op1$$Register, $op2$$Register); 11656 %} 11657 ins_pipe(ialu_reg_reg); 11658 %} 11659 11660 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11661 %{ 11662 match(Set cr (OverflowSubL op1 op2)); 11663 11664 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11665 ins_encode %{ 11666 __ cmpq($op1$$Register, $op2$$constant); 11667 %} 11668 ins_pipe(ialu_reg_reg); 11669 %} 11670 11671 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11672 %{ 11673 match(Set cr (OverflowSubI zero op2)); 11674 effect(DEF cr, USE_KILL op2); 11675 11676 format %{ "negl $op2\t# overflow check int" %} 11677 ins_encode %{ 11678 __ negl($op2$$Register); 11679 %} 11680 ins_pipe(ialu_reg_reg); 11681 %} 11682 11683 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11684 %{ 11685 match(Set cr (OverflowSubL zero op2)); 11686 effect(DEF cr, USE_KILL op2); 11687 11688 format %{ "negq $op2\t# overflow check long" %} 11689 ins_encode %{ 11690 __ negq($op2$$Register); 11691 %} 11692 ins_pipe(ialu_reg_reg); 11693 %} 11694 11695 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11696 %{ 11697 match(Set cr (OverflowMulI op1 op2)); 11698 effect(DEF cr, USE_KILL op1, USE op2); 11699 11700 format %{ "imull $op1, $op2\t# overflow check int" %} 11701 ins_encode %{ 11702 __ imull($op1$$Register, $op2$$Register); 11703 %} 11704 ins_pipe(ialu_reg_reg_alu0); 11705 %} 11706 11707 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11708 %{ 11709 match(Set cr (OverflowMulI op1 op2)); 11710 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11711 11712 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11713 ins_encode %{ 11714 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11715 %} 11716 ins_pipe(ialu_reg_reg_alu0); 11717 %} 11718 11719 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11720 %{ 11721 match(Set cr (OverflowMulL op1 op2)); 11722 effect(DEF cr, USE_KILL op1, USE op2); 11723 11724 format %{ "imulq $op1, $op2\t# overflow check long" %} 11725 ins_encode %{ 11726 __ imulq($op1$$Register, $op2$$Register); 11727 %} 11728 ins_pipe(ialu_reg_reg_alu0); 11729 %} 11730 11731 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11732 %{ 11733 match(Set cr (OverflowMulL op1 op2)); 11734 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11735 11736 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11737 ins_encode %{ 11738 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11739 %} 11740 ins_pipe(ialu_reg_reg_alu0); 11741 %} 11742 11743 11744 //----------Control Flow Instructions------------------------------------------ 11745 // Signed compare Instructions 11746 11747 // XXX more variants!! 11748 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11749 %{ 11750 match(Set cr (CmpI op1 op2)); 11751 effect(DEF cr, USE op1, USE op2); 11752 11753 format %{ "cmpl $op1, $op2" %} 11754 opcode(0x3B); /* Opcode 3B /r */ 11755 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11756 ins_pipe(ialu_cr_reg_reg); 11757 %} 11758 11759 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11760 %{ 11761 match(Set cr (CmpI op1 op2)); 11762 11763 format %{ "cmpl $op1, $op2" %} 11764 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11765 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11766 ins_pipe(ialu_cr_reg_imm); 11767 %} 11768 11769 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11770 %{ 11771 match(Set cr (CmpI op1 (LoadI op2))); 11772 11773 ins_cost(500); // XXX 11774 format %{ "cmpl $op1, $op2" %} 11775 opcode(0x3B); /* Opcode 3B /r */ 11776 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11777 ins_pipe(ialu_cr_reg_mem); 11778 %} 11779 11780 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11781 %{ 11782 match(Set cr (CmpI src zero)); 11783 11784 format %{ "testl $src, $src" %} 11785 opcode(0x85); 11786 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11787 ins_pipe(ialu_cr_reg_imm); 11788 %} 11789 11790 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11791 %{ 11792 match(Set cr (CmpI (AndI src con) zero)); 11793 11794 format %{ "testl $src, $con" %} 11795 opcode(0xF7, 0x00); 11796 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11797 ins_pipe(ialu_cr_reg_imm); 11798 %} 11799 11800 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11801 %{ 11802 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11803 11804 format %{ "testl $src, $mem" %} 11805 opcode(0x85); 11806 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11807 ins_pipe(ialu_cr_reg_mem); 11808 %} 11809 11810 // Unsigned compare Instructions; really, same as signed except they 11811 // produce an rFlagsRegU instead of rFlagsReg. 11812 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11813 %{ 11814 match(Set cr (CmpU op1 op2)); 11815 11816 format %{ "cmpl $op1, $op2\t# unsigned" %} 11817 opcode(0x3B); /* Opcode 3B /r */ 11818 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11819 ins_pipe(ialu_cr_reg_reg); 11820 %} 11821 11822 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11823 %{ 11824 match(Set cr (CmpU op1 op2)); 11825 11826 format %{ "cmpl $op1, $op2\t# unsigned" %} 11827 opcode(0x81,0x07); /* Opcode 81 /7 */ 11828 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11829 ins_pipe(ialu_cr_reg_imm); 11830 %} 11831 11832 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11833 %{ 11834 match(Set cr (CmpU op1 (LoadI op2))); 11835 11836 ins_cost(500); // XXX 11837 format %{ "cmpl $op1, $op2\t# unsigned" %} 11838 opcode(0x3B); /* Opcode 3B /r */ 11839 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11840 ins_pipe(ialu_cr_reg_mem); 11841 %} 11842 11843 // // // Cisc-spilled version of cmpU_rReg 11844 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11845 // //%{ 11846 // // match(Set cr (CmpU (LoadI op1) op2)); 11847 // // 11848 // // format %{ "CMPu $op1,$op2" %} 11849 // // ins_cost(500); 11850 // // opcode(0x39); /* Opcode 39 /r */ 11851 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11852 // //%} 11853 11854 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11855 %{ 11856 match(Set cr (CmpU src zero)); 11857 11858 format %{ "testl $src, $src\t# unsigned" %} 11859 opcode(0x85); 11860 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11861 ins_pipe(ialu_cr_reg_imm); 11862 %} 11863 11864 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11865 %{ 11866 match(Set cr (CmpP op1 op2)); 11867 11868 format %{ "cmpq $op1, $op2\t# ptr" %} 11869 opcode(0x3B); /* Opcode 3B /r */ 11870 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11871 ins_pipe(ialu_cr_reg_reg); 11872 %} 11873 11874 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11875 %{ 11876 match(Set cr (CmpP op1 (LoadP op2))); 11877 11878 ins_cost(500); // XXX 11879 format %{ "cmpq $op1, $op2\t# ptr" %} 11880 opcode(0x3B); /* Opcode 3B /r */ 11881 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11882 ins_pipe(ialu_cr_reg_mem); 11883 %} 11884 11885 // // // Cisc-spilled version of cmpP_rReg 11886 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11887 // //%{ 11888 // // match(Set cr (CmpP (LoadP op1) op2)); 11889 // // 11890 // // format %{ "CMPu $op1,$op2" %} 11891 // // ins_cost(500); 11892 // // opcode(0x39); /* Opcode 39 /r */ 11893 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11894 // //%} 11895 11896 // XXX this is generalized by compP_rReg_mem??? 11897 // Compare raw pointer (used in out-of-heap check). 11898 // Only works because non-oop pointers must be raw pointers 11899 // and raw pointers have no anti-dependencies. 11900 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11901 %{ 11902 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11903 match(Set cr (CmpP op1 (LoadP op2))); 11904 11905 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11906 opcode(0x3B); /* Opcode 3B /r */ 11907 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11908 ins_pipe(ialu_cr_reg_mem); 11909 %} 11910 11911 // This will generate a signed flags result. This should be OK since 11912 // any compare to a zero should be eq/neq. 11913 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11914 %{ 11915 match(Set cr (CmpP src zero)); 11916 11917 format %{ "testq $src, $src\t# ptr" %} 11918 opcode(0x85); 11919 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11920 ins_pipe(ialu_cr_reg_imm); 11921 %} 11922 11923 // This will generate a signed flags result. This should be OK since 11924 // any compare to a zero should be eq/neq. 11925 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11926 %{ 11927 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11928 match(Set cr (CmpP (LoadP op) zero)); 11929 11930 ins_cost(500); // XXX 11931 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11932 opcode(0xF7); /* Opcode F7 /0 */ 11933 ins_encode(REX_mem_wide(op), 11934 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11935 ins_pipe(ialu_cr_reg_imm); 11936 %} 11937 11938 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11939 %{ 11940 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11941 match(Set cr (CmpP (LoadP mem) zero)); 11942 11943 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11944 ins_encode %{ 11945 __ cmpq(r12, $mem$$Address); 11946 %} 11947 ins_pipe(ialu_cr_reg_mem); 11948 %} 11949 11950 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11951 %{ 11952 match(Set cr (CmpN op1 op2)); 11953 11954 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11955 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11956 ins_pipe(ialu_cr_reg_reg); 11957 %} 11958 11959 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11960 %{ 11961 match(Set cr (CmpN src (LoadN mem))); 11962 11963 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11964 ins_encode %{ 11965 __ cmpl($src$$Register, $mem$$Address); 11966 %} 11967 ins_pipe(ialu_cr_reg_mem); 11968 %} 11969 11970 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11971 match(Set cr (CmpN op1 op2)); 11972 11973 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11974 ins_encode %{ 11975 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11976 %} 11977 ins_pipe(ialu_cr_reg_imm); 11978 %} 11979 11980 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11981 %{ 11982 match(Set cr (CmpN src (LoadN mem))); 11983 11984 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11985 ins_encode %{ 11986 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11987 %} 11988 ins_pipe(ialu_cr_reg_mem); 11989 %} 11990 11991 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11992 match(Set cr (CmpN op1 op2)); 11993 11994 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11995 ins_encode %{ 11996 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11997 %} 11998 ins_pipe(ialu_cr_reg_imm); 11999 %} 12000 12001 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 12002 %{ 12003 match(Set cr (CmpN src (LoadNKlass mem))); 12004 12005 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 12006 ins_encode %{ 12007 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 12008 %} 12009 ins_pipe(ialu_cr_reg_mem); 12010 %} 12011 12012 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 12013 match(Set cr (CmpN src zero)); 12014 12015 format %{ "testl $src, $src\t# compressed ptr" %} 12016 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 12017 ins_pipe(ialu_cr_reg_imm); 12018 %} 12019 12020 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 12021 %{ 12022 predicate(Universe::narrow_oop_base() != NULL); 12023 match(Set cr (CmpN (LoadN mem) zero)); 12024 12025 ins_cost(500); // XXX 12026 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 12027 ins_encode %{ 12028 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 12029 %} 12030 ins_pipe(ialu_cr_reg_mem); 12031 %} 12032 12033 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 12034 %{ 12035 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 12036 match(Set cr (CmpN (LoadN mem) zero)); 12037 12038 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 12039 ins_encode %{ 12040 __ cmpl(r12, $mem$$Address); 12041 %} 12042 ins_pipe(ialu_cr_reg_mem); 12043 %} 12044 12045 // Yanked all unsigned pointer compare operations. 12046 // Pointer compares are done with CmpP which is already unsigned. 12047 12048 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 12049 %{ 12050 match(Set cr (CmpL op1 op2)); 12051 12052 format %{ "cmpq $op1, $op2" %} 12053 opcode(0x3B); /* Opcode 3B /r */ 12054 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12055 ins_pipe(ialu_cr_reg_reg); 12056 %} 12057 12058 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 12059 %{ 12060 match(Set cr (CmpL op1 op2)); 12061 12062 format %{ "cmpq $op1, $op2" %} 12063 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12064 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12065 ins_pipe(ialu_cr_reg_imm); 12066 %} 12067 12068 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 12069 %{ 12070 match(Set cr (CmpL op1 (LoadL op2))); 12071 12072 format %{ "cmpq $op1, $op2" %} 12073 opcode(0x3B); /* Opcode 3B /r */ 12074 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12075 ins_pipe(ialu_cr_reg_mem); 12076 %} 12077 12078 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12079 %{ 12080 match(Set cr (CmpL src zero)); 12081 12082 format %{ "testq $src, $src" %} 12083 opcode(0x85); 12084 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12085 ins_pipe(ialu_cr_reg_imm); 12086 %} 12087 12088 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12089 %{ 12090 match(Set cr (CmpL (AndL src con) zero)); 12091 12092 format %{ "testq $src, $con\t# long" %} 12093 opcode(0xF7, 0x00); 12094 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 12095 ins_pipe(ialu_cr_reg_imm); 12096 %} 12097 12098 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12099 %{ 12100 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12101 12102 format %{ "testq $src, $mem" %} 12103 opcode(0x85); 12104 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12105 ins_pipe(ialu_cr_reg_mem); 12106 %} 12107 12108 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12109 %{ 12110 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12111 12112 format %{ "testq $src, $mem" %} 12113 opcode(0x85); 12114 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12115 ins_pipe(ialu_cr_reg_mem); 12116 %} 12117 12118 // Manifest a CmpL result in an integer register. Very painful. 12119 // This is the test to avoid. 12120 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12121 %{ 12122 match(Set dst (CmpL3 src1 src2)); 12123 effect(KILL flags); 12124 12125 ins_cost(275); // XXX 12126 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12127 "movl $dst, -1\n\t" 12128 "jl,s done\n\t" 12129 "setne $dst\n\t" 12130 "movzbl $dst, $dst\n\t" 12131 "done:" %} 12132 ins_encode(cmpl3_flag(src1, src2, dst)); 12133 ins_pipe(pipe_slow); 12134 %} 12135 12136 // Unsigned long compare Instructions; really, same as signed long except they 12137 // produce an rFlagsRegU instead of rFlagsReg. 12138 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12139 %{ 12140 match(Set cr (CmpUL op1 op2)); 12141 12142 format %{ "cmpq $op1, $op2\t# unsigned" %} 12143 opcode(0x3B); /* Opcode 3B /r */ 12144 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12145 ins_pipe(ialu_cr_reg_reg); 12146 %} 12147 12148 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12149 %{ 12150 match(Set cr (CmpUL op1 op2)); 12151 12152 format %{ "cmpq $op1, $op2\t# unsigned" %} 12153 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12154 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12155 ins_pipe(ialu_cr_reg_imm); 12156 %} 12157 12158 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12159 %{ 12160 match(Set cr (CmpUL op1 (LoadL op2))); 12161 12162 format %{ "cmpq $op1, $op2\t# unsigned" %} 12163 opcode(0x3B); /* Opcode 3B /r */ 12164 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12165 ins_pipe(ialu_cr_reg_mem); 12166 %} 12167 12168 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12169 %{ 12170 match(Set cr (CmpUL src zero)); 12171 12172 format %{ "testq $src, $src\t# unsigned" %} 12173 opcode(0x85); 12174 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12175 ins_pipe(ialu_cr_reg_imm); 12176 %} 12177 12178 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12179 %{ 12180 match(Set cr (CmpI (LoadB mem) imm)); 12181 12182 ins_cost(125); 12183 format %{ "cmpb $mem, $imm" %} 12184 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12185 ins_pipe(ialu_cr_reg_mem); 12186 %} 12187 12188 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 12189 %{ 12190 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12191 12192 ins_cost(125); 12193 format %{ "testb $mem, $imm\t# ubyte" %} 12194 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12195 ins_pipe(ialu_cr_reg_mem); 12196 %} 12197 12198 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 12199 %{ 12200 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12201 12202 ins_cost(125); 12203 format %{ "testb $mem, $imm\t# byte" %} 12204 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12205 ins_pipe(ialu_cr_reg_mem); 12206 %} 12207 12208 //----------Max and Min-------------------------------------------------------- 12209 // Min Instructions 12210 12211 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12212 %{ 12213 effect(USE_DEF dst, USE src, USE cr); 12214 12215 format %{ "cmovlgt $dst, $src\t# min" %} 12216 opcode(0x0F, 0x4F); 12217 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12218 ins_pipe(pipe_cmov_reg); 12219 %} 12220 12221 12222 instruct minI_rReg(rRegI dst, rRegI src) 12223 %{ 12224 match(Set dst (MinI dst src)); 12225 12226 ins_cost(200); 12227 expand %{ 12228 rFlagsReg cr; 12229 compI_rReg(cr, dst, src); 12230 cmovI_reg_g(dst, src, cr); 12231 %} 12232 %} 12233 12234 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12235 %{ 12236 effect(USE_DEF dst, USE src, USE cr); 12237 12238 format %{ "cmovllt $dst, $src\t# max" %} 12239 opcode(0x0F, 0x4C); 12240 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12241 ins_pipe(pipe_cmov_reg); 12242 %} 12243 12244 12245 instruct maxI_rReg(rRegI dst, rRegI src) 12246 %{ 12247 match(Set dst (MaxI dst src)); 12248 12249 ins_cost(200); 12250 expand %{ 12251 rFlagsReg cr; 12252 compI_rReg(cr, dst, src); 12253 cmovI_reg_l(dst, src, cr); 12254 %} 12255 %} 12256 12257 // ============================================================================ 12258 // Branch Instructions 12259 12260 // Jump Direct - Label defines a relative address from JMP+1 12261 instruct jmpDir(label labl) 12262 %{ 12263 match(Goto); 12264 effect(USE labl); 12265 12266 ins_cost(300); 12267 format %{ "jmp $labl" %} 12268 size(5); 12269 ins_encode %{ 12270 Label* L = $labl$$label; 12271 __ jmp(*L, false); // Always long jump 12272 %} 12273 ins_pipe(pipe_jmp); 12274 %} 12275 12276 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12277 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12278 %{ 12279 match(If cop cr); 12280 effect(USE labl); 12281 12282 ins_cost(300); 12283 format %{ "j$cop $labl" %} 12284 size(6); 12285 ins_encode %{ 12286 Label* L = $labl$$label; 12287 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12288 %} 12289 ins_pipe(pipe_jcc); 12290 %} 12291 12292 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12293 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12294 %{ 12295 predicate(!n->has_vector_mask_set()); 12296 match(CountedLoopEnd cop cr); 12297 effect(USE labl); 12298 12299 ins_cost(300); 12300 format %{ "j$cop $labl\t# loop end" %} 12301 size(6); 12302 ins_encode %{ 12303 Label* L = $labl$$label; 12304 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12305 %} 12306 ins_pipe(pipe_jcc); 12307 %} 12308 12309 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12310 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12311 predicate(!n->has_vector_mask_set()); 12312 match(CountedLoopEnd cop cmp); 12313 effect(USE labl); 12314 12315 ins_cost(300); 12316 format %{ "j$cop,u $labl\t# loop end" %} 12317 size(6); 12318 ins_encode %{ 12319 Label* L = $labl$$label; 12320 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12321 %} 12322 ins_pipe(pipe_jcc); 12323 %} 12324 12325 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12326 predicate(!n->has_vector_mask_set()); 12327 match(CountedLoopEnd cop cmp); 12328 effect(USE labl); 12329 12330 ins_cost(200); 12331 format %{ "j$cop,u $labl\t# loop end" %} 12332 size(6); 12333 ins_encode %{ 12334 Label* L = $labl$$label; 12335 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12336 %} 12337 ins_pipe(pipe_jcc); 12338 %} 12339 12340 // mask version 12341 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12342 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12343 %{ 12344 predicate(n->has_vector_mask_set()); 12345 match(CountedLoopEnd cop cr); 12346 effect(USE labl); 12347 12348 ins_cost(400); 12349 format %{ "j$cop $labl\t# loop end\n\t" 12350 "restorevectmask \t# vector mask restore for loops" %} 12351 size(10); 12352 ins_encode %{ 12353 Label* L = $labl$$label; 12354 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12355 __ restorevectmask(); 12356 %} 12357 ins_pipe(pipe_jcc); 12358 %} 12359 12360 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12361 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12362 predicate(n->has_vector_mask_set()); 12363 match(CountedLoopEnd cop cmp); 12364 effect(USE labl); 12365 12366 ins_cost(400); 12367 format %{ "j$cop,u $labl\t# loop end\n\t" 12368 "restorevectmask \t# vector mask restore for loops" %} 12369 size(10); 12370 ins_encode %{ 12371 Label* L = $labl$$label; 12372 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12373 __ restorevectmask(); 12374 %} 12375 ins_pipe(pipe_jcc); 12376 %} 12377 12378 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12379 predicate(n->has_vector_mask_set()); 12380 match(CountedLoopEnd cop cmp); 12381 effect(USE labl); 12382 12383 ins_cost(300); 12384 format %{ "j$cop,u $labl\t# loop end\n\t" 12385 "restorevectmask \t# vector mask restore for loops" %} 12386 size(10); 12387 ins_encode %{ 12388 Label* L = $labl$$label; 12389 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12390 __ restorevectmask(); 12391 %} 12392 ins_pipe(pipe_jcc); 12393 %} 12394 12395 // Jump Direct Conditional - using unsigned comparison 12396 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12397 match(If cop cmp); 12398 effect(USE labl); 12399 12400 ins_cost(300); 12401 format %{ "j$cop,u $labl" %} 12402 size(6); 12403 ins_encode %{ 12404 Label* L = $labl$$label; 12405 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12406 %} 12407 ins_pipe(pipe_jcc); 12408 %} 12409 12410 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12411 match(If cop cmp); 12412 effect(USE labl); 12413 12414 ins_cost(200); 12415 format %{ "j$cop,u $labl" %} 12416 size(6); 12417 ins_encode %{ 12418 Label* L = $labl$$label; 12419 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12420 %} 12421 ins_pipe(pipe_jcc); 12422 %} 12423 12424 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12425 match(If cop cmp); 12426 effect(USE labl); 12427 12428 ins_cost(200); 12429 format %{ $$template 12430 if ($cop$$cmpcode == Assembler::notEqual) { 12431 $$emit$$"jp,u $labl\n\t" 12432 $$emit$$"j$cop,u $labl" 12433 } else { 12434 $$emit$$"jp,u done\n\t" 12435 $$emit$$"j$cop,u $labl\n\t" 12436 $$emit$$"done:" 12437 } 12438 %} 12439 ins_encode %{ 12440 Label* l = $labl$$label; 12441 if ($cop$$cmpcode == Assembler::notEqual) { 12442 __ jcc(Assembler::parity, *l, false); 12443 __ jcc(Assembler::notEqual, *l, false); 12444 } else if ($cop$$cmpcode == Assembler::equal) { 12445 Label done; 12446 __ jccb(Assembler::parity, done); 12447 __ jcc(Assembler::equal, *l, false); 12448 __ bind(done); 12449 } else { 12450 ShouldNotReachHere(); 12451 } 12452 %} 12453 ins_pipe(pipe_jcc); 12454 %} 12455 12456 // ============================================================================ 12457 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12458 // superklass array for an instance of the superklass. Set a hidden 12459 // internal cache on a hit (cache is checked with exposed code in 12460 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12461 // encoding ALSO sets flags. 12462 12463 instruct partialSubtypeCheck(rdi_RegP result, 12464 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12465 rFlagsReg cr) 12466 %{ 12467 match(Set result (PartialSubtypeCheck sub super)); 12468 effect(KILL rcx, KILL cr); 12469 12470 ins_cost(1100); // slightly larger than the next version 12471 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12472 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12473 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12474 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12475 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12476 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12477 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12478 "miss:\t" %} 12479 12480 opcode(0x1); // Force a XOR of RDI 12481 ins_encode(enc_PartialSubtypeCheck()); 12482 ins_pipe(pipe_slow); 12483 %} 12484 12485 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12486 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12487 immP0 zero, 12488 rdi_RegP result) 12489 %{ 12490 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12491 effect(KILL rcx, KILL result); 12492 12493 ins_cost(1000); 12494 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12495 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12496 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12497 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12498 "jne,s miss\t\t# Missed: flags nz\n\t" 12499 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12500 "miss:\t" %} 12501 12502 opcode(0x0); // No need to XOR RDI 12503 ins_encode(enc_PartialSubtypeCheck()); 12504 ins_pipe(pipe_slow); 12505 %} 12506 12507 // ============================================================================ 12508 // Branch Instructions -- short offset versions 12509 // 12510 // These instructions are used to replace jumps of a long offset (the default 12511 // match) with jumps of a shorter offset. These instructions are all tagged 12512 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12513 // match rules in general matching. Instead, the ADLC generates a conversion 12514 // method in the MachNode which can be used to do in-place replacement of the 12515 // long variant with the shorter variant. The compiler will determine if a 12516 // branch can be taken by the is_short_branch_offset() predicate in the machine 12517 // specific code section of the file. 12518 12519 // Jump Direct - Label defines a relative address from JMP+1 12520 instruct jmpDir_short(label labl) %{ 12521 match(Goto); 12522 effect(USE labl); 12523 12524 ins_cost(300); 12525 format %{ "jmp,s $labl" %} 12526 size(2); 12527 ins_encode %{ 12528 Label* L = $labl$$label; 12529 __ jmpb(*L); 12530 %} 12531 ins_pipe(pipe_jmp); 12532 ins_short_branch(1); 12533 %} 12534 12535 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12536 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12537 match(If cop cr); 12538 effect(USE labl); 12539 12540 ins_cost(300); 12541 format %{ "j$cop,s $labl" %} 12542 size(2); 12543 ins_encode %{ 12544 Label* L = $labl$$label; 12545 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12546 %} 12547 ins_pipe(pipe_jcc); 12548 ins_short_branch(1); 12549 %} 12550 12551 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12552 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12553 match(CountedLoopEnd cop cr); 12554 effect(USE labl); 12555 12556 ins_cost(300); 12557 format %{ "j$cop,s $labl\t# loop end" %} 12558 size(2); 12559 ins_encode %{ 12560 Label* L = $labl$$label; 12561 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12562 %} 12563 ins_pipe(pipe_jcc); 12564 ins_short_branch(1); 12565 %} 12566 12567 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12568 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12569 match(CountedLoopEnd cop cmp); 12570 effect(USE labl); 12571 12572 ins_cost(300); 12573 format %{ "j$cop,us $labl\t# loop end" %} 12574 size(2); 12575 ins_encode %{ 12576 Label* L = $labl$$label; 12577 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12578 %} 12579 ins_pipe(pipe_jcc); 12580 ins_short_branch(1); 12581 %} 12582 12583 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12584 match(CountedLoopEnd cop cmp); 12585 effect(USE labl); 12586 12587 ins_cost(300); 12588 format %{ "j$cop,us $labl\t# loop end" %} 12589 size(2); 12590 ins_encode %{ 12591 Label* L = $labl$$label; 12592 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12593 %} 12594 ins_pipe(pipe_jcc); 12595 ins_short_branch(1); 12596 %} 12597 12598 // Jump Direct Conditional - using unsigned comparison 12599 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12600 match(If cop cmp); 12601 effect(USE labl); 12602 12603 ins_cost(300); 12604 format %{ "j$cop,us $labl" %} 12605 size(2); 12606 ins_encode %{ 12607 Label* L = $labl$$label; 12608 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12609 %} 12610 ins_pipe(pipe_jcc); 12611 ins_short_branch(1); 12612 %} 12613 12614 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12615 match(If cop cmp); 12616 effect(USE labl); 12617 12618 ins_cost(300); 12619 format %{ "j$cop,us $labl" %} 12620 size(2); 12621 ins_encode %{ 12622 Label* L = $labl$$label; 12623 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12624 %} 12625 ins_pipe(pipe_jcc); 12626 ins_short_branch(1); 12627 %} 12628 12629 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12630 match(If cop cmp); 12631 effect(USE labl); 12632 12633 ins_cost(300); 12634 format %{ $$template 12635 if ($cop$$cmpcode == Assembler::notEqual) { 12636 $$emit$$"jp,u,s $labl\n\t" 12637 $$emit$$"j$cop,u,s $labl" 12638 } else { 12639 $$emit$$"jp,u,s done\n\t" 12640 $$emit$$"j$cop,u,s $labl\n\t" 12641 $$emit$$"done:" 12642 } 12643 %} 12644 size(4); 12645 ins_encode %{ 12646 Label* l = $labl$$label; 12647 if ($cop$$cmpcode == Assembler::notEqual) { 12648 __ jccb(Assembler::parity, *l); 12649 __ jccb(Assembler::notEqual, *l); 12650 } else if ($cop$$cmpcode == Assembler::equal) { 12651 Label done; 12652 __ jccb(Assembler::parity, done); 12653 __ jccb(Assembler::equal, *l); 12654 __ bind(done); 12655 } else { 12656 ShouldNotReachHere(); 12657 } 12658 %} 12659 ins_pipe(pipe_jcc); 12660 ins_short_branch(1); 12661 %} 12662 12663 // ============================================================================ 12664 // inlined locking and unlocking 12665 12666 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12667 predicate(Compile::current()->use_rtm()); 12668 match(Set cr (FastLock object box)); 12669 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12670 ins_cost(300); 12671 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12672 ins_encode %{ 12673 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12674 $scr$$Register, $cx1$$Register, $cx2$$Register, 12675 _counters, _rtm_counters, _stack_rtm_counters, 12676 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12677 true, ra_->C->profile_rtm()); 12678 %} 12679 ins_pipe(pipe_slow); 12680 %} 12681 12682 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12683 predicate(!Compile::current()->use_rtm()); 12684 match(Set cr (FastLock object box)); 12685 effect(TEMP tmp, TEMP scr, USE_KILL box); 12686 ins_cost(300); 12687 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12688 ins_encode %{ 12689 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12690 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12691 %} 12692 ins_pipe(pipe_slow); 12693 %} 12694 12695 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12696 match(Set cr (FastUnlock object box)); 12697 effect(TEMP tmp, USE_KILL box); 12698 ins_cost(300); 12699 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12700 ins_encode %{ 12701 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12702 %} 12703 ins_pipe(pipe_slow); 12704 %} 12705 12706 12707 // ============================================================================ 12708 // Safepoint Instructions 12709 instruct safePoint_poll(rFlagsReg cr) 12710 %{ 12711 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12712 match(SafePoint); 12713 effect(KILL cr); 12714 12715 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12716 "# Safepoint: poll for GC" %} 12717 ins_cost(125); 12718 ins_encode %{ 12719 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12720 __ testl(rax, addr); 12721 %} 12722 ins_pipe(ialu_reg_mem); 12723 %} 12724 12725 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12726 %{ 12727 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12728 match(SafePoint poll); 12729 effect(KILL cr, USE poll); 12730 12731 format %{ "testl rax, [$poll]\t" 12732 "# Safepoint: poll for GC" %} 12733 ins_cost(125); 12734 ins_encode %{ 12735 __ relocate(relocInfo::poll_type); 12736 __ testl(rax, Address($poll$$Register, 0)); 12737 %} 12738 ins_pipe(ialu_reg_mem); 12739 %} 12740 12741 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12742 %{ 12743 predicate(SafepointMechanism::uses_thread_local_poll()); 12744 match(SafePoint poll); 12745 effect(KILL cr, USE poll); 12746 12747 format %{ "testl rax, [$poll]\t" 12748 "# Safepoint: poll for GC" %} 12749 ins_cost(125); 12750 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12751 ins_encode %{ 12752 __ relocate(relocInfo::poll_type); 12753 address pre_pc = __ pc(); 12754 __ testl(rax, Address($poll$$Register, 0)); 12755 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12756 %} 12757 ins_pipe(ialu_reg_mem); 12758 %} 12759 12760 // ============================================================================ 12761 // Procedure Call/Return Instructions 12762 // Call Java Static Instruction 12763 // Note: If this code changes, the corresponding ret_addr_offset() and 12764 // compute_padding() functions will have to be adjusted. 12765 instruct CallStaticJavaDirect(method meth) %{ 12766 match(CallStaticJava); 12767 effect(USE meth); 12768 12769 ins_cost(300); 12770 format %{ "call,static " %} 12771 opcode(0xE8); /* E8 cd */ 12772 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12773 ins_pipe(pipe_slow); 12774 ins_alignment(4); 12775 %} 12776 12777 // Call Java Dynamic Instruction 12778 // Note: If this code changes, the corresponding ret_addr_offset() and 12779 // compute_padding() functions will have to be adjusted. 12780 instruct CallDynamicJavaDirect(method meth) 12781 %{ 12782 match(CallDynamicJava); 12783 effect(USE meth); 12784 12785 ins_cost(300); 12786 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12787 "call,dynamic " %} 12788 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12789 ins_pipe(pipe_slow); 12790 ins_alignment(4); 12791 %} 12792 12793 // Call Runtime Instruction 12794 instruct CallRuntimeDirect(method meth) 12795 %{ 12796 match(CallRuntime); 12797 effect(USE meth); 12798 12799 ins_cost(300); 12800 format %{ "call,runtime " %} 12801 ins_encode(clear_avx, Java_To_Runtime(meth)); 12802 ins_pipe(pipe_slow); 12803 %} 12804 12805 // Call runtime without safepoint 12806 instruct CallLeafDirect(method meth) 12807 %{ 12808 match(CallLeaf); 12809 effect(USE meth); 12810 12811 ins_cost(300); 12812 format %{ "call_leaf,runtime " %} 12813 ins_encode(clear_avx, Java_To_Runtime(meth)); 12814 ins_pipe(pipe_slow); 12815 %} 12816 12817 // Call runtime without safepoint 12818 instruct CallLeafNoFPDirect(method meth) 12819 %{ 12820 match(CallLeafNoFP); 12821 effect(USE meth); 12822 12823 ins_cost(300); 12824 format %{ "call_leaf_nofp,runtime " %} 12825 ins_encode(clear_avx, Java_To_Runtime(meth)); 12826 ins_pipe(pipe_slow); 12827 %} 12828 12829 // Return Instruction 12830 // Remove the return address & jump to it. 12831 // Notice: We always emit a nop after a ret to make sure there is room 12832 // for safepoint patching 12833 instruct Ret() 12834 %{ 12835 match(Return); 12836 12837 format %{ "ret" %} 12838 opcode(0xC3); 12839 ins_encode(OpcP); 12840 ins_pipe(pipe_jmp); 12841 %} 12842 12843 // Tail Call; Jump from runtime stub to Java code. 12844 // Also known as an 'interprocedural jump'. 12845 // Target of jump will eventually return to caller. 12846 // TailJump below removes the return address. 12847 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12848 %{ 12849 match(TailCall jump_target method_oop); 12850 12851 ins_cost(300); 12852 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12853 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12854 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12855 ins_pipe(pipe_jmp); 12856 %} 12857 12858 // Tail Jump; remove the return address; jump to target. 12859 // TailCall above leaves the return address around. 12860 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12861 %{ 12862 match(TailJump jump_target ex_oop); 12863 12864 ins_cost(300); 12865 format %{ "popq rdx\t# pop return address\n\t" 12866 "jmp $jump_target" %} 12867 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12868 ins_encode(Opcode(0x5a), // popq rdx 12869 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12870 ins_pipe(pipe_jmp); 12871 %} 12872 12873 // Create exception oop: created by stack-crawling runtime code. 12874 // Created exception is now available to this handler, and is setup 12875 // just prior to jumping to this handler. No code emitted. 12876 instruct CreateException(rax_RegP ex_oop) 12877 %{ 12878 match(Set ex_oop (CreateEx)); 12879 12880 size(0); 12881 // use the following format syntax 12882 format %{ "# exception oop is in rax; no code emitted" %} 12883 ins_encode(); 12884 ins_pipe(empty); 12885 %} 12886 12887 // Rethrow exception: 12888 // The exception oop will come in the first argument position. 12889 // Then JUMP (not call) to the rethrow stub code. 12890 instruct RethrowException() 12891 %{ 12892 match(Rethrow); 12893 12894 // use the following format syntax 12895 format %{ "jmp rethrow_stub" %} 12896 ins_encode(enc_rethrow); 12897 ins_pipe(pipe_jmp); 12898 %} 12899 12900 // ============================================================================ 12901 // This name is KNOWN by the ADLC and cannot be changed. 12902 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12903 // for this guy. 12904 instruct tlsLoadP(r15_RegP dst) %{ 12905 match(Set dst (ThreadLocal)); 12906 effect(DEF dst); 12907 12908 size(0); 12909 format %{ "# TLS is in R15" %} 12910 ins_encode( /*empty encoding*/ ); 12911 ins_pipe(ialu_reg_reg); 12912 %} 12913 12914 12915 //----------PEEPHOLE RULES----------------------------------------------------- 12916 // These must follow all instruction definitions as they use the names 12917 // defined in the instructions definitions. 12918 // 12919 // peepmatch ( root_instr_name [preceding_instruction]* ); 12920 // 12921 // peepconstraint %{ 12922 // (instruction_number.operand_name relational_op instruction_number.operand_name 12923 // [, ...] ); 12924 // // instruction numbers are zero-based using left to right order in peepmatch 12925 // 12926 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12927 // // provide an instruction_number.operand_name for each operand that appears 12928 // // in the replacement instruction's match rule 12929 // 12930 // ---------VM FLAGS--------------------------------------------------------- 12931 // 12932 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12933 // 12934 // Each peephole rule is given an identifying number starting with zero and 12935 // increasing by one in the order seen by the parser. An individual peephole 12936 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12937 // on the command-line. 12938 // 12939 // ---------CURRENT LIMITATIONS---------------------------------------------- 12940 // 12941 // Only match adjacent instructions in same basic block 12942 // Only equality constraints 12943 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12944 // Only one replacement instruction 12945 // 12946 // ---------EXAMPLE---------------------------------------------------------- 12947 // 12948 // // pertinent parts of existing instructions in architecture description 12949 // instruct movI(rRegI dst, rRegI src) 12950 // %{ 12951 // match(Set dst (CopyI src)); 12952 // %} 12953 // 12954 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12955 // %{ 12956 // match(Set dst (AddI dst src)); 12957 // effect(KILL cr); 12958 // %} 12959 // 12960 // // Change (inc mov) to lea 12961 // peephole %{ 12962 // // increment preceeded by register-register move 12963 // peepmatch ( incI_rReg movI ); 12964 // // require that the destination register of the increment 12965 // // match the destination register of the move 12966 // peepconstraint ( 0.dst == 1.dst ); 12967 // // construct a replacement instruction that sets 12968 // // the destination to ( move's source register + one ) 12969 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12970 // %} 12971 // 12972 12973 // Implementation no longer uses movX instructions since 12974 // machine-independent system no longer uses CopyX nodes. 12975 // 12976 // peephole 12977 // %{ 12978 // peepmatch (incI_rReg movI); 12979 // peepconstraint (0.dst == 1.dst); 12980 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12981 // %} 12982 12983 // peephole 12984 // %{ 12985 // peepmatch (decI_rReg movI); 12986 // peepconstraint (0.dst == 1.dst); 12987 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12988 // %} 12989 12990 // peephole 12991 // %{ 12992 // peepmatch (addI_rReg_imm movI); 12993 // peepconstraint (0.dst == 1.dst); 12994 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12995 // %} 12996 12997 // peephole 12998 // %{ 12999 // peepmatch (incL_rReg movL); 13000 // peepconstraint (0.dst == 1.dst); 13001 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13002 // %} 13003 13004 // peephole 13005 // %{ 13006 // peepmatch (decL_rReg movL); 13007 // peepconstraint (0.dst == 1.dst); 13008 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13009 // %} 13010 13011 // peephole 13012 // %{ 13013 // peepmatch (addL_rReg_imm movL); 13014 // peepconstraint (0.dst == 1.dst); 13015 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13016 // %} 13017 13018 // peephole 13019 // %{ 13020 // peepmatch (addP_rReg_imm movP); 13021 // peepconstraint (0.dst == 1.dst); 13022 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13023 // %} 13024 13025 // // Change load of spilled value to only a spill 13026 // instruct storeI(memory mem, rRegI src) 13027 // %{ 13028 // match(Set mem (StoreI mem src)); 13029 // %} 13030 // 13031 // instruct loadI(rRegI dst, memory mem) 13032 // %{ 13033 // match(Set dst (LoadI mem)); 13034 // %} 13035 // 13036 13037 peephole 13038 %{ 13039 peepmatch (loadI storeI); 13040 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13041 peepreplace (storeI(1.mem 1.mem 1.src)); 13042 %} 13043 13044 peephole 13045 %{ 13046 peepmatch (loadL storeL); 13047 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13048 peepreplace (storeL(1.mem 1.mem 1.src)); 13049 %} 13050 13051 //----------SMARTSPILL RULES--------------------------------------------------- 13052 // These must follow all instruction definitions as they use the names 13053 // defined in the instructions definitions.