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 if (C->clinit_barrier_on_entry()) { 875 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 876 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 877 878 Label L_skip_barrier; 879 Register klass = rscratch1; 880 881 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 882 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 883 884 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 885 886 __ bind(L_skip_barrier); 887 } 888 889 __ verified_entry(C); 890 __ bind(*_verified_entry); 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 __ restore_stack(C); 965 966 967 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 968 __ reserved_stack_check(); 969 } 970 971 if (do_polling() && C->is_method_compilation()) { 972 MacroAssembler _masm(&cbuf); 973 if (SafepointMechanism::uses_thread_local_poll()) { 974 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 975 __ relocate(relocInfo::poll_return_type); 976 __ testl(rax, Address(rscratch1, 0)); 977 } else { 978 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 979 if (Assembler::is_polling_page_far()) { 980 __ lea(rscratch1, polling_page); 981 __ relocate(relocInfo::poll_return_type); 982 __ testl(rax, Address(rscratch1, 0)); 983 } else { 984 __ testl(rax, polling_page); 985 } 986 } 987 } 988 } 989 990 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 991 { 992 return MachNode::size(ra_); // too many variables; just compute it 993 // the hard way 994 } 995 996 int MachEpilogNode::reloc() const 997 { 998 return 2; // a large enough number 999 } 1000 1001 const Pipeline* MachEpilogNode::pipeline() const 1002 { 1003 return MachNode::pipeline_class(); 1004 } 1005 1006 int MachEpilogNode::safepoint_offset() const 1007 { 1008 return 0; 1009 } 1010 1011 //============================================================================= 1012 1013 enum RC { 1014 rc_bad, 1015 rc_int, 1016 rc_float, 1017 rc_stack 1018 }; 1019 1020 static enum RC rc_class(OptoReg::Name reg) 1021 { 1022 if( !OptoReg::is_valid(reg) ) return rc_bad; 1023 1024 if (OptoReg::is_stack(reg)) return rc_stack; 1025 1026 VMReg r = OptoReg::as_VMReg(reg); 1027 1028 if (r->is_Register()) return rc_int; 1029 1030 assert(r->is_XMMRegister(), "must be"); 1031 return rc_float; 1032 } 1033 1034 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1035 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1036 int src_hi, int dst_hi, uint ireg, outputStream* st); 1037 1038 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1039 int stack_offset, int reg, uint ireg, outputStream* st); 1040 1041 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1042 int dst_offset, uint ireg, outputStream* st) { 1043 if (cbuf) { 1044 MacroAssembler _masm(cbuf); 1045 switch (ireg) { 1046 case Op_VecS: 1047 __ movq(Address(rsp, -8), rax); 1048 __ movl(rax, Address(rsp, src_offset)); 1049 __ movl(Address(rsp, dst_offset), rax); 1050 __ movq(rax, Address(rsp, -8)); 1051 break; 1052 case Op_VecD: 1053 __ pushq(Address(rsp, src_offset)); 1054 __ popq (Address(rsp, dst_offset)); 1055 break; 1056 case Op_VecX: 1057 __ pushq(Address(rsp, src_offset)); 1058 __ popq (Address(rsp, dst_offset)); 1059 __ pushq(Address(rsp, src_offset+8)); 1060 __ popq (Address(rsp, dst_offset+8)); 1061 break; 1062 case Op_VecY: 1063 __ vmovdqu(Address(rsp, -32), xmm0); 1064 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1065 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1066 __ vmovdqu(xmm0, Address(rsp, -32)); 1067 break; 1068 case Op_VecZ: 1069 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1070 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1071 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1072 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1073 break; 1074 default: 1075 ShouldNotReachHere(); 1076 } 1077 #ifndef PRODUCT 1078 } else { 1079 switch (ireg) { 1080 case Op_VecS: 1081 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1082 "movl rax, [rsp + #%d]\n\t" 1083 "movl [rsp + #%d], rax\n\t" 1084 "movq rax, [rsp - #8]", 1085 src_offset, dst_offset); 1086 break; 1087 case Op_VecD: 1088 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1089 "popq [rsp + #%d]", 1090 src_offset, dst_offset); 1091 break; 1092 case Op_VecX: 1093 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1094 "popq [rsp + #%d]\n\t" 1095 "pushq [rsp + #%d]\n\t" 1096 "popq [rsp + #%d]", 1097 src_offset, dst_offset, src_offset+8, dst_offset+8); 1098 break; 1099 case Op_VecY: 1100 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1101 "vmovdqu xmm0, [rsp + #%d]\n\t" 1102 "vmovdqu [rsp + #%d], xmm0\n\t" 1103 "vmovdqu xmm0, [rsp - #32]", 1104 src_offset, dst_offset); 1105 break; 1106 case Op_VecZ: 1107 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1108 "vmovdqu xmm0, [rsp + #%d]\n\t" 1109 "vmovdqu [rsp + #%d], xmm0\n\t" 1110 "vmovdqu xmm0, [rsp - #64]", 1111 src_offset, dst_offset); 1112 break; 1113 default: 1114 ShouldNotReachHere(); 1115 } 1116 #endif 1117 } 1118 } 1119 1120 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1121 PhaseRegAlloc* ra_, 1122 bool do_size, 1123 outputStream* st) const { 1124 assert(cbuf != NULL || st != NULL, "sanity"); 1125 // Get registers to move 1126 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1127 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1128 OptoReg::Name dst_second = ra_->get_reg_second(this); 1129 OptoReg::Name dst_first = ra_->get_reg_first(this); 1130 1131 enum RC src_second_rc = rc_class(src_second); 1132 enum RC src_first_rc = rc_class(src_first); 1133 enum RC dst_second_rc = rc_class(dst_second); 1134 enum RC dst_first_rc = rc_class(dst_first); 1135 1136 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1137 "must move at least 1 register" ); 1138 1139 if (src_first == dst_first && src_second == dst_second) { 1140 // Self copy, no move 1141 return 0; 1142 } 1143 if (bottom_type()->isa_vect() != NULL) { 1144 uint ireg = ideal_reg(); 1145 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1146 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1147 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1148 // mem -> mem 1149 int src_offset = ra_->reg2offset(src_first); 1150 int dst_offset = ra_->reg2offset(dst_first); 1151 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1152 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1153 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1154 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1155 int stack_offset = ra_->reg2offset(dst_first); 1156 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1157 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1158 int stack_offset = ra_->reg2offset(src_first); 1159 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1160 } else { 1161 ShouldNotReachHere(); 1162 } 1163 return 0; 1164 } 1165 if (src_first_rc == rc_stack) { 1166 // mem -> 1167 if (dst_first_rc == rc_stack) { 1168 // mem -> mem 1169 assert(src_second != dst_first, "overlap"); 1170 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1171 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1172 // 64-bit 1173 int src_offset = ra_->reg2offset(src_first); 1174 int dst_offset = ra_->reg2offset(dst_first); 1175 if (cbuf) { 1176 MacroAssembler _masm(cbuf); 1177 __ pushq(Address(rsp, src_offset)); 1178 __ popq (Address(rsp, dst_offset)); 1179 #ifndef PRODUCT 1180 } else { 1181 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1182 "popq [rsp + #%d]", 1183 src_offset, dst_offset); 1184 #endif 1185 } 1186 } else { 1187 // 32-bit 1188 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1189 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1190 // No pushl/popl, so: 1191 int src_offset = ra_->reg2offset(src_first); 1192 int dst_offset = ra_->reg2offset(dst_first); 1193 if (cbuf) { 1194 MacroAssembler _masm(cbuf); 1195 __ movq(Address(rsp, -8), rax); 1196 __ movl(rax, Address(rsp, src_offset)); 1197 __ movl(Address(rsp, dst_offset), rax); 1198 __ movq(rax, Address(rsp, -8)); 1199 #ifndef PRODUCT 1200 } else { 1201 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1202 "movl rax, [rsp + #%d]\n\t" 1203 "movl [rsp + #%d], rax\n\t" 1204 "movq rax, [rsp - #8]", 1205 src_offset, dst_offset); 1206 #endif 1207 } 1208 } 1209 return 0; 1210 } else if (dst_first_rc == rc_int) { 1211 // mem -> gpr 1212 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1213 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1214 // 64-bit 1215 int offset = ra_->reg2offset(src_first); 1216 if (cbuf) { 1217 MacroAssembler _masm(cbuf); 1218 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1219 #ifndef PRODUCT 1220 } else { 1221 st->print("movq %s, [rsp + #%d]\t# spill", 1222 Matcher::regName[dst_first], 1223 offset); 1224 #endif 1225 } 1226 } else { 1227 // 32-bit 1228 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1229 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1230 int offset = ra_->reg2offset(src_first); 1231 if (cbuf) { 1232 MacroAssembler _masm(cbuf); 1233 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1234 #ifndef PRODUCT 1235 } else { 1236 st->print("movl %s, [rsp + #%d]\t# spill", 1237 Matcher::regName[dst_first], 1238 offset); 1239 #endif 1240 } 1241 } 1242 return 0; 1243 } else if (dst_first_rc == rc_float) { 1244 // mem-> xmm 1245 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1246 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1247 // 64-bit 1248 int offset = ra_->reg2offset(src_first); 1249 if (cbuf) { 1250 MacroAssembler _masm(cbuf); 1251 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1252 #ifndef PRODUCT 1253 } else { 1254 st->print("%s %s, [rsp + #%d]\t# spill", 1255 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1256 Matcher::regName[dst_first], 1257 offset); 1258 #endif 1259 } 1260 } else { 1261 // 32-bit 1262 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1263 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1264 int offset = ra_->reg2offset(src_first); 1265 if (cbuf) { 1266 MacroAssembler _masm(cbuf); 1267 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1268 #ifndef PRODUCT 1269 } else { 1270 st->print("movss %s, [rsp + #%d]\t# spill", 1271 Matcher::regName[dst_first], 1272 offset); 1273 #endif 1274 } 1275 } 1276 return 0; 1277 } 1278 } else if (src_first_rc == rc_int) { 1279 // gpr -> 1280 if (dst_first_rc == rc_stack) { 1281 // gpr -> mem 1282 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1283 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1284 // 64-bit 1285 int offset = ra_->reg2offset(dst_first); 1286 if (cbuf) { 1287 MacroAssembler _masm(cbuf); 1288 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1289 #ifndef PRODUCT 1290 } else { 1291 st->print("movq [rsp + #%d], %s\t# spill", 1292 offset, 1293 Matcher::regName[src_first]); 1294 #endif 1295 } 1296 } else { 1297 // 32-bit 1298 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1299 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1300 int offset = ra_->reg2offset(dst_first); 1301 if (cbuf) { 1302 MacroAssembler _masm(cbuf); 1303 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1304 #ifndef PRODUCT 1305 } else { 1306 st->print("movl [rsp + #%d], %s\t# spill", 1307 offset, 1308 Matcher::regName[src_first]); 1309 #endif 1310 } 1311 } 1312 return 0; 1313 } else if (dst_first_rc == rc_int) { 1314 // gpr -> gpr 1315 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1316 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1317 // 64-bit 1318 if (cbuf) { 1319 MacroAssembler _masm(cbuf); 1320 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1321 as_Register(Matcher::_regEncode[src_first])); 1322 #ifndef PRODUCT 1323 } else { 1324 st->print("movq %s, %s\t# spill", 1325 Matcher::regName[dst_first], 1326 Matcher::regName[src_first]); 1327 #endif 1328 } 1329 return 0; 1330 } else { 1331 // 32-bit 1332 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1333 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1334 if (cbuf) { 1335 MacroAssembler _masm(cbuf); 1336 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1337 as_Register(Matcher::_regEncode[src_first])); 1338 #ifndef PRODUCT 1339 } else { 1340 st->print("movl %s, %s\t# spill", 1341 Matcher::regName[dst_first], 1342 Matcher::regName[src_first]); 1343 #endif 1344 } 1345 return 0; 1346 } 1347 } else if (dst_first_rc == rc_float) { 1348 // gpr -> xmm 1349 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1350 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1351 // 64-bit 1352 if (cbuf) { 1353 MacroAssembler _masm(cbuf); 1354 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1355 #ifndef PRODUCT 1356 } else { 1357 st->print("movdq %s, %s\t# spill", 1358 Matcher::regName[dst_first], 1359 Matcher::regName[src_first]); 1360 #endif 1361 } 1362 } else { 1363 // 32-bit 1364 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1365 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1366 if (cbuf) { 1367 MacroAssembler _masm(cbuf); 1368 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1369 #ifndef PRODUCT 1370 } else { 1371 st->print("movdl %s, %s\t# spill", 1372 Matcher::regName[dst_first], 1373 Matcher::regName[src_first]); 1374 #endif 1375 } 1376 } 1377 return 0; 1378 } 1379 } else if (src_first_rc == rc_float) { 1380 // xmm -> 1381 if (dst_first_rc == rc_stack) { 1382 // xmm -> mem 1383 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1384 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1385 // 64-bit 1386 int offset = ra_->reg2offset(dst_first); 1387 if (cbuf) { 1388 MacroAssembler _masm(cbuf); 1389 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1390 #ifndef PRODUCT 1391 } else { 1392 st->print("movsd [rsp + #%d], %s\t# spill", 1393 offset, 1394 Matcher::regName[src_first]); 1395 #endif 1396 } 1397 } else { 1398 // 32-bit 1399 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1400 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1401 int offset = ra_->reg2offset(dst_first); 1402 if (cbuf) { 1403 MacroAssembler _masm(cbuf); 1404 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1405 #ifndef PRODUCT 1406 } else { 1407 st->print("movss [rsp + #%d], %s\t# spill", 1408 offset, 1409 Matcher::regName[src_first]); 1410 #endif 1411 } 1412 } 1413 return 0; 1414 } else if (dst_first_rc == rc_int) { 1415 // xmm -> gpr 1416 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1417 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1418 // 64-bit 1419 if (cbuf) { 1420 MacroAssembler _masm(cbuf); 1421 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1422 #ifndef PRODUCT 1423 } else { 1424 st->print("movdq %s, %s\t# spill", 1425 Matcher::regName[dst_first], 1426 Matcher::regName[src_first]); 1427 #endif 1428 } 1429 } else { 1430 // 32-bit 1431 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1432 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1433 if (cbuf) { 1434 MacroAssembler _masm(cbuf); 1435 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1436 #ifndef PRODUCT 1437 } else { 1438 st->print("movdl %s, %s\t# spill", 1439 Matcher::regName[dst_first], 1440 Matcher::regName[src_first]); 1441 #endif 1442 } 1443 } 1444 return 0; 1445 } else if (dst_first_rc == rc_float) { 1446 // xmm -> xmm 1447 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1448 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1449 // 64-bit 1450 if (cbuf) { 1451 MacroAssembler _masm(cbuf); 1452 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1453 #ifndef PRODUCT 1454 } else { 1455 st->print("%s %s, %s\t# spill", 1456 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1457 Matcher::regName[dst_first], 1458 Matcher::regName[src_first]); 1459 #endif 1460 } 1461 } else { 1462 // 32-bit 1463 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1464 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1465 if (cbuf) { 1466 MacroAssembler _masm(cbuf); 1467 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1468 #ifndef PRODUCT 1469 } else { 1470 st->print("%s %s, %s\t# spill", 1471 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1472 Matcher::regName[dst_first], 1473 Matcher::regName[src_first]); 1474 #endif 1475 } 1476 } 1477 return 0; 1478 } 1479 } 1480 1481 assert(0," foo "); 1482 Unimplemented(); 1483 return 0; 1484 } 1485 1486 #ifndef PRODUCT 1487 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1488 implementation(NULL, ra_, false, st); 1489 } 1490 #endif 1491 1492 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1493 implementation(&cbuf, ra_, false, NULL); 1494 } 1495 1496 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1497 return MachNode::size(ra_); 1498 } 1499 1500 //============================================================================= 1501 #ifndef PRODUCT 1502 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1503 { 1504 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1505 int reg = ra_->get_reg_first(this); 1506 st->print("leaq %s, [rsp + #%d]\t# box lock", 1507 Matcher::regName[reg], offset); 1508 } 1509 #endif 1510 1511 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1512 { 1513 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1514 int reg = ra_->get_encode(this); 1515 if (offset >= 0x80) { 1516 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1517 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1518 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1519 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1520 emit_d32(cbuf, offset); 1521 } else { 1522 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1523 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1524 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1525 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1526 emit_d8(cbuf, offset); 1527 } 1528 } 1529 1530 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1531 { 1532 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1533 return (offset < 0x80) ? 5 : 8; // REX 1534 } 1535 1536 //============================================================================= 1537 #ifndef PRODUCT 1538 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1539 { 1540 st->print_cr("MachVEPNode"); 1541 } 1542 #endif 1543 1544 void MachVEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1545 { 1546 MacroAssembler masm(&cbuf); 1547 if (!_verified) { 1548 uint insts_size = cbuf.insts_size(); 1549 if (UseCompressedClassPointers) { 1550 masm.load_klass(rscratch1, j_rarg0); 1551 masm.cmpptr(rax, rscratch1); 1552 } else { 1553 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1554 } 1555 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1556 } else { 1557 // Unpack value type args passed as oop and then jump to 1558 // the verified entry point (skipping the unverified entry). 1559 masm.unpack_value_args(ra_->C, _receiver_only); 1560 masm.jmp(*_verified_entry); 1561 } 1562 } 1563 1564 uint MachVEPNode::size(PhaseRegAlloc* ra_) const 1565 { 1566 return MachNode::size(ra_); // too many variables; just compute it the hard way 1567 } 1568 1569 //============================================================================= 1570 #ifndef PRODUCT 1571 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1572 { 1573 if (UseCompressedClassPointers) { 1574 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1575 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1576 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1577 } else { 1578 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1579 "# Inline cache check"); 1580 } 1581 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1582 st->print_cr("\tnop\t# nops to align entry point"); 1583 } 1584 #endif 1585 1586 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1587 { 1588 MacroAssembler masm(&cbuf); 1589 uint insts_size = cbuf.insts_size(); 1590 if (UseCompressedClassPointers) { 1591 masm.load_klass(rscratch1, j_rarg0); 1592 masm.cmpptr(rax, rscratch1); 1593 } else { 1594 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1595 } 1596 1597 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1598 1599 /* WARNING these NOPs are critical so that verified entry point is properly 1600 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1601 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1602 if (OptoBreakpoint) { 1603 // Leave space for int3 1604 nops_cnt -= 1; 1605 } 1606 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1607 if (nops_cnt > 0) 1608 masm.nop(nops_cnt); 1609 } 1610 1611 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1612 { 1613 return MachNode::size(ra_); // too many variables; just compute it 1614 // the hard way 1615 } 1616 1617 1618 //============================================================================= 1619 1620 int Matcher::regnum_to_fpu_offset(int regnum) 1621 { 1622 return regnum - 32; // The FP registers are in the second chunk 1623 } 1624 1625 // This is UltraSparc specific, true just means we have fast l2f conversion 1626 const bool Matcher::convL2FSupported(void) { 1627 return true; 1628 } 1629 1630 // Is this branch offset short enough that a short branch can be used? 1631 // 1632 // NOTE: If the platform does not provide any short branch variants, then 1633 // this method should return false for offset 0. 1634 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1635 // The passed offset is relative to address of the branch. 1636 // On 86 a branch displacement is calculated relative to address 1637 // of a next instruction. 1638 offset -= br_size; 1639 1640 // the short version of jmpConUCF2 contains multiple branches, 1641 // making the reach slightly less 1642 if (rule == jmpConUCF2_rule) 1643 return (-126 <= offset && offset <= 125); 1644 return (-128 <= offset && offset <= 127); 1645 } 1646 1647 const bool Matcher::isSimpleConstant64(jlong value) { 1648 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1649 //return value == (int) value; // Cf. storeImmL and immL32. 1650 1651 // Probably always true, even if a temp register is required. 1652 return true; 1653 } 1654 1655 // The ecx parameter to rep stosq for the ClearArray node is in words. 1656 const bool Matcher::init_array_count_is_in_bytes = false; 1657 1658 // No additional cost for CMOVL. 1659 const int Matcher::long_cmove_cost() { return 0; } 1660 1661 // No CMOVF/CMOVD with SSE2 1662 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1663 1664 // Does the CPU require late expand (see block.cpp for description of late expand)? 1665 const bool Matcher::require_postalloc_expand = false; 1666 1667 // Do we need to mask the count passed to shift instructions or does 1668 // the cpu only look at the lower 5/6 bits anyway? 1669 const bool Matcher::need_masked_shift_count = false; 1670 1671 bool Matcher::narrow_oop_use_complex_address() { 1672 assert(UseCompressedOops, "only for compressed oops code"); 1673 return (LogMinObjAlignmentInBytes <= 3); 1674 } 1675 1676 bool Matcher::narrow_klass_use_complex_address() { 1677 assert(UseCompressedClassPointers, "only for compressed klass code"); 1678 return (LogKlassAlignmentInBytes <= 3); 1679 } 1680 1681 bool Matcher::const_oop_prefer_decode() { 1682 // Prefer ConN+DecodeN over ConP. 1683 return true; 1684 } 1685 1686 bool Matcher::const_klass_prefer_decode() { 1687 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1688 // or condisider the following: 1689 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1690 //return CompressedKlassPointers::base() == NULL; 1691 return true; 1692 } 1693 1694 // Is it better to copy float constants, or load them directly from 1695 // memory? Intel can load a float constant from a direct address, 1696 // requiring no extra registers. Most RISCs will have to materialize 1697 // an address into a register first, so they would do better to copy 1698 // the constant from stack. 1699 const bool Matcher::rematerialize_float_constants = true; // XXX 1700 1701 // If CPU can load and store mis-aligned doubles directly then no 1702 // fixup is needed. Else we split the double into 2 integer pieces 1703 // and move it piece-by-piece. Only happens when passing doubles into 1704 // C code as the Java calling convention forces doubles to be aligned. 1705 const bool Matcher::misaligned_doubles_ok = true; 1706 1707 // No-op on amd64 1708 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1709 1710 // Advertise here if the CPU requires explicit rounding operations to 1711 // implement the UseStrictFP mode. 1712 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1713 1714 // Are floats conerted to double when stored to stack during deoptimization? 1715 // On x64 it is stored without convertion so we can use normal access. 1716 bool Matcher::float_in_double() { return false; } 1717 1718 // Do ints take an entire long register or just half? 1719 const bool Matcher::int_in_long = true; 1720 1721 // Return whether or not this register is ever used as an argument. 1722 // This function is used on startup to build the trampoline stubs in 1723 // generateOptoStub. Registers not mentioned will be killed by the VM 1724 // call in the trampoline, and arguments in those registers not be 1725 // available to the callee. 1726 bool Matcher::can_be_java_arg(int reg) 1727 { 1728 return 1729 reg == RDI_num || reg == RDI_H_num || 1730 reg == RSI_num || reg == RSI_H_num || 1731 reg == RDX_num || reg == RDX_H_num || 1732 reg == RCX_num || reg == RCX_H_num || 1733 reg == R8_num || reg == R8_H_num || 1734 reg == R9_num || reg == R9_H_num || 1735 reg == R12_num || reg == R12_H_num || 1736 reg == XMM0_num || reg == XMM0b_num || 1737 reg == XMM1_num || reg == XMM1b_num || 1738 reg == XMM2_num || reg == XMM2b_num || 1739 reg == XMM3_num || reg == XMM3b_num || 1740 reg == XMM4_num || reg == XMM4b_num || 1741 reg == XMM5_num || reg == XMM5b_num || 1742 reg == XMM6_num || reg == XMM6b_num || 1743 reg == XMM7_num || reg == XMM7b_num; 1744 } 1745 1746 bool Matcher::is_spillable_arg(int reg) 1747 { 1748 return can_be_java_arg(reg); 1749 } 1750 1751 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1752 // In 64 bit mode a code which use multiply when 1753 // devisor is constant is faster than hardware 1754 // DIV instruction (it uses MulHiL). 1755 return false; 1756 } 1757 1758 // Register for DIVI projection of divmodI 1759 RegMask Matcher::divI_proj_mask() { 1760 return INT_RAX_REG_mask(); 1761 } 1762 1763 // Register for MODI projection of divmodI 1764 RegMask Matcher::modI_proj_mask() { 1765 return INT_RDX_REG_mask(); 1766 } 1767 1768 // Register for DIVL projection of divmodL 1769 RegMask Matcher::divL_proj_mask() { 1770 return LONG_RAX_REG_mask(); 1771 } 1772 1773 // Register for MODL projection of divmodL 1774 RegMask Matcher::modL_proj_mask() { 1775 return LONG_RDX_REG_mask(); 1776 } 1777 1778 // Register for saving SP into on method handle invokes. Not used on x86_64. 1779 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1780 return NO_REG_mask(); 1781 } 1782 1783 %} 1784 1785 //----------ENCODING BLOCK----------------------------------------------------- 1786 // This block specifies the encoding classes used by the compiler to 1787 // output byte streams. Encoding classes are parameterized macros 1788 // used by Machine Instruction Nodes in order to generate the bit 1789 // encoding of the instruction. Operands specify their base encoding 1790 // interface with the interface keyword. There are currently 1791 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1792 // COND_INTER. REG_INTER causes an operand to generate a function 1793 // which returns its register number when queried. CONST_INTER causes 1794 // an operand to generate a function which returns the value of the 1795 // constant when queried. MEMORY_INTER causes an operand to generate 1796 // four functions which return the Base Register, the Index Register, 1797 // the Scale Value, and the Offset Value of the operand when queried. 1798 // COND_INTER causes an operand to generate six functions which return 1799 // the encoding code (ie - encoding bits for the instruction) 1800 // associated with each basic boolean condition for a conditional 1801 // instruction. 1802 // 1803 // Instructions specify two basic values for encoding. Again, a 1804 // function is available to check if the constant displacement is an 1805 // oop. They use the ins_encode keyword to specify their encoding 1806 // classes (which must be a sequence of enc_class names, and their 1807 // parameters, specified in the encoding block), and they use the 1808 // opcode keyword to specify, in order, their primary, secondary, and 1809 // tertiary opcode. Only the opcode sections which a particular 1810 // instruction needs for encoding need to be specified. 1811 encode %{ 1812 // Build emit functions for each basic byte or larger field in the 1813 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1814 // from C++ code in the enc_class source block. Emit functions will 1815 // live in the main source block for now. In future, we can 1816 // generalize this by adding a syntax that specifies the sizes of 1817 // fields in an order, so that the adlc can build the emit functions 1818 // automagically 1819 1820 // Emit primary opcode 1821 enc_class OpcP 1822 %{ 1823 emit_opcode(cbuf, $primary); 1824 %} 1825 1826 // Emit secondary opcode 1827 enc_class OpcS 1828 %{ 1829 emit_opcode(cbuf, $secondary); 1830 %} 1831 1832 // Emit tertiary opcode 1833 enc_class OpcT 1834 %{ 1835 emit_opcode(cbuf, $tertiary); 1836 %} 1837 1838 // Emit opcode directly 1839 enc_class Opcode(immI d8) 1840 %{ 1841 emit_opcode(cbuf, $d8$$constant); 1842 %} 1843 1844 // Emit size prefix 1845 enc_class SizePrefix 1846 %{ 1847 emit_opcode(cbuf, 0x66); 1848 %} 1849 1850 enc_class reg(rRegI reg) 1851 %{ 1852 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1853 %} 1854 1855 enc_class reg_reg(rRegI dst, rRegI src) 1856 %{ 1857 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1858 %} 1859 1860 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1861 %{ 1862 emit_opcode(cbuf, $opcode$$constant); 1863 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1864 %} 1865 1866 enc_class cdql_enc(no_rax_rdx_RegI div) 1867 %{ 1868 // Full implementation of Java idiv and irem; checks for 1869 // special case as described in JVM spec., p.243 & p.271. 1870 // 1871 // normal case special case 1872 // 1873 // input : rax: dividend min_int 1874 // reg: divisor -1 1875 // 1876 // output: rax: quotient (= rax idiv reg) min_int 1877 // rdx: remainder (= rax irem reg) 0 1878 // 1879 // Code sequnce: 1880 // 1881 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1882 // 5: 75 07/08 jne e <normal> 1883 // 7: 33 d2 xor %edx,%edx 1884 // [div >= 8 -> offset + 1] 1885 // [REX_B] 1886 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1887 // c: 74 03/04 je 11 <done> 1888 // 000000000000000e <normal>: 1889 // e: 99 cltd 1890 // [div >= 8 -> offset + 1] 1891 // [REX_B] 1892 // f: f7 f9 idiv $div 1893 // 0000000000000011 <done>: 1894 1895 // cmp $0x80000000,%eax 1896 emit_opcode(cbuf, 0x3d); 1897 emit_d8(cbuf, 0x00); 1898 emit_d8(cbuf, 0x00); 1899 emit_d8(cbuf, 0x00); 1900 emit_d8(cbuf, 0x80); 1901 1902 // jne e <normal> 1903 emit_opcode(cbuf, 0x75); 1904 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1905 1906 // xor %edx,%edx 1907 emit_opcode(cbuf, 0x33); 1908 emit_d8(cbuf, 0xD2); 1909 1910 // cmp $0xffffffffffffffff,%ecx 1911 if ($div$$reg >= 8) { 1912 emit_opcode(cbuf, Assembler::REX_B); 1913 } 1914 emit_opcode(cbuf, 0x83); 1915 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1916 emit_d8(cbuf, 0xFF); 1917 1918 // je 11 <done> 1919 emit_opcode(cbuf, 0x74); 1920 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1921 1922 // <normal> 1923 // cltd 1924 emit_opcode(cbuf, 0x99); 1925 1926 // idivl (note: must be emitted by the user of this rule) 1927 // <done> 1928 %} 1929 1930 enc_class cdqq_enc(no_rax_rdx_RegL div) 1931 %{ 1932 // Full implementation of Java ldiv and lrem; checks for 1933 // special case as described in JVM spec., p.243 & p.271. 1934 // 1935 // normal case special case 1936 // 1937 // input : rax: dividend min_long 1938 // reg: divisor -1 1939 // 1940 // output: rax: quotient (= rax idiv reg) min_long 1941 // rdx: remainder (= rax irem reg) 0 1942 // 1943 // Code sequnce: 1944 // 1945 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1946 // 7: 00 00 80 1947 // a: 48 39 d0 cmp %rdx,%rax 1948 // d: 75 08 jne 17 <normal> 1949 // f: 33 d2 xor %edx,%edx 1950 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1951 // 15: 74 05 je 1c <done> 1952 // 0000000000000017 <normal>: 1953 // 17: 48 99 cqto 1954 // 19: 48 f7 f9 idiv $div 1955 // 000000000000001c <done>: 1956 1957 // mov $0x8000000000000000,%rdx 1958 emit_opcode(cbuf, Assembler::REX_W); 1959 emit_opcode(cbuf, 0xBA); 1960 emit_d8(cbuf, 0x00); 1961 emit_d8(cbuf, 0x00); 1962 emit_d8(cbuf, 0x00); 1963 emit_d8(cbuf, 0x00); 1964 emit_d8(cbuf, 0x00); 1965 emit_d8(cbuf, 0x00); 1966 emit_d8(cbuf, 0x00); 1967 emit_d8(cbuf, 0x80); 1968 1969 // cmp %rdx,%rax 1970 emit_opcode(cbuf, Assembler::REX_W); 1971 emit_opcode(cbuf, 0x39); 1972 emit_d8(cbuf, 0xD0); 1973 1974 // jne 17 <normal> 1975 emit_opcode(cbuf, 0x75); 1976 emit_d8(cbuf, 0x08); 1977 1978 // xor %edx,%edx 1979 emit_opcode(cbuf, 0x33); 1980 emit_d8(cbuf, 0xD2); 1981 1982 // cmp $0xffffffffffffffff,$div 1983 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1984 emit_opcode(cbuf, 0x83); 1985 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1986 emit_d8(cbuf, 0xFF); 1987 1988 // je 1e <done> 1989 emit_opcode(cbuf, 0x74); 1990 emit_d8(cbuf, 0x05); 1991 1992 // <normal> 1993 // cqto 1994 emit_opcode(cbuf, Assembler::REX_W); 1995 emit_opcode(cbuf, 0x99); 1996 1997 // idivq (note: must be emitted by the user of this rule) 1998 // <done> 1999 %} 2000 2001 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2002 enc_class OpcSE(immI imm) 2003 %{ 2004 // Emit primary opcode and set sign-extend bit 2005 // Check for 8-bit immediate, and set sign extend bit in opcode 2006 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2007 emit_opcode(cbuf, $primary | 0x02); 2008 } else { 2009 // 32-bit immediate 2010 emit_opcode(cbuf, $primary); 2011 } 2012 %} 2013 2014 enc_class OpcSErm(rRegI dst, immI imm) 2015 %{ 2016 // OpcSEr/m 2017 int dstenc = $dst$$reg; 2018 if (dstenc >= 8) { 2019 emit_opcode(cbuf, Assembler::REX_B); 2020 dstenc -= 8; 2021 } 2022 // Emit primary opcode and set sign-extend bit 2023 // Check for 8-bit immediate, and set sign extend bit in opcode 2024 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2025 emit_opcode(cbuf, $primary | 0x02); 2026 } else { 2027 // 32-bit immediate 2028 emit_opcode(cbuf, $primary); 2029 } 2030 // Emit r/m byte with secondary opcode, after primary opcode. 2031 emit_rm(cbuf, 0x3, $secondary, dstenc); 2032 %} 2033 2034 enc_class OpcSErm_wide(rRegL dst, immI imm) 2035 %{ 2036 // OpcSEr/m 2037 int dstenc = $dst$$reg; 2038 if (dstenc < 8) { 2039 emit_opcode(cbuf, Assembler::REX_W); 2040 } else { 2041 emit_opcode(cbuf, Assembler::REX_WB); 2042 dstenc -= 8; 2043 } 2044 // Emit primary opcode and set sign-extend bit 2045 // Check for 8-bit immediate, and set sign extend bit in opcode 2046 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2047 emit_opcode(cbuf, $primary | 0x02); 2048 } else { 2049 // 32-bit immediate 2050 emit_opcode(cbuf, $primary); 2051 } 2052 // Emit r/m byte with secondary opcode, after primary opcode. 2053 emit_rm(cbuf, 0x3, $secondary, dstenc); 2054 %} 2055 2056 enc_class Con8or32(immI imm) 2057 %{ 2058 // Check for 8-bit immediate, and set sign extend bit in opcode 2059 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2060 $$$emit8$imm$$constant; 2061 } else { 2062 // 32-bit immediate 2063 $$$emit32$imm$$constant; 2064 } 2065 %} 2066 2067 enc_class opc2_reg(rRegI dst) 2068 %{ 2069 // BSWAP 2070 emit_cc(cbuf, $secondary, $dst$$reg); 2071 %} 2072 2073 enc_class opc3_reg(rRegI dst) 2074 %{ 2075 // BSWAP 2076 emit_cc(cbuf, $tertiary, $dst$$reg); 2077 %} 2078 2079 enc_class reg_opc(rRegI div) 2080 %{ 2081 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2082 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2083 %} 2084 2085 enc_class enc_cmov(cmpOp cop) 2086 %{ 2087 // CMOV 2088 $$$emit8$primary; 2089 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2090 %} 2091 2092 enc_class enc_PartialSubtypeCheck() 2093 %{ 2094 Register Rrdi = as_Register(RDI_enc); // result register 2095 Register Rrax = as_Register(RAX_enc); // super class 2096 Register Rrcx = as_Register(RCX_enc); // killed 2097 Register Rrsi = as_Register(RSI_enc); // sub class 2098 Label miss; 2099 const bool set_cond_codes = true; 2100 2101 MacroAssembler _masm(&cbuf); 2102 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2103 NULL, &miss, 2104 /*set_cond_codes:*/ true); 2105 if ($primary) { 2106 __ xorptr(Rrdi, Rrdi); 2107 } 2108 __ bind(miss); 2109 %} 2110 2111 enc_class clear_avx %{ 2112 debug_only(int off0 = cbuf.insts_size()); 2113 if (generate_vzeroupper(Compile::current())) { 2114 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2115 // Clear upper bits of YMM registers when current compiled code uses 2116 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2117 MacroAssembler _masm(&cbuf); 2118 __ vzeroupper(); 2119 } 2120 debug_only(int off1 = cbuf.insts_size()); 2121 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2122 %} 2123 2124 enc_class Java_To_Runtime(method meth) %{ 2125 // No relocation needed 2126 MacroAssembler _masm(&cbuf); 2127 __ mov64(r10, (int64_t) $meth$$method); 2128 __ call(r10); 2129 %} 2130 2131 enc_class Java_To_Interpreter(method meth) 2132 %{ 2133 // CALL Java_To_Interpreter 2134 // This is the instruction starting address for relocation info. 2135 cbuf.set_insts_mark(); 2136 $$$emit8$primary; 2137 // CALL directly to the runtime 2138 emit_d32_reloc(cbuf, 2139 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2140 runtime_call_Relocation::spec(), 2141 RELOC_DISP32); 2142 %} 2143 2144 enc_class Java_Static_Call(method meth) 2145 %{ 2146 // JAVA STATIC CALL 2147 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2148 // determine who we intended to call. 2149 cbuf.set_insts_mark(); 2150 $$$emit8$primary; 2151 2152 if (!_method) { 2153 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2154 runtime_call_Relocation::spec(), 2155 RELOC_DISP32); 2156 } else { 2157 int method_index = resolved_method_index(cbuf); 2158 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2159 : static_call_Relocation::spec(method_index); 2160 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2161 rspec, RELOC_DISP32); 2162 // Emit stubs for static call. 2163 address mark = cbuf.insts_mark(); 2164 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2165 if (stub == NULL) { 2166 ciEnv::current()->record_failure("CodeCache is full"); 2167 return; 2168 } 2169 #if INCLUDE_AOT 2170 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2171 #endif 2172 } 2173 %} 2174 2175 enc_class Java_Dynamic_Call(method meth) %{ 2176 MacroAssembler _masm(&cbuf); 2177 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2178 %} 2179 2180 enc_class Java_Compiled_Call(method meth) 2181 %{ 2182 // JAVA COMPILED CALL 2183 int disp = in_bytes(Method:: from_compiled_offset()); 2184 2185 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2186 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2187 2188 // callq *disp(%rax) 2189 cbuf.set_insts_mark(); 2190 $$$emit8$primary; 2191 if (disp < 0x80) { 2192 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2193 emit_d8(cbuf, disp); // Displacement 2194 } else { 2195 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2196 emit_d32(cbuf, disp); // Displacement 2197 } 2198 %} 2199 2200 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2201 %{ 2202 // SAL, SAR, SHR 2203 int dstenc = $dst$$reg; 2204 if (dstenc >= 8) { 2205 emit_opcode(cbuf, Assembler::REX_B); 2206 dstenc -= 8; 2207 } 2208 $$$emit8$primary; 2209 emit_rm(cbuf, 0x3, $secondary, dstenc); 2210 $$$emit8$shift$$constant; 2211 %} 2212 2213 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2214 %{ 2215 // SAL, SAR, SHR 2216 int dstenc = $dst$$reg; 2217 if (dstenc < 8) { 2218 emit_opcode(cbuf, Assembler::REX_W); 2219 } else { 2220 emit_opcode(cbuf, Assembler::REX_WB); 2221 dstenc -= 8; 2222 } 2223 $$$emit8$primary; 2224 emit_rm(cbuf, 0x3, $secondary, dstenc); 2225 $$$emit8$shift$$constant; 2226 %} 2227 2228 enc_class load_immI(rRegI dst, immI src) 2229 %{ 2230 int dstenc = $dst$$reg; 2231 if (dstenc >= 8) { 2232 emit_opcode(cbuf, Assembler::REX_B); 2233 dstenc -= 8; 2234 } 2235 emit_opcode(cbuf, 0xB8 | dstenc); 2236 $$$emit32$src$$constant; 2237 %} 2238 2239 enc_class load_immL(rRegL dst, immL src) 2240 %{ 2241 int dstenc = $dst$$reg; 2242 if (dstenc < 8) { 2243 emit_opcode(cbuf, Assembler::REX_W); 2244 } else { 2245 emit_opcode(cbuf, Assembler::REX_WB); 2246 dstenc -= 8; 2247 } 2248 emit_opcode(cbuf, 0xB8 | dstenc); 2249 emit_d64(cbuf, $src$$constant); 2250 %} 2251 2252 enc_class load_immUL32(rRegL dst, immUL32 src) 2253 %{ 2254 // same as load_immI, but this time we care about zeroes in the high word 2255 int dstenc = $dst$$reg; 2256 if (dstenc >= 8) { 2257 emit_opcode(cbuf, Assembler::REX_B); 2258 dstenc -= 8; 2259 } 2260 emit_opcode(cbuf, 0xB8 | dstenc); 2261 $$$emit32$src$$constant; 2262 %} 2263 2264 enc_class load_immL32(rRegL dst, immL32 src) 2265 %{ 2266 int dstenc = $dst$$reg; 2267 if (dstenc < 8) { 2268 emit_opcode(cbuf, Assembler::REX_W); 2269 } else { 2270 emit_opcode(cbuf, Assembler::REX_WB); 2271 dstenc -= 8; 2272 } 2273 emit_opcode(cbuf, 0xC7); 2274 emit_rm(cbuf, 0x03, 0x00, dstenc); 2275 $$$emit32$src$$constant; 2276 %} 2277 2278 enc_class load_immP31(rRegP dst, immP32 src) 2279 %{ 2280 // same as load_immI, but this time we care about zeroes in the high word 2281 int dstenc = $dst$$reg; 2282 if (dstenc >= 8) { 2283 emit_opcode(cbuf, Assembler::REX_B); 2284 dstenc -= 8; 2285 } 2286 emit_opcode(cbuf, 0xB8 | dstenc); 2287 $$$emit32$src$$constant; 2288 %} 2289 2290 enc_class load_immP(rRegP dst, immP src) 2291 %{ 2292 int dstenc = $dst$$reg; 2293 if (dstenc < 8) { 2294 emit_opcode(cbuf, Assembler::REX_W); 2295 } else { 2296 emit_opcode(cbuf, Assembler::REX_WB); 2297 dstenc -= 8; 2298 } 2299 emit_opcode(cbuf, 0xB8 | dstenc); 2300 // This next line should be generated from ADLC 2301 if ($src->constant_reloc() != relocInfo::none) { 2302 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2303 } else { 2304 emit_d64(cbuf, $src$$constant); 2305 } 2306 %} 2307 2308 enc_class Con32(immI src) 2309 %{ 2310 // Output immediate 2311 $$$emit32$src$$constant; 2312 %} 2313 2314 enc_class Con32F_as_bits(immF src) 2315 %{ 2316 // Output Float immediate bits 2317 jfloat jf = $src$$constant; 2318 jint jf_as_bits = jint_cast(jf); 2319 emit_d32(cbuf, jf_as_bits); 2320 %} 2321 2322 enc_class Con16(immI src) 2323 %{ 2324 // Output immediate 2325 $$$emit16$src$$constant; 2326 %} 2327 2328 // How is this different from Con32??? XXX 2329 enc_class Con_d32(immI src) 2330 %{ 2331 emit_d32(cbuf,$src$$constant); 2332 %} 2333 2334 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2335 // Output immediate memory reference 2336 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2337 emit_d32(cbuf, 0x00); 2338 %} 2339 2340 enc_class lock_prefix() 2341 %{ 2342 emit_opcode(cbuf, 0xF0); // lock 2343 %} 2344 2345 enc_class REX_mem(memory mem) 2346 %{ 2347 if ($mem$$base >= 8) { 2348 if ($mem$$index < 8) { 2349 emit_opcode(cbuf, Assembler::REX_B); 2350 } else { 2351 emit_opcode(cbuf, Assembler::REX_XB); 2352 } 2353 } else { 2354 if ($mem$$index >= 8) { 2355 emit_opcode(cbuf, Assembler::REX_X); 2356 } 2357 } 2358 %} 2359 2360 enc_class REX_mem_wide(memory mem) 2361 %{ 2362 if ($mem$$base >= 8) { 2363 if ($mem$$index < 8) { 2364 emit_opcode(cbuf, Assembler::REX_WB); 2365 } else { 2366 emit_opcode(cbuf, Assembler::REX_WXB); 2367 } 2368 } else { 2369 if ($mem$$index < 8) { 2370 emit_opcode(cbuf, Assembler::REX_W); 2371 } else { 2372 emit_opcode(cbuf, Assembler::REX_WX); 2373 } 2374 } 2375 %} 2376 2377 // for byte regs 2378 enc_class REX_breg(rRegI reg) 2379 %{ 2380 if ($reg$$reg >= 4) { 2381 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2382 } 2383 %} 2384 2385 // for byte regs 2386 enc_class REX_reg_breg(rRegI dst, rRegI src) 2387 %{ 2388 if ($dst$$reg < 8) { 2389 if ($src$$reg >= 4) { 2390 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2391 } 2392 } else { 2393 if ($src$$reg < 8) { 2394 emit_opcode(cbuf, Assembler::REX_R); 2395 } else { 2396 emit_opcode(cbuf, Assembler::REX_RB); 2397 } 2398 } 2399 %} 2400 2401 // for byte regs 2402 enc_class REX_breg_mem(rRegI reg, memory mem) 2403 %{ 2404 if ($reg$$reg < 8) { 2405 if ($mem$$base < 8) { 2406 if ($mem$$index >= 8) { 2407 emit_opcode(cbuf, Assembler::REX_X); 2408 } else if ($reg$$reg >= 4) { 2409 emit_opcode(cbuf, Assembler::REX); 2410 } 2411 } else { 2412 if ($mem$$index < 8) { 2413 emit_opcode(cbuf, Assembler::REX_B); 2414 } else { 2415 emit_opcode(cbuf, Assembler::REX_XB); 2416 } 2417 } 2418 } else { 2419 if ($mem$$base < 8) { 2420 if ($mem$$index < 8) { 2421 emit_opcode(cbuf, Assembler::REX_R); 2422 } else { 2423 emit_opcode(cbuf, Assembler::REX_RX); 2424 } 2425 } else { 2426 if ($mem$$index < 8) { 2427 emit_opcode(cbuf, Assembler::REX_RB); 2428 } else { 2429 emit_opcode(cbuf, Assembler::REX_RXB); 2430 } 2431 } 2432 } 2433 %} 2434 2435 enc_class REX_reg(rRegI reg) 2436 %{ 2437 if ($reg$$reg >= 8) { 2438 emit_opcode(cbuf, Assembler::REX_B); 2439 } 2440 %} 2441 2442 enc_class REX_reg_wide(rRegI reg) 2443 %{ 2444 if ($reg$$reg < 8) { 2445 emit_opcode(cbuf, Assembler::REX_W); 2446 } else { 2447 emit_opcode(cbuf, Assembler::REX_WB); 2448 } 2449 %} 2450 2451 enc_class REX_reg_reg(rRegI dst, rRegI src) 2452 %{ 2453 if ($dst$$reg < 8) { 2454 if ($src$$reg >= 8) { 2455 emit_opcode(cbuf, Assembler::REX_B); 2456 } 2457 } else { 2458 if ($src$$reg < 8) { 2459 emit_opcode(cbuf, Assembler::REX_R); 2460 } else { 2461 emit_opcode(cbuf, Assembler::REX_RB); 2462 } 2463 } 2464 %} 2465 2466 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2467 %{ 2468 if ($dst$$reg < 8) { 2469 if ($src$$reg < 8) { 2470 emit_opcode(cbuf, Assembler::REX_W); 2471 } else { 2472 emit_opcode(cbuf, Assembler::REX_WB); 2473 } 2474 } else { 2475 if ($src$$reg < 8) { 2476 emit_opcode(cbuf, Assembler::REX_WR); 2477 } else { 2478 emit_opcode(cbuf, Assembler::REX_WRB); 2479 } 2480 } 2481 %} 2482 2483 enc_class REX_reg_mem(rRegI reg, memory mem) 2484 %{ 2485 if ($reg$$reg < 8) { 2486 if ($mem$$base < 8) { 2487 if ($mem$$index >= 8) { 2488 emit_opcode(cbuf, Assembler::REX_X); 2489 } 2490 } else { 2491 if ($mem$$index < 8) { 2492 emit_opcode(cbuf, Assembler::REX_B); 2493 } else { 2494 emit_opcode(cbuf, Assembler::REX_XB); 2495 } 2496 } 2497 } else { 2498 if ($mem$$base < 8) { 2499 if ($mem$$index < 8) { 2500 emit_opcode(cbuf, Assembler::REX_R); 2501 } else { 2502 emit_opcode(cbuf, Assembler::REX_RX); 2503 } 2504 } else { 2505 if ($mem$$index < 8) { 2506 emit_opcode(cbuf, Assembler::REX_RB); 2507 } else { 2508 emit_opcode(cbuf, Assembler::REX_RXB); 2509 } 2510 } 2511 } 2512 %} 2513 2514 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2515 %{ 2516 if ($reg$$reg < 8) { 2517 if ($mem$$base < 8) { 2518 if ($mem$$index < 8) { 2519 emit_opcode(cbuf, Assembler::REX_W); 2520 } else { 2521 emit_opcode(cbuf, Assembler::REX_WX); 2522 } 2523 } else { 2524 if ($mem$$index < 8) { 2525 emit_opcode(cbuf, Assembler::REX_WB); 2526 } else { 2527 emit_opcode(cbuf, Assembler::REX_WXB); 2528 } 2529 } 2530 } else { 2531 if ($mem$$base < 8) { 2532 if ($mem$$index < 8) { 2533 emit_opcode(cbuf, Assembler::REX_WR); 2534 } else { 2535 emit_opcode(cbuf, Assembler::REX_WRX); 2536 } 2537 } else { 2538 if ($mem$$index < 8) { 2539 emit_opcode(cbuf, Assembler::REX_WRB); 2540 } else { 2541 emit_opcode(cbuf, Assembler::REX_WRXB); 2542 } 2543 } 2544 } 2545 %} 2546 2547 enc_class reg_mem(rRegI ereg, memory mem) 2548 %{ 2549 // High registers handle in encode_RegMem 2550 int reg = $ereg$$reg; 2551 int base = $mem$$base; 2552 int index = $mem$$index; 2553 int scale = $mem$$scale; 2554 int disp = $mem$$disp; 2555 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2556 2557 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2558 %} 2559 2560 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2561 %{ 2562 int rm_byte_opcode = $rm_opcode$$constant; 2563 2564 // High registers handle in encode_RegMem 2565 int base = $mem$$base; 2566 int index = $mem$$index; 2567 int scale = $mem$$scale; 2568 int displace = $mem$$disp; 2569 2570 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2571 // working with static 2572 // globals 2573 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2574 disp_reloc); 2575 %} 2576 2577 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2578 %{ 2579 int reg_encoding = $dst$$reg; 2580 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2581 int index = 0x04; // 0x04 indicates no index 2582 int scale = 0x00; // 0x00 indicates no scale 2583 int displace = $src1$$constant; // 0x00 indicates no displacement 2584 relocInfo::relocType disp_reloc = relocInfo::none; 2585 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2586 disp_reloc); 2587 %} 2588 2589 enc_class neg_reg(rRegI dst) 2590 %{ 2591 int dstenc = $dst$$reg; 2592 if (dstenc >= 8) { 2593 emit_opcode(cbuf, Assembler::REX_B); 2594 dstenc -= 8; 2595 } 2596 // NEG $dst 2597 emit_opcode(cbuf, 0xF7); 2598 emit_rm(cbuf, 0x3, 0x03, dstenc); 2599 %} 2600 2601 enc_class neg_reg_wide(rRegI dst) 2602 %{ 2603 int dstenc = $dst$$reg; 2604 if (dstenc < 8) { 2605 emit_opcode(cbuf, Assembler::REX_W); 2606 } else { 2607 emit_opcode(cbuf, Assembler::REX_WB); 2608 dstenc -= 8; 2609 } 2610 // NEG $dst 2611 emit_opcode(cbuf, 0xF7); 2612 emit_rm(cbuf, 0x3, 0x03, dstenc); 2613 %} 2614 2615 enc_class setLT_reg(rRegI dst) 2616 %{ 2617 int dstenc = $dst$$reg; 2618 if (dstenc >= 8) { 2619 emit_opcode(cbuf, Assembler::REX_B); 2620 dstenc -= 8; 2621 } else if (dstenc >= 4) { 2622 emit_opcode(cbuf, Assembler::REX); 2623 } 2624 // SETLT $dst 2625 emit_opcode(cbuf, 0x0F); 2626 emit_opcode(cbuf, 0x9C); 2627 emit_rm(cbuf, 0x3, 0x0, dstenc); 2628 %} 2629 2630 enc_class setNZ_reg(rRegI dst) 2631 %{ 2632 int dstenc = $dst$$reg; 2633 if (dstenc >= 8) { 2634 emit_opcode(cbuf, Assembler::REX_B); 2635 dstenc -= 8; 2636 } else if (dstenc >= 4) { 2637 emit_opcode(cbuf, Assembler::REX); 2638 } 2639 // SETNZ $dst 2640 emit_opcode(cbuf, 0x0F); 2641 emit_opcode(cbuf, 0x95); 2642 emit_rm(cbuf, 0x3, 0x0, dstenc); 2643 %} 2644 2645 2646 // Compare the lonogs and set -1, 0, or 1 into dst 2647 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2648 %{ 2649 int src1enc = $src1$$reg; 2650 int src2enc = $src2$$reg; 2651 int dstenc = $dst$$reg; 2652 2653 // cmpq $src1, $src2 2654 if (src1enc < 8) { 2655 if (src2enc < 8) { 2656 emit_opcode(cbuf, Assembler::REX_W); 2657 } else { 2658 emit_opcode(cbuf, Assembler::REX_WB); 2659 } 2660 } else { 2661 if (src2enc < 8) { 2662 emit_opcode(cbuf, Assembler::REX_WR); 2663 } else { 2664 emit_opcode(cbuf, Assembler::REX_WRB); 2665 } 2666 } 2667 emit_opcode(cbuf, 0x3B); 2668 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2669 2670 // movl $dst, -1 2671 if (dstenc >= 8) { 2672 emit_opcode(cbuf, Assembler::REX_B); 2673 } 2674 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2675 emit_d32(cbuf, -1); 2676 2677 // jl,s done 2678 emit_opcode(cbuf, 0x7C); 2679 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2680 2681 // setne $dst 2682 if (dstenc >= 4) { 2683 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2684 } 2685 emit_opcode(cbuf, 0x0F); 2686 emit_opcode(cbuf, 0x95); 2687 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2688 2689 // movzbl $dst, $dst 2690 if (dstenc >= 4) { 2691 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2692 } 2693 emit_opcode(cbuf, 0x0F); 2694 emit_opcode(cbuf, 0xB6); 2695 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2696 %} 2697 2698 enc_class Push_ResultXD(regD dst) %{ 2699 MacroAssembler _masm(&cbuf); 2700 __ fstp_d(Address(rsp, 0)); 2701 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2702 __ addptr(rsp, 8); 2703 %} 2704 2705 enc_class Push_SrcXD(regD src) %{ 2706 MacroAssembler _masm(&cbuf); 2707 __ subptr(rsp, 8); 2708 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2709 __ fld_d(Address(rsp, 0)); 2710 %} 2711 2712 2713 enc_class enc_rethrow() 2714 %{ 2715 cbuf.set_insts_mark(); 2716 emit_opcode(cbuf, 0xE9); // jmp entry 2717 emit_d32_reloc(cbuf, 2718 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2719 runtime_call_Relocation::spec(), 2720 RELOC_DISP32); 2721 %} 2722 2723 %} 2724 2725 2726 2727 //----------FRAME-------------------------------------------------------------- 2728 // Definition of frame structure and management information. 2729 // 2730 // S T A C K L A Y O U T Allocators stack-slot number 2731 // | (to get allocators register number 2732 // G Owned by | | v add OptoReg::stack0()) 2733 // r CALLER | | 2734 // o | +--------+ pad to even-align allocators stack-slot 2735 // w V | pad0 | numbers; owned by CALLER 2736 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2737 // h ^ | in | 5 2738 // | | args | 4 Holes in incoming args owned by SELF 2739 // | | | | 3 2740 // | | +--------+ 2741 // V | | old out| Empty on Intel, window on Sparc 2742 // | old |preserve| Must be even aligned. 2743 // | SP-+--------+----> Matcher::_old_SP, even aligned 2744 // | | in | 3 area for Intel ret address 2745 // Owned by |preserve| Empty on Sparc. 2746 // SELF +--------+ 2747 // | | pad2 | 2 pad to align old SP 2748 // | +--------+ 1 2749 // | | locks | 0 2750 // | +--------+----> OptoReg::stack0(), even aligned 2751 // | | pad1 | 11 pad to align new SP 2752 // | +--------+ 2753 // | | | 10 2754 // | | spills | 9 spills 2755 // V | | 8 (pad0 slot for callee) 2756 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2757 // ^ | out | 7 2758 // | | args | 6 Holes in outgoing args owned by CALLEE 2759 // Owned by +--------+ 2760 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2761 // | new |preserve| Must be even-aligned. 2762 // | SP-+--------+----> Matcher::_new_SP, even aligned 2763 // | | | 2764 // 2765 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2766 // known from SELF's arguments and the Java calling convention. 2767 // Region 6-7 is determined per call site. 2768 // Note 2: If the calling convention leaves holes in the incoming argument 2769 // area, those holes are owned by SELF. Holes in the outgoing area 2770 // are owned by the CALLEE. Holes should not be nessecary in the 2771 // incoming area, as the Java calling convention is completely under 2772 // the control of the AD file. Doubles can be sorted and packed to 2773 // avoid holes. Holes in the outgoing arguments may be nessecary for 2774 // varargs C calling conventions. 2775 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2776 // even aligned with pad0 as needed. 2777 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2778 // region 6-11 is even aligned; it may be padded out more so that 2779 // the region from SP to FP meets the minimum stack alignment. 2780 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2781 // alignment. Region 11, pad1, may be dynamically extended so that 2782 // SP meets the minimum alignment. 2783 2784 frame 2785 %{ 2786 // What direction does stack grow in (assumed to be same for C & Java) 2787 stack_direction(TOWARDS_LOW); 2788 2789 // These three registers define part of the calling convention 2790 // between compiled code and the interpreter. 2791 inline_cache_reg(RAX); // Inline Cache Register 2792 interpreter_method_oop_reg(RBX); // Method Oop Register when 2793 // calling interpreter 2794 2795 // Optional: name the operand used by cisc-spilling to access 2796 // [stack_pointer + offset] 2797 cisc_spilling_operand_name(indOffset32); 2798 2799 // Number of stack slots consumed by locking an object 2800 sync_stack_slots(2); 2801 2802 // Compiled code's Frame Pointer 2803 frame_pointer(RSP); 2804 2805 // Interpreter stores its frame pointer in a register which is 2806 // stored to the stack by I2CAdaptors. 2807 // I2CAdaptors convert from interpreted java to compiled java. 2808 interpreter_frame_pointer(RBP); 2809 2810 // Stack alignment requirement 2811 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2812 2813 // Number of stack slots between incoming argument block and the start of 2814 // a new frame. The PROLOG must add this many slots to the stack. The 2815 // EPILOG must remove this many slots. amd64 needs two slots for 2816 // return address. 2817 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2818 2819 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2820 // for calls to C. Supports the var-args backing area for register parms. 2821 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2822 2823 // The after-PROLOG location of the return address. Location of 2824 // return address specifies a type (REG or STACK) and a number 2825 // representing the register number (i.e. - use a register name) or 2826 // stack slot. 2827 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2828 // Otherwise, it is above the locks and verification slot and alignment word 2829 return_addr(STACK - 2 + 2830 align_up((Compile::current()->in_preserve_stack_slots() + 2831 Compile::current()->fixed_slots()), 2832 stack_alignment_in_slots())); 2833 2834 // Body of function which returns an integer array locating 2835 // arguments either in registers or in stack slots. Passed an array 2836 // of ideal registers called "sig" and a "length" count. Stack-slot 2837 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2838 // arguments for a CALLEE. Incoming stack arguments are 2839 // automatically biased by the preserve_stack_slots field above. 2840 2841 calling_convention 2842 %{ 2843 // No difference between ingoing/outgoing just pass false 2844 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2845 %} 2846 2847 c_calling_convention 2848 %{ 2849 // This is obviously always outgoing 2850 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2851 %} 2852 2853 // Location of compiled Java return values. Same as C for now. 2854 return_value 2855 %{ 2856 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2857 "only return normal values"); 2858 2859 static const int lo[Op_RegL + 1] = { 2860 0, 2861 0, 2862 RAX_num, // Op_RegN 2863 RAX_num, // Op_RegI 2864 RAX_num, // Op_RegP 2865 XMM0_num, // Op_RegF 2866 XMM0_num, // Op_RegD 2867 RAX_num // Op_RegL 2868 }; 2869 static const int hi[Op_RegL + 1] = { 2870 0, 2871 0, 2872 OptoReg::Bad, // Op_RegN 2873 OptoReg::Bad, // Op_RegI 2874 RAX_H_num, // Op_RegP 2875 OptoReg::Bad, // Op_RegF 2876 XMM0b_num, // Op_RegD 2877 RAX_H_num // Op_RegL 2878 }; 2879 // Excluded flags and vector registers. 2880 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2881 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2882 %} 2883 %} 2884 2885 //----------ATTRIBUTES--------------------------------------------------------- 2886 //----------Operand Attributes------------------------------------------------- 2887 op_attrib op_cost(0); // Required cost attribute 2888 2889 //----------Instruction Attributes--------------------------------------------- 2890 ins_attrib ins_cost(100); // Required cost attribute 2891 ins_attrib ins_size(8); // Required size attribute (in bits) 2892 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2893 // a non-matching short branch variant 2894 // of some long branch? 2895 ins_attrib ins_alignment(1); // Required alignment attribute (must 2896 // be a power of 2) specifies the 2897 // alignment that some part of the 2898 // instruction (not necessarily the 2899 // start) requires. If > 1, a 2900 // compute_padding() function must be 2901 // provided for the instruction 2902 2903 //----------OPERANDS----------------------------------------------------------- 2904 // Operand definitions must precede instruction definitions for correct parsing 2905 // in the ADLC because operands constitute user defined types which are used in 2906 // instruction definitions. 2907 2908 //----------Simple Operands---------------------------------------------------- 2909 // Immediate Operands 2910 // Integer Immediate 2911 operand immI() 2912 %{ 2913 match(ConI); 2914 2915 op_cost(10); 2916 format %{ %} 2917 interface(CONST_INTER); 2918 %} 2919 2920 // Constant for test vs zero 2921 operand immI0() 2922 %{ 2923 predicate(n->get_int() == 0); 2924 match(ConI); 2925 2926 op_cost(0); 2927 format %{ %} 2928 interface(CONST_INTER); 2929 %} 2930 2931 // Constant for increment 2932 operand immI1() 2933 %{ 2934 predicate(n->get_int() == 1); 2935 match(ConI); 2936 2937 op_cost(0); 2938 format %{ %} 2939 interface(CONST_INTER); 2940 %} 2941 2942 // Constant for decrement 2943 operand immI_M1() 2944 %{ 2945 predicate(n->get_int() == -1); 2946 match(ConI); 2947 2948 op_cost(0); 2949 format %{ %} 2950 interface(CONST_INTER); 2951 %} 2952 2953 // Valid scale values for addressing modes 2954 operand immI2() 2955 %{ 2956 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2957 match(ConI); 2958 2959 format %{ %} 2960 interface(CONST_INTER); 2961 %} 2962 2963 operand immI8() 2964 %{ 2965 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2966 match(ConI); 2967 2968 op_cost(5); 2969 format %{ %} 2970 interface(CONST_INTER); 2971 %} 2972 2973 operand immU8() 2974 %{ 2975 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2976 match(ConI); 2977 2978 op_cost(5); 2979 format %{ %} 2980 interface(CONST_INTER); 2981 %} 2982 2983 operand immI16() 2984 %{ 2985 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2986 match(ConI); 2987 2988 op_cost(10); 2989 format %{ %} 2990 interface(CONST_INTER); 2991 %} 2992 2993 // Int Immediate non-negative 2994 operand immU31() 2995 %{ 2996 predicate(n->get_int() >= 0); 2997 match(ConI); 2998 2999 op_cost(0); 3000 format %{ %} 3001 interface(CONST_INTER); 3002 %} 3003 3004 // Constant for long shifts 3005 operand immI_32() 3006 %{ 3007 predicate( n->get_int() == 32 ); 3008 match(ConI); 3009 3010 op_cost(0); 3011 format %{ %} 3012 interface(CONST_INTER); 3013 %} 3014 3015 // Constant for long shifts 3016 operand immI_64() 3017 %{ 3018 predicate( n->get_int() == 64 ); 3019 match(ConI); 3020 3021 op_cost(0); 3022 format %{ %} 3023 interface(CONST_INTER); 3024 %} 3025 3026 // Pointer Immediate 3027 operand immP() 3028 %{ 3029 match(ConP); 3030 3031 op_cost(10); 3032 format %{ %} 3033 interface(CONST_INTER); 3034 %} 3035 3036 // NULL Pointer Immediate 3037 operand immP0() 3038 %{ 3039 predicate(n->get_ptr() == 0); 3040 match(ConP); 3041 3042 op_cost(5); 3043 format %{ %} 3044 interface(CONST_INTER); 3045 %} 3046 3047 // Pointer Immediate 3048 operand immN() %{ 3049 match(ConN); 3050 3051 op_cost(10); 3052 format %{ %} 3053 interface(CONST_INTER); 3054 %} 3055 3056 operand immNKlass() %{ 3057 match(ConNKlass); 3058 3059 op_cost(10); 3060 format %{ %} 3061 interface(CONST_INTER); 3062 %} 3063 3064 // NULL Pointer Immediate 3065 operand immN0() %{ 3066 predicate(n->get_narrowcon() == 0); 3067 match(ConN); 3068 3069 op_cost(5); 3070 format %{ %} 3071 interface(CONST_INTER); 3072 %} 3073 3074 operand immP31() 3075 %{ 3076 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3077 && (n->get_ptr() >> 31) == 0); 3078 match(ConP); 3079 3080 op_cost(5); 3081 format %{ %} 3082 interface(CONST_INTER); 3083 %} 3084 3085 3086 // Long Immediate 3087 operand immL() 3088 %{ 3089 match(ConL); 3090 3091 op_cost(20); 3092 format %{ %} 3093 interface(CONST_INTER); 3094 %} 3095 3096 // Long Immediate 8-bit 3097 operand immL8() 3098 %{ 3099 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3100 match(ConL); 3101 3102 op_cost(5); 3103 format %{ %} 3104 interface(CONST_INTER); 3105 %} 3106 3107 // Long Immediate 32-bit unsigned 3108 operand immUL32() 3109 %{ 3110 predicate(n->get_long() == (unsigned int) (n->get_long())); 3111 match(ConL); 3112 3113 op_cost(10); 3114 format %{ %} 3115 interface(CONST_INTER); 3116 %} 3117 3118 // Long Immediate 32-bit signed 3119 operand immL32() 3120 %{ 3121 predicate(n->get_long() == (int) (n->get_long())); 3122 match(ConL); 3123 3124 op_cost(15); 3125 format %{ %} 3126 interface(CONST_INTER); 3127 %} 3128 3129 // Long Immediate zero 3130 operand immL0() 3131 %{ 3132 predicate(n->get_long() == 0L); 3133 match(ConL); 3134 3135 op_cost(10); 3136 format %{ %} 3137 interface(CONST_INTER); 3138 %} 3139 3140 // Constant for increment 3141 operand immL1() 3142 %{ 3143 predicate(n->get_long() == 1); 3144 match(ConL); 3145 3146 format %{ %} 3147 interface(CONST_INTER); 3148 %} 3149 3150 // Constant for decrement 3151 operand immL_M1() 3152 %{ 3153 predicate(n->get_long() == -1); 3154 match(ConL); 3155 3156 format %{ %} 3157 interface(CONST_INTER); 3158 %} 3159 3160 // Long Immediate: the value 10 3161 operand immL10() 3162 %{ 3163 predicate(n->get_long() == 10); 3164 match(ConL); 3165 3166 format %{ %} 3167 interface(CONST_INTER); 3168 %} 3169 3170 // Long immediate from 0 to 127. 3171 // Used for a shorter form of long mul by 10. 3172 operand immL_127() 3173 %{ 3174 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3175 match(ConL); 3176 3177 op_cost(10); 3178 format %{ %} 3179 interface(CONST_INTER); 3180 %} 3181 3182 // Long Immediate: low 32-bit mask 3183 operand immL_32bits() 3184 %{ 3185 predicate(n->get_long() == 0xFFFFFFFFL); 3186 match(ConL); 3187 op_cost(20); 3188 3189 format %{ %} 3190 interface(CONST_INTER); 3191 %} 3192 3193 // Float Immediate zero 3194 operand immF0() 3195 %{ 3196 predicate(jint_cast(n->getf()) == 0); 3197 match(ConF); 3198 3199 op_cost(5); 3200 format %{ %} 3201 interface(CONST_INTER); 3202 %} 3203 3204 // Float Immediate 3205 operand immF() 3206 %{ 3207 match(ConF); 3208 3209 op_cost(15); 3210 format %{ %} 3211 interface(CONST_INTER); 3212 %} 3213 3214 // Double Immediate zero 3215 operand immD0() 3216 %{ 3217 predicate(jlong_cast(n->getd()) == 0); 3218 match(ConD); 3219 3220 op_cost(5); 3221 format %{ %} 3222 interface(CONST_INTER); 3223 %} 3224 3225 // Double Immediate 3226 operand immD() 3227 %{ 3228 match(ConD); 3229 3230 op_cost(15); 3231 format %{ %} 3232 interface(CONST_INTER); 3233 %} 3234 3235 // Immediates for special shifts (sign extend) 3236 3237 // Constants for increment 3238 operand immI_16() 3239 %{ 3240 predicate(n->get_int() == 16); 3241 match(ConI); 3242 3243 format %{ %} 3244 interface(CONST_INTER); 3245 %} 3246 3247 operand immI_24() 3248 %{ 3249 predicate(n->get_int() == 24); 3250 match(ConI); 3251 3252 format %{ %} 3253 interface(CONST_INTER); 3254 %} 3255 3256 // Constant for byte-wide masking 3257 operand immI_255() 3258 %{ 3259 predicate(n->get_int() == 255); 3260 match(ConI); 3261 3262 format %{ %} 3263 interface(CONST_INTER); 3264 %} 3265 3266 // Constant for short-wide masking 3267 operand immI_65535() 3268 %{ 3269 predicate(n->get_int() == 65535); 3270 match(ConI); 3271 3272 format %{ %} 3273 interface(CONST_INTER); 3274 %} 3275 3276 // Constant for byte-wide masking 3277 operand immL_255() 3278 %{ 3279 predicate(n->get_long() == 255); 3280 match(ConL); 3281 3282 format %{ %} 3283 interface(CONST_INTER); 3284 %} 3285 3286 // Constant for short-wide masking 3287 operand immL_65535() 3288 %{ 3289 predicate(n->get_long() == 65535); 3290 match(ConL); 3291 3292 format %{ %} 3293 interface(CONST_INTER); 3294 %} 3295 3296 // Register Operands 3297 // Integer Register 3298 operand rRegI() 3299 %{ 3300 constraint(ALLOC_IN_RC(int_reg)); 3301 match(RegI); 3302 3303 match(rax_RegI); 3304 match(rbx_RegI); 3305 match(rcx_RegI); 3306 match(rdx_RegI); 3307 match(rdi_RegI); 3308 3309 format %{ %} 3310 interface(REG_INTER); 3311 %} 3312 3313 // Special Registers 3314 operand rax_RegI() 3315 %{ 3316 constraint(ALLOC_IN_RC(int_rax_reg)); 3317 match(RegI); 3318 match(rRegI); 3319 3320 format %{ "RAX" %} 3321 interface(REG_INTER); 3322 %} 3323 3324 // Special Registers 3325 operand rbx_RegI() 3326 %{ 3327 constraint(ALLOC_IN_RC(int_rbx_reg)); 3328 match(RegI); 3329 match(rRegI); 3330 3331 format %{ "RBX" %} 3332 interface(REG_INTER); 3333 %} 3334 3335 operand rcx_RegI() 3336 %{ 3337 constraint(ALLOC_IN_RC(int_rcx_reg)); 3338 match(RegI); 3339 match(rRegI); 3340 3341 format %{ "RCX" %} 3342 interface(REG_INTER); 3343 %} 3344 3345 operand rdx_RegI() 3346 %{ 3347 constraint(ALLOC_IN_RC(int_rdx_reg)); 3348 match(RegI); 3349 match(rRegI); 3350 3351 format %{ "RDX" %} 3352 interface(REG_INTER); 3353 %} 3354 3355 operand rdi_RegI() 3356 %{ 3357 constraint(ALLOC_IN_RC(int_rdi_reg)); 3358 match(RegI); 3359 match(rRegI); 3360 3361 format %{ "RDI" %} 3362 interface(REG_INTER); 3363 %} 3364 3365 operand no_rcx_RegI() 3366 %{ 3367 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3368 match(RegI); 3369 match(rax_RegI); 3370 match(rbx_RegI); 3371 match(rdx_RegI); 3372 match(rdi_RegI); 3373 3374 format %{ %} 3375 interface(REG_INTER); 3376 %} 3377 3378 operand no_rax_rdx_RegI() 3379 %{ 3380 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3381 match(RegI); 3382 match(rbx_RegI); 3383 match(rcx_RegI); 3384 match(rdi_RegI); 3385 3386 format %{ %} 3387 interface(REG_INTER); 3388 %} 3389 3390 // Pointer Register 3391 operand any_RegP() 3392 %{ 3393 constraint(ALLOC_IN_RC(any_reg)); 3394 match(RegP); 3395 match(rax_RegP); 3396 match(rbx_RegP); 3397 match(rdi_RegP); 3398 match(rsi_RegP); 3399 match(rbp_RegP); 3400 match(r15_RegP); 3401 match(rRegP); 3402 3403 format %{ %} 3404 interface(REG_INTER); 3405 %} 3406 3407 operand rRegP() 3408 %{ 3409 constraint(ALLOC_IN_RC(ptr_reg)); 3410 match(RegP); 3411 match(rax_RegP); 3412 match(rbx_RegP); 3413 match(rdi_RegP); 3414 match(rsi_RegP); 3415 match(rbp_RegP); // See Q&A below about 3416 match(r15_RegP); // r15_RegP and rbp_RegP. 3417 3418 format %{ %} 3419 interface(REG_INTER); 3420 %} 3421 3422 operand rRegN() %{ 3423 constraint(ALLOC_IN_RC(int_reg)); 3424 match(RegN); 3425 3426 format %{ %} 3427 interface(REG_INTER); 3428 %} 3429 3430 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3431 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3432 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3433 // The output of an instruction is controlled by the allocator, which respects 3434 // register class masks, not match rules. Unless an instruction mentions 3435 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3436 // by the allocator as an input. 3437 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3438 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3439 // result, RBP is not included in the output of the instruction either. 3440 3441 operand no_rax_RegP() 3442 %{ 3443 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3444 match(RegP); 3445 match(rbx_RegP); 3446 match(rsi_RegP); 3447 match(rdi_RegP); 3448 3449 format %{ %} 3450 interface(REG_INTER); 3451 %} 3452 3453 // This operand is not allowed to use RBP even if 3454 // RBP is not used to hold the frame pointer. 3455 operand no_rbp_RegP() 3456 %{ 3457 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3458 match(RegP); 3459 match(rbx_RegP); 3460 match(rsi_RegP); 3461 match(rdi_RegP); 3462 3463 format %{ %} 3464 interface(REG_INTER); 3465 %} 3466 3467 operand no_rax_rbx_RegP() 3468 %{ 3469 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3470 match(RegP); 3471 match(rsi_RegP); 3472 match(rdi_RegP); 3473 3474 format %{ %} 3475 interface(REG_INTER); 3476 %} 3477 3478 // Special Registers 3479 // Return a pointer value 3480 operand rax_RegP() 3481 %{ 3482 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3483 match(RegP); 3484 match(rRegP); 3485 3486 format %{ %} 3487 interface(REG_INTER); 3488 %} 3489 3490 // Special Registers 3491 // Return a compressed pointer value 3492 operand rax_RegN() 3493 %{ 3494 constraint(ALLOC_IN_RC(int_rax_reg)); 3495 match(RegN); 3496 match(rRegN); 3497 3498 format %{ %} 3499 interface(REG_INTER); 3500 %} 3501 3502 // Used in AtomicAdd 3503 operand rbx_RegP() 3504 %{ 3505 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3506 match(RegP); 3507 match(rRegP); 3508 3509 format %{ %} 3510 interface(REG_INTER); 3511 %} 3512 3513 operand rsi_RegP() 3514 %{ 3515 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3516 match(RegP); 3517 match(rRegP); 3518 3519 format %{ %} 3520 interface(REG_INTER); 3521 %} 3522 3523 // Used in rep stosq 3524 operand rdi_RegP() 3525 %{ 3526 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3527 match(RegP); 3528 match(rRegP); 3529 3530 format %{ %} 3531 interface(REG_INTER); 3532 %} 3533 3534 operand r15_RegP() 3535 %{ 3536 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3537 match(RegP); 3538 match(rRegP); 3539 3540 format %{ %} 3541 interface(REG_INTER); 3542 %} 3543 3544 operand rRegL() 3545 %{ 3546 constraint(ALLOC_IN_RC(long_reg)); 3547 match(RegL); 3548 match(rax_RegL); 3549 match(rdx_RegL); 3550 3551 format %{ %} 3552 interface(REG_INTER); 3553 %} 3554 3555 // Special Registers 3556 operand no_rax_rdx_RegL() 3557 %{ 3558 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3559 match(RegL); 3560 match(rRegL); 3561 3562 format %{ %} 3563 interface(REG_INTER); 3564 %} 3565 3566 operand no_rax_RegL() 3567 %{ 3568 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3569 match(RegL); 3570 match(rRegL); 3571 match(rdx_RegL); 3572 3573 format %{ %} 3574 interface(REG_INTER); 3575 %} 3576 3577 operand no_rcx_RegL() 3578 %{ 3579 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3580 match(RegL); 3581 match(rRegL); 3582 3583 format %{ %} 3584 interface(REG_INTER); 3585 %} 3586 3587 operand rax_RegL() 3588 %{ 3589 constraint(ALLOC_IN_RC(long_rax_reg)); 3590 match(RegL); 3591 match(rRegL); 3592 3593 format %{ "RAX" %} 3594 interface(REG_INTER); 3595 %} 3596 3597 operand rcx_RegL() 3598 %{ 3599 constraint(ALLOC_IN_RC(long_rcx_reg)); 3600 match(RegL); 3601 match(rRegL); 3602 3603 format %{ %} 3604 interface(REG_INTER); 3605 %} 3606 3607 operand rdx_RegL() 3608 %{ 3609 constraint(ALLOC_IN_RC(long_rdx_reg)); 3610 match(RegL); 3611 match(rRegL); 3612 3613 format %{ %} 3614 interface(REG_INTER); 3615 %} 3616 3617 // Flags register, used as output of compare instructions 3618 operand rFlagsReg() 3619 %{ 3620 constraint(ALLOC_IN_RC(int_flags)); 3621 match(RegFlags); 3622 3623 format %{ "RFLAGS" %} 3624 interface(REG_INTER); 3625 %} 3626 3627 // Flags register, used as output of FLOATING POINT compare instructions 3628 operand rFlagsRegU() 3629 %{ 3630 constraint(ALLOC_IN_RC(int_flags)); 3631 match(RegFlags); 3632 3633 format %{ "RFLAGS_U" %} 3634 interface(REG_INTER); 3635 %} 3636 3637 operand rFlagsRegUCF() %{ 3638 constraint(ALLOC_IN_RC(int_flags)); 3639 match(RegFlags); 3640 predicate(false); 3641 3642 format %{ "RFLAGS_U_CF" %} 3643 interface(REG_INTER); 3644 %} 3645 3646 // Float register operands 3647 operand regF() %{ 3648 constraint(ALLOC_IN_RC(float_reg)); 3649 match(RegF); 3650 3651 format %{ %} 3652 interface(REG_INTER); 3653 %} 3654 3655 // Float register operands 3656 operand legRegF() %{ 3657 constraint(ALLOC_IN_RC(float_reg_legacy)); 3658 match(RegF); 3659 3660 format %{ %} 3661 interface(REG_INTER); 3662 %} 3663 3664 // Float register operands 3665 operand vlRegF() %{ 3666 constraint(ALLOC_IN_RC(float_reg_vl)); 3667 match(RegF); 3668 3669 format %{ %} 3670 interface(REG_INTER); 3671 %} 3672 3673 // Double register operands 3674 operand regD() %{ 3675 constraint(ALLOC_IN_RC(double_reg)); 3676 match(RegD); 3677 3678 format %{ %} 3679 interface(REG_INTER); 3680 %} 3681 3682 // Double register operands 3683 operand legRegD() %{ 3684 constraint(ALLOC_IN_RC(double_reg_legacy)); 3685 match(RegD); 3686 3687 format %{ %} 3688 interface(REG_INTER); 3689 %} 3690 3691 // Double register operands 3692 operand vlRegD() %{ 3693 constraint(ALLOC_IN_RC(double_reg_vl)); 3694 match(RegD); 3695 3696 format %{ %} 3697 interface(REG_INTER); 3698 %} 3699 3700 // Vectors 3701 operand vecS() %{ 3702 constraint(ALLOC_IN_RC(vectors_reg_vlbwdq)); 3703 match(VecS); 3704 3705 format %{ %} 3706 interface(REG_INTER); 3707 %} 3708 3709 // Vectors 3710 operand legVecS() %{ 3711 constraint(ALLOC_IN_RC(vectors_reg_legacy)); 3712 match(VecS); 3713 3714 format %{ %} 3715 interface(REG_INTER); 3716 %} 3717 3718 operand vecD() %{ 3719 constraint(ALLOC_IN_RC(vectord_reg_vlbwdq)); 3720 match(VecD); 3721 3722 format %{ %} 3723 interface(REG_INTER); 3724 %} 3725 3726 operand legVecD() %{ 3727 constraint(ALLOC_IN_RC(vectord_reg_legacy)); 3728 match(VecD); 3729 3730 format %{ %} 3731 interface(REG_INTER); 3732 %} 3733 3734 operand vecX() %{ 3735 constraint(ALLOC_IN_RC(vectorx_reg_vlbwdq)); 3736 match(VecX); 3737 3738 format %{ %} 3739 interface(REG_INTER); 3740 %} 3741 3742 operand legVecX() %{ 3743 constraint(ALLOC_IN_RC(vectorx_reg_legacy)); 3744 match(VecX); 3745 3746 format %{ %} 3747 interface(REG_INTER); 3748 %} 3749 3750 operand vecY() %{ 3751 constraint(ALLOC_IN_RC(vectory_reg_vlbwdq)); 3752 match(VecY); 3753 3754 format %{ %} 3755 interface(REG_INTER); 3756 %} 3757 3758 operand legVecY() %{ 3759 constraint(ALLOC_IN_RC(vectory_reg_legacy)); 3760 match(VecY); 3761 3762 format %{ %} 3763 interface(REG_INTER); 3764 %} 3765 3766 //----------Memory Operands---------------------------------------------------- 3767 // Direct Memory Operand 3768 // operand direct(immP addr) 3769 // %{ 3770 // match(addr); 3771 3772 // format %{ "[$addr]" %} 3773 // interface(MEMORY_INTER) %{ 3774 // base(0xFFFFFFFF); 3775 // index(0x4); 3776 // scale(0x0); 3777 // disp($addr); 3778 // %} 3779 // %} 3780 3781 // Indirect Memory Operand 3782 operand indirect(any_RegP reg) 3783 %{ 3784 constraint(ALLOC_IN_RC(ptr_reg)); 3785 match(reg); 3786 3787 format %{ "[$reg]" %} 3788 interface(MEMORY_INTER) %{ 3789 base($reg); 3790 index(0x4); 3791 scale(0x0); 3792 disp(0x0); 3793 %} 3794 %} 3795 3796 // Indirect Memory Plus Short Offset Operand 3797 operand indOffset8(any_RegP reg, immL8 off) 3798 %{ 3799 constraint(ALLOC_IN_RC(ptr_reg)); 3800 match(AddP reg off); 3801 3802 format %{ "[$reg + $off (8-bit)]" %} 3803 interface(MEMORY_INTER) %{ 3804 base($reg); 3805 index(0x4); 3806 scale(0x0); 3807 disp($off); 3808 %} 3809 %} 3810 3811 // Indirect Memory Plus Long Offset Operand 3812 operand indOffset32(any_RegP reg, immL32 off) 3813 %{ 3814 constraint(ALLOC_IN_RC(ptr_reg)); 3815 match(AddP reg off); 3816 3817 format %{ "[$reg + $off (32-bit)]" %} 3818 interface(MEMORY_INTER) %{ 3819 base($reg); 3820 index(0x4); 3821 scale(0x0); 3822 disp($off); 3823 %} 3824 %} 3825 3826 // Indirect Memory Plus Index Register Plus Offset Operand 3827 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3828 %{ 3829 constraint(ALLOC_IN_RC(ptr_reg)); 3830 match(AddP (AddP reg lreg) off); 3831 3832 op_cost(10); 3833 format %{"[$reg + $off + $lreg]" %} 3834 interface(MEMORY_INTER) %{ 3835 base($reg); 3836 index($lreg); 3837 scale(0x0); 3838 disp($off); 3839 %} 3840 %} 3841 3842 // Indirect Memory Plus Index Register Plus Offset Operand 3843 operand indIndex(any_RegP reg, rRegL lreg) 3844 %{ 3845 constraint(ALLOC_IN_RC(ptr_reg)); 3846 match(AddP reg lreg); 3847 3848 op_cost(10); 3849 format %{"[$reg + $lreg]" %} 3850 interface(MEMORY_INTER) %{ 3851 base($reg); 3852 index($lreg); 3853 scale(0x0); 3854 disp(0x0); 3855 %} 3856 %} 3857 3858 // Indirect Memory Times Scale Plus Index Register 3859 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3860 %{ 3861 constraint(ALLOC_IN_RC(ptr_reg)); 3862 match(AddP reg (LShiftL lreg scale)); 3863 3864 op_cost(10); 3865 format %{"[$reg + $lreg << $scale]" %} 3866 interface(MEMORY_INTER) %{ 3867 base($reg); 3868 index($lreg); 3869 scale($scale); 3870 disp(0x0); 3871 %} 3872 %} 3873 3874 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3875 %{ 3876 constraint(ALLOC_IN_RC(ptr_reg)); 3877 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3878 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3879 3880 op_cost(10); 3881 format %{"[$reg + pos $idx << $scale]" %} 3882 interface(MEMORY_INTER) %{ 3883 base($reg); 3884 index($idx); 3885 scale($scale); 3886 disp(0x0); 3887 %} 3888 %} 3889 3890 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3891 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3892 %{ 3893 constraint(ALLOC_IN_RC(ptr_reg)); 3894 match(AddP (AddP reg (LShiftL lreg scale)) off); 3895 3896 op_cost(10); 3897 format %{"[$reg + $off + $lreg << $scale]" %} 3898 interface(MEMORY_INTER) %{ 3899 base($reg); 3900 index($lreg); 3901 scale($scale); 3902 disp($off); 3903 %} 3904 %} 3905 3906 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3907 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3908 %{ 3909 constraint(ALLOC_IN_RC(ptr_reg)); 3910 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3911 match(AddP (AddP reg (ConvI2L idx)) off); 3912 3913 op_cost(10); 3914 format %{"[$reg + $off + $idx]" %} 3915 interface(MEMORY_INTER) %{ 3916 base($reg); 3917 index($idx); 3918 scale(0x0); 3919 disp($off); 3920 %} 3921 %} 3922 3923 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3924 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3925 %{ 3926 constraint(ALLOC_IN_RC(ptr_reg)); 3927 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3928 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3929 3930 op_cost(10); 3931 format %{"[$reg + $off + $idx << $scale]" %} 3932 interface(MEMORY_INTER) %{ 3933 base($reg); 3934 index($idx); 3935 scale($scale); 3936 disp($off); 3937 %} 3938 %} 3939 3940 // Indirect Narrow Oop Plus Offset Operand 3941 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3942 // we can't free r12 even with CompressedOops::base() == NULL. 3943 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3944 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3945 constraint(ALLOC_IN_RC(ptr_reg)); 3946 match(AddP (DecodeN reg) off); 3947 3948 op_cost(10); 3949 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3950 interface(MEMORY_INTER) %{ 3951 base(0xc); // R12 3952 index($reg); 3953 scale(0x3); 3954 disp($off); 3955 %} 3956 %} 3957 3958 // Indirect Memory Operand 3959 operand indirectNarrow(rRegN reg) 3960 %{ 3961 predicate(CompressedOops::shift() == 0); 3962 constraint(ALLOC_IN_RC(ptr_reg)); 3963 match(DecodeN reg); 3964 3965 format %{ "[$reg]" %} 3966 interface(MEMORY_INTER) %{ 3967 base($reg); 3968 index(0x4); 3969 scale(0x0); 3970 disp(0x0); 3971 %} 3972 %} 3973 3974 // Indirect Memory Plus Short Offset Operand 3975 operand indOffset8Narrow(rRegN reg, immL8 off) 3976 %{ 3977 predicate(CompressedOops::shift() == 0); 3978 constraint(ALLOC_IN_RC(ptr_reg)); 3979 match(AddP (DecodeN reg) off); 3980 3981 format %{ "[$reg + $off (8-bit)]" %} 3982 interface(MEMORY_INTER) %{ 3983 base($reg); 3984 index(0x4); 3985 scale(0x0); 3986 disp($off); 3987 %} 3988 %} 3989 3990 // Indirect Memory Plus Long Offset Operand 3991 operand indOffset32Narrow(rRegN reg, immL32 off) 3992 %{ 3993 predicate(CompressedOops::shift() == 0); 3994 constraint(ALLOC_IN_RC(ptr_reg)); 3995 match(AddP (DecodeN reg) off); 3996 3997 format %{ "[$reg + $off (32-bit)]" %} 3998 interface(MEMORY_INTER) %{ 3999 base($reg); 4000 index(0x4); 4001 scale(0x0); 4002 disp($off); 4003 %} 4004 %} 4005 4006 // Indirect Memory Plus Index Register Plus Offset Operand 4007 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4008 %{ 4009 predicate(CompressedOops::shift() == 0); 4010 constraint(ALLOC_IN_RC(ptr_reg)); 4011 match(AddP (AddP (DecodeN reg) lreg) off); 4012 4013 op_cost(10); 4014 format %{"[$reg + $off + $lreg]" %} 4015 interface(MEMORY_INTER) %{ 4016 base($reg); 4017 index($lreg); 4018 scale(0x0); 4019 disp($off); 4020 %} 4021 %} 4022 4023 // Indirect Memory Plus Index Register Plus Offset Operand 4024 operand indIndexNarrow(rRegN reg, rRegL lreg) 4025 %{ 4026 predicate(CompressedOops::shift() == 0); 4027 constraint(ALLOC_IN_RC(ptr_reg)); 4028 match(AddP (DecodeN reg) lreg); 4029 4030 op_cost(10); 4031 format %{"[$reg + $lreg]" %} 4032 interface(MEMORY_INTER) %{ 4033 base($reg); 4034 index($lreg); 4035 scale(0x0); 4036 disp(0x0); 4037 %} 4038 %} 4039 4040 // Indirect Memory Times Scale Plus Index Register 4041 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4042 %{ 4043 predicate(CompressedOops::shift() == 0); 4044 constraint(ALLOC_IN_RC(ptr_reg)); 4045 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4046 4047 op_cost(10); 4048 format %{"[$reg + $lreg << $scale]" %} 4049 interface(MEMORY_INTER) %{ 4050 base($reg); 4051 index($lreg); 4052 scale($scale); 4053 disp(0x0); 4054 %} 4055 %} 4056 4057 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4058 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4059 %{ 4060 predicate(CompressedOops::shift() == 0); 4061 constraint(ALLOC_IN_RC(ptr_reg)); 4062 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4063 4064 op_cost(10); 4065 format %{"[$reg + $off + $lreg << $scale]" %} 4066 interface(MEMORY_INTER) %{ 4067 base($reg); 4068 index($lreg); 4069 scale($scale); 4070 disp($off); 4071 %} 4072 %} 4073 4074 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4075 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4076 %{ 4077 constraint(ALLOC_IN_RC(ptr_reg)); 4078 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4079 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4080 4081 op_cost(10); 4082 format %{"[$reg + $off + $idx]" %} 4083 interface(MEMORY_INTER) %{ 4084 base($reg); 4085 index($idx); 4086 scale(0x0); 4087 disp($off); 4088 %} 4089 %} 4090 4091 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4092 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4093 %{ 4094 constraint(ALLOC_IN_RC(ptr_reg)); 4095 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4096 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4097 4098 op_cost(10); 4099 format %{"[$reg + $off + $idx << $scale]" %} 4100 interface(MEMORY_INTER) %{ 4101 base($reg); 4102 index($idx); 4103 scale($scale); 4104 disp($off); 4105 %} 4106 %} 4107 4108 //----------Special Memory Operands-------------------------------------------- 4109 // Stack Slot Operand - This operand is used for loading and storing temporary 4110 // values on the stack where a match requires a value to 4111 // flow through memory. 4112 operand stackSlotP(sRegP reg) 4113 %{ 4114 constraint(ALLOC_IN_RC(stack_slots)); 4115 // No match rule because this operand is only generated in matching 4116 4117 format %{ "[$reg]" %} 4118 interface(MEMORY_INTER) %{ 4119 base(0x4); // RSP 4120 index(0x4); // No Index 4121 scale(0x0); // No Scale 4122 disp($reg); // Stack Offset 4123 %} 4124 %} 4125 4126 operand stackSlotI(sRegI reg) 4127 %{ 4128 constraint(ALLOC_IN_RC(stack_slots)); 4129 // No match rule because this operand is only generated in matching 4130 4131 format %{ "[$reg]" %} 4132 interface(MEMORY_INTER) %{ 4133 base(0x4); // RSP 4134 index(0x4); // No Index 4135 scale(0x0); // No Scale 4136 disp($reg); // Stack Offset 4137 %} 4138 %} 4139 4140 operand stackSlotF(sRegF reg) 4141 %{ 4142 constraint(ALLOC_IN_RC(stack_slots)); 4143 // No match rule because this operand is only generated in matching 4144 4145 format %{ "[$reg]" %} 4146 interface(MEMORY_INTER) %{ 4147 base(0x4); // RSP 4148 index(0x4); // No Index 4149 scale(0x0); // No Scale 4150 disp($reg); // Stack Offset 4151 %} 4152 %} 4153 4154 operand stackSlotD(sRegD reg) 4155 %{ 4156 constraint(ALLOC_IN_RC(stack_slots)); 4157 // No match rule because this operand is only generated in matching 4158 4159 format %{ "[$reg]" %} 4160 interface(MEMORY_INTER) %{ 4161 base(0x4); // RSP 4162 index(0x4); // No Index 4163 scale(0x0); // No Scale 4164 disp($reg); // Stack Offset 4165 %} 4166 %} 4167 operand stackSlotL(sRegL reg) 4168 %{ 4169 constraint(ALLOC_IN_RC(stack_slots)); 4170 // No match rule because this operand is only generated in matching 4171 4172 format %{ "[$reg]" %} 4173 interface(MEMORY_INTER) %{ 4174 base(0x4); // RSP 4175 index(0x4); // No Index 4176 scale(0x0); // No Scale 4177 disp($reg); // Stack Offset 4178 %} 4179 %} 4180 4181 //----------Conditional Branch Operands---------------------------------------- 4182 // Comparison Op - This is the operation of the comparison, and is limited to 4183 // the following set of codes: 4184 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4185 // 4186 // Other attributes of the comparison, such as unsignedness, are specified 4187 // by the comparison instruction that sets a condition code flags register. 4188 // That result is represented by a flags operand whose subtype is appropriate 4189 // to the unsignedness (etc.) of the comparison. 4190 // 4191 // Later, the instruction which matches both the Comparison Op (a Bool) and 4192 // the flags (produced by the Cmp) specifies the coding of the comparison op 4193 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4194 4195 // Comparision Code 4196 operand cmpOp() 4197 %{ 4198 match(Bool); 4199 4200 format %{ "" %} 4201 interface(COND_INTER) %{ 4202 equal(0x4, "e"); 4203 not_equal(0x5, "ne"); 4204 less(0xC, "l"); 4205 greater_equal(0xD, "ge"); 4206 less_equal(0xE, "le"); 4207 greater(0xF, "g"); 4208 overflow(0x0, "o"); 4209 no_overflow(0x1, "no"); 4210 %} 4211 %} 4212 4213 // Comparison Code, unsigned compare. Used by FP also, with 4214 // C2 (unordered) turned into GT or LT already. The other bits 4215 // C0 and C3 are turned into Carry & Zero flags. 4216 operand cmpOpU() 4217 %{ 4218 match(Bool); 4219 4220 format %{ "" %} 4221 interface(COND_INTER) %{ 4222 equal(0x4, "e"); 4223 not_equal(0x5, "ne"); 4224 less(0x2, "b"); 4225 greater_equal(0x3, "nb"); 4226 less_equal(0x6, "be"); 4227 greater(0x7, "nbe"); 4228 overflow(0x0, "o"); 4229 no_overflow(0x1, "no"); 4230 %} 4231 %} 4232 4233 4234 // Floating comparisons that don't require any fixup for the unordered case 4235 operand cmpOpUCF() %{ 4236 match(Bool); 4237 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4238 n->as_Bool()->_test._test == BoolTest::ge || 4239 n->as_Bool()->_test._test == BoolTest::le || 4240 n->as_Bool()->_test._test == BoolTest::gt); 4241 format %{ "" %} 4242 interface(COND_INTER) %{ 4243 equal(0x4, "e"); 4244 not_equal(0x5, "ne"); 4245 less(0x2, "b"); 4246 greater_equal(0x3, "nb"); 4247 less_equal(0x6, "be"); 4248 greater(0x7, "nbe"); 4249 overflow(0x0, "o"); 4250 no_overflow(0x1, "no"); 4251 %} 4252 %} 4253 4254 4255 // Floating comparisons that can be fixed up with extra conditional jumps 4256 operand cmpOpUCF2() %{ 4257 match(Bool); 4258 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4259 n->as_Bool()->_test._test == BoolTest::eq); 4260 format %{ "" %} 4261 interface(COND_INTER) %{ 4262 equal(0x4, "e"); 4263 not_equal(0x5, "ne"); 4264 less(0x2, "b"); 4265 greater_equal(0x3, "nb"); 4266 less_equal(0x6, "be"); 4267 greater(0x7, "nbe"); 4268 overflow(0x0, "o"); 4269 no_overflow(0x1, "no"); 4270 %} 4271 %} 4272 4273 // Operands for bound floating pointer register arguments 4274 operand rxmm0() %{ 4275 constraint(ALLOC_IN_RC(xmm0_reg)); 4276 match(VecX); 4277 format%{%} 4278 interface(REG_INTER); 4279 %} 4280 operand rxmm1() %{ 4281 constraint(ALLOC_IN_RC(xmm1_reg)); 4282 match(VecX); 4283 format%{%} 4284 interface(REG_INTER); 4285 %} 4286 operand rxmm2() %{ 4287 constraint(ALLOC_IN_RC(xmm2_reg)); 4288 match(VecX); 4289 format%{%} 4290 interface(REG_INTER); 4291 %} 4292 operand rxmm3() %{ 4293 constraint(ALLOC_IN_RC(xmm3_reg)); 4294 match(VecX); 4295 format%{%} 4296 interface(REG_INTER); 4297 %} 4298 operand rxmm4() %{ 4299 constraint(ALLOC_IN_RC(xmm4_reg)); 4300 match(VecX); 4301 format%{%} 4302 interface(REG_INTER); 4303 %} 4304 operand rxmm5() %{ 4305 constraint(ALLOC_IN_RC(xmm5_reg)); 4306 match(VecX); 4307 format%{%} 4308 interface(REG_INTER); 4309 %} 4310 operand rxmm6() %{ 4311 constraint(ALLOC_IN_RC(xmm6_reg)); 4312 match(VecX); 4313 format%{%} 4314 interface(REG_INTER); 4315 %} 4316 operand rxmm7() %{ 4317 constraint(ALLOC_IN_RC(xmm7_reg)); 4318 match(VecX); 4319 format%{%} 4320 interface(REG_INTER); 4321 %} 4322 operand rxmm8() %{ 4323 constraint(ALLOC_IN_RC(xmm8_reg)); 4324 match(VecX); 4325 format%{%} 4326 interface(REG_INTER); 4327 %} 4328 operand rxmm9() %{ 4329 constraint(ALLOC_IN_RC(xmm9_reg)); 4330 match(VecX); 4331 format%{%} 4332 interface(REG_INTER); 4333 %} 4334 operand rxmm10() %{ 4335 constraint(ALLOC_IN_RC(xmm10_reg)); 4336 match(VecX); 4337 format%{%} 4338 interface(REG_INTER); 4339 %} 4340 operand rxmm11() %{ 4341 constraint(ALLOC_IN_RC(xmm11_reg)); 4342 match(VecX); 4343 format%{%} 4344 interface(REG_INTER); 4345 %} 4346 operand rxmm12() %{ 4347 constraint(ALLOC_IN_RC(xmm12_reg)); 4348 match(VecX); 4349 format%{%} 4350 interface(REG_INTER); 4351 %} 4352 operand rxmm13() %{ 4353 constraint(ALLOC_IN_RC(xmm13_reg)); 4354 match(VecX); 4355 format%{%} 4356 interface(REG_INTER); 4357 %} 4358 operand rxmm14() %{ 4359 constraint(ALLOC_IN_RC(xmm14_reg)); 4360 match(VecX); 4361 format%{%} 4362 interface(REG_INTER); 4363 %} 4364 operand rxmm15() %{ 4365 constraint(ALLOC_IN_RC(xmm15_reg)); 4366 match(VecX); 4367 format%{%} 4368 interface(REG_INTER); 4369 %} 4370 operand rxmm16() %{ 4371 constraint(ALLOC_IN_RC(xmm16_reg)); 4372 match(VecX); 4373 format%{%} 4374 interface(REG_INTER); 4375 %} 4376 operand rxmm17() %{ 4377 constraint(ALLOC_IN_RC(xmm17_reg)); 4378 match(VecX); 4379 format%{%} 4380 interface(REG_INTER); 4381 %} 4382 operand rxmm18() %{ 4383 constraint(ALLOC_IN_RC(xmm18_reg)); 4384 match(VecX); 4385 format%{%} 4386 interface(REG_INTER); 4387 %} 4388 operand rxmm19() %{ 4389 constraint(ALLOC_IN_RC(xmm19_reg)); 4390 match(VecX); 4391 format%{%} 4392 interface(REG_INTER); 4393 %} 4394 operand rxmm20() %{ 4395 constraint(ALLOC_IN_RC(xmm20_reg)); 4396 match(VecX); 4397 format%{%} 4398 interface(REG_INTER); 4399 %} 4400 operand rxmm21() %{ 4401 constraint(ALLOC_IN_RC(xmm21_reg)); 4402 match(VecX); 4403 format%{%} 4404 interface(REG_INTER); 4405 %} 4406 operand rxmm22() %{ 4407 constraint(ALLOC_IN_RC(xmm22_reg)); 4408 match(VecX); 4409 format%{%} 4410 interface(REG_INTER); 4411 %} 4412 operand rxmm23() %{ 4413 constraint(ALLOC_IN_RC(xmm23_reg)); 4414 match(VecX); 4415 format%{%} 4416 interface(REG_INTER); 4417 %} 4418 operand rxmm24() %{ 4419 constraint(ALLOC_IN_RC(xmm24_reg)); 4420 match(VecX); 4421 format%{%} 4422 interface(REG_INTER); 4423 %} 4424 operand rxmm25() %{ 4425 constraint(ALLOC_IN_RC(xmm25_reg)); 4426 match(VecX); 4427 format%{%} 4428 interface(REG_INTER); 4429 %} 4430 operand rxmm26() %{ 4431 constraint(ALLOC_IN_RC(xmm26_reg)); 4432 match(VecX); 4433 format%{%} 4434 interface(REG_INTER); 4435 %} 4436 operand rxmm27() %{ 4437 constraint(ALLOC_IN_RC(xmm27_reg)); 4438 match(VecX); 4439 format%{%} 4440 interface(REG_INTER); 4441 %} 4442 operand rxmm28() %{ 4443 constraint(ALLOC_IN_RC(xmm28_reg)); 4444 match(VecX); 4445 format%{%} 4446 interface(REG_INTER); 4447 %} 4448 operand rxmm29() %{ 4449 constraint(ALLOC_IN_RC(xmm29_reg)); 4450 match(VecX); 4451 format%{%} 4452 interface(REG_INTER); 4453 %} 4454 operand rxmm30() %{ 4455 constraint(ALLOC_IN_RC(xmm30_reg)); 4456 match(VecX); 4457 format%{%} 4458 interface(REG_INTER); 4459 %} 4460 operand rxmm31() %{ 4461 constraint(ALLOC_IN_RC(xmm31_reg)); 4462 match(VecX); 4463 format%{%} 4464 interface(REG_INTER); 4465 %} 4466 4467 //----------OPERAND CLASSES---------------------------------------------------- 4468 // Operand Classes are groups of operands that are used as to simplify 4469 // instruction definitions by not requiring the AD writer to specify separate 4470 // instructions for every form of operand when the instruction accepts 4471 // multiple operand types with the same basic encoding and format. The classic 4472 // case of this is memory operands. 4473 4474 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4475 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4476 indCompressedOopOffset, 4477 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4478 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4479 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4480 4481 //----------PIPELINE----------------------------------------------------------- 4482 // Rules which define the behavior of the target architectures pipeline. 4483 pipeline %{ 4484 4485 //----------ATTRIBUTES--------------------------------------------------------- 4486 attributes %{ 4487 variable_size_instructions; // Fixed size instructions 4488 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4489 instruction_unit_size = 1; // An instruction is 1 bytes long 4490 instruction_fetch_unit_size = 16; // The processor fetches one line 4491 instruction_fetch_units = 1; // of 16 bytes 4492 4493 // List of nop instructions 4494 nops( MachNop ); 4495 %} 4496 4497 //----------RESOURCES---------------------------------------------------------- 4498 // Resources are the functional units available to the machine 4499 4500 // Generic P2/P3 pipeline 4501 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4502 // 3 instructions decoded per cycle. 4503 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4504 // 3 ALU op, only ALU0 handles mul instructions. 4505 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4506 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4507 BR, FPU, 4508 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4509 4510 //----------PIPELINE DESCRIPTION----------------------------------------------- 4511 // Pipeline Description specifies the stages in the machine's pipeline 4512 4513 // Generic P2/P3 pipeline 4514 pipe_desc(S0, S1, S2, S3, S4, S5); 4515 4516 //----------PIPELINE CLASSES--------------------------------------------------- 4517 // Pipeline Classes describe the stages in which input and output are 4518 // referenced by the hardware pipeline. 4519 4520 // Naming convention: ialu or fpu 4521 // Then: _reg 4522 // Then: _reg if there is a 2nd register 4523 // Then: _long if it's a pair of instructions implementing a long 4524 // Then: _fat if it requires the big decoder 4525 // Or: _mem if it requires the big decoder and a memory unit. 4526 4527 // Integer ALU reg operation 4528 pipe_class ialu_reg(rRegI dst) 4529 %{ 4530 single_instruction; 4531 dst : S4(write); 4532 dst : S3(read); 4533 DECODE : S0; // any decoder 4534 ALU : S3; // any alu 4535 %} 4536 4537 // Long ALU reg operation 4538 pipe_class ialu_reg_long(rRegL dst) 4539 %{ 4540 instruction_count(2); 4541 dst : S4(write); 4542 dst : S3(read); 4543 DECODE : S0(2); // any 2 decoders 4544 ALU : S3(2); // both alus 4545 %} 4546 4547 // Integer ALU reg operation using big decoder 4548 pipe_class ialu_reg_fat(rRegI dst) 4549 %{ 4550 single_instruction; 4551 dst : S4(write); 4552 dst : S3(read); 4553 D0 : S0; // big decoder only 4554 ALU : S3; // any alu 4555 %} 4556 4557 // Long ALU reg operation using big decoder 4558 pipe_class ialu_reg_long_fat(rRegL dst) 4559 %{ 4560 instruction_count(2); 4561 dst : S4(write); 4562 dst : S3(read); 4563 D0 : S0(2); // big decoder only; twice 4564 ALU : S3(2); // any 2 alus 4565 %} 4566 4567 // Integer ALU reg-reg operation 4568 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4569 %{ 4570 single_instruction; 4571 dst : S4(write); 4572 src : S3(read); 4573 DECODE : S0; // any decoder 4574 ALU : S3; // any alu 4575 %} 4576 4577 // Long ALU reg-reg operation 4578 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4579 %{ 4580 instruction_count(2); 4581 dst : S4(write); 4582 src : S3(read); 4583 DECODE : S0(2); // any 2 decoders 4584 ALU : S3(2); // both alus 4585 %} 4586 4587 // Integer ALU reg-reg operation 4588 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4589 %{ 4590 single_instruction; 4591 dst : S4(write); 4592 src : S3(read); 4593 D0 : S0; // big decoder only 4594 ALU : S3; // any alu 4595 %} 4596 4597 // Long ALU reg-reg operation 4598 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4599 %{ 4600 instruction_count(2); 4601 dst : S4(write); 4602 src : S3(read); 4603 D0 : S0(2); // big decoder only; twice 4604 ALU : S3(2); // both alus 4605 %} 4606 4607 // Integer ALU reg-mem operation 4608 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4609 %{ 4610 single_instruction; 4611 dst : S5(write); 4612 mem : S3(read); 4613 D0 : S0; // big decoder only 4614 ALU : S4; // any alu 4615 MEM : S3; // any mem 4616 %} 4617 4618 // Integer mem operation (prefetch) 4619 pipe_class ialu_mem(memory mem) 4620 %{ 4621 single_instruction; 4622 mem : S3(read); 4623 D0 : S0; // big decoder only 4624 MEM : S3; // any mem 4625 %} 4626 4627 // Integer Store to Memory 4628 pipe_class ialu_mem_reg(memory mem, rRegI src) 4629 %{ 4630 single_instruction; 4631 mem : S3(read); 4632 src : S5(read); 4633 D0 : S0; // big decoder only 4634 ALU : S4; // any alu 4635 MEM : S3; 4636 %} 4637 4638 // // Long Store to Memory 4639 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4640 // %{ 4641 // instruction_count(2); 4642 // mem : S3(read); 4643 // src : S5(read); 4644 // D0 : S0(2); // big decoder only; twice 4645 // ALU : S4(2); // any 2 alus 4646 // MEM : S3(2); // Both mems 4647 // %} 4648 4649 // Integer Store to Memory 4650 pipe_class ialu_mem_imm(memory mem) 4651 %{ 4652 single_instruction; 4653 mem : S3(read); 4654 D0 : S0; // big decoder only 4655 ALU : S4; // any alu 4656 MEM : S3; 4657 %} 4658 4659 // Integer ALU0 reg-reg operation 4660 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4661 %{ 4662 single_instruction; 4663 dst : S4(write); 4664 src : S3(read); 4665 D0 : S0; // Big decoder only 4666 ALU0 : S3; // only alu0 4667 %} 4668 4669 // Integer ALU0 reg-mem operation 4670 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4671 %{ 4672 single_instruction; 4673 dst : S5(write); 4674 mem : S3(read); 4675 D0 : S0; // big decoder only 4676 ALU0 : S4; // ALU0 only 4677 MEM : S3; // any mem 4678 %} 4679 4680 // Integer ALU reg-reg operation 4681 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4682 %{ 4683 single_instruction; 4684 cr : S4(write); 4685 src1 : S3(read); 4686 src2 : S3(read); 4687 DECODE : S0; // any decoder 4688 ALU : S3; // any alu 4689 %} 4690 4691 // Integer ALU reg-imm operation 4692 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4693 %{ 4694 single_instruction; 4695 cr : S4(write); 4696 src1 : S3(read); 4697 DECODE : S0; // any decoder 4698 ALU : S3; // any alu 4699 %} 4700 4701 // Integer ALU reg-mem operation 4702 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4703 %{ 4704 single_instruction; 4705 cr : S4(write); 4706 src1 : S3(read); 4707 src2 : S3(read); 4708 D0 : S0; // big decoder only 4709 ALU : S4; // any alu 4710 MEM : S3; 4711 %} 4712 4713 // Conditional move reg-reg 4714 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4715 %{ 4716 instruction_count(4); 4717 y : S4(read); 4718 q : S3(read); 4719 p : S3(read); 4720 DECODE : S0(4); // any decoder 4721 %} 4722 4723 // Conditional move reg-reg 4724 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4725 %{ 4726 single_instruction; 4727 dst : S4(write); 4728 src : S3(read); 4729 cr : S3(read); 4730 DECODE : S0; // any decoder 4731 %} 4732 4733 // Conditional move reg-mem 4734 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4735 %{ 4736 single_instruction; 4737 dst : S4(write); 4738 src : S3(read); 4739 cr : S3(read); 4740 DECODE : S0; // any decoder 4741 MEM : S3; 4742 %} 4743 4744 // Conditional move reg-reg long 4745 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4746 %{ 4747 single_instruction; 4748 dst : S4(write); 4749 src : S3(read); 4750 cr : S3(read); 4751 DECODE : S0(2); // any 2 decoders 4752 %} 4753 4754 // XXX 4755 // // Conditional move double reg-reg 4756 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4757 // %{ 4758 // single_instruction; 4759 // dst : S4(write); 4760 // src : S3(read); 4761 // cr : S3(read); 4762 // DECODE : S0; // any decoder 4763 // %} 4764 4765 // Float reg-reg operation 4766 pipe_class fpu_reg(regD dst) 4767 %{ 4768 instruction_count(2); 4769 dst : S3(read); 4770 DECODE : S0(2); // any 2 decoders 4771 FPU : S3; 4772 %} 4773 4774 // Float reg-reg operation 4775 pipe_class fpu_reg_reg(regD dst, regD src) 4776 %{ 4777 instruction_count(2); 4778 dst : S4(write); 4779 src : S3(read); 4780 DECODE : S0(2); // any 2 decoders 4781 FPU : S3; 4782 %} 4783 4784 // Float reg-reg operation 4785 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4786 %{ 4787 instruction_count(3); 4788 dst : S4(write); 4789 src1 : S3(read); 4790 src2 : S3(read); 4791 DECODE : S0(3); // any 3 decoders 4792 FPU : S3(2); 4793 %} 4794 4795 // Float reg-reg operation 4796 pipe_class fpu_reg_reg_reg_reg(regD dst, regD 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 : S0(4); // any 3 decoders 4804 FPU : S3(2); 4805 %} 4806 4807 // Float reg-reg operation 4808 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4809 %{ 4810 instruction_count(4); 4811 dst : S4(write); 4812 src1 : S3(read); 4813 src2 : S3(read); 4814 src3 : S3(read); 4815 DECODE : S1(3); // any 3 decoders 4816 D0 : S0; // Big decoder only 4817 FPU : S3(2); 4818 MEM : S3; 4819 %} 4820 4821 // Float reg-mem operation 4822 pipe_class fpu_reg_mem(regD dst, memory mem) 4823 %{ 4824 instruction_count(2); 4825 dst : S5(write); 4826 mem : S3(read); 4827 D0 : S0; // big decoder only 4828 DECODE : S1; // any decoder for FPU POP 4829 FPU : S4; 4830 MEM : S3; // any mem 4831 %} 4832 4833 // Float reg-mem operation 4834 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4835 %{ 4836 instruction_count(3); 4837 dst : S5(write); 4838 src1 : S3(read); 4839 mem : S3(read); 4840 D0 : S0; // big decoder only 4841 DECODE : S1(2); // any decoder for FPU POP 4842 FPU : S4; 4843 MEM : S3; // any mem 4844 %} 4845 4846 // Float mem-reg operation 4847 pipe_class fpu_mem_reg(memory mem, regD src) 4848 %{ 4849 instruction_count(2); 4850 src : S5(read); 4851 mem : S3(read); 4852 DECODE : S0; // 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_reg(memory mem, regD src1, regD src2) 4859 %{ 4860 instruction_count(3); 4861 src1 : S3(read); 4862 src2 : S3(read); 4863 mem : S3(read); 4864 DECODE : S0(2); // any decoder for FPU PUSH 4865 D0 : S1; // big decoder only 4866 FPU : S4; 4867 MEM : S3; // any mem 4868 %} 4869 4870 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4871 %{ 4872 instruction_count(3); 4873 src1 : S3(read); 4874 src2 : S3(read); 4875 mem : S4(read); 4876 DECODE : S0; // any decoder for FPU PUSH 4877 D0 : S0(2); // big decoder only 4878 FPU : S4; 4879 MEM : S3(2); // any mem 4880 %} 4881 4882 pipe_class fpu_mem_mem(memory dst, memory src1) 4883 %{ 4884 instruction_count(2); 4885 src1 : S3(read); 4886 dst : S4(read); 4887 D0 : S0(2); // big decoder only 4888 MEM : S3(2); // any mem 4889 %} 4890 4891 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4892 %{ 4893 instruction_count(3); 4894 src1 : S3(read); 4895 src2 : S3(read); 4896 dst : S4(read); 4897 D0 : S0(3); // big decoder only 4898 FPU : S4; 4899 MEM : S3(3); // any mem 4900 %} 4901 4902 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4903 %{ 4904 instruction_count(3); 4905 src1 : S4(read); 4906 mem : S4(read); 4907 DECODE : S0; // any decoder for FPU PUSH 4908 D0 : S0(2); // big decoder only 4909 FPU : S4; 4910 MEM : S3(2); // any mem 4911 %} 4912 4913 // Float load constant 4914 pipe_class fpu_reg_con(regD dst) 4915 %{ 4916 instruction_count(2); 4917 dst : S5(write); 4918 D0 : S0; // big decoder only for the load 4919 DECODE : S1; // any decoder for FPU POP 4920 FPU : S4; 4921 MEM : S3; // any mem 4922 %} 4923 4924 // Float load constant 4925 pipe_class fpu_reg_reg_con(regD dst, regD src) 4926 %{ 4927 instruction_count(3); 4928 dst : S5(write); 4929 src : S3(read); 4930 D0 : S0; // big decoder only for the load 4931 DECODE : S1(2); // any decoder for FPU POP 4932 FPU : S4; 4933 MEM : S3; // any mem 4934 %} 4935 4936 // UnConditional branch 4937 pipe_class pipe_jmp(label labl) 4938 %{ 4939 single_instruction; 4940 BR : S3; 4941 %} 4942 4943 // Conditional branch 4944 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4945 %{ 4946 single_instruction; 4947 cr : S1(read); 4948 BR : S3; 4949 %} 4950 4951 // Allocation idiom 4952 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4953 %{ 4954 instruction_count(1); force_serialization; 4955 fixed_latency(6); 4956 heap_ptr : S3(read); 4957 DECODE : S0(3); 4958 D0 : S2; 4959 MEM : S3; 4960 ALU : S3(2); 4961 dst : S5(write); 4962 BR : S5; 4963 %} 4964 4965 // Generic big/slow expanded idiom 4966 pipe_class pipe_slow() 4967 %{ 4968 instruction_count(10); multiple_bundles; force_serialization; 4969 fixed_latency(100); 4970 D0 : S0(2); 4971 MEM : S3(2); 4972 %} 4973 4974 // The real do-nothing guy 4975 pipe_class empty() 4976 %{ 4977 instruction_count(0); 4978 %} 4979 4980 // Define the class for the Nop node 4981 define 4982 %{ 4983 MachNop = empty; 4984 %} 4985 4986 %} 4987 4988 //----------INSTRUCTIONS------------------------------------------------------- 4989 // 4990 // match -- States which machine-independent subtree may be replaced 4991 // by this instruction. 4992 // ins_cost -- The estimated cost of this instruction is used by instruction 4993 // selection to identify a minimum cost tree of machine 4994 // instructions that matches a tree of machine-independent 4995 // instructions. 4996 // format -- A string providing the disassembly for this instruction. 4997 // The value of an instruction's operand may be inserted 4998 // by referring to it with a '$' prefix. 4999 // opcode -- Three instruction opcodes may be provided. These are referred 5000 // to within an encode class as $primary, $secondary, and $tertiary 5001 // rrspectively. The primary opcode is commonly used to 5002 // indicate the type of machine instruction, while secondary 5003 // and tertiary are often used for prefix options or addressing 5004 // modes. 5005 // ins_encode -- A list of encode classes with parameters. The encode class 5006 // name must have been defined in an 'enc_class' specification 5007 // in the encode section of the architecture description. 5008 5009 5010 //----------Load/Store/Move Instructions--------------------------------------- 5011 //----------Load Instructions-------------------------------------------------- 5012 5013 // Load Byte (8 bit signed) 5014 instruct loadB(rRegI dst, memory mem) 5015 %{ 5016 match(Set dst (LoadB mem)); 5017 5018 ins_cost(125); 5019 format %{ "movsbl $dst, $mem\t# byte" %} 5020 5021 ins_encode %{ 5022 __ movsbl($dst$$Register, $mem$$Address); 5023 %} 5024 5025 ins_pipe(ialu_reg_mem); 5026 %} 5027 5028 // Load Byte (8 bit signed) into Long Register 5029 instruct loadB2L(rRegL dst, memory mem) 5030 %{ 5031 match(Set dst (ConvI2L (LoadB mem))); 5032 5033 ins_cost(125); 5034 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5035 5036 ins_encode %{ 5037 __ movsbq($dst$$Register, $mem$$Address); 5038 %} 5039 5040 ins_pipe(ialu_reg_mem); 5041 %} 5042 5043 // Load Unsigned Byte (8 bit UNsigned) 5044 instruct loadUB(rRegI dst, memory mem) 5045 %{ 5046 match(Set dst (LoadUB mem)); 5047 5048 ins_cost(125); 5049 format %{ "movzbl $dst, $mem\t# ubyte" %} 5050 5051 ins_encode %{ 5052 __ movzbl($dst$$Register, $mem$$Address); 5053 %} 5054 5055 ins_pipe(ialu_reg_mem); 5056 %} 5057 5058 // Load Unsigned Byte (8 bit UNsigned) into Long Register 5059 instruct loadUB2L(rRegL dst, memory mem) 5060 %{ 5061 match(Set dst (ConvI2L (LoadUB mem))); 5062 5063 ins_cost(125); 5064 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5065 5066 ins_encode %{ 5067 __ movzbq($dst$$Register, $mem$$Address); 5068 %} 5069 5070 ins_pipe(ialu_reg_mem); 5071 %} 5072 5073 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 5074 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5075 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5076 effect(KILL cr); 5077 5078 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 5079 "andl $dst, right_n_bits($mask, 8)" %} 5080 ins_encode %{ 5081 Register Rdst = $dst$$Register; 5082 __ movzbq(Rdst, $mem$$Address); 5083 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 5084 %} 5085 ins_pipe(ialu_reg_mem); 5086 %} 5087 5088 // Load Short (16 bit signed) 5089 instruct loadS(rRegI dst, memory mem) 5090 %{ 5091 match(Set dst (LoadS mem)); 5092 5093 ins_cost(125); 5094 format %{ "movswl $dst, $mem\t# short" %} 5095 5096 ins_encode %{ 5097 __ movswl($dst$$Register, $mem$$Address); 5098 %} 5099 5100 ins_pipe(ialu_reg_mem); 5101 %} 5102 5103 // Load Short (16 bit signed) to Byte (8 bit signed) 5104 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5105 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5106 5107 ins_cost(125); 5108 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5109 ins_encode %{ 5110 __ movsbl($dst$$Register, $mem$$Address); 5111 %} 5112 ins_pipe(ialu_reg_mem); 5113 %} 5114 5115 // Load Short (16 bit signed) into Long Register 5116 instruct loadS2L(rRegL dst, memory mem) 5117 %{ 5118 match(Set dst (ConvI2L (LoadS mem))); 5119 5120 ins_cost(125); 5121 format %{ "movswq $dst, $mem\t# short -> long" %} 5122 5123 ins_encode %{ 5124 __ movswq($dst$$Register, $mem$$Address); 5125 %} 5126 5127 ins_pipe(ialu_reg_mem); 5128 %} 5129 5130 // Load Unsigned Short/Char (16 bit UNsigned) 5131 instruct loadUS(rRegI dst, memory mem) 5132 %{ 5133 match(Set dst (LoadUS mem)); 5134 5135 ins_cost(125); 5136 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5137 5138 ins_encode %{ 5139 __ movzwl($dst$$Register, $mem$$Address); 5140 %} 5141 5142 ins_pipe(ialu_reg_mem); 5143 %} 5144 5145 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5146 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5147 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5148 5149 ins_cost(125); 5150 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5151 ins_encode %{ 5152 __ movsbl($dst$$Register, $mem$$Address); 5153 %} 5154 ins_pipe(ialu_reg_mem); 5155 %} 5156 5157 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5158 instruct loadUS2L(rRegL dst, memory mem) 5159 %{ 5160 match(Set dst (ConvI2L (LoadUS mem))); 5161 5162 ins_cost(125); 5163 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5164 5165 ins_encode %{ 5166 __ movzwq($dst$$Register, $mem$$Address); 5167 %} 5168 5169 ins_pipe(ialu_reg_mem); 5170 %} 5171 5172 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5173 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5174 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5175 5176 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5177 ins_encode %{ 5178 __ movzbq($dst$$Register, $mem$$Address); 5179 %} 5180 ins_pipe(ialu_reg_mem); 5181 %} 5182 5183 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5184 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5185 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5186 effect(KILL cr); 5187 5188 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5189 "andl $dst, right_n_bits($mask, 16)" %} 5190 ins_encode %{ 5191 Register Rdst = $dst$$Register; 5192 __ movzwq(Rdst, $mem$$Address); 5193 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5194 %} 5195 ins_pipe(ialu_reg_mem); 5196 %} 5197 5198 // Load Integer 5199 instruct loadI(rRegI dst, memory mem) 5200 %{ 5201 match(Set dst (LoadI mem)); 5202 5203 ins_cost(125); 5204 format %{ "movl $dst, $mem\t# int" %} 5205 5206 ins_encode %{ 5207 __ movl($dst$$Register, $mem$$Address); 5208 %} 5209 5210 ins_pipe(ialu_reg_mem); 5211 %} 5212 5213 // Load Integer (32 bit signed) to Byte (8 bit signed) 5214 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5215 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5216 5217 ins_cost(125); 5218 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5219 ins_encode %{ 5220 __ movsbl($dst$$Register, $mem$$Address); 5221 %} 5222 ins_pipe(ialu_reg_mem); 5223 %} 5224 5225 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5226 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5227 match(Set dst (AndI (LoadI mem) mask)); 5228 5229 ins_cost(125); 5230 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5231 ins_encode %{ 5232 __ movzbl($dst$$Register, $mem$$Address); 5233 %} 5234 ins_pipe(ialu_reg_mem); 5235 %} 5236 5237 // Load Integer (32 bit signed) to Short (16 bit signed) 5238 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5239 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5240 5241 ins_cost(125); 5242 format %{ "movswl $dst, $mem\t# int -> short" %} 5243 ins_encode %{ 5244 __ movswl($dst$$Register, $mem$$Address); 5245 %} 5246 ins_pipe(ialu_reg_mem); 5247 %} 5248 5249 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5250 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5251 match(Set dst (AndI (LoadI mem) mask)); 5252 5253 ins_cost(125); 5254 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5255 ins_encode %{ 5256 __ movzwl($dst$$Register, $mem$$Address); 5257 %} 5258 ins_pipe(ialu_reg_mem); 5259 %} 5260 5261 // Load Integer into Long Register 5262 instruct loadI2L(rRegL dst, memory mem) 5263 %{ 5264 match(Set dst (ConvI2L (LoadI mem))); 5265 5266 ins_cost(125); 5267 format %{ "movslq $dst, $mem\t# int -> long" %} 5268 5269 ins_encode %{ 5270 __ movslq($dst$$Register, $mem$$Address); 5271 %} 5272 5273 ins_pipe(ialu_reg_mem); 5274 %} 5275 5276 // Load Integer with mask 0xFF into Long Register 5277 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5278 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5279 5280 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5281 ins_encode %{ 5282 __ movzbq($dst$$Register, $mem$$Address); 5283 %} 5284 ins_pipe(ialu_reg_mem); 5285 %} 5286 5287 // Load Integer with mask 0xFFFF into Long Register 5288 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5289 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5290 5291 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5292 ins_encode %{ 5293 __ movzwq($dst$$Register, $mem$$Address); 5294 %} 5295 ins_pipe(ialu_reg_mem); 5296 %} 5297 5298 // Load Integer with a 31-bit mask into Long Register 5299 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5300 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5301 effect(KILL cr); 5302 5303 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5304 "andl $dst, $mask" %} 5305 ins_encode %{ 5306 Register Rdst = $dst$$Register; 5307 __ movl(Rdst, $mem$$Address); 5308 __ andl(Rdst, $mask$$constant); 5309 %} 5310 ins_pipe(ialu_reg_mem); 5311 %} 5312 5313 // Load Unsigned Integer into Long Register 5314 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5315 %{ 5316 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5317 5318 ins_cost(125); 5319 format %{ "movl $dst, $mem\t# uint -> long" %} 5320 5321 ins_encode %{ 5322 __ movl($dst$$Register, $mem$$Address); 5323 %} 5324 5325 ins_pipe(ialu_reg_mem); 5326 %} 5327 5328 // Load Long 5329 instruct loadL(rRegL dst, memory mem) 5330 %{ 5331 match(Set dst (LoadL mem)); 5332 5333 ins_cost(125); 5334 format %{ "movq $dst, $mem\t# long" %} 5335 5336 ins_encode %{ 5337 __ movq($dst$$Register, $mem$$Address); 5338 %} 5339 5340 ins_pipe(ialu_reg_mem); // XXX 5341 %} 5342 5343 // Load Range 5344 instruct loadRange(rRegI dst, memory mem) 5345 %{ 5346 match(Set dst (LoadRange mem)); 5347 5348 ins_cost(125); // XXX 5349 format %{ "movl $dst, $mem\t# range" %} 5350 opcode(0x8B); 5351 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5352 ins_pipe(ialu_reg_mem); 5353 %} 5354 5355 // Load Pointer 5356 instruct loadP(rRegP dst, memory mem) 5357 %{ 5358 match(Set dst (LoadP mem)); 5359 5360 ins_cost(125); // XXX 5361 format %{ "movq $dst, $mem\t# ptr" %} 5362 opcode(0x8B); 5363 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5364 ins_pipe(ialu_reg_mem); // XXX 5365 %} 5366 5367 // Load Compressed Pointer 5368 instruct loadN(rRegN dst, memory mem) 5369 %{ 5370 match(Set dst (LoadN mem)); 5371 5372 ins_cost(125); // XXX 5373 format %{ "movl $dst, $mem\t# compressed ptr" %} 5374 ins_encode %{ 5375 __ movl($dst$$Register, $mem$$Address); 5376 %} 5377 ins_pipe(ialu_reg_mem); // XXX 5378 %} 5379 5380 5381 // Load Klass Pointer 5382 instruct loadKlass(rRegP dst, memory mem) 5383 %{ 5384 match(Set dst (LoadKlass mem)); 5385 5386 ins_cost(125); // XXX 5387 format %{ "movq $dst, $mem\t# class" %} 5388 opcode(0x8B); 5389 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5390 ins_pipe(ialu_reg_mem); // XXX 5391 %} 5392 5393 // Load narrow Klass Pointer 5394 instruct loadNKlass(rRegN dst, memory mem) 5395 %{ 5396 match(Set dst (LoadNKlass mem)); 5397 5398 ins_cost(125); // XXX 5399 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5400 ins_encode %{ 5401 __ movl($dst$$Register, $mem$$Address); 5402 %} 5403 ins_pipe(ialu_reg_mem); // XXX 5404 %} 5405 5406 // Load Float 5407 instruct loadF(regF dst, memory mem) 5408 %{ 5409 match(Set dst (LoadF mem)); 5410 5411 ins_cost(145); // XXX 5412 format %{ "movss $dst, $mem\t# float" %} 5413 ins_encode %{ 5414 __ movflt($dst$$XMMRegister, $mem$$Address); 5415 %} 5416 ins_pipe(pipe_slow); // XXX 5417 %} 5418 5419 // Load Float 5420 instruct MoveF2VL(vlRegF dst, regF src) %{ 5421 match(Set dst src); 5422 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5423 ins_encode %{ 5424 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5425 %} 5426 ins_pipe( fpu_reg_reg ); 5427 %} 5428 5429 // Load Float 5430 instruct MoveF2LEG(legRegF dst, regF src) %{ 5431 match(Set dst src); 5432 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5433 ins_encode %{ 5434 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5435 %} 5436 ins_pipe( fpu_reg_reg ); 5437 %} 5438 5439 // Load Float 5440 instruct MoveVL2F(regF dst, vlRegF src) %{ 5441 match(Set dst src); 5442 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5443 ins_encode %{ 5444 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5445 %} 5446 ins_pipe( fpu_reg_reg ); 5447 %} 5448 5449 // Load Float 5450 instruct MoveLEG2F(regF dst, legRegF src) %{ 5451 match(Set dst src); 5452 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5453 ins_encode %{ 5454 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5455 %} 5456 ins_pipe( fpu_reg_reg ); 5457 %} 5458 5459 // Load Double 5460 instruct loadD_partial(regD dst, memory mem) 5461 %{ 5462 predicate(!UseXmmLoadAndClearUpper); 5463 match(Set dst (LoadD mem)); 5464 5465 ins_cost(145); // XXX 5466 format %{ "movlpd $dst, $mem\t# double" %} 5467 ins_encode %{ 5468 __ movdbl($dst$$XMMRegister, $mem$$Address); 5469 %} 5470 ins_pipe(pipe_slow); // XXX 5471 %} 5472 5473 instruct loadD(regD dst, memory mem) 5474 %{ 5475 predicate(UseXmmLoadAndClearUpper); 5476 match(Set dst (LoadD mem)); 5477 5478 ins_cost(145); // XXX 5479 format %{ "movsd $dst, $mem\t# double" %} 5480 ins_encode %{ 5481 __ movdbl($dst$$XMMRegister, $mem$$Address); 5482 %} 5483 ins_pipe(pipe_slow); // XXX 5484 %} 5485 5486 // Load Double 5487 instruct MoveD2VL(vlRegD dst, regD src) %{ 5488 match(Set dst src); 5489 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5490 ins_encode %{ 5491 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5492 %} 5493 ins_pipe( fpu_reg_reg ); 5494 %} 5495 5496 // Load Double 5497 instruct MoveD2LEG(legRegD dst, regD src) %{ 5498 match(Set dst src); 5499 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5500 ins_encode %{ 5501 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5502 %} 5503 ins_pipe( fpu_reg_reg ); 5504 %} 5505 5506 // Load Double 5507 instruct MoveVL2D(regD dst, vlRegD src) %{ 5508 match(Set dst src); 5509 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5510 ins_encode %{ 5511 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5512 %} 5513 ins_pipe( fpu_reg_reg ); 5514 %} 5515 5516 // Load Double 5517 instruct MoveLEG2D(regD dst, legRegD src) %{ 5518 match(Set dst src); 5519 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5520 ins_encode %{ 5521 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5522 %} 5523 ins_pipe( fpu_reg_reg ); 5524 %} 5525 5526 // Following pseudo code describes the algorithm for max[FD]: 5527 // Min algorithm is on similar lines 5528 // btmp = (b < +0.0) ? a : b 5529 // atmp = (b < +0.0) ? b : a 5530 // Tmp = Max_Float(atmp , btmp) 5531 // Res = (atmp == NaN) ? atmp : Tmp 5532 5533 // max = java.lang.Math.max(float a, float b) 5534 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5535 predicate(UseAVX > 0 && !n->is_reduction()); 5536 match(Set dst (MaxF a b)); 5537 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5538 format %{ 5539 "blendvps $btmp,$b,$a,$b \n\t" 5540 "blendvps $atmp,$a,$b,$b \n\t" 5541 "vmaxss $tmp,$atmp,$btmp \n\t" 5542 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5543 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5544 %} 5545 ins_encode %{ 5546 int vector_len = Assembler::AVX_128bit; 5547 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5548 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5549 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5550 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5551 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5552 %} 5553 ins_pipe( pipe_slow ); 5554 %} 5555 5556 instruct maxF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{ 5557 predicate(UseAVX > 0 && n->is_reduction()); 5558 match(Set dst (MaxF a b)); 5559 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5560 5561 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 5562 ins_encode %{ 5563 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5564 false /*min*/, true /*single*/); 5565 %} 5566 ins_pipe( pipe_slow ); 5567 %} 5568 5569 // max = java.lang.Math.max(double a, double b) 5570 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5571 predicate(UseAVX > 0 && !n->is_reduction()); 5572 match(Set dst (MaxD a b)); 5573 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 5574 format %{ 5575 "blendvpd $btmp,$b,$a,$b \n\t" 5576 "blendvpd $atmp,$a,$b,$b \n\t" 5577 "vmaxsd $tmp,$atmp,$btmp \n\t" 5578 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5579 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5580 %} 5581 ins_encode %{ 5582 int vector_len = Assembler::AVX_128bit; 5583 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5584 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5585 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5586 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5587 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5588 %} 5589 ins_pipe( pipe_slow ); 5590 %} 5591 5592 instruct maxD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{ 5593 predicate(UseAVX > 0 && n->is_reduction()); 5594 match(Set dst (MaxD a b)); 5595 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5596 5597 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 5598 ins_encode %{ 5599 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5600 false /*min*/, false /*single*/); 5601 %} 5602 ins_pipe( pipe_slow ); 5603 %} 5604 5605 // min = java.lang.Math.min(float a, float b) 5606 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5607 predicate(UseAVX > 0 && !n->is_reduction()); 5608 match(Set dst (MinF a b)); 5609 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5610 format %{ 5611 "blendvps $atmp,$a,$b,$a \n\t" 5612 "blendvps $btmp,$b,$a,$a \n\t" 5613 "vminss $tmp,$atmp,$btmp \n\t" 5614 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5615 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5616 %} 5617 ins_encode %{ 5618 int vector_len = Assembler::AVX_128bit; 5619 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5620 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5621 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5622 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5623 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5624 %} 5625 ins_pipe( pipe_slow ); 5626 %} 5627 5628 instruct minF_reduction_reg(regF dst, regF a, regF b, regF xmmt, rRegI tmp, rFlagsReg cr) %{ 5629 predicate(UseAVX > 0 && n->is_reduction()); 5630 match(Set dst (MinF a b)); 5631 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5632 5633 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 5634 ins_encode %{ 5635 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5636 true /*min*/, true /*single*/); 5637 %} 5638 ins_pipe( pipe_slow ); 5639 %} 5640 5641 // min = java.lang.Math.min(double a, double b) 5642 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5643 predicate(UseAVX > 0 && !n->is_reduction()); 5644 match(Set dst (MinD a b)); 5645 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5646 format %{ 5647 "blendvpd $atmp,$a,$b,$a \n\t" 5648 "blendvpd $btmp,$b,$a,$a \n\t" 5649 "vminsd $tmp,$atmp,$btmp \n\t" 5650 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5651 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5652 %} 5653 ins_encode %{ 5654 int vector_len = Assembler::AVX_128bit; 5655 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5656 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5657 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5658 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5659 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5660 %} 5661 ins_pipe( pipe_slow ); 5662 %} 5663 5664 instruct minD_reduction_reg(regD dst, regD a, regD b, regD xmmt, rRegL tmp, rFlagsReg cr) %{ 5665 predicate(UseAVX > 0 && n->is_reduction()); 5666 match(Set dst (MinD a b)); 5667 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5668 5669 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 5670 ins_encode %{ 5671 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5672 true /*min*/, false /*single*/); 5673 %} 5674 ins_pipe( pipe_slow ); 5675 %} 5676 5677 // Load Effective Address 5678 instruct leaP8(rRegP dst, indOffset8 mem) 5679 %{ 5680 match(Set dst mem); 5681 5682 ins_cost(110); // XXX 5683 format %{ "leaq $dst, $mem\t# ptr 8" %} 5684 opcode(0x8D); 5685 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5686 ins_pipe(ialu_reg_reg_fat); 5687 %} 5688 5689 instruct leaP32(rRegP dst, indOffset32 mem) 5690 %{ 5691 match(Set dst mem); 5692 5693 ins_cost(110); 5694 format %{ "leaq $dst, $mem\t# ptr 32" %} 5695 opcode(0x8D); 5696 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5697 ins_pipe(ialu_reg_reg_fat); 5698 %} 5699 5700 // instruct leaPIdx(rRegP dst, indIndex mem) 5701 // %{ 5702 // match(Set dst mem); 5703 5704 // ins_cost(110); 5705 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5706 // opcode(0x8D); 5707 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5708 // ins_pipe(ialu_reg_reg_fat); 5709 // %} 5710 5711 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5712 %{ 5713 match(Set dst mem); 5714 5715 ins_cost(110); 5716 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5717 opcode(0x8D); 5718 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5719 ins_pipe(ialu_reg_reg_fat); 5720 %} 5721 5722 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5723 %{ 5724 match(Set dst mem); 5725 5726 ins_cost(110); 5727 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5728 opcode(0x8D); 5729 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5730 ins_pipe(ialu_reg_reg_fat); 5731 %} 5732 5733 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5734 %{ 5735 match(Set dst mem); 5736 5737 ins_cost(110); 5738 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5739 opcode(0x8D); 5740 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5741 ins_pipe(ialu_reg_reg_fat); 5742 %} 5743 5744 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5745 %{ 5746 match(Set dst mem); 5747 5748 ins_cost(110); 5749 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5750 opcode(0x8D); 5751 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5752 ins_pipe(ialu_reg_reg_fat); 5753 %} 5754 5755 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5756 %{ 5757 match(Set dst mem); 5758 5759 ins_cost(110); 5760 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5761 opcode(0x8D); 5762 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5763 ins_pipe(ialu_reg_reg_fat); 5764 %} 5765 5766 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5767 %{ 5768 match(Set dst mem); 5769 5770 ins_cost(110); 5771 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5772 opcode(0x8D); 5773 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5774 ins_pipe(ialu_reg_reg_fat); 5775 %} 5776 5777 // Load Effective Address which uses Narrow (32-bits) oop 5778 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5779 %{ 5780 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 5781 match(Set dst mem); 5782 5783 ins_cost(110); 5784 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 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 leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5791 %{ 5792 predicate(CompressedOops::shift() == 0); 5793 match(Set dst mem); 5794 5795 ins_cost(110); // XXX 5796 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 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 leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5803 %{ 5804 predicate(CompressedOops::shift() == 0); 5805 match(Set dst mem); 5806 5807 ins_cost(110); 5808 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 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 leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5815 %{ 5816 predicate(CompressedOops::shift() == 0); 5817 match(Set dst mem); 5818 5819 ins_cost(110); 5820 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 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 leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5827 %{ 5828 predicate(CompressedOops::shift() == 0); 5829 match(Set dst mem); 5830 5831 ins_cost(110); 5832 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 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 leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5839 %{ 5840 predicate(CompressedOops::shift() == 0); 5841 match(Set dst mem); 5842 5843 ins_cost(110); 5844 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 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 leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5851 %{ 5852 predicate(CompressedOops::shift() == 0); 5853 match(Set dst mem); 5854 5855 ins_cost(110); 5856 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 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 leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5863 %{ 5864 predicate(CompressedOops::shift() == 0); 5865 match(Set dst mem); 5866 5867 ins_cost(110); 5868 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5869 opcode(0x8D); 5870 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5871 ins_pipe(ialu_reg_reg_fat); 5872 %} 5873 5874 instruct loadConI(rRegI dst, immI src) 5875 %{ 5876 match(Set dst src); 5877 5878 format %{ "movl $dst, $src\t# int" %} 5879 ins_encode(load_immI(dst, src)); 5880 ins_pipe(ialu_reg_fat); // XXX 5881 %} 5882 5883 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5884 %{ 5885 match(Set dst src); 5886 effect(KILL cr); 5887 5888 ins_cost(50); 5889 format %{ "xorl $dst, $dst\t# int" %} 5890 opcode(0x33); /* + rd */ 5891 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5892 ins_pipe(ialu_reg); 5893 %} 5894 5895 instruct loadConL(rRegL dst, immL src) 5896 %{ 5897 match(Set dst src); 5898 5899 ins_cost(150); 5900 format %{ "movq $dst, $src\t# long" %} 5901 ins_encode(load_immL(dst, src)); 5902 ins_pipe(ialu_reg); 5903 %} 5904 5905 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5906 %{ 5907 match(Set dst src); 5908 effect(KILL cr); 5909 5910 ins_cost(50); 5911 format %{ "xorl $dst, $dst\t# long" %} 5912 opcode(0x33); /* + rd */ 5913 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5914 ins_pipe(ialu_reg); // XXX 5915 %} 5916 5917 instruct loadConUL32(rRegL dst, immUL32 src) 5918 %{ 5919 match(Set dst src); 5920 5921 ins_cost(60); 5922 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5923 ins_encode(load_immUL32(dst, src)); 5924 ins_pipe(ialu_reg); 5925 %} 5926 5927 instruct loadConL32(rRegL dst, immL32 src) 5928 %{ 5929 match(Set dst src); 5930 5931 ins_cost(70); 5932 format %{ "movq $dst, $src\t# long (32-bit)" %} 5933 ins_encode(load_immL32(dst, src)); 5934 ins_pipe(ialu_reg); 5935 %} 5936 5937 instruct loadConP(rRegP dst, immP con) %{ 5938 match(Set dst con); 5939 5940 format %{ "movq $dst, $con\t# ptr" %} 5941 ins_encode(load_immP(dst, con)); 5942 ins_pipe(ialu_reg_fat); // XXX 5943 %} 5944 5945 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5946 %{ 5947 match(Set dst src); 5948 effect(KILL cr); 5949 5950 ins_cost(50); 5951 format %{ "xorl $dst, $dst\t# ptr" %} 5952 opcode(0x33); /* + rd */ 5953 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5954 ins_pipe(ialu_reg); 5955 %} 5956 5957 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5958 %{ 5959 match(Set dst src); 5960 effect(KILL cr); 5961 5962 ins_cost(60); 5963 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5964 ins_encode(load_immP31(dst, src)); 5965 ins_pipe(ialu_reg); 5966 %} 5967 5968 instruct loadConF(regF dst, immF con) %{ 5969 match(Set dst con); 5970 ins_cost(125); 5971 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5972 ins_encode %{ 5973 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5974 %} 5975 ins_pipe(pipe_slow); 5976 %} 5977 5978 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5979 match(Set dst src); 5980 effect(KILL cr); 5981 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5982 ins_encode %{ 5983 __ xorq($dst$$Register, $dst$$Register); 5984 %} 5985 ins_pipe(ialu_reg); 5986 %} 5987 5988 instruct loadConN(rRegN dst, immN src) %{ 5989 match(Set dst src); 5990 5991 ins_cost(125); 5992 format %{ "movl $dst, $src\t# compressed ptr" %} 5993 ins_encode %{ 5994 address con = (address)$src$$constant; 5995 if (con == NULL) { 5996 ShouldNotReachHere(); 5997 } else { 5998 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5999 } 6000 %} 6001 ins_pipe(ialu_reg_fat); // XXX 6002 %} 6003 6004 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 6005 match(Set dst src); 6006 6007 ins_cost(125); 6008 format %{ "movl $dst, $src\t# compressed klass ptr" %} 6009 ins_encode %{ 6010 address con = (address)$src$$constant; 6011 if (con == NULL) { 6012 ShouldNotReachHere(); 6013 } else { 6014 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 6015 } 6016 %} 6017 ins_pipe(ialu_reg_fat); // XXX 6018 %} 6019 6020 instruct loadConF0(regF dst, immF0 src) 6021 %{ 6022 match(Set dst src); 6023 ins_cost(100); 6024 6025 format %{ "xorps $dst, $dst\t# float 0.0" %} 6026 ins_encode %{ 6027 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 6028 %} 6029 ins_pipe(pipe_slow); 6030 %} 6031 6032 // Use the same format since predicate() can not be used here. 6033 instruct loadConD(regD dst, immD con) %{ 6034 match(Set dst con); 6035 ins_cost(125); 6036 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 6037 ins_encode %{ 6038 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 6039 %} 6040 ins_pipe(pipe_slow); 6041 %} 6042 6043 instruct loadConD0(regD dst, immD0 src) 6044 %{ 6045 match(Set dst src); 6046 ins_cost(100); 6047 6048 format %{ "xorpd $dst, $dst\t# double 0.0" %} 6049 ins_encode %{ 6050 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 6051 %} 6052 ins_pipe(pipe_slow); 6053 %} 6054 6055 instruct loadSSI(rRegI dst, stackSlotI src) 6056 %{ 6057 match(Set dst src); 6058 6059 ins_cost(125); 6060 format %{ "movl $dst, $src\t# int stk" %} 6061 opcode(0x8B); 6062 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6063 ins_pipe(ialu_reg_mem); 6064 %} 6065 6066 instruct loadSSL(rRegL dst, stackSlotL src) 6067 %{ 6068 match(Set dst src); 6069 6070 ins_cost(125); 6071 format %{ "movq $dst, $src\t# long stk" %} 6072 opcode(0x8B); 6073 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6074 ins_pipe(ialu_reg_mem); 6075 %} 6076 6077 instruct loadSSP(rRegP dst, stackSlotP src) 6078 %{ 6079 match(Set dst src); 6080 6081 ins_cost(125); 6082 format %{ "movq $dst, $src\t# ptr stk" %} 6083 opcode(0x8B); 6084 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6085 ins_pipe(ialu_reg_mem); 6086 %} 6087 6088 instruct loadSSF(regF dst, stackSlotF src) 6089 %{ 6090 match(Set dst src); 6091 6092 ins_cost(125); 6093 format %{ "movss $dst, $src\t# float stk" %} 6094 ins_encode %{ 6095 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 6096 %} 6097 ins_pipe(pipe_slow); // XXX 6098 %} 6099 6100 // Use the same format since predicate() can not be used here. 6101 instruct loadSSD(regD dst, stackSlotD src) 6102 %{ 6103 match(Set dst src); 6104 6105 ins_cost(125); 6106 format %{ "movsd $dst, $src\t# double stk" %} 6107 ins_encode %{ 6108 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 6109 %} 6110 ins_pipe(pipe_slow); // XXX 6111 %} 6112 6113 // Prefetch instructions for allocation. 6114 // Must be safe to execute with invalid address (cannot fault). 6115 6116 instruct prefetchAlloc( memory mem ) %{ 6117 predicate(AllocatePrefetchInstr==3); 6118 match(PrefetchAllocation mem); 6119 ins_cost(125); 6120 6121 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 6122 ins_encode %{ 6123 __ prefetchw($mem$$Address); 6124 %} 6125 ins_pipe(ialu_mem); 6126 %} 6127 6128 instruct prefetchAllocNTA( memory mem ) %{ 6129 predicate(AllocatePrefetchInstr==0); 6130 match(PrefetchAllocation mem); 6131 ins_cost(125); 6132 6133 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 6134 ins_encode %{ 6135 __ prefetchnta($mem$$Address); 6136 %} 6137 ins_pipe(ialu_mem); 6138 %} 6139 6140 instruct prefetchAllocT0( memory mem ) %{ 6141 predicate(AllocatePrefetchInstr==1); 6142 match(PrefetchAllocation mem); 6143 ins_cost(125); 6144 6145 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 6146 ins_encode %{ 6147 __ prefetcht0($mem$$Address); 6148 %} 6149 ins_pipe(ialu_mem); 6150 %} 6151 6152 instruct prefetchAllocT2( memory mem ) %{ 6153 predicate(AllocatePrefetchInstr==2); 6154 match(PrefetchAllocation mem); 6155 ins_cost(125); 6156 6157 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 6158 ins_encode %{ 6159 __ prefetcht2($mem$$Address); 6160 %} 6161 ins_pipe(ialu_mem); 6162 %} 6163 6164 //----------Store Instructions------------------------------------------------- 6165 6166 // Store Byte 6167 instruct storeB(memory mem, rRegI src) 6168 %{ 6169 match(Set mem (StoreB mem src)); 6170 6171 ins_cost(125); // XXX 6172 format %{ "movb $mem, $src\t# byte" %} 6173 opcode(0x88); 6174 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6175 ins_pipe(ialu_mem_reg); 6176 %} 6177 6178 // Store Char/Short 6179 instruct storeC(memory mem, rRegI src) 6180 %{ 6181 match(Set mem (StoreC mem src)); 6182 6183 ins_cost(125); // XXX 6184 format %{ "movw $mem, $src\t# char/short" %} 6185 opcode(0x89); 6186 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6187 ins_pipe(ialu_mem_reg); 6188 %} 6189 6190 // Store Integer 6191 instruct storeI(memory mem, rRegI src) 6192 %{ 6193 match(Set mem (StoreI mem src)); 6194 6195 ins_cost(125); // XXX 6196 format %{ "movl $mem, $src\t# int" %} 6197 opcode(0x89); 6198 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6199 ins_pipe(ialu_mem_reg); 6200 %} 6201 6202 // Store Long 6203 instruct storeL(memory mem, rRegL src) 6204 %{ 6205 match(Set mem (StoreL mem src)); 6206 6207 ins_cost(125); // XXX 6208 format %{ "movq $mem, $src\t# long" %} 6209 opcode(0x89); 6210 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6211 ins_pipe(ialu_mem_reg); // XXX 6212 %} 6213 6214 // Store Pointer 6215 instruct storeP(memory mem, any_RegP src) 6216 %{ 6217 match(Set mem (StoreP mem src)); 6218 6219 ins_cost(125); // XXX 6220 format %{ "movq $mem, $src\t# ptr" %} 6221 opcode(0x89); 6222 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6223 ins_pipe(ialu_mem_reg); 6224 %} 6225 6226 instruct storeImmP0(memory mem, immP0 zero) 6227 %{ 6228 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6229 match(Set mem (StoreP mem zero)); 6230 6231 ins_cost(125); // XXX 6232 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6233 ins_encode %{ 6234 __ movq($mem$$Address, r12); 6235 %} 6236 ins_pipe(ialu_mem_reg); 6237 %} 6238 6239 // Store NULL Pointer, mark word, or other simple pointer constant. 6240 instruct storeImmP(memory mem, immP31 src) 6241 %{ 6242 match(Set mem (StoreP mem src)); 6243 6244 ins_cost(150); // XXX 6245 format %{ "movq $mem, $src\t# ptr" %} 6246 opcode(0xC7); /* C7 /0 */ 6247 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6248 ins_pipe(ialu_mem_imm); 6249 %} 6250 6251 // Store Compressed Pointer 6252 instruct storeN(memory mem, rRegN src) 6253 %{ 6254 match(Set mem (StoreN mem src)); 6255 6256 ins_cost(125); // XXX 6257 format %{ "movl $mem, $src\t# compressed ptr" %} 6258 ins_encode %{ 6259 __ movl($mem$$Address, $src$$Register); 6260 %} 6261 ins_pipe(ialu_mem_reg); 6262 %} 6263 6264 instruct storeNKlass(memory mem, rRegN src) 6265 %{ 6266 match(Set mem (StoreNKlass mem src)); 6267 6268 ins_cost(125); // XXX 6269 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6270 ins_encode %{ 6271 __ movl($mem$$Address, $src$$Register); 6272 %} 6273 ins_pipe(ialu_mem_reg); 6274 %} 6275 6276 instruct storeImmN0(memory mem, immN0 zero) 6277 %{ 6278 predicate(CompressedOops::base() == NULL && CompressedKlassPointers::base() == NULL); 6279 match(Set mem (StoreN mem zero)); 6280 6281 ins_cost(125); // XXX 6282 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6283 ins_encode %{ 6284 __ movl($mem$$Address, r12); 6285 %} 6286 ins_pipe(ialu_mem_reg); 6287 %} 6288 6289 instruct storeImmN(memory mem, immN src) 6290 %{ 6291 match(Set mem (StoreN mem src)); 6292 6293 ins_cost(150); // XXX 6294 format %{ "movl $mem, $src\t# compressed ptr" %} 6295 ins_encode %{ 6296 address con = (address)$src$$constant; 6297 if (con == NULL) { 6298 __ movl($mem$$Address, (int32_t)0); 6299 } else { 6300 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6301 } 6302 %} 6303 ins_pipe(ialu_mem_imm); 6304 %} 6305 6306 instruct storeImmNKlass(memory mem, immNKlass src) 6307 %{ 6308 match(Set mem (StoreNKlass mem src)); 6309 6310 ins_cost(150); // XXX 6311 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6312 ins_encode %{ 6313 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6314 %} 6315 ins_pipe(ialu_mem_imm); 6316 %} 6317 6318 // Store Integer Immediate 6319 instruct storeImmI0(memory mem, immI0 zero) 6320 %{ 6321 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6322 match(Set mem (StoreI mem zero)); 6323 6324 ins_cost(125); // XXX 6325 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6326 ins_encode %{ 6327 __ movl($mem$$Address, r12); 6328 %} 6329 ins_pipe(ialu_mem_reg); 6330 %} 6331 6332 instruct storeImmI(memory mem, immI src) 6333 %{ 6334 match(Set mem (StoreI mem src)); 6335 6336 ins_cost(150); 6337 format %{ "movl $mem, $src\t# int" %} 6338 opcode(0xC7); /* C7 /0 */ 6339 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6340 ins_pipe(ialu_mem_imm); 6341 %} 6342 6343 // Store Long Immediate 6344 instruct storeImmL0(memory mem, immL0 zero) 6345 %{ 6346 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6347 match(Set mem (StoreL mem zero)); 6348 6349 ins_cost(125); // XXX 6350 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6351 ins_encode %{ 6352 __ movq($mem$$Address, r12); 6353 %} 6354 ins_pipe(ialu_mem_reg); 6355 %} 6356 6357 instruct storeImmL(memory mem, immL32 src) 6358 %{ 6359 match(Set mem (StoreL mem src)); 6360 6361 ins_cost(150); 6362 format %{ "movq $mem, $src\t# long" %} 6363 opcode(0xC7); /* C7 /0 */ 6364 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6365 ins_pipe(ialu_mem_imm); 6366 %} 6367 6368 // Store Short/Char Immediate 6369 instruct storeImmC0(memory mem, immI0 zero) 6370 %{ 6371 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6372 match(Set mem (StoreC mem zero)); 6373 6374 ins_cost(125); // XXX 6375 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6376 ins_encode %{ 6377 __ movw($mem$$Address, r12); 6378 %} 6379 ins_pipe(ialu_mem_reg); 6380 %} 6381 6382 instruct storeImmI16(memory mem, immI16 src) 6383 %{ 6384 predicate(UseStoreImmI16); 6385 match(Set mem (StoreC mem src)); 6386 6387 ins_cost(150); 6388 format %{ "movw $mem, $src\t# short/char" %} 6389 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6390 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6391 ins_pipe(ialu_mem_imm); 6392 %} 6393 6394 // Store Byte Immediate 6395 instruct storeImmB0(memory mem, immI0 zero) 6396 %{ 6397 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6398 match(Set mem (StoreB mem zero)); 6399 6400 ins_cost(125); // XXX 6401 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6402 ins_encode %{ 6403 __ movb($mem$$Address, r12); 6404 %} 6405 ins_pipe(ialu_mem_reg); 6406 %} 6407 6408 instruct storeImmB(memory mem, immI8 src) 6409 %{ 6410 match(Set mem (StoreB mem src)); 6411 6412 ins_cost(150); // XXX 6413 format %{ "movb $mem, $src\t# byte" %} 6414 opcode(0xC6); /* C6 /0 */ 6415 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6416 ins_pipe(ialu_mem_imm); 6417 %} 6418 6419 // Store CMS card-mark Immediate 6420 instruct storeImmCM0_reg(memory mem, immI0 zero) 6421 %{ 6422 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6423 match(Set mem (StoreCM mem zero)); 6424 6425 ins_cost(125); // XXX 6426 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6427 ins_encode %{ 6428 __ movb($mem$$Address, r12); 6429 %} 6430 ins_pipe(ialu_mem_reg); 6431 %} 6432 6433 instruct storeImmCM0(memory mem, immI0 src) 6434 %{ 6435 match(Set mem (StoreCM mem src)); 6436 6437 ins_cost(150); // XXX 6438 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6439 opcode(0xC6); /* C6 /0 */ 6440 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6441 ins_pipe(ialu_mem_imm); 6442 %} 6443 6444 // Store Float 6445 instruct storeF(memory mem, regF src) 6446 %{ 6447 match(Set mem (StoreF mem src)); 6448 6449 ins_cost(95); // XXX 6450 format %{ "movss $mem, $src\t# float" %} 6451 ins_encode %{ 6452 __ movflt($mem$$Address, $src$$XMMRegister); 6453 %} 6454 ins_pipe(pipe_slow); // XXX 6455 %} 6456 6457 // Store immediate Float value (it is faster than store from XMM register) 6458 instruct storeF0(memory mem, immF0 zero) 6459 %{ 6460 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6461 match(Set mem (StoreF mem zero)); 6462 6463 ins_cost(25); // XXX 6464 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6465 ins_encode %{ 6466 __ movl($mem$$Address, r12); 6467 %} 6468 ins_pipe(ialu_mem_reg); 6469 %} 6470 6471 instruct storeF_imm(memory mem, immF src) 6472 %{ 6473 match(Set mem (StoreF mem src)); 6474 6475 ins_cost(50); 6476 format %{ "movl $mem, $src\t# float" %} 6477 opcode(0xC7); /* C7 /0 */ 6478 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6479 ins_pipe(ialu_mem_imm); 6480 %} 6481 6482 // Store Double 6483 instruct storeD(memory mem, regD src) 6484 %{ 6485 match(Set mem (StoreD mem src)); 6486 6487 ins_cost(95); // XXX 6488 format %{ "movsd $mem, $src\t# double" %} 6489 ins_encode %{ 6490 __ movdbl($mem$$Address, $src$$XMMRegister); 6491 %} 6492 ins_pipe(pipe_slow); // XXX 6493 %} 6494 6495 // Store immediate double 0.0 (it is faster than store from XMM register) 6496 instruct storeD0_imm(memory mem, immD0 src) 6497 %{ 6498 predicate(!UseCompressedOops || (CompressedOops::base() != NULL)); 6499 match(Set mem (StoreD mem src)); 6500 6501 ins_cost(50); 6502 format %{ "movq $mem, $src\t# double 0." %} 6503 opcode(0xC7); /* C7 /0 */ 6504 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6505 ins_pipe(ialu_mem_imm); 6506 %} 6507 6508 instruct storeD0(memory mem, immD0 zero) 6509 %{ 6510 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6511 match(Set mem (StoreD mem zero)); 6512 6513 ins_cost(25); // XXX 6514 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6515 ins_encode %{ 6516 __ movq($mem$$Address, r12); 6517 %} 6518 ins_pipe(ialu_mem_reg); 6519 %} 6520 6521 instruct storeSSI(stackSlotI dst, rRegI src) 6522 %{ 6523 match(Set dst src); 6524 6525 ins_cost(100); 6526 format %{ "movl $dst, $src\t# int stk" %} 6527 opcode(0x89); 6528 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6529 ins_pipe( ialu_mem_reg ); 6530 %} 6531 6532 instruct storeSSL(stackSlotL dst, rRegL src) 6533 %{ 6534 match(Set dst src); 6535 6536 ins_cost(100); 6537 format %{ "movq $dst, $src\t# long stk" %} 6538 opcode(0x89); 6539 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6540 ins_pipe(ialu_mem_reg); 6541 %} 6542 6543 instruct storeSSP(stackSlotP dst, rRegP src) 6544 %{ 6545 match(Set dst src); 6546 6547 ins_cost(100); 6548 format %{ "movq $dst, $src\t# ptr stk" %} 6549 opcode(0x89); 6550 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6551 ins_pipe(ialu_mem_reg); 6552 %} 6553 6554 instruct storeSSF(stackSlotF dst, regF src) 6555 %{ 6556 match(Set dst src); 6557 6558 ins_cost(95); // XXX 6559 format %{ "movss $dst, $src\t# float stk" %} 6560 ins_encode %{ 6561 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6562 %} 6563 ins_pipe(pipe_slow); // XXX 6564 %} 6565 6566 instruct storeSSD(stackSlotD dst, regD src) 6567 %{ 6568 match(Set dst src); 6569 6570 ins_cost(95); // XXX 6571 format %{ "movsd $dst, $src\t# double stk" %} 6572 ins_encode %{ 6573 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6574 %} 6575 ins_pipe(pipe_slow); // XXX 6576 %} 6577 6578 //----------BSWAP Instructions------------------------------------------------- 6579 instruct bytes_reverse_int(rRegI dst) %{ 6580 match(Set dst (ReverseBytesI dst)); 6581 6582 format %{ "bswapl $dst" %} 6583 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6584 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6585 ins_pipe( ialu_reg ); 6586 %} 6587 6588 instruct bytes_reverse_long(rRegL dst) %{ 6589 match(Set dst (ReverseBytesL dst)); 6590 6591 format %{ "bswapq $dst" %} 6592 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6593 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6594 ins_pipe( ialu_reg); 6595 %} 6596 6597 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6598 match(Set dst (ReverseBytesUS dst)); 6599 effect(KILL cr); 6600 6601 format %{ "bswapl $dst\n\t" 6602 "shrl $dst,16\n\t" %} 6603 ins_encode %{ 6604 __ bswapl($dst$$Register); 6605 __ shrl($dst$$Register, 16); 6606 %} 6607 ins_pipe( ialu_reg ); 6608 %} 6609 6610 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6611 match(Set dst (ReverseBytesS dst)); 6612 effect(KILL cr); 6613 6614 format %{ "bswapl $dst\n\t" 6615 "sar $dst,16\n\t" %} 6616 ins_encode %{ 6617 __ bswapl($dst$$Register); 6618 __ sarl($dst$$Register, 16); 6619 %} 6620 ins_pipe( ialu_reg ); 6621 %} 6622 6623 //---------- Zeros Count Instructions ------------------------------------------ 6624 6625 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6626 predicate(UseCountLeadingZerosInstruction); 6627 match(Set dst (CountLeadingZerosI src)); 6628 effect(KILL cr); 6629 6630 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6631 ins_encode %{ 6632 __ lzcntl($dst$$Register, $src$$Register); 6633 %} 6634 ins_pipe(ialu_reg); 6635 %} 6636 6637 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6638 predicate(!UseCountLeadingZerosInstruction); 6639 match(Set dst (CountLeadingZerosI src)); 6640 effect(KILL cr); 6641 6642 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6643 "jnz skip\n\t" 6644 "movl $dst, -1\n" 6645 "skip:\n\t" 6646 "negl $dst\n\t" 6647 "addl $dst, 31" %} 6648 ins_encode %{ 6649 Register Rdst = $dst$$Register; 6650 Register Rsrc = $src$$Register; 6651 Label skip; 6652 __ bsrl(Rdst, Rsrc); 6653 __ jccb(Assembler::notZero, skip); 6654 __ movl(Rdst, -1); 6655 __ bind(skip); 6656 __ negl(Rdst); 6657 __ addl(Rdst, BitsPerInt - 1); 6658 %} 6659 ins_pipe(ialu_reg); 6660 %} 6661 6662 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6663 predicate(UseCountLeadingZerosInstruction); 6664 match(Set dst (CountLeadingZerosL src)); 6665 effect(KILL cr); 6666 6667 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6668 ins_encode %{ 6669 __ lzcntq($dst$$Register, $src$$Register); 6670 %} 6671 ins_pipe(ialu_reg); 6672 %} 6673 6674 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6675 predicate(!UseCountLeadingZerosInstruction); 6676 match(Set dst (CountLeadingZerosL src)); 6677 effect(KILL cr); 6678 6679 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6680 "jnz skip\n\t" 6681 "movl $dst, -1\n" 6682 "skip:\n\t" 6683 "negl $dst\n\t" 6684 "addl $dst, 63" %} 6685 ins_encode %{ 6686 Register Rdst = $dst$$Register; 6687 Register Rsrc = $src$$Register; 6688 Label skip; 6689 __ bsrq(Rdst, Rsrc); 6690 __ jccb(Assembler::notZero, skip); 6691 __ movl(Rdst, -1); 6692 __ bind(skip); 6693 __ negl(Rdst); 6694 __ addl(Rdst, BitsPerLong - 1); 6695 %} 6696 ins_pipe(ialu_reg); 6697 %} 6698 6699 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6700 predicate(UseCountTrailingZerosInstruction); 6701 match(Set dst (CountTrailingZerosI src)); 6702 effect(KILL cr); 6703 6704 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6705 ins_encode %{ 6706 __ tzcntl($dst$$Register, $src$$Register); 6707 %} 6708 ins_pipe(ialu_reg); 6709 %} 6710 6711 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6712 predicate(!UseCountTrailingZerosInstruction); 6713 match(Set dst (CountTrailingZerosI src)); 6714 effect(KILL cr); 6715 6716 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6717 "jnz done\n\t" 6718 "movl $dst, 32\n" 6719 "done:" %} 6720 ins_encode %{ 6721 Register Rdst = $dst$$Register; 6722 Label done; 6723 __ bsfl(Rdst, $src$$Register); 6724 __ jccb(Assembler::notZero, done); 6725 __ movl(Rdst, BitsPerInt); 6726 __ bind(done); 6727 %} 6728 ins_pipe(ialu_reg); 6729 %} 6730 6731 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6732 predicate(UseCountTrailingZerosInstruction); 6733 match(Set dst (CountTrailingZerosL src)); 6734 effect(KILL cr); 6735 6736 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6737 ins_encode %{ 6738 __ tzcntq($dst$$Register, $src$$Register); 6739 %} 6740 ins_pipe(ialu_reg); 6741 %} 6742 6743 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6744 predicate(!UseCountTrailingZerosInstruction); 6745 match(Set dst (CountTrailingZerosL src)); 6746 effect(KILL cr); 6747 6748 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6749 "jnz done\n\t" 6750 "movl $dst, 64\n" 6751 "done:" %} 6752 ins_encode %{ 6753 Register Rdst = $dst$$Register; 6754 Label done; 6755 __ bsfq(Rdst, $src$$Register); 6756 __ jccb(Assembler::notZero, done); 6757 __ movl(Rdst, BitsPerLong); 6758 __ bind(done); 6759 %} 6760 ins_pipe(ialu_reg); 6761 %} 6762 6763 6764 //---------- Population Count Instructions ------------------------------------- 6765 6766 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6767 predicate(UsePopCountInstruction); 6768 match(Set dst (PopCountI src)); 6769 effect(KILL cr); 6770 6771 format %{ "popcnt $dst, $src" %} 6772 ins_encode %{ 6773 __ popcntl($dst$$Register, $src$$Register); 6774 %} 6775 ins_pipe(ialu_reg); 6776 %} 6777 6778 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6779 predicate(UsePopCountInstruction); 6780 match(Set dst (PopCountI (LoadI mem))); 6781 effect(KILL cr); 6782 6783 format %{ "popcnt $dst, $mem" %} 6784 ins_encode %{ 6785 __ popcntl($dst$$Register, $mem$$Address); 6786 %} 6787 ins_pipe(ialu_reg); 6788 %} 6789 6790 // Note: Long.bitCount(long) returns an int. 6791 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6792 predicate(UsePopCountInstruction); 6793 match(Set dst (PopCountL src)); 6794 effect(KILL cr); 6795 6796 format %{ "popcnt $dst, $src" %} 6797 ins_encode %{ 6798 __ popcntq($dst$$Register, $src$$Register); 6799 %} 6800 ins_pipe(ialu_reg); 6801 %} 6802 6803 // Note: Long.bitCount(long) returns an int. 6804 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6805 predicate(UsePopCountInstruction); 6806 match(Set dst (PopCountL (LoadL mem))); 6807 effect(KILL cr); 6808 6809 format %{ "popcnt $dst, $mem" %} 6810 ins_encode %{ 6811 __ popcntq($dst$$Register, $mem$$Address); 6812 %} 6813 ins_pipe(ialu_reg); 6814 %} 6815 6816 6817 //----------MemBar Instructions----------------------------------------------- 6818 // Memory barrier flavors 6819 6820 instruct membar_acquire() 6821 %{ 6822 match(MemBarAcquire); 6823 match(LoadFence); 6824 ins_cost(0); 6825 6826 size(0); 6827 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6828 ins_encode(); 6829 ins_pipe(empty); 6830 %} 6831 6832 instruct membar_acquire_lock() 6833 %{ 6834 match(MemBarAcquireLock); 6835 ins_cost(0); 6836 6837 size(0); 6838 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6839 ins_encode(); 6840 ins_pipe(empty); 6841 %} 6842 6843 instruct membar_release() 6844 %{ 6845 match(MemBarRelease); 6846 match(StoreFence); 6847 ins_cost(0); 6848 6849 size(0); 6850 format %{ "MEMBAR-release ! (empty encoding)" %} 6851 ins_encode(); 6852 ins_pipe(empty); 6853 %} 6854 6855 instruct membar_release_lock() 6856 %{ 6857 match(MemBarReleaseLock); 6858 ins_cost(0); 6859 6860 size(0); 6861 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6862 ins_encode(); 6863 ins_pipe(empty); 6864 %} 6865 6866 instruct membar_volatile(rFlagsReg cr) %{ 6867 match(MemBarVolatile); 6868 effect(KILL cr); 6869 ins_cost(400); 6870 6871 format %{ 6872 $$template 6873 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6874 %} 6875 ins_encode %{ 6876 __ membar(Assembler::StoreLoad); 6877 %} 6878 ins_pipe(pipe_slow); 6879 %} 6880 6881 instruct unnecessary_membar_volatile() 6882 %{ 6883 match(MemBarVolatile); 6884 predicate(Matcher::post_store_load_barrier(n)); 6885 ins_cost(0); 6886 6887 size(0); 6888 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6889 ins_encode(); 6890 ins_pipe(empty); 6891 %} 6892 6893 instruct membar_storestore() %{ 6894 match(MemBarStoreStore); 6895 ins_cost(0); 6896 6897 size(0); 6898 format %{ "MEMBAR-storestore (empty encoding)" %} 6899 ins_encode( ); 6900 ins_pipe(empty); 6901 %} 6902 6903 //----------Move Instructions-------------------------------------------------- 6904 6905 instruct castX2P(rRegP dst, rRegL src) 6906 %{ 6907 match(Set dst (CastX2P src)); 6908 6909 format %{ "movq $dst, $src\t# long->ptr" %} 6910 ins_encode %{ 6911 if ($dst$$reg != $src$$reg) { 6912 __ movptr($dst$$Register, $src$$Register); 6913 } 6914 %} 6915 ins_pipe(ialu_reg_reg); // XXX 6916 %} 6917 6918 instruct castN2X(rRegL dst, rRegN src) 6919 %{ 6920 match(Set dst (CastP2X src)); 6921 6922 format %{ "movq $dst, $src\t# ptr -> long" %} 6923 ins_encode %{ 6924 if ($dst$$reg != $src$$reg) { 6925 __ movptr($dst$$Register, $src$$Register); 6926 } 6927 %} 6928 ins_pipe(ialu_reg_reg); // XXX 6929 %} 6930 6931 instruct castP2X(rRegL dst, rRegP src) 6932 %{ 6933 match(Set dst (CastP2X src)); 6934 6935 format %{ "movq $dst, $src\t# ptr -> long" %} 6936 ins_encode %{ 6937 if ($dst$$reg != $src$$reg) { 6938 __ movptr($dst$$Register, $src$$Register); 6939 } 6940 %} 6941 ins_pipe(ialu_reg_reg); // XXX 6942 %} 6943 6944 instruct castN2I(rRegI dst, rRegN src) 6945 %{ 6946 match(Set dst (CastN2I src)); 6947 6948 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6949 ins_encode %{ 6950 if ($dst$$reg != $src$$reg) { 6951 __ movl($dst$$Register, $src$$Register); 6952 } 6953 %} 6954 ins_pipe(ialu_reg_reg); // XXX 6955 %} 6956 6957 instruct castI2N(rRegN dst, rRegI src) 6958 %{ 6959 match(Set dst (CastI2N src)); 6960 6961 format %{ "movl $dst, $src\t# int -> compressed ptr" %} 6962 ins_encode %{ 6963 if ($dst$$reg != $src$$reg) { 6964 __ movl($dst$$Register, $src$$Register); 6965 } 6966 %} 6967 ins_pipe(ialu_reg_reg); // XXX 6968 %} 6969 6970 6971 // Convert oop into int for vectors alignment masking 6972 instruct convP2I(rRegI dst, rRegP src) 6973 %{ 6974 match(Set dst (ConvL2I (CastP2X src))); 6975 6976 format %{ "movl $dst, $src\t# ptr -> int" %} 6977 ins_encode %{ 6978 __ movl($dst$$Register, $src$$Register); 6979 %} 6980 ins_pipe(ialu_reg_reg); // XXX 6981 %} 6982 6983 // Convert compressed oop into int for vectors alignment masking 6984 // in case of 32bit oops (heap < 4Gb). 6985 instruct convN2I(rRegI dst, rRegN src) 6986 %{ 6987 predicate(CompressedOops::shift() == 0); 6988 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6989 6990 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6991 ins_encode %{ 6992 __ movl($dst$$Register, $src$$Register); 6993 %} 6994 ins_pipe(ialu_reg_reg); // XXX 6995 %} 6996 6997 // Convert oop pointer into compressed form 6998 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6999 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7000 match(Set dst (EncodeP src)); 7001 effect(KILL cr); 7002 format %{ "encode_heap_oop $dst,$src" %} 7003 ins_encode %{ 7004 Register s = $src$$Register; 7005 Register d = $dst$$Register; 7006 if (s != d) { 7007 __ movq(d, s); 7008 } 7009 __ encode_heap_oop(d); 7010 %} 7011 ins_pipe(ialu_reg_long); 7012 %} 7013 7014 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7015 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7016 match(Set dst (EncodeP src)); 7017 effect(KILL cr); 7018 format %{ "encode_heap_oop_not_null $dst,$src" %} 7019 ins_encode %{ 7020 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7021 %} 7022 ins_pipe(ialu_reg_long); 7023 %} 7024 7025 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 7026 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7027 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7028 match(Set dst (DecodeN src)); 7029 effect(KILL cr); 7030 format %{ "decode_heap_oop $dst,$src" %} 7031 ins_encode %{ 7032 Register s = $src$$Register; 7033 Register d = $dst$$Register; 7034 if (s != d) { 7035 __ movq(d, s); 7036 } 7037 __ decode_heap_oop(d); 7038 %} 7039 ins_pipe(ialu_reg_long); 7040 %} 7041 7042 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7043 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7044 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7045 match(Set dst (DecodeN src)); 7046 effect(KILL cr); 7047 format %{ "decode_heap_oop_not_null $dst,$src" %} 7048 ins_encode %{ 7049 Register s = $src$$Register; 7050 Register d = $dst$$Register; 7051 if (s != d) { 7052 __ decode_heap_oop_not_null(d, s); 7053 } else { 7054 __ decode_heap_oop_not_null(d); 7055 } 7056 %} 7057 ins_pipe(ialu_reg_long); 7058 %} 7059 7060 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7061 match(Set dst (EncodePKlass src)); 7062 effect(KILL cr); 7063 format %{ "encode_klass_not_null $dst,$src" %} 7064 ins_encode %{ 7065 __ encode_klass_not_null($dst$$Register, $src$$Register); 7066 %} 7067 ins_pipe(ialu_reg_long); 7068 %} 7069 7070 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7071 match(Set dst (DecodeNKlass src)); 7072 effect(KILL cr); 7073 format %{ "decode_klass_not_null $dst,$src" %} 7074 ins_encode %{ 7075 Register s = $src$$Register; 7076 Register d = $dst$$Register; 7077 if (s != d) { 7078 __ decode_klass_not_null(d, s); 7079 } else { 7080 __ decode_klass_not_null(d); 7081 } 7082 %} 7083 ins_pipe(ialu_reg_long); 7084 %} 7085 7086 7087 //----------Conditional Move--------------------------------------------------- 7088 // Jump 7089 // dummy instruction for generating temp registers 7090 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7091 match(Jump (LShiftL switch_val shift)); 7092 ins_cost(350); 7093 predicate(false); 7094 effect(TEMP dest); 7095 7096 format %{ "leaq $dest, [$constantaddress]\n\t" 7097 "jmp [$dest + $switch_val << $shift]\n\t" %} 7098 ins_encode %{ 7099 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7100 // to do that and the compiler is using that register as one it can allocate. 7101 // So we build it all by hand. 7102 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 7103 // ArrayAddress dispatch(table, index); 7104 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 7105 __ lea($dest$$Register, $constantaddress); 7106 __ jmp(dispatch); 7107 %} 7108 ins_pipe(pipe_jmp); 7109 %} 7110 7111 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7112 match(Jump (AddL (LShiftL switch_val shift) offset)); 7113 ins_cost(350); 7114 effect(TEMP dest); 7115 7116 format %{ "leaq $dest, [$constantaddress]\n\t" 7117 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7118 ins_encode %{ 7119 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7120 // to do that and the compiler is using that register as one it can allocate. 7121 // So we build it all by hand. 7122 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7123 // ArrayAddress dispatch(table, index); 7124 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7125 __ lea($dest$$Register, $constantaddress); 7126 __ jmp(dispatch); 7127 %} 7128 ins_pipe(pipe_jmp); 7129 %} 7130 7131 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7132 match(Jump switch_val); 7133 ins_cost(350); 7134 effect(TEMP dest); 7135 7136 format %{ "leaq $dest, [$constantaddress]\n\t" 7137 "jmp [$dest + $switch_val]\n\t" %} 7138 ins_encode %{ 7139 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7140 // to do that and the compiler is using that register as one it can allocate. 7141 // So we build it all by hand. 7142 // Address index(noreg, switch_reg, Address::times_1); 7143 // ArrayAddress dispatch(table, index); 7144 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 7145 __ lea($dest$$Register, $constantaddress); 7146 __ jmp(dispatch); 7147 %} 7148 ins_pipe(pipe_jmp); 7149 %} 7150 7151 // Conditional move 7152 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 7153 %{ 7154 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7155 7156 ins_cost(200); // XXX 7157 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7158 opcode(0x0F, 0x40); 7159 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7160 ins_pipe(pipe_cmov_reg); 7161 %} 7162 7163 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 7164 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7165 7166 ins_cost(200); // XXX 7167 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7168 opcode(0x0F, 0x40); 7169 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7170 ins_pipe(pipe_cmov_reg); 7171 %} 7172 7173 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 7174 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7175 ins_cost(200); 7176 expand %{ 7177 cmovI_regU(cop, cr, dst, src); 7178 %} 7179 %} 7180 7181 // Conditional move 7182 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7183 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7184 7185 ins_cost(250); // XXX 7186 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7187 opcode(0x0F, 0x40); 7188 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7189 ins_pipe(pipe_cmov_mem); 7190 %} 7191 7192 // Conditional move 7193 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7194 %{ 7195 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7196 7197 ins_cost(250); // XXX 7198 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7199 opcode(0x0F, 0x40); 7200 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7201 ins_pipe(pipe_cmov_mem); 7202 %} 7203 7204 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7205 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7206 ins_cost(250); 7207 expand %{ 7208 cmovI_memU(cop, cr, dst, src); 7209 %} 7210 %} 7211 7212 // Conditional move 7213 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7214 %{ 7215 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7216 7217 ins_cost(200); // XXX 7218 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7219 opcode(0x0F, 0x40); 7220 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7221 ins_pipe(pipe_cmov_reg); 7222 %} 7223 7224 // Conditional move 7225 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7226 %{ 7227 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7228 7229 ins_cost(200); // XXX 7230 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7231 opcode(0x0F, 0x40); 7232 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7233 ins_pipe(pipe_cmov_reg); 7234 %} 7235 7236 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7237 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7238 ins_cost(200); 7239 expand %{ 7240 cmovN_regU(cop, cr, dst, src); 7241 %} 7242 %} 7243 7244 // Conditional move 7245 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7246 %{ 7247 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7248 7249 ins_cost(200); // XXX 7250 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7251 opcode(0x0F, 0x40); 7252 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7253 ins_pipe(pipe_cmov_reg); // XXX 7254 %} 7255 7256 // Conditional move 7257 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7258 %{ 7259 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7260 7261 ins_cost(200); // XXX 7262 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7263 opcode(0x0F, 0x40); 7264 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7265 ins_pipe(pipe_cmov_reg); // XXX 7266 %} 7267 7268 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7269 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7270 ins_cost(200); 7271 expand %{ 7272 cmovP_regU(cop, cr, dst, src); 7273 %} 7274 %} 7275 7276 // DISABLED: Requires the ADLC to emit a bottom_type call that 7277 // correctly meets the two pointer arguments; one is an incoming 7278 // register but the other is a memory operand. ALSO appears to 7279 // be buggy with implicit null checks. 7280 // 7281 //// Conditional move 7282 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7283 //%{ 7284 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7285 // ins_cost(250); 7286 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7287 // opcode(0x0F,0x40); 7288 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7289 // ins_pipe( pipe_cmov_mem ); 7290 //%} 7291 // 7292 //// Conditional move 7293 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7294 //%{ 7295 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7296 // ins_cost(250); 7297 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7298 // opcode(0x0F,0x40); 7299 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7300 // ins_pipe( pipe_cmov_mem ); 7301 //%} 7302 7303 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7304 %{ 7305 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7306 7307 ins_cost(200); // XXX 7308 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7309 opcode(0x0F, 0x40); 7310 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7311 ins_pipe(pipe_cmov_reg); // XXX 7312 %} 7313 7314 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7315 %{ 7316 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7317 7318 ins_cost(200); // XXX 7319 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7320 opcode(0x0F, 0x40); 7321 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7322 ins_pipe(pipe_cmov_mem); // XXX 7323 %} 7324 7325 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7326 %{ 7327 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7328 7329 ins_cost(200); // XXX 7330 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7331 opcode(0x0F, 0x40); 7332 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7333 ins_pipe(pipe_cmov_reg); // XXX 7334 %} 7335 7336 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7337 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7338 ins_cost(200); 7339 expand %{ 7340 cmovL_regU(cop, cr, dst, src); 7341 %} 7342 %} 7343 7344 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7345 %{ 7346 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7347 7348 ins_cost(200); // XXX 7349 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7350 opcode(0x0F, 0x40); 7351 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7352 ins_pipe(pipe_cmov_mem); // XXX 7353 %} 7354 7355 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7356 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7357 ins_cost(200); 7358 expand %{ 7359 cmovL_memU(cop, cr, dst, src); 7360 %} 7361 %} 7362 7363 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7364 %{ 7365 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7366 7367 ins_cost(200); // XXX 7368 format %{ "jn$cop skip\t# signed cmove float\n\t" 7369 "movss $dst, $src\n" 7370 "skip:" %} 7371 ins_encode %{ 7372 Label Lskip; 7373 // Invert sense of branch from sense of CMOV 7374 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7375 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7376 __ bind(Lskip); 7377 %} 7378 ins_pipe(pipe_slow); 7379 %} 7380 7381 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7382 // %{ 7383 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7384 7385 // ins_cost(200); // XXX 7386 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7387 // "movss $dst, $src\n" 7388 // "skip:" %} 7389 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7390 // ins_pipe(pipe_slow); 7391 // %} 7392 7393 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7394 %{ 7395 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7396 7397 ins_cost(200); // XXX 7398 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7399 "movss $dst, $src\n" 7400 "skip:" %} 7401 ins_encode %{ 7402 Label Lskip; 7403 // Invert sense of branch from sense of CMOV 7404 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7405 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7406 __ bind(Lskip); 7407 %} 7408 ins_pipe(pipe_slow); 7409 %} 7410 7411 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7412 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7413 ins_cost(200); 7414 expand %{ 7415 cmovF_regU(cop, cr, dst, src); 7416 %} 7417 %} 7418 7419 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7420 %{ 7421 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7422 7423 ins_cost(200); // XXX 7424 format %{ "jn$cop skip\t# signed cmove double\n\t" 7425 "movsd $dst, $src\n" 7426 "skip:" %} 7427 ins_encode %{ 7428 Label Lskip; 7429 // Invert sense of branch from sense of CMOV 7430 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7431 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7432 __ bind(Lskip); 7433 %} 7434 ins_pipe(pipe_slow); 7435 %} 7436 7437 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7438 %{ 7439 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7440 7441 ins_cost(200); // XXX 7442 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7443 "movsd $dst, $src\n" 7444 "skip:" %} 7445 ins_encode %{ 7446 Label Lskip; 7447 // Invert sense of branch from sense of CMOV 7448 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7449 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7450 __ bind(Lskip); 7451 %} 7452 ins_pipe(pipe_slow); 7453 %} 7454 7455 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7456 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7457 ins_cost(200); 7458 expand %{ 7459 cmovD_regU(cop, cr, dst, src); 7460 %} 7461 %} 7462 7463 //----------Arithmetic Instructions-------------------------------------------- 7464 //----------Addition Instructions---------------------------------------------- 7465 7466 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7467 %{ 7468 match(Set dst (AddI dst src)); 7469 effect(KILL cr); 7470 7471 format %{ "addl $dst, $src\t# int" %} 7472 opcode(0x03); 7473 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7474 ins_pipe(ialu_reg_reg); 7475 %} 7476 7477 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7478 %{ 7479 match(Set dst (AddI dst src)); 7480 effect(KILL cr); 7481 7482 format %{ "addl $dst, $src\t# int" %} 7483 opcode(0x81, 0x00); /* /0 id */ 7484 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7485 ins_pipe( ialu_reg ); 7486 %} 7487 7488 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7489 %{ 7490 match(Set dst (AddI dst (LoadI src))); 7491 effect(KILL cr); 7492 7493 ins_cost(125); // XXX 7494 format %{ "addl $dst, $src\t# int" %} 7495 opcode(0x03); 7496 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7497 ins_pipe(ialu_reg_mem); 7498 %} 7499 7500 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7501 %{ 7502 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7503 effect(KILL cr); 7504 7505 ins_cost(150); // XXX 7506 format %{ "addl $dst, $src\t# int" %} 7507 opcode(0x01); /* Opcode 01 /r */ 7508 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7509 ins_pipe(ialu_mem_reg); 7510 %} 7511 7512 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7513 %{ 7514 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7515 effect(KILL cr); 7516 7517 ins_cost(125); // XXX 7518 format %{ "addl $dst, $src\t# int" %} 7519 opcode(0x81); /* Opcode 81 /0 id */ 7520 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7521 ins_pipe(ialu_mem_imm); 7522 %} 7523 7524 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7525 %{ 7526 predicate(UseIncDec); 7527 match(Set dst (AddI dst src)); 7528 effect(KILL cr); 7529 7530 format %{ "incl $dst\t# int" %} 7531 opcode(0xFF, 0x00); // FF /0 7532 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7533 ins_pipe(ialu_reg); 7534 %} 7535 7536 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7537 %{ 7538 predicate(UseIncDec); 7539 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7540 effect(KILL cr); 7541 7542 ins_cost(125); // XXX 7543 format %{ "incl $dst\t# int" %} 7544 opcode(0xFF); /* Opcode FF /0 */ 7545 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7546 ins_pipe(ialu_mem_imm); 7547 %} 7548 7549 // XXX why does that use AddI 7550 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7551 %{ 7552 predicate(UseIncDec); 7553 match(Set dst (AddI dst src)); 7554 effect(KILL cr); 7555 7556 format %{ "decl $dst\t# int" %} 7557 opcode(0xFF, 0x01); // FF /1 7558 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7559 ins_pipe(ialu_reg); 7560 %} 7561 7562 // XXX why does that use AddI 7563 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7564 %{ 7565 predicate(UseIncDec); 7566 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7567 effect(KILL cr); 7568 7569 ins_cost(125); // XXX 7570 format %{ "decl $dst\t# int" %} 7571 opcode(0xFF); /* Opcode FF /1 */ 7572 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7573 ins_pipe(ialu_mem_imm); 7574 %} 7575 7576 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7577 %{ 7578 match(Set dst (AddI src0 src1)); 7579 7580 ins_cost(110); 7581 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7582 opcode(0x8D); /* 0x8D /r */ 7583 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7584 ins_pipe(ialu_reg_reg); 7585 %} 7586 7587 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7588 %{ 7589 match(Set dst (AddL dst src)); 7590 effect(KILL cr); 7591 7592 format %{ "addq $dst, $src\t# long" %} 7593 opcode(0x03); 7594 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7595 ins_pipe(ialu_reg_reg); 7596 %} 7597 7598 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7599 %{ 7600 match(Set dst (AddL dst src)); 7601 effect(KILL cr); 7602 7603 format %{ "addq $dst, $src\t# long" %} 7604 opcode(0x81, 0x00); /* /0 id */ 7605 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7606 ins_pipe( ialu_reg ); 7607 %} 7608 7609 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7610 %{ 7611 match(Set dst (AddL dst (LoadL src))); 7612 effect(KILL cr); 7613 7614 ins_cost(125); // XXX 7615 format %{ "addq $dst, $src\t# long" %} 7616 opcode(0x03); 7617 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7618 ins_pipe(ialu_reg_mem); 7619 %} 7620 7621 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7622 %{ 7623 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7624 effect(KILL cr); 7625 7626 ins_cost(150); // XXX 7627 format %{ "addq $dst, $src\t# long" %} 7628 opcode(0x01); /* Opcode 01 /r */ 7629 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7630 ins_pipe(ialu_mem_reg); 7631 %} 7632 7633 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7634 %{ 7635 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7636 effect(KILL cr); 7637 7638 ins_cost(125); // XXX 7639 format %{ "addq $dst, $src\t# long" %} 7640 opcode(0x81); /* Opcode 81 /0 id */ 7641 ins_encode(REX_mem_wide(dst), 7642 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7643 ins_pipe(ialu_mem_imm); 7644 %} 7645 7646 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7647 %{ 7648 predicate(UseIncDec); 7649 match(Set dst (AddL dst src)); 7650 effect(KILL cr); 7651 7652 format %{ "incq $dst\t# long" %} 7653 opcode(0xFF, 0x00); // FF /0 7654 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7655 ins_pipe(ialu_reg); 7656 %} 7657 7658 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7659 %{ 7660 predicate(UseIncDec); 7661 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7662 effect(KILL cr); 7663 7664 ins_cost(125); // XXX 7665 format %{ "incq $dst\t# long" %} 7666 opcode(0xFF); /* Opcode FF /0 */ 7667 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7668 ins_pipe(ialu_mem_imm); 7669 %} 7670 7671 // XXX why does that use AddL 7672 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7673 %{ 7674 predicate(UseIncDec); 7675 match(Set dst (AddL dst src)); 7676 effect(KILL cr); 7677 7678 format %{ "decq $dst\t# long" %} 7679 opcode(0xFF, 0x01); // FF /1 7680 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7681 ins_pipe(ialu_reg); 7682 %} 7683 7684 // XXX why does that use AddL 7685 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7686 %{ 7687 predicate(UseIncDec); 7688 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7689 effect(KILL cr); 7690 7691 ins_cost(125); // XXX 7692 format %{ "decq $dst\t# long" %} 7693 opcode(0xFF); /* Opcode FF /1 */ 7694 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7695 ins_pipe(ialu_mem_imm); 7696 %} 7697 7698 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7699 %{ 7700 match(Set dst (AddL src0 src1)); 7701 7702 ins_cost(110); 7703 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7704 opcode(0x8D); /* 0x8D /r */ 7705 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7706 ins_pipe(ialu_reg_reg); 7707 %} 7708 7709 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7710 %{ 7711 match(Set dst (AddP dst src)); 7712 effect(KILL cr); 7713 7714 format %{ "addq $dst, $src\t# ptr" %} 7715 opcode(0x03); 7716 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7717 ins_pipe(ialu_reg_reg); 7718 %} 7719 7720 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7721 %{ 7722 match(Set dst (AddP dst src)); 7723 effect(KILL cr); 7724 7725 format %{ "addq $dst, $src\t# ptr" %} 7726 opcode(0x81, 0x00); /* /0 id */ 7727 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7728 ins_pipe( ialu_reg ); 7729 %} 7730 7731 // XXX addP mem ops ???? 7732 7733 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7734 %{ 7735 match(Set dst (AddP src0 src1)); 7736 7737 ins_cost(110); 7738 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7739 opcode(0x8D); /* 0x8D /r */ 7740 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7741 ins_pipe(ialu_reg_reg); 7742 %} 7743 7744 instruct checkCastPP(rRegP dst) 7745 %{ 7746 match(Set dst (CheckCastPP dst)); 7747 7748 size(0); 7749 format %{ "# checkcastPP of $dst" %} 7750 ins_encode(/* empty encoding */); 7751 ins_pipe(empty); 7752 %} 7753 7754 instruct castPP(rRegP dst) 7755 %{ 7756 match(Set dst (CastPP dst)); 7757 7758 size(0); 7759 format %{ "# castPP of $dst" %} 7760 ins_encode(/* empty encoding */); 7761 ins_pipe(empty); 7762 %} 7763 7764 instruct castII(rRegI dst) 7765 %{ 7766 match(Set dst (CastII dst)); 7767 7768 size(0); 7769 format %{ "# castII of $dst" %} 7770 ins_encode(/* empty encoding */); 7771 ins_cost(0); 7772 ins_pipe(empty); 7773 %} 7774 7775 // LoadP-locked same as a regular LoadP when used with compare-swap 7776 instruct loadPLocked(rRegP dst, memory mem) 7777 %{ 7778 match(Set dst (LoadPLocked mem)); 7779 7780 ins_cost(125); // XXX 7781 format %{ "movq $dst, $mem\t# ptr locked" %} 7782 opcode(0x8B); 7783 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7784 ins_pipe(ialu_reg_mem); // XXX 7785 %} 7786 7787 // Conditional-store of the updated heap-top. 7788 // Used during allocation of the shared heap. 7789 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7790 7791 instruct storePConditional(memory heap_top_ptr, 7792 rax_RegP oldval, rRegP newval, 7793 rFlagsReg cr) 7794 %{ 7795 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7796 7797 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7798 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7799 opcode(0x0F, 0xB1); 7800 ins_encode(lock_prefix, 7801 REX_reg_mem_wide(newval, heap_top_ptr), 7802 OpcP, OpcS, 7803 reg_mem(newval, heap_top_ptr)); 7804 ins_pipe(pipe_cmpxchg); 7805 %} 7806 7807 // Conditional-store of an int value. 7808 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7809 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7810 %{ 7811 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7812 effect(KILL oldval); 7813 7814 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7815 opcode(0x0F, 0xB1); 7816 ins_encode(lock_prefix, 7817 REX_reg_mem(newval, mem), 7818 OpcP, OpcS, 7819 reg_mem(newval, mem)); 7820 ins_pipe(pipe_cmpxchg); 7821 %} 7822 7823 // Conditional-store of a long value. 7824 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7825 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7826 %{ 7827 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7828 effect(KILL oldval); 7829 7830 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7831 opcode(0x0F, 0xB1); 7832 ins_encode(lock_prefix, 7833 REX_reg_mem_wide(newval, mem), 7834 OpcP, OpcS, 7835 reg_mem(newval, mem)); 7836 ins_pipe(pipe_cmpxchg); 7837 %} 7838 7839 7840 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7841 instruct compareAndSwapP(rRegI res, 7842 memory mem_ptr, 7843 rax_RegP oldval, rRegP newval, 7844 rFlagsReg cr) 7845 %{ 7846 predicate(VM_Version::supports_cx8()); 7847 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7848 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7849 effect(KILL cr, KILL oldval); 7850 7851 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7852 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7853 "sete $res\n\t" 7854 "movzbl $res, $res" %} 7855 opcode(0x0F, 0xB1); 7856 ins_encode(lock_prefix, 7857 REX_reg_mem_wide(newval, mem_ptr), 7858 OpcP, OpcS, 7859 reg_mem(newval, mem_ptr), 7860 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7861 REX_reg_breg(res, res), // movzbl 7862 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7863 ins_pipe( pipe_cmpxchg ); 7864 %} 7865 7866 instruct compareAndSwapL(rRegI res, 7867 memory mem_ptr, 7868 rax_RegL oldval, rRegL newval, 7869 rFlagsReg cr) 7870 %{ 7871 predicate(VM_Version::supports_cx8()); 7872 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7873 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7874 effect(KILL cr, KILL oldval); 7875 7876 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7877 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7878 "sete $res\n\t" 7879 "movzbl $res, $res" %} 7880 opcode(0x0F, 0xB1); 7881 ins_encode(lock_prefix, 7882 REX_reg_mem_wide(newval, mem_ptr), 7883 OpcP, OpcS, 7884 reg_mem(newval, mem_ptr), 7885 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7886 REX_reg_breg(res, res), // movzbl 7887 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7888 ins_pipe( pipe_cmpxchg ); 7889 %} 7890 7891 instruct compareAndSwapI(rRegI res, 7892 memory mem_ptr, 7893 rax_RegI oldval, rRegI newval, 7894 rFlagsReg cr) 7895 %{ 7896 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7897 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7898 effect(KILL cr, KILL oldval); 7899 7900 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7901 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7902 "sete $res\n\t" 7903 "movzbl $res, $res" %} 7904 opcode(0x0F, 0xB1); 7905 ins_encode(lock_prefix, 7906 REX_reg_mem(newval, mem_ptr), 7907 OpcP, OpcS, 7908 reg_mem(newval, mem_ptr), 7909 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7910 REX_reg_breg(res, res), // movzbl 7911 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7912 ins_pipe( pipe_cmpxchg ); 7913 %} 7914 7915 instruct compareAndSwapB(rRegI res, 7916 memory mem_ptr, 7917 rax_RegI oldval, rRegI newval, 7918 rFlagsReg cr) 7919 %{ 7920 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7921 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7922 effect(KILL cr, KILL oldval); 7923 7924 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7925 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7926 "sete $res\n\t" 7927 "movzbl $res, $res" %} 7928 opcode(0x0F, 0xB0); 7929 ins_encode(lock_prefix, 7930 REX_breg_mem(newval, mem_ptr), 7931 OpcP, OpcS, 7932 reg_mem(newval, mem_ptr), 7933 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7934 REX_reg_breg(res, res), // movzbl 7935 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7936 ins_pipe( pipe_cmpxchg ); 7937 %} 7938 7939 instruct compareAndSwapS(rRegI res, 7940 memory mem_ptr, 7941 rax_RegI oldval, rRegI newval, 7942 rFlagsReg cr) 7943 %{ 7944 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7945 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7946 effect(KILL cr, KILL oldval); 7947 7948 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7949 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7950 "sete $res\n\t" 7951 "movzbl $res, $res" %} 7952 opcode(0x0F, 0xB1); 7953 ins_encode(lock_prefix, 7954 SizePrefix, 7955 REX_reg_mem(newval, mem_ptr), 7956 OpcP, OpcS, 7957 reg_mem(newval, mem_ptr), 7958 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7959 REX_reg_breg(res, res), // movzbl 7960 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7961 ins_pipe( pipe_cmpxchg ); 7962 %} 7963 7964 instruct compareAndSwapN(rRegI res, 7965 memory mem_ptr, 7966 rax_RegN oldval, rRegN newval, 7967 rFlagsReg cr) %{ 7968 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7969 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7970 effect(KILL cr, KILL oldval); 7971 7972 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7973 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7974 "sete $res\n\t" 7975 "movzbl $res, $res" %} 7976 opcode(0x0F, 0xB1); 7977 ins_encode(lock_prefix, 7978 REX_reg_mem(newval, mem_ptr), 7979 OpcP, OpcS, 7980 reg_mem(newval, mem_ptr), 7981 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7982 REX_reg_breg(res, res), // movzbl 7983 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7984 ins_pipe( pipe_cmpxchg ); 7985 %} 7986 7987 instruct compareAndExchangeB( 7988 memory mem_ptr, 7989 rax_RegI oldval, rRegI newval, 7990 rFlagsReg cr) 7991 %{ 7992 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7993 effect(KILL cr); 7994 7995 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7996 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7997 opcode(0x0F, 0xB0); 7998 ins_encode(lock_prefix, 7999 REX_breg_mem(newval, mem_ptr), 8000 OpcP, OpcS, 8001 reg_mem(newval, mem_ptr) // lock cmpxchg 8002 ); 8003 ins_pipe( pipe_cmpxchg ); 8004 %} 8005 8006 instruct compareAndExchangeS( 8007 memory mem_ptr, 8008 rax_RegI oldval, rRegI newval, 8009 rFlagsReg cr) 8010 %{ 8011 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 8012 effect(KILL cr); 8013 8014 format %{ "cmpxchgw $mem_ptr,$newval\t# " 8015 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8016 opcode(0x0F, 0xB1); 8017 ins_encode(lock_prefix, 8018 SizePrefix, 8019 REX_reg_mem(newval, mem_ptr), 8020 OpcP, OpcS, 8021 reg_mem(newval, mem_ptr) // lock cmpxchg 8022 ); 8023 ins_pipe( pipe_cmpxchg ); 8024 %} 8025 8026 instruct compareAndExchangeI( 8027 memory mem_ptr, 8028 rax_RegI oldval, rRegI newval, 8029 rFlagsReg cr) 8030 %{ 8031 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 8032 effect(KILL cr); 8033 8034 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8035 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8036 opcode(0x0F, 0xB1); 8037 ins_encode(lock_prefix, 8038 REX_reg_mem(newval, mem_ptr), 8039 OpcP, OpcS, 8040 reg_mem(newval, mem_ptr) // lock cmpxchg 8041 ); 8042 ins_pipe( pipe_cmpxchg ); 8043 %} 8044 8045 instruct compareAndExchangeL( 8046 memory mem_ptr, 8047 rax_RegL oldval, rRegL newval, 8048 rFlagsReg cr) 8049 %{ 8050 predicate(VM_Version::supports_cx8()); 8051 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 8052 effect(KILL cr); 8053 8054 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8055 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8056 opcode(0x0F, 0xB1); 8057 ins_encode(lock_prefix, 8058 REX_reg_mem_wide(newval, mem_ptr), 8059 OpcP, OpcS, 8060 reg_mem(newval, mem_ptr) // lock cmpxchg 8061 ); 8062 ins_pipe( pipe_cmpxchg ); 8063 %} 8064 8065 instruct compareAndExchangeN( 8066 memory mem_ptr, 8067 rax_RegN oldval, rRegN newval, 8068 rFlagsReg cr) %{ 8069 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 8070 effect(KILL cr); 8071 8072 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8073 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8074 opcode(0x0F, 0xB1); 8075 ins_encode(lock_prefix, 8076 REX_reg_mem(newval, mem_ptr), 8077 OpcP, OpcS, 8078 reg_mem(newval, mem_ptr) // lock cmpxchg 8079 ); 8080 ins_pipe( pipe_cmpxchg ); 8081 %} 8082 8083 instruct compareAndExchangeP( 8084 memory mem_ptr, 8085 rax_RegP oldval, rRegP newval, 8086 rFlagsReg cr) 8087 %{ 8088 predicate(VM_Version::supports_cx8()); 8089 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 8090 effect(KILL cr); 8091 8092 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8093 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8094 opcode(0x0F, 0xB1); 8095 ins_encode(lock_prefix, 8096 REX_reg_mem_wide(newval, mem_ptr), 8097 OpcP, OpcS, 8098 reg_mem(newval, mem_ptr) // lock cmpxchg 8099 ); 8100 ins_pipe( pipe_cmpxchg ); 8101 %} 8102 8103 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8104 predicate(n->as_LoadStore()->result_not_used()); 8105 match(Set dummy (GetAndAddB mem add)); 8106 effect(KILL cr); 8107 format %{ "ADDB [$mem],$add" %} 8108 ins_encode %{ 8109 __ lock(); 8110 __ addb($mem$$Address, $add$$constant); 8111 %} 8112 ins_pipe( pipe_cmpxchg ); 8113 %} 8114 8115 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 8116 match(Set newval (GetAndAddB mem newval)); 8117 effect(KILL cr); 8118 format %{ "XADDB [$mem],$newval" %} 8119 ins_encode %{ 8120 __ lock(); 8121 __ xaddb($mem$$Address, $newval$$Register); 8122 %} 8123 ins_pipe( pipe_cmpxchg ); 8124 %} 8125 8126 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8127 predicate(n->as_LoadStore()->result_not_used()); 8128 match(Set dummy (GetAndAddS mem add)); 8129 effect(KILL cr); 8130 format %{ "ADDW [$mem],$add" %} 8131 ins_encode %{ 8132 __ lock(); 8133 __ addw($mem$$Address, $add$$constant); 8134 %} 8135 ins_pipe( pipe_cmpxchg ); 8136 %} 8137 8138 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 8139 match(Set newval (GetAndAddS mem newval)); 8140 effect(KILL cr); 8141 format %{ "XADDW [$mem],$newval" %} 8142 ins_encode %{ 8143 __ lock(); 8144 __ xaddw($mem$$Address, $newval$$Register); 8145 %} 8146 ins_pipe( pipe_cmpxchg ); 8147 %} 8148 8149 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8150 predicate(n->as_LoadStore()->result_not_used()); 8151 match(Set dummy (GetAndAddI mem add)); 8152 effect(KILL cr); 8153 format %{ "ADDL [$mem],$add" %} 8154 ins_encode %{ 8155 __ lock(); 8156 __ addl($mem$$Address, $add$$constant); 8157 %} 8158 ins_pipe( pipe_cmpxchg ); 8159 %} 8160 8161 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 8162 match(Set newval (GetAndAddI mem newval)); 8163 effect(KILL cr); 8164 format %{ "XADDL [$mem],$newval" %} 8165 ins_encode %{ 8166 __ lock(); 8167 __ xaddl($mem$$Address, $newval$$Register); 8168 %} 8169 ins_pipe( pipe_cmpxchg ); 8170 %} 8171 8172 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8173 predicate(n->as_LoadStore()->result_not_used()); 8174 match(Set dummy (GetAndAddL mem add)); 8175 effect(KILL cr); 8176 format %{ "ADDQ [$mem],$add" %} 8177 ins_encode %{ 8178 __ lock(); 8179 __ addq($mem$$Address, $add$$constant); 8180 %} 8181 ins_pipe( pipe_cmpxchg ); 8182 %} 8183 8184 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 8185 match(Set newval (GetAndAddL mem newval)); 8186 effect(KILL cr); 8187 format %{ "XADDQ [$mem],$newval" %} 8188 ins_encode %{ 8189 __ lock(); 8190 __ xaddq($mem$$Address, $newval$$Register); 8191 %} 8192 ins_pipe( pipe_cmpxchg ); 8193 %} 8194 8195 instruct xchgB( memory mem, rRegI newval) %{ 8196 match(Set newval (GetAndSetB mem newval)); 8197 format %{ "XCHGB $newval,[$mem]" %} 8198 ins_encode %{ 8199 __ xchgb($newval$$Register, $mem$$Address); 8200 %} 8201 ins_pipe( pipe_cmpxchg ); 8202 %} 8203 8204 instruct xchgS( memory mem, rRegI newval) %{ 8205 match(Set newval (GetAndSetS mem newval)); 8206 format %{ "XCHGW $newval,[$mem]" %} 8207 ins_encode %{ 8208 __ xchgw($newval$$Register, $mem$$Address); 8209 %} 8210 ins_pipe( pipe_cmpxchg ); 8211 %} 8212 8213 instruct xchgI( memory mem, rRegI newval) %{ 8214 match(Set newval (GetAndSetI mem newval)); 8215 format %{ "XCHGL $newval,[$mem]" %} 8216 ins_encode %{ 8217 __ xchgl($newval$$Register, $mem$$Address); 8218 %} 8219 ins_pipe( pipe_cmpxchg ); 8220 %} 8221 8222 instruct xchgL( memory mem, rRegL newval) %{ 8223 match(Set newval (GetAndSetL mem newval)); 8224 format %{ "XCHGL $newval,[$mem]" %} 8225 ins_encode %{ 8226 __ xchgq($newval$$Register, $mem$$Address); 8227 %} 8228 ins_pipe( pipe_cmpxchg ); 8229 %} 8230 8231 instruct xchgP( memory mem, rRegP newval) %{ 8232 match(Set newval (GetAndSetP mem newval)); 8233 format %{ "XCHGQ $newval,[$mem]" %} 8234 ins_encode %{ 8235 __ xchgq($newval$$Register, $mem$$Address); 8236 %} 8237 ins_pipe( pipe_cmpxchg ); 8238 %} 8239 8240 instruct xchgN( memory mem, rRegN newval) %{ 8241 match(Set newval (GetAndSetN mem newval)); 8242 format %{ "XCHGL $newval,$mem]" %} 8243 ins_encode %{ 8244 __ xchgl($newval$$Register, $mem$$Address); 8245 %} 8246 ins_pipe( pipe_cmpxchg ); 8247 %} 8248 8249 //----------Abs Instructions------------------------------------------- 8250 8251 // Integer Absolute Instructions 8252 instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr) 8253 %{ 8254 match(Set dst (AbsI src)); 8255 effect(TEMP dst, TEMP tmp, KILL cr); 8256 format %{ "movl $tmp, $src\n\t" 8257 "sarl $tmp, 31\n\t" 8258 "movl $dst, $src\n\t" 8259 "xorl $dst, $tmp\n\t" 8260 "subl $dst, $tmp\n" 8261 %} 8262 ins_encode %{ 8263 __ movl($tmp$$Register, $src$$Register); 8264 __ sarl($tmp$$Register, 31); 8265 __ movl($dst$$Register, $src$$Register); 8266 __ xorl($dst$$Register, $tmp$$Register); 8267 __ subl($dst$$Register, $tmp$$Register); 8268 %} 8269 8270 ins_pipe(ialu_reg_reg); 8271 %} 8272 8273 // Long Absolute Instructions 8274 instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr) 8275 %{ 8276 match(Set dst (AbsL src)); 8277 effect(TEMP dst, TEMP tmp, KILL cr); 8278 format %{ "movq $tmp, $src\n\t" 8279 "sarq $tmp, 63\n\t" 8280 "movq $dst, $src\n\t" 8281 "xorq $dst, $tmp\n\t" 8282 "subq $dst, $tmp\n" 8283 %} 8284 ins_encode %{ 8285 __ movq($tmp$$Register, $src$$Register); 8286 __ sarq($tmp$$Register, 63); 8287 __ movq($dst$$Register, $src$$Register); 8288 __ xorq($dst$$Register, $tmp$$Register); 8289 __ subq($dst$$Register, $tmp$$Register); 8290 %} 8291 8292 ins_pipe(ialu_reg_reg); 8293 %} 8294 8295 //----------Subtraction Instructions------------------------------------------- 8296 8297 // Integer Subtraction Instructions 8298 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8299 %{ 8300 match(Set dst (SubI dst src)); 8301 effect(KILL cr); 8302 8303 format %{ "subl $dst, $src\t# int" %} 8304 opcode(0x2B); 8305 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8306 ins_pipe(ialu_reg_reg); 8307 %} 8308 8309 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8310 %{ 8311 match(Set dst (SubI dst src)); 8312 effect(KILL cr); 8313 8314 format %{ "subl $dst, $src\t# int" %} 8315 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8316 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8317 ins_pipe(ialu_reg); 8318 %} 8319 8320 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8321 %{ 8322 match(Set dst (SubI dst (LoadI src))); 8323 effect(KILL cr); 8324 8325 ins_cost(125); 8326 format %{ "subl $dst, $src\t# int" %} 8327 opcode(0x2B); 8328 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8329 ins_pipe(ialu_reg_mem); 8330 %} 8331 8332 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8333 %{ 8334 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8335 effect(KILL cr); 8336 8337 ins_cost(150); 8338 format %{ "subl $dst, $src\t# int" %} 8339 opcode(0x29); /* Opcode 29 /r */ 8340 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8341 ins_pipe(ialu_mem_reg); 8342 %} 8343 8344 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8345 %{ 8346 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8347 effect(KILL cr); 8348 8349 ins_cost(125); // XXX 8350 format %{ "subl $dst, $src\t# int" %} 8351 opcode(0x81); /* Opcode 81 /5 id */ 8352 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8353 ins_pipe(ialu_mem_imm); 8354 %} 8355 8356 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8357 %{ 8358 match(Set dst (SubL dst src)); 8359 effect(KILL cr); 8360 8361 format %{ "subq $dst, $src\t# long" %} 8362 opcode(0x2B); 8363 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8364 ins_pipe(ialu_reg_reg); 8365 %} 8366 8367 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8368 %{ 8369 match(Set dst (SubL dst src)); 8370 effect(KILL cr); 8371 8372 format %{ "subq $dst, $src\t# long" %} 8373 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8374 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8375 ins_pipe(ialu_reg); 8376 %} 8377 8378 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8379 %{ 8380 match(Set dst (SubL dst (LoadL src))); 8381 effect(KILL cr); 8382 8383 ins_cost(125); 8384 format %{ "subq $dst, $src\t# long" %} 8385 opcode(0x2B); 8386 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8387 ins_pipe(ialu_reg_mem); 8388 %} 8389 8390 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8391 %{ 8392 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8393 effect(KILL cr); 8394 8395 ins_cost(150); 8396 format %{ "subq $dst, $src\t# long" %} 8397 opcode(0x29); /* Opcode 29 /r */ 8398 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8399 ins_pipe(ialu_mem_reg); 8400 %} 8401 8402 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8403 %{ 8404 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8405 effect(KILL cr); 8406 8407 ins_cost(125); // XXX 8408 format %{ "subq $dst, $src\t# long" %} 8409 opcode(0x81); /* Opcode 81 /5 id */ 8410 ins_encode(REX_mem_wide(dst), 8411 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8412 ins_pipe(ialu_mem_imm); 8413 %} 8414 8415 // Subtract from a pointer 8416 // XXX hmpf??? 8417 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8418 %{ 8419 match(Set dst (AddP dst (SubI zero src))); 8420 effect(KILL cr); 8421 8422 format %{ "subq $dst, $src\t# ptr - int" %} 8423 opcode(0x2B); 8424 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8425 ins_pipe(ialu_reg_reg); 8426 %} 8427 8428 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8429 %{ 8430 match(Set dst (SubI zero dst)); 8431 effect(KILL cr); 8432 8433 format %{ "negl $dst\t# int" %} 8434 opcode(0xF7, 0x03); // Opcode F7 /3 8435 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8436 ins_pipe(ialu_reg); 8437 %} 8438 8439 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8440 %{ 8441 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8442 effect(KILL cr); 8443 8444 format %{ "negl $dst\t# int" %} 8445 opcode(0xF7, 0x03); // Opcode F7 /3 8446 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8447 ins_pipe(ialu_reg); 8448 %} 8449 8450 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8451 %{ 8452 match(Set dst (SubL zero dst)); 8453 effect(KILL cr); 8454 8455 format %{ "negq $dst\t# long" %} 8456 opcode(0xF7, 0x03); // Opcode F7 /3 8457 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8458 ins_pipe(ialu_reg); 8459 %} 8460 8461 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8462 %{ 8463 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8464 effect(KILL cr); 8465 8466 format %{ "negq $dst\t# long" %} 8467 opcode(0xF7, 0x03); // Opcode F7 /3 8468 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8469 ins_pipe(ialu_reg); 8470 %} 8471 8472 //----------Multiplication/Division Instructions------------------------------- 8473 // Integer Multiplication Instructions 8474 // Multiply Register 8475 8476 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8477 %{ 8478 match(Set dst (MulI dst src)); 8479 effect(KILL cr); 8480 8481 ins_cost(300); 8482 format %{ "imull $dst, $src\t# int" %} 8483 opcode(0x0F, 0xAF); 8484 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8485 ins_pipe(ialu_reg_reg_alu0); 8486 %} 8487 8488 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8489 %{ 8490 match(Set dst (MulI src imm)); 8491 effect(KILL cr); 8492 8493 ins_cost(300); 8494 format %{ "imull $dst, $src, $imm\t# int" %} 8495 opcode(0x69); /* 69 /r id */ 8496 ins_encode(REX_reg_reg(dst, src), 8497 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8498 ins_pipe(ialu_reg_reg_alu0); 8499 %} 8500 8501 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8502 %{ 8503 match(Set dst (MulI dst (LoadI src))); 8504 effect(KILL cr); 8505 8506 ins_cost(350); 8507 format %{ "imull $dst, $src\t# int" %} 8508 opcode(0x0F, 0xAF); 8509 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8510 ins_pipe(ialu_reg_mem_alu0); 8511 %} 8512 8513 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8514 %{ 8515 match(Set dst (MulI (LoadI src) imm)); 8516 effect(KILL cr); 8517 8518 ins_cost(300); 8519 format %{ "imull $dst, $src, $imm\t# int" %} 8520 opcode(0x69); /* 69 /r id */ 8521 ins_encode(REX_reg_mem(dst, src), 8522 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8523 ins_pipe(ialu_reg_mem_alu0); 8524 %} 8525 8526 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8527 %{ 8528 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8529 effect(KILL cr, KILL src2); 8530 8531 expand %{ mulI_rReg(dst, src1, cr); 8532 mulI_rReg(src2, src3, cr); 8533 addI_rReg(dst, src2, cr); %} 8534 %} 8535 8536 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8537 %{ 8538 match(Set dst (MulL dst src)); 8539 effect(KILL cr); 8540 8541 ins_cost(300); 8542 format %{ "imulq $dst, $src\t# long" %} 8543 opcode(0x0F, 0xAF); 8544 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8545 ins_pipe(ialu_reg_reg_alu0); 8546 %} 8547 8548 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8549 %{ 8550 match(Set dst (MulL src imm)); 8551 effect(KILL cr); 8552 8553 ins_cost(300); 8554 format %{ "imulq $dst, $src, $imm\t# long" %} 8555 opcode(0x69); /* 69 /r id */ 8556 ins_encode(REX_reg_reg_wide(dst, src), 8557 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8558 ins_pipe(ialu_reg_reg_alu0); 8559 %} 8560 8561 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8562 %{ 8563 match(Set dst (MulL dst (LoadL src))); 8564 effect(KILL cr); 8565 8566 ins_cost(350); 8567 format %{ "imulq $dst, $src\t# long" %} 8568 opcode(0x0F, 0xAF); 8569 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8570 ins_pipe(ialu_reg_mem_alu0); 8571 %} 8572 8573 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8574 %{ 8575 match(Set dst (MulL (LoadL src) imm)); 8576 effect(KILL cr); 8577 8578 ins_cost(300); 8579 format %{ "imulq $dst, $src, $imm\t# long" %} 8580 opcode(0x69); /* 69 /r id */ 8581 ins_encode(REX_reg_mem_wide(dst, src), 8582 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8583 ins_pipe(ialu_reg_mem_alu0); 8584 %} 8585 8586 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8587 %{ 8588 match(Set dst (MulHiL src rax)); 8589 effect(USE_KILL rax, KILL cr); 8590 8591 ins_cost(300); 8592 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8593 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8594 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8595 ins_pipe(ialu_reg_reg_alu0); 8596 %} 8597 8598 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8599 rFlagsReg cr) 8600 %{ 8601 match(Set rax (DivI rax div)); 8602 effect(KILL rdx, KILL cr); 8603 8604 ins_cost(30*100+10*100); // XXX 8605 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8606 "jne,s normal\n\t" 8607 "xorl rdx, rdx\n\t" 8608 "cmpl $div, -1\n\t" 8609 "je,s done\n" 8610 "normal: cdql\n\t" 8611 "idivl $div\n" 8612 "done:" %} 8613 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8614 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8615 ins_pipe(ialu_reg_reg_alu0); 8616 %} 8617 8618 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8619 rFlagsReg cr) 8620 %{ 8621 match(Set rax (DivL rax div)); 8622 effect(KILL rdx, KILL cr); 8623 8624 ins_cost(30*100+10*100); // XXX 8625 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8626 "cmpq rax, rdx\n\t" 8627 "jne,s normal\n\t" 8628 "xorl rdx, rdx\n\t" 8629 "cmpq $div, -1\n\t" 8630 "je,s done\n" 8631 "normal: cdqq\n\t" 8632 "idivq $div\n" 8633 "done:" %} 8634 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8635 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8636 ins_pipe(ialu_reg_reg_alu0); 8637 %} 8638 8639 // Integer DIVMOD with Register, both quotient and mod results 8640 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8641 rFlagsReg cr) 8642 %{ 8643 match(DivModI rax div); 8644 effect(KILL cr); 8645 8646 ins_cost(30*100+10*100); // XXX 8647 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8648 "jne,s normal\n\t" 8649 "xorl rdx, rdx\n\t" 8650 "cmpl $div, -1\n\t" 8651 "je,s done\n" 8652 "normal: cdql\n\t" 8653 "idivl $div\n" 8654 "done:" %} 8655 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8656 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8657 ins_pipe(pipe_slow); 8658 %} 8659 8660 // Long DIVMOD with Register, both quotient and mod results 8661 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8662 rFlagsReg cr) 8663 %{ 8664 match(DivModL rax div); 8665 effect(KILL cr); 8666 8667 ins_cost(30*100+10*100); // XXX 8668 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8669 "cmpq rax, rdx\n\t" 8670 "jne,s normal\n\t" 8671 "xorl rdx, rdx\n\t" 8672 "cmpq $div, -1\n\t" 8673 "je,s done\n" 8674 "normal: cdqq\n\t" 8675 "idivq $div\n" 8676 "done:" %} 8677 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8678 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8679 ins_pipe(pipe_slow); 8680 %} 8681 8682 //----------- DivL-By-Constant-Expansions-------------------------------------- 8683 // DivI cases are handled by the compiler 8684 8685 // Magic constant, reciprocal of 10 8686 instruct loadConL_0x6666666666666667(rRegL dst) 8687 %{ 8688 effect(DEF dst); 8689 8690 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8691 ins_encode(load_immL(dst, 0x6666666666666667)); 8692 ins_pipe(ialu_reg); 8693 %} 8694 8695 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8696 %{ 8697 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8698 8699 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8700 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8701 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8702 ins_pipe(ialu_reg_reg_alu0); 8703 %} 8704 8705 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8706 %{ 8707 effect(USE_DEF dst, KILL cr); 8708 8709 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8710 opcode(0xC1, 0x7); /* C1 /7 ib */ 8711 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8712 ins_pipe(ialu_reg); 8713 %} 8714 8715 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8716 %{ 8717 effect(USE_DEF dst, KILL cr); 8718 8719 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8720 opcode(0xC1, 0x7); /* C1 /7 ib */ 8721 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8722 ins_pipe(ialu_reg); 8723 %} 8724 8725 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8726 %{ 8727 match(Set dst (DivL src div)); 8728 8729 ins_cost((5+8)*100); 8730 expand %{ 8731 rax_RegL rax; // Killed temp 8732 rFlagsReg cr; // Killed 8733 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8734 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8735 sarL_rReg_63(src, cr); // sarq src, 63 8736 sarL_rReg_2(dst, cr); // sarq rdx, 2 8737 subL_rReg(dst, src, cr); // subl rdx, src 8738 %} 8739 %} 8740 8741 //----------------------------------------------------------------------------- 8742 8743 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8744 rFlagsReg cr) 8745 %{ 8746 match(Set rdx (ModI rax div)); 8747 effect(KILL rax, KILL cr); 8748 8749 ins_cost(300); // XXX 8750 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8751 "jne,s normal\n\t" 8752 "xorl rdx, rdx\n\t" 8753 "cmpl $div, -1\n\t" 8754 "je,s done\n" 8755 "normal: cdql\n\t" 8756 "idivl $div\n" 8757 "done:" %} 8758 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8759 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8760 ins_pipe(ialu_reg_reg_alu0); 8761 %} 8762 8763 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8764 rFlagsReg cr) 8765 %{ 8766 match(Set rdx (ModL rax div)); 8767 effect(KILL rax, KILL cr); 8768 8769 ins_cost(300); // XXX 8770 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8771 "cmpq rax, rdx\n\t" 8772 "jne,s normal\n\t" 8773 "xorl rdx, rdx\n\t" 8774 "cmpq $div, -1\n\t" 8775 "je,s done\n" 8776 "normal: cdqq\n\t" 8777 "idivq $div\n" 8778 "done:" %} 8779 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8780 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8781 ins_pipe(ialu_reg_reg_alu0); 8782 %} 8783 8784 // Integer Shift Instructions 8785 // Shift Left by one 8786 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8787 %{ 8788 match(Set dst (LShiftI dst shift)); 8789 effect(KILL cr); 8790 8791 format %{ "sall $dst, $shift" %} 8792 opcode(0xD1, 0x4); /* D1 /4 */ 8793 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8794 ins_pipe(ialu_reg); 8795 %} 8796 8797 // Shift Left by one 8798 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8799 %{ 8800 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8801 effect(KILL cr); 8802 8803 format %{ "sall $dst, $shift\t" %} 8804 opcode(0xD1, 0x4); /* D1 /4 */ 8805 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8806 ins_pipe(ialu_mem_imm); 8807 %} 8808 8809 // Shift Left by 8-bit immediate 8810 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8811 %{ 8812 match(Set dst (LShiftI dst shift)); 8813 effect(KILL cr); 8814 8815 format %{ "sall $dst, $shift" %} 8816 opcode(0xC1, 0x4); /* C1 /4 ib */ 8817 ins_encode(reg_opc_imm(dst, shift)); 8818 ins_pipe(ialu_reg); 8819 %} 8820 8821 // Shift Left by 8-bit immediate 8822 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8823 %{ 8824 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8825 effect(KILL cr); 8826 8827 format %{ "sall $dst, $shift" %} 8828 opcode(0xC1, 0x4); /* C1 /4 ib */ 8829 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8830 ins_pipe(ialu_mem_imm); 8831 %} 8832 8833 // Shift Left by variable 8834 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8835 %{ 8836 match(Set dst (LShiftI dst shift)); 8837 effect(KILL cr); 8838 8839 format %{ "sall $dst, $shift" %} 8840 opcode(0xD3, 0x4); /* D3 /4 */ 8841 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8842 ins_pipe(ialu_reg_reg); 8843 %} 8844 8845 // Shift Left by variable 8846 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8847 %{ 8848 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8849 effect(KILL cr); 8850 8851 format %{ "sall $dst, $shift" %} 8852 opcode(0xD3, 0x4); /* D3 /4 */ 8853 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8854 ins_pipe(ialu_mem_reg); 8855 %} 8856 8857 // Arithmetic shift right by one 8858 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8859 %{ 8860 match(Set dst (RShiftI dst shift)); 8861 effect(KILL cr); 8862 8863 format %{ "sarl $dst, $shift" %} 8864 opcode(0xD1, 0x7); /* D1 /7 */ 8865 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8866 ins_pipe(ialu_reg); 8867 %} 8868 8869 // Arithmetic shift right by one 8870 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8871 %{ 8872 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8873 effect(KILL cr); 8874 8875 format %{ "sarl $dst, $shift" %} 8876 opcode(0xD1, 0x7); /* D1 /7 */ 8877 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8878 ins_pipe(ialu_mem_imm); 8879 %} 8880 8881 // Arithmetic Shift Right by 8-bit immediate 8882 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8883 %{ 8884 match(Set dst (RShiftI dst shift)); 8885 effect(KILL cr); 8886 8887 format %{ "sarl $dst, $shift" %} 8888 opcode(0xC1, 0x7); /* C1 /7 ib */ 8889 ins_encode(reg_opc_imm(dst, shift)); 8890 ins_pipe(ialu_mem_imm); 8891 %} 8892 8893 // Arithmetic Shift Right by 8-bit immediate 8894 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8895 %{ 8896 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8897 effect(KILL cr); 8898 8899 format %{ "sarl $dst, $shift" %} 8900 opcode(0xC1, 0x7); /* C1 /7 ib */ 8901 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8902 ins_pipe(ialu_mem_imm); 8903 %} 8904 8905 // Arithmetic Shift Right by variable 8906 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8907 %{ 8908 match(Set dst (RShiftI dst shift)); 8909 effect(KILL cr); 8910 8911 format %{ "sarl $dst, $shift" %} 8912 opcode(0xD3, 0x7); /* D3 /7 */ 8913 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8914 ins_pipe(ialu_reg_reg); 8915 %} 8916 8917 // Arithmetic Shift Right by variable 8918 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8919 %{ 8920 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8921 effect(KILL cr); 8922 8923 format %{ "sarl $dst, $shift" %} 8924 opcode(0xD3, 0x7); /* D3 /7 */ 8925 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8926 ins_pipe(ialu_mem_reg); 8927 %} 8928 8929 // Logical shift right by one 8930 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8931 %{ 8932 match(Set dst (URShiftI dst shift)); 8933 effect(KILL cr); 8934 8935 format %{ "shrl $dst, $shift" %} 8936 opcode(0xD1, 0x5); /* D1 /5 */ 8937 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8938 ins_pipe(ialu_reg); 8939 %} 8940 8941 // Logical shift right by one 8942 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8943 %{ 8944 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8945 effect(KILL cr); 8946 8947 format %{ "shrl $dst, $shift" %} 8948 opcode(0xD1, 0x5); /* D1 /5 */ 8949 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8950 ins_pipe(ialu_mem_imm); 8951 %} 8952 8953 // Logical Shift Right by 8-bit immediate 8954 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8955 %{ 8956 match(Set dst (URShiftI dst shift)); 8957 effect(KILL cr); 8958 8959 format %{ "shrl $dst, $shift" %} 8960 opcode(0xC1, 0x5); /* C1 /5 ib */ 8961 ins_encode(reg_opc_imm(dst, shift)); 8962 ins_pipe(ialu_reg); 8963 %} 8964 8965 // Logical Shift Right by 8-bit immediate 8966 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8967 %{ 8968 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8969 effect(KILL cr); 8970 8971 format %{ "shrl $dst, $shift" %} 8972 opcode(0xC1, 0x5); /* C1 /5 ib */ 8973 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8974 ins_pipe(ialu_mem_imm); 8975 %} 8976 8977 // Logical Shift Right by variable 8978 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8979 %{ 8980 match(Set dst (URShiftI dst shift)); 8981 effect(KILL cr); 8982 8983 format %{ "shrl $dst, $shift" %} 8984 opcode(0xD3, 0x5); /* D3 /5 */ 8985 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8986 ins_pipe(ialu_reg_reg); 8987 %} 8988 8989 // Logical Shift Right by variable 8990 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8991 %{ 8992 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8993 effect(KILL cr); 8994 8995 format %{ "shrl $dst, $shift" %} 8996 opcode(0xD3, 0x5); /* D3 /5 */ 8997 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8998 ins_pipe(ialu_mem_reg); 8999 %} 9000 9001 // Long Shift Instructions 9002 // Shift Left by one 9003 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9004 %{ 9005 match(Set dst (LShiftL dst shift)); 9006 effect(KILL cr); 9007 9008 format %{ "salq $dst, $shift" %} 9009 opcode(0xD1, 0x4); /* D1 /4 */ 9010 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9011 ins_pipe(ialu_reg); 9012 %} 9013 9014 // Shift Left by one 9015 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9016 %{ 9017 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9018 effect(KILL cr); 9019 9020 format %{ "salq $dst, $shift" %} 9021 opcode(0xD1, 0x4); /* D1 /4 */ 9022 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9023 ins_pipe(ialu_mem_imm); 9024 %} 9025 9026 // Shift Left by 8-bit immediate 9027 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9028 %{ 9029 match(Set dst (LShiftL dst shift)); 9030 effect(KILL cr); 9031 9032 format %{ "salq $dst, $shift" %} 9033 opcode(0xC1, 0x4); /* C1 /4 ib */ 9034 ins_encode(reg_opc_imm_wide(dst, shift)); 9035 ins_pipe(ialu_reg); 9036 %} 9037 9038 // Shift Left by 8-bit immediate 9039 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9040 %{ 9041 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9042 effect(KILL cr); 9043 9044 format %{ "salq $dst, $shift" %} 9045 opcode(0xC1, 0x4); /* C1 /4 ib */ 9046 ins_encode(REX_mem_wide(dst), OpcP, 9047 RM_opc_mem(secondary, dst), Con8or32(shift)); 9048 ins_pipe(ialu_mem_imm); 9049 %} 9050 9051 // Shift Left by variable 9052 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9053 %{ 9054 match(Set dst (LShiftL dst shift)); 9055 effect(KILL cr); 9056 9057 format %{ "salq $dst, $shift" %} 9058 opcode(0xD3, 0x4); /* D3 /4 */ 9059 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9060 ins_pipe(ialu_reg_reg); 9061 %} 9062 9063 // Shift Left by variable 9064 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9065 %{ 9066 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9067 effect(KILL cr); 9068 9069 format %{ "salq $dst, $shift" %} 9070 opcode(0xD3, 0x4); /* D3 /4 */ 9071 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9072 ins_pipe(ialu_mem_reg); 9073 %} 9074 9075 // Arithmetic shift right by one 9076 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9077 %{ 9078 match(Set dst (RShiftL dst shift)); 9079 effect(KILL cr); 9080 9081 format %{ "sarq $dst, $shift" %} 9082 opcode(0xD1, 0x7); /* D1 /7 */ 9083 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9084 ins_pipe(ialu_reg); 9085 %} 9086 9087 // Arithmetic shift right by one 9088 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9089 %{ 9090 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9091 effect(KILL cr); 9092 9093 format %{ "sarq $dst, $shift" %} 9094 opcode(0xD1, 0x7); /* D1 /7 */ 9095 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9096 ins_pipe(ialu_mem_imm); 9097 %} 9098 9099 // Arithmetic Shift Right by 8-bit immediate 9100 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9101 %{ 9102 match(Set dst (RShiftL dst shift)); 9103 effect(KILL cr); 9104 9105 format %{ "sarq $dst, $shift" %} 9106 opcode(0xC1, 0x7); /* C1 /7 ib */ 9107 ins_encode(reg_opc_imm_wide(dst, shift)); 9108 ins_pipe(ialu_mem_imm); 9109 %} 9110 9111 // Arithmetic Shift Right by 8-bit immediate 9112 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9113 %{ 9114 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9115 effect(KILL cr); 9116 9117 format %{ "sarq $dst, $shift" %} 9118 opcode(0xC1, 0x7); /* C1 /7 ib */ 9119 ins_encode(REX_mem_wide(dst), OpcP, 9120 RM_opc_mem(secondary, dst), Con8or32(shift)); 9121 ins_pipe(ialu_mem_imm); 9122 %} 9123 9124 // Arithmetic Shift Right by variable 9125 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9126 %{ 9127 match(Set dst (RShiftL dst shift)); 9128 effect(KILL cr); 9129 9130 format %{ "sarq $dst, $shift" %} 9131 opcode(0xD3, 0x7); /* D3 /7 */ 9132 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9133 ins_pipe(ialu_reg_reg); 9134 %} 9135 9136 // Arithmetic Shift Right by variable 9137 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9138 %{ 9139 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9140 effect(KILL cr); 9141 9142 format %{ "sarq $dst, $shift" %} 9143 opcode(0xD3, 0x7); /* D3 /7 */ 9144 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9145 ins_pipe(ialu_mem_reg); 9146 %} 9147 9148 // Logical shift right by one 9149 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9150 %{ 9151 match(Set dst (URShiftL dst shift)); 9152 effect(KILL cr); 9153 9154 format %{ "shrq $dst, $shift" %} 9155 opcode(0xD1, 0x5); /* D1 /5 */ 9156 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 9157 ins_pipe(ialu_reg); 9158 %} 9159 9160 // Logical shift right by one 9161 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9162 %{ 9163 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9164 effect(KILL cr); 9165 9166 format %{ "shrq $dst, $shift" %} 9167 opcode(0xD1, 0x5); /* D1 /5 */ 9168 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9169 ins_pipe(ialu_mem_imm); 9170 %} 9171 9172 // Logical Shift Right by 8-bit immediate 9173 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9174 %{ 9175 match(Set dst (URShiftL dst shift)); 9176 effect(KILL cr); 9177 9178 format %{ "shrq $dst, $shift" %} 9179 opcode(0xC1, 0x5); /* C1 /5 ib */ 9180 ins_encode(reg_opc_imm_wide(dst, shift)); 9181 ins_pipe(ialu_reg); 9182 %} 9183 9184 9185 // Logical Shift Right by 8-bit immediate 9186 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9187 %{ 9188 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9189 effect(KILL cr); 9190 9191 format %{ "shrq $dst, $shift" %} 9192 opcode(0xC1, 0x5); /* C1 /5 ib */ 9193 ins_encode(REX_mem_wide(dst), OpcP, 9194 RM_opc_mem(secondary, dst), Con8or32(shift)); 9195 ins_pipe(ialu_mem_imm); 9196 %} 9197 9198 // Logical Shift Right by variable 9199 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9200 %{ 9201 match(Set dst (URShiftL dst shift)); 9202 effect(KILL cr); 9203 9204 format %{ "shrq $dst, $shift" %} 9205 opcode(0xD3, 0x5); /* D3 /5 */ 9206 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9207 ins_pipe(ialu_reg_reg); 9208 %} 9209 9210 // Logical Shift Right by variable 9211 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9212 %{ 9213 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9214 effect(KILL cr); 9215 9216 format %{ "shrq $dst, $shift" %} 9217 opcode(0xD3, 0x5); /* D3 /5 */ 9218 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9219 ins_pipe(ialu_mem_reg); 9220 %} 9221 9222 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9223 // This idiom is used by the compiler for the i2b bytecode. 9224 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9225 %{ 9226 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9227 9228 format %{ "movsbl $dst, $src\t# i2b" %} 9229 opcode(0x0F, 0xBE); 9230 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9231 ins_pipe(ialu_reg_reg); 9232 %} 9233 9234 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9235 // This idiom is used by the compiler the i2s bytecode. 9236 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9237 %{ 9238 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9239 9240 format %{ "movswl $dst, $src\t# i2s" %} 9241 opcode(0x0F, 0xBF); 9242 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9243 ins_pipe(ialu_reg_reg); 9244 %} 9245 9246 // ROL/ROR instructions 9247 9248 // ROL expand 9249 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9250 effect(KILL cr, USE_DEF dst); 9251 9252 format %{ "roll $dst" %} 9253 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9254 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9255 ins_pipe(ialu_reg); 9256 %} 9257 9258 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9259 effect(USE_DEF dst, USE shift, KILL cr); 9260 9261 format %{ "roll $dst, $shift" %} 9262 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9263 ins_encode( reg_opc_imm(dst, shift) ); 9264 ins_pipe(ialu_reg); 9265 %} 9266 9267 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9268 %{ 9269 effect(USE_DEF dst, USE shift, KILL cr); 9270 9271 format %{ "roll $dst, $shift" %} 9272 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9273 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9274 ins_pipe(ialu_reg_reg); 9275 %} 9276 // end of ROL expand 9277 9278 // Rotate Left by one 9279 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9280 %{ 9281 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9282 9283 expand %{ 9284 rolI_rReg_imm1(dst, cr); 9285 %} 9286 %} 9287 9288 // Rotate Left by 8-bit immediate 9289 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9290 %{ 9291 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9292 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9293 9294 expand %{ 9295 rolI_rReg_imm8(dst, lshift, cr); 9296 %} 9297 %} 9298 9299 // Rotate Left by variable 9300 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9301 %{ 9302 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9303 9304 expand %{ 9305 rolI_rReg_CL(dst, shift, cr); 9306 %} 9307 %} 9308 9309 // Rotate Left by variable 9310 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9311 %{ 9312 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9313 9314 expand %{ 9315 rolI_rReg_CL(dst, shift, cr); 9316 %} 9317 %} 9318 9319 // ROR expand 9320 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9321 %{ 9322 effect(USE_DEF dst, KILL cr); 9323 9324 format %{ "rorl $dst" %} 9325 opcode(0xD1, 0x1); /* D1 /1 */ 9326 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9327 ins_pipe(ialu_reg); 9328 %} 9329 9330 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9331 %{ 9332 effect(USE_DEF dst, USE shift, KILL cr); 9333 9334 format %{ "rorl $dst, $shift" %} 9335 opcode(0xC1, 0x1); /* C1 /1 ib */ 9336 ins_encode(reg_opc_imm(dst, shift)); 9337 ins_pipe(ialu_reg); 9338 %} 9339 9340 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9341 %{ 9342 effect(USE_DEF dst, USE shift, KILL cr); 9343 9344 format %{ "rorl $dst, $shift" %} 9345 opcode(0xD3, 0x1); /* D3 /1 */ 9346 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9347 ins_pipe(ialu_reg_reg); 9348 %} 9349 // end of ROR expand 9350 9351 // Rotate Right by one 9352 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9353 %{ 9354 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9355 9356 expand %{ 9357 rorI_rReg_imm1(dst, cr); 9358 %} 9359 %} 9360 9361 // Rotate Right by 8-bit immediate 9362 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9363 %{ 9364 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9365 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9366 9367 expand %{ 9368 rorI_rReg_imm8(dst, rshift, cr); 9369 %} 9370 %} 9371 9372 // Rotate Right by variable 9373 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9374 %{ 9375 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9376 9377 expand %{ 9378 rorI_rReg_CL(dst, shift, cr); 9379 %} 9380 %} 9381 9382 // Rotate Right by variable 9383 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9384 %{ 9385 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9386 9387 expand %{ 9388 rorI_rReg_CL(dst, shift, cr); 9389 %} 9390 %} 9391 9392 // for long rotate 9393 // ROL expand 9394 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9395 effect(USE_DEF dst, KILL cr); 9396 9397 format %{ "rolq $dst" %} 9398 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9399 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9400 ins_pipe(ialu_reg); 9401 %} 9402 9403 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9404 effect(USE_DEF dst, USE shift, KILL cr); 9405 9406 format %{ "rolq $dst, $shift" %} 9407 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9408 ins_encode( reg_opc_imm_wide(dst, shift) ); 9409 ins_pipe(ialu_reg); 9410 %} 9411 9412 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9413 %{ 9414 effect(USE_DEF dst, USE shift, KILL cr); 9415 9416 format %{ "rolq $dst, $shift" %} 9417 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9418 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9419 ins_pipe(ialu_reg_reg); 9420 %} 9421 // end of ROL expand 9422 9423 // Rotate Left by one 9424 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9425 %{ 9426 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9427 9428 expand %{ 9429 rolL_rReg_imm1(dst, cr); 9430 %} 9431 %} 9432 9433 // Rotate Left by 8-bit immediate 9434 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9435 %{ 9436 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9437 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9438 9439 expand %{ 9440 rolL_rReg_imm8(dst, lshift, cr); 9441 %} 9442 %} 9443 9444 // Rotate Left by variable 9445 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9446 %{ 9447 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9448 9449 expand %{ 9450 rolL_rReg_CL(dst, shift, cr); 9451 %} 9452 %} 9453 9454 // Rotate Left by variable 9455 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9456 %{ 9457 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9458 9459 expand %{ 9460 rolL_rReg_CL(dst, shift, cr); 9461 %} 9462 %} 9463 9464 // ROR expand 9465 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9466 %{ 9467 effect(USE_DEF dst, KILL cr); 9468 9469 format %{ "rorq $dst" %} 9470 opcode(0xD1, 0x1); /* D1 /1 */ 9471 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9472 ins_pipe(ialu_reg); 9473 %} 9474 9475 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9476 %{ 9477 effect(USE_DEF dst, USE shift, KILL cr); 9478 9479 format %{ "rorq $dst, $shift" %} 9480 opcode(0xC1, 0x1); /* C1 /1 ib */ 9481 ins_encode(reg_opc_imm_wide(dst, shift)); 9482 ins_pipe(ialu_reg); 9483 %} 9484 9485 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9486 %{ 9487 effect(USE_DEF dst, USE shift, KILL cr); 9488 9489 format %{ "rorq $dst, $shift" %} 9490 opcode(0xD3, 0x1); /* D3 /1 */ 9491 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9492 ins_pipe(ialu_reg_reg); 9493 %} 9494 // end of ROR expand 9495 9496 // Rotate Right by one 9497 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9498 %{ 9499 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9500 9501 expand %{ 9502 rorL_rReg_imm1(dst, cr); 9503 %} 9504 %} 9505 9506 // Rotate Right by 8-bit immediate 9507 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9508 %{ 9509 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9510 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9511 9512 expand %{ 9513 rorL_rReg_imm8(dst, rshift, cr); 9514 %} 9515 %} 9516 9517 // Rotate Right by variable 9518 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9519 %{ 9520 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9521 9522 expand %{ 9523 rorL_rReg_CL(dst, shift, cr); 9524 %} 9525 %} 9526 9527 // Rotate Right by variable 9528 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9529 %{ 9530 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9531 9532 expand %{ 9533 rorL_rReg_CL(dst, shift, cr); 9534 %} 9535 %} 9536 9537 // Logical Instructions 9538 9539 // Integer Logical Instructions 9540 9541 // And Instructions 9542 // And Register with Register 9543 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9544 %{ 9545 match(Set dst (AndI dst src)); 9546 effect(KILL cr); 9547 9548 format %{ "andl $dst, $src\t# int" %} 9549 opcode(0x23); 9550 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9551 ins_pipe(ialu_reg_reg); 9552 %} 9553 9554 // And Register with Immediate 255 9555 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9556 %{ 9557 match(Set dst (AndI dst src)); 9558 9559 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9560 opcode(0x0F, 0xB6); 9561 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9562 ins_pipe(ialu_reg); 9563 %} 9564 9565 // And Register with Immediate 255 and promote to long 9566 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9567 %{ 9568 match(Set dst (ConvI2L (AndI src mask))); 9569 9570 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9571 opcode(0x0F, 0xB6); 9572 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9573 ins_pipe(ialu_reg); 9574 %} 9575 9576 // And Register with Immediate 65535 9577 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9578 %{ 9579 match(Set dst (AndI dst src)); 9580 9581 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9582 opcode(0x0F, 0xB7); 9583 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9584 ins_pipe(ialu_reg); 9585 %} 9586 9587 // And Register with Immediate 65535 and promote to long 9588 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9589 %{ 9590 match(Set dst (ConvI2L (AndI src mask))); 9591 9592 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9593 opcode(0x0F, 0xB7); 9594 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9595 ins_pipe(ialu_reg); 9596 %} 9597 9598 // And Register with Immediate 9599 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9600 %{ 9601 match(Set dst (AndI dst src)); 9602 effect(KILL cr); 9603 9604 format %{ "andl $dst, $src\t# int" %} 9605 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9606 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9607 ins_pipe(ialu_reg); 9608 %} 9609 9610 // And Register with Memory 9611 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9612 %{ 9613 match(Set dst (AndI dst (LoadI src))); 9614 effect(KILL cr); 9615 9616 ins_cost(125); 9617 format %{ "andl $dst, $src\t# int" %} 9618 opcode(0x23); 9619 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9620 ins_pipe(ialu_reg_mem); 9621 %} 9622 9623 // And Memory with Register 9624 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9625 %{ 9626 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9627 effect(KILL cr); 9628 9629 ins_cost(150); 9630 format %{ "andb $dst, $src\t# byte" %} 9631 opcode(0x20); 9632 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9633 ins_pipe(ialu_mem_reg); 9634 %} 9635 9636 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9637 %{ 9638 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9639 effect(KILL cr); 9640 9641 ins_cost(150); 9642 format %{ "andl $dst, $src\t# int" %} 9643 opcode(0x21); /* Opcode 21 /r */ 9644 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9645 ins_pipe(ialu_mem_reg); 9646 %} 9647 9648 // And Memory with Immediate 9649 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9650 %{ 9651 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9652 effect(KILL cr); 9653 9654 ins_cost(125); 9655 format %{ "andl $dst, $src\t# int" %} 9656 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9657 ins_encode(REX_mem(dst), OpcSE(src), 9658 RM_opc_mem(secondary, dst), Con8or32(src)); 9659 ins_pipe(ialu_mem_imm); 9660 %} 9661 9662 // BMI1 instructions 9663 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9664 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9665 predicate(UseBMI1Instructions); 9666 effect(KILL cr); 9667 9668 ins_cost(125); 9669 format %{ "andnl $dst, $src1, $src2" %} 9670 9671 ins_encode %{ 9672 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9673 %} 9674 ins_pipe(ialu_reg_mem); 9675 %} 9676 9677 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9678 match(Set dst (AndI (XorI src1 minus_1) src2)); 9679 predicate(UseBMI1Instructions); 9680 effect(KILL cr); 9681 9682 format %{ "andnl $dst, $src1, $src2" %} 9683 9684 ins_encode %{ 9685 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9686 %} 9687 ins_pipe(ialu_reg); 9688 %} 9689 9690 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9691 match(Set dst (AndI (SubI imm_zero src) src)); 9692 predicate(UseBMI1Instructions); 9693 effect(KILL cr); 9694 9695 format %{ "blsil $dst, $src" %} 9696 9697 ins_encode %{ 9698 __ blsil($dst$$Register, $src$$Register); 9699 %} 9700 ins_pipe(ialu_reg); 9701 %} 9702 9703 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9704 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9705 predicate(UseBMI1Instructions); 9706 effect(KILL cr); 9707 9708 ins_cost(125); 9709 format %{ "blsil $dst, $src" %} 9710 9711 ins_encode %{ 9712 __ blsil($dst$$Register, $src$$Address); 9713 %} 9714 ins_pipe(ialu_reg_mem); 9715 %} 9716 9717 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9718 %{ 9719 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9720 predicate(UseBMI1Instructions); 9721 effect(KILL cr); 9722 9723 ins_cost(125); 9724 format %{ "blsmskl $dst, $src" %} 9725 9726 ins_encode %{ 9727 __ blsmskl($dst$$Register, $src$$Address); 9728 %} 9729 ins_pipe(ialu_reg_mem); 9730 %} 9731 9732 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9733 %{ 9734 match(Set dst (XorI (AddI src minus_1) src)); 9735 predicate(UseBMI1Instructions); 9736 effect(KILL cr); 9737 9738 format %{ "blsmskl $dst, $src" %} 9739 9740 ins_encode %{ 9741 __ blsmskl($dst$$Register, $src$$Register); 9742 %} 9743 9744 ins_pipe(ialu_reg); 9745 %} 9746 9747 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9748 %{ 9749 match(Set dst (AndI (AddI src minus_1) src) ); 9750 predicate(UseBMI1Instructions); 9751 effect(KILL cr); 9752 9753 format %{ "blsrl $dst, $src" %} 9754 9755 ins_encode %{ 9756 __ blsrl($dst$$Register, $src$$Register); 9757 %} 9758 9759 ins_pipe(ialu_reg_mem); 9760 %} 9761 9762 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9763 %{ 9764 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9765 predicate(UseBMI1Instructions); 9766 effect(KILL cr); 9767 9768 ins_cost(125); 9769 format %{ "blsrl $dst, $src" %} 9770 9771 ins_encode %{ 9772 __ blsrl($dst$$Register, $src$$Address); 9773 %} 9774 9775 ins_pipe(ialu_reg); 9776 %} 9777 9778 // Or Instructions 9779 // Or Register with Register 9780 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9781 %{ 9782 match(Set dst (OrI dst src)); 9783 effect(KILL cr); 9784 9785 format %{ "orl $dst, $src\t# int" %} 9786 opcode(0x0B); 9787 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9788 ins_pipe(ialu_reg_reg); 9789 %} 9790 9791 // Or Register with Immediate 9792 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9793 %{ 9794 match(Set dst (OrI dst src)); 9795 effect(KILL cr); 9796 9797 format %{ "orl $dst, $src\t# int" %} 9798 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9799 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9800 ins_pipe(ialu_reg); 9801 %} 9802 9803 // Or Register with Memory 9804 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9805 %{ 9806 match(Set dst (OrI dst (LoadI src))); 9807 effect(KILL cr); 9808 9809 ins_cost(125); 9810 format %{ "orl $dst, $src\t# int" %} 9811 opcode(0x0B); 9812 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9813 ins_pipe(ialu_reg_mem); 9814 %} 9815 9816 // Or Memory with Register 9817 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9818 %{ 9819 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9820 effect(KILL cr); 9821 9822 ins_cost(150); 9823 format %{ "orb $dst, $src\t# byte" %} 9824 opcode(0x08); 9825 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9826 ins_pipe(ialu_mem_reg); 9827 %} 9828 9829 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9830 %{ 9831 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9832 effect(KILL cr); 9833 9834 ins_cost(150); 9835 format %{ "orl $dst, $src\t# int" %} 9836 opcode(0x09); /* Opcode 09 /r */ 9837 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9838 ins_pipe(ialu_mem_reg); 9839 %} 9840 9841 // Or Memory with Immediate 9842 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9843 %{ 9844 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9845 effect(KILL cr); 9846 9847 ins_cost(125); 9848 format %{ "orl $dst, $src\t# int" %} 9849 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9850 ins_encode(REX_mem(dst), OpcSE(src), 9851 RM_opc_mem(secondary, dst), Con8or32(src)); 9852 ins_pipe(ialu_mem_imm); 9853 %} 9854 9855 // Xor Instructions 9856 // Xor Register with Register 9857 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9858 %{ 9859 match(Set dst (XorI dst src)); 9860 effect(KILL cr); 9861 9862 format %{ "xorl $dst, $src\t# int" %} 9863 opcode(0x33); 9864 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9865 ins_pipe(ialu_reg_reg); 9866 %} 9867 9868 // Xor Register with Immediate -1 9869 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9870 match(Set dst (XorI dst imm)); 9871 9872 format %{ "not $dst" %} 9873 ins_encode %{ 9874 __ notl($dst$$Register); 9875 %} 9876 ins_pipe(ialu_reg); 9877 %} 9878 9879 // Xor Register with Immediate 9880 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9881 %{ 9882 match(Set dst (XorI dst src)); 9883 effect(KILL cr); 9884 9885 format %{ "xorl $dst, $src\t# int" %} 9886 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9887 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9888 ins_pipe(ialu_reg); 9889 %} 9890 9891 // Xor Register with Memory 9892 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9893 %{ 9894 match(Set dst (XorI dst (LoadI src))); 9895 effect(KILL cr); 9896 9897 ins_cost(125); 9898 format %{ "xorl $dst, $src\t# int" %} 9899 opcode(0x33); 9900 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9901 ins_pipe(ialu_reg_mem); 9902 %} 9903 9904 // Xor Memory with Register 9905 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9906 %{ 9907 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9908 effect(KILL cr); 9909 9910 ins_cost(150); 9911 format %{ "xorb $dst, $src\t# byte" %} 9912 opcode(0x30); 9913 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9914 ins_pipe(ialu_mem_reg); 9915 %} 9916 9917 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9918 %{ 9919 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9920 effect(KILL cr); 9921 9922 ins_cost(150); 9923 format %{ "xorl $dst, $src\t# int" %} 9924 opcode(0x31); /* Opcode 31 /r */ 9925 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9926 ins_pipe(ialu_mem_reg); 9927 %} 9928 9929 // Xor Memory with Immediate 9930 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9931 %{ 9932 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9933 effect(KILL cr); 9934 9935 ins_cost(125); 9936 format %{ "xorl $dst, $src\t# int" %} 9937 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9938 ins_encode(REX_mem(dst), OpcSE(src), 9939 RM_opc_mem(secondary, dst), Con8or32(src)); 9940 ins_pipe(ialu_mem_imm); 9941 %} 9942 9943 9944 // Long Logical Instructions 9945 9946 // And Instructions 9947 // And Register with Register 9948 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9949 %{ 9950 match(Set dst (AndL dst src)); 9951 effect(KILL cr); 9952 9953 format %{ "andq $dst, $src\t# long" %} 9954 opcode(0x23); 9955 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9956 ins_pipe(ialu_reg_reg); 9957 %} 9958 9959 // And Register with Immediate 255 9960 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9961 %{ 9962 match(Set dst (AndL dst src)); 9963 9964 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9965 opcode(0x0F, 0xB6); 9966 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9967 ins_pipe(ialu_reg); 9968 %} 9969 9970 // And Register with Immediate 65535 9971 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9972 %{ 9973 match(Set dst (AndL dst src)); 9974 9975 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9976 opcode(0x0F, 0xB7); 9977 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9978 ins_pipe(ialu_reg); 9979 %} 9980 9981 // And Register with Immediate 9982 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9983 %{ 9984 match(Set dst (AndL dst src)); 9985 effect(KILL cr); 9986 9987 format %{ "andq $dst, $src\t# long" %} 9988 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9989 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9990 ins_pipe(ialu_reg); 9991 %} 9992 9993 // And Register with Memory 9994 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9995 %{ 9996 match(Set dst (AndL dst (LoadL src))); 9997 effect(KILL cr); 9998 9999 ins_cost(125); 10000 format %{ "andq $dst, $src\t# long" %} 10001 opcode(0x23); 10002 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10003 ins_pipe(ialu_reg_mem); 10004 %} 10005 10006 // And Memory with Register 10007 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10008 %{ 10009 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10010 effect(KILL cr); 10011 10012 ins_cost(150); 10013 format %{ "andq $dst, $src\t# long" %} 10014 opcode(0x21); /* Opcode 21 /r */ 10015 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10016 ins_pipe(ialu_mem_reg); 10017 %} 10018 10019 // And Memory with Immediate 10020 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10021 %{ 10022 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10023 effect(KILL cr); 10024 10025 ins_cost(125); 10026 format %{ "andq $dst, $src\t# long" %} 10027 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 10028 ins_encode(REX_mem_wide(dst), OpcSE(src), 10029 RM_opc_mem(secondary, dst), Con8or32(src)); 10030 ins_pipe(ialu_mem_imm); 10031 %} 10032 10033 // BMI1 instructions 10034 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10035 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10036 predicate(UseBMI1Instructions); 10037 effect(KILL cr); 10038 10039 ins_cost(125); 10040 format %{ "andnq $dst, $src1, $src2" %} 10041 10042 ins_encode %{ 10043 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10044 %} 10045 ins_pipe(ialu_reg_mem); 10046 %} 10047 10048 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10049 match(Set dst (AndL (XorL src1 minus_1) src2)); 10050 predicate(UseBMI1Instructions); 10051 effect(KILL cr); 10052 10053 format %{ "andnq $dst, $src1, $src2" %} 10054 10055 ins_encode %{ 10056 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10057 %} 10058 ins_pipe(ialu_reg_mem); 10059 %} 10060 10061 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10062 match(Set dst (AndL (SubL imm_zero src) src)); 10063 predicate(UseBMI1Instructions); 10064 effect(KILL cr); 10065 10066 format %{ "blsiq $dst, $src" %} 10067 10068 ins_encode %{ 10069 __ blsiq($dst$$Register, $src$$Register); 10070 %} 10071 ins_pipe(ialu_reg); 10072 %} 10073 10074 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10075 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10076 predicate(UseBMI1Instructions); 10077 effect(KILL cr); 10078 10079 ins_cost(125); 10080 format %{ "blsiq $dst, $src" %} 10081 10082 ins_encode %{ 10083 __ blsiq($dst$$Register, $src$$Address); 10084 %} 10085 ins_pipe(ialu_reg_mem); 10086 %} 10087 10088 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10089 %{ 10090 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 10091 predicate(UseBMI1Instructions); 10092 effect(KILL cr); 10093 10094 ins_cost(125); 10095 format %{ "blsmskq $dst, $src" %} 10096 10097 ins_encode %{ 10098 __ blsmskq($dst$$Register, $src$$Address); 10099 %} 10100 ins_pipe(ialu_reg_mem); 10101 %} 10102 10103 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10104 %{ 10105 match(Set dst (XorL (AddL src minus_1) src)); 10106 predicate(UseBMI1Instructions); 10107 effect(KILL cr); 10108 10109 format %{ "blsmskq $dst, $src" %} 10110 10111 ins_encode %{ 10112 __ blsmskq($dst$$Register, $src$$Register); 10113 %} 10114 10115 ins_pipe(ialu_reg); 10116 %} 10117 10118 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10119 %{ 10120 match(Set dst (AndL (AddL src minus_1) src) ); 10121 predicate(UseBMI1Instructions); 10122 effect(KILL cr); 10123 10124 format %{ "blsrq $dst, $src" %} 10125 10126 ins_encode %{ 10127 __ blsrq($dst$$Register, $src$$Register); 10128 %} 10129 10130 ins_pipe(ialu_reg); 10131 %} 10132 10133 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10134 %{ 10135 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 10136 predicate(UseBMI1Instructions); 10137 effect(KILL cr); 10138 10139 ins_cost(125); 10140 format %{ "blsrq $dst, $src" %} 10141 10142 ins_encode %{ 10143 __ blsrq($dst$$Register, $src$$Address); 10144 %} 10145 10146 ins_pipe(ialu_reg); 10147 %} 10148 10149 // Or Instructions 10150 // Or Register with Register 10151 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10152 %{ 10153 match(Set dst (OrL dst src)); 10154 effect(KILL cr); 10155 10156 format %{ "orq $dst, $src\t# long" %} 10157 opcode(0x0B); 10158 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10159 ins_pipe(ialu_reg_reg); 10160 %} 10161 10162 // Use any_RegP to match R15 (TLS register) without spilling. 10163 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 10164 match(Set dst (OrL dst (CastP2X src))); 10165 effect(KILL cr); 10166 10167 format %{ "orq $dst, $src\t# long" %} 10168 opcode(0x0B); 10169 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10170 ins_pipe(ialu_reg_reg); 10171 %} 10172 10173 10174 // Or Register with Immediate 10175 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10176 %{ 10177 match(Set dst (OrL dst src)); 10178 effect(KILL cr); 10179 10180 format %{ "orq $dst, $src\t# long" %} 10181 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 10182 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10183 ins_pipe(ialu_reg); 10184 %} 10185 10186 // Or Register with Memory 10187 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10188 %{ 10189 match(Set dst (OrL dst (LoadL src))); 10190 effect(KILL cr); 10191 10192 ins_cost(125); 10193 format %{ "orq $dst, $src\t# long" %} 10194 opcode(0x0B); 10195 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10196 ins_pipe(ialu_reg_mem); 10197 %} 10198 10199 // Or Memory with Register 10200 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10201 %{ 10202 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10203 effect(KILL cr); 10204 10205 ins_cost(150); 10206 format %{ "orq $dst, $src\t# long" %} 10207 opcode(0x09); /* Opcode 09 /r */ 10208 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10209 ins_pipe(ialu_mem_reg); 10210 %} 10211 10212 // Or Memory with Immediate 10213 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10214 %{ 10215 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10216 effect(KILL cr); 10217 10218 ins_cost(125); 10219 format %{ "orq $dst, $src\t# long" %} 10220 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 10221 ins_encode(REX_mem_wide(dst), OpcSE(src), 10222 RM_opc_mem(secondary, dst), Con8or32(src)); 10223 ins_pipe(ialu_mem_imm); 10224 %} 10225 10226 // Xor Instructions 10227 // Xor Register with Register 10228 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10229 %{ 10230 match(Set dst (XorL dst src)); 10231 effect(KILL cr); 10232 10233 format %{ "xorq $dst, $src\t# long" %} 10234 opcode(0x33); 10235 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10236 ins_pipe(ialu_reg_reg); 10237 %} 10238 10239 // Xor Register with Immediate -1 10240 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10241 match(Set dst (XorL dst imm)); 10242 10243 format %{ "notq $dst" %} 10244 ins_encode %{ 10245 __ notq($dst$$Register); 10246 %} 10247 ins_pipe(ialu_reg); 10248 %} 10249 10250 // Xor Register with Immediate 10251 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10252 %{ 10253 match(Set dst (XorL dst src)); 10254 effect(KILL cr); 10255 10256 format %{ "xorq $dst, $src\t# long" %} 10257 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10258 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10259 ins_pipe(ialu_reg); 10260 %} 10261 10262 // Xor Register with Memory 10263 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10264 %{ 10265 match(Set dst (XorL dst (LoadL src))); 10266 effect(KILL cr); 10267 10268 ins_cost(125); 10269 format %{ "xorq $dst, $src\t# long" %} 10270 opcode(0x33); 10271 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10272 ins_pipe(ialu_reg_mem); 10273 %} 10274 10275 // Xor Memory with Register 10276 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10277 %{ 10278 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10279 effect(KILL cr); 10280 10281 ins_cost(150); 10282 format %{ "xorq $dst, $src\t# long" %} 10283 opcode(0x31); /* Opcode 31 /r */ 10284 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10285 ins_pipe(ialu_mem_reg); 10286 %} 10287 10288 // Xor Memory with Immediate 10289 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10290 %{ 10291 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10292 effect(KILL cr); 10293 10294 ins_cost(125); 10295 format %{ "xorq $dst, $src\t# long" %} 10296 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10297 ins_encode(REX_mem_wide(dst), OpcSE(src), 10298 RM_opc_mem(secondary, dst), Con8or32(src)); 10299 ins_pipe(ialu_mem_imm); 10300 %} 10301 10302 // Convert Int to Boolean 10303 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10304 %{ 10305 match(Set dst (Conv2B src)); 10306 effect(KILL cr); 10307 10308 format %{ "testl $src, $src\t# ci2b\n\t" 10309 "setnz $dst\n\t" 10310 "movzbl $dst, $dst" %} 10311 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10312 setNZ_reg(dst), 10313 REX_reg_breg(dst, dst), // movzbl 10314 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10315 ins_pipe(pipe_slow); // XXX 10316 %} 10317 10318 // Convert Pointer to Boolean 10319 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10320 %{ 10321 match(Set dst (Conv2B src)); 10322 effect(KILL cr); 10323 10324 format %{ "testq $src, $src\t# cp2b\n\t" 10325 "setnz $dst\n\t" 10326 "movzbl $dst, $dst" %} 10327 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10328 setNZ_reg(dst), 10329 REX_reg_breg(dst, dst), // movzbl 10330 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10331 ins_pipe(pipe_slow); // XXX 10332 %} 10333 10334 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10335 %{ 10336 match(Set dst (CmpLTMask p q)); 10337 effect(KILL cr); 10338 10339 ins_cost(400); 10340 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10341 "setlt $dst\n\t" 10342 "movzbl $dst, $dst\n\t" 10343 "negl $dst" %} 10344 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10345 setLT_reg(dst), 10346 REX_reg_breg(dst, dst), // movzbl 10347 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10348 neg_reg(dst)); 10349 ins_pipe(pipe_slow); 10350 %} 10351 10352 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10353 %{ 10354 match(Set dst (CmpLTMask dst zero)); 10355 effect(KILL cr); 10356 10357 ins_cost(100); 10358 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10359 ins_encode %{ 10360 __ sarl($dst$$Register, 31); 10361 %} 10362 ins_pipe(ialu_reg); 10363 %} 10364 10365 /* Better to save a register than avoid a branch */ 10366 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10367 %{ 10368 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10369 effect(KILL cr); 10370 ins_cost(300); 10371 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10372 "jge done\n\t" 10373 "addl $p,$y\n" 10374 "done: " %} 10375 ins_encode %{ 10376 Register Rp = $p$$Register; 10377 Register Rq = $q$$Register; 10378 Register Ry = $y$$Register; 10379 Label done; 10380 __ subl(Rp, Rq); 10381 __ jccb(Assembler::greaterEqual, done); 10382 __ addl(Rp, Ry); 10383 __ bind(done); 10384 %} 10385 ins_pipe(pipe_cmplt); 10386 %} 10387 10388 /* Better to save a register than avoid a branch */ 10389 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10390 %{ 10391 match(Set y (AndI (CmpLTMask p q) y)); 10392 effect(KILL cr); 10393 10394 ins_cost(300); 10395 10396 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10397 "jlt done\n\t" 10398 "xorl $y, $y\n" 10399 "done: " %} 10400 ins_encode %{ 10401 Register Rp = $p$$Register; 10402 Register Rq = $q$$Register; 10403 Register Ry = $y$$Register; 10404 Label done; 10405 __ cmpl(Rp, Rq); 10406 __ jccb(Assembler::less, done); 10407 __ xorl(Ry, Ry); 10408 __ bind(done); 10409 %} 10410 ins_pipe(pipe_cmplt); 10411 %} 10412 10413 10414 //---------- FP Instructions------------------------------------------------ 10415 10416 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10417 %{ 10418 match(Set cr (CmpF src1 src2)); 10419 10420 ins_cost(145); 10421 format %{ "ucomiss $src1, $src2\n\t" 10422 "jnp,s exit\n\t" 10423 "pushfq\t# saw NaN, set CF\n\t" 10424 "andq [rsp], #0xffffff2b\n\t" 10425 "popfq\n" 10426 "exit:" %} 10427 ins_encode %{ 10428 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10429 emit_cmpfp_fixup(_masm); 10430 %} 10431 ins_pipe(pipe_slow); 10432 %} 10433 10434 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10435 match(Set cr (CmpF src1 src2)); 10436 10437 ins_cost(100); 10438 format %{ "ucomiss $src1, $src2" %} 10439 ins_encode %{ 10440 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10441 %} 10442 ins_pipe(pipe_slow); 10443 %} 10444 10445 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10446 %{ 10447 match(Set cr (CmpF src1 (LoadF src2))); 10448 10449 ins_cost(145); 10450 format %{ "ucomiss $src1, $src2\n\t" 10451 "jnp,s exit\n\t" 10452 "pushfq\t# saw NaN, set CF\n\t" 10453 "andq [rsp], #0xffffff2b\n\t" 10454 "popfq\n" 10455 "exit:" %} 10456 ins_encode %{ 10457 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10458 emit_cmpfp_fixup(_masm); 10459 %} 10460 ins_pipe(pipe_slow); 10461 %} 10462 10463 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10464 match(Set cr (CmpF src1 (LoadF src2))); 10465 10466 ins_cost(100); 10467 format %{ "ucomiss $src1, $src2" %} 10468 ins_encode %{ 10469 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10470 %} 10471 ins_pipe(pipe_slow); 10472 %} 10473 10474 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10475 match(Set cr (CmpF src con)); 10476 10477 ins_cost(145); 10478 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10479 "jnp,s exit\n\t" 10480 "pushfq\t# saw NaN, set CF\n\t" 10481 "andq [rsp], #0xffffff2b\n\t" 10482 "popfq\n" 10483 "exit:" %} 10484 ins_encode %{ 10485 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10486 emit_cmpfp_fixup(_masm); 10487 %} 10488 ins_pipe(pipe_slow); 10489 %} 10490 10491 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10492 match(Set cr (CmpF src con)); 10493 ins_cost(100); 10494 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10495 ins_encode %{ 10496 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10497 %} 10498 ins_pipe(pipe_slow); 10499 %} 10500 10501 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10502 %{ 10503 match(Set cr (CmpD src1 src2)); 10504 10505 ins_cost(145); 10506 format %{ "ucomisd $src1, $src2\n\t" 10507 "jnp,s exit\n\t" 10508 "pushfq\t# saw NaN, set CF\n\t" 10509 "andq [rsp], #0xffffff2b\n\t" 10510 "popfq\n" 10511 "exit:" %} 10512 ins_encode %{ 10513 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10514 emit_cmpfp_fixup(_masm); 10515 %} 10516 ins_pipe(pipe_slow); 10517 %} 10518 10519 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10520 match(Set cr (CmpD src1 src2)); 10521 10522 ins_cost(100); 10523 format %{ "ucomisd $src1, $src2 test" %} 10524 ins_encode %{ 10525 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10526 %} 10527 ins_pipe(pipe_slow); 10528 %} 10529 10530 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10531 %{ 10532 match(Set cr (CmpD src1 (LoadD src2))); 10533 10534 ins_cost(145); 10535 format %{ "ucomisd $src1, $src2\n\t" 10536 "jnp,s exit\n\t" 10537 "pushfq\t# saw NaN, set CF\n\t" 10538 "andq [rsp], #0xffffff2b\n\t" 10539 "popfq\n" 10540 "exit:" %} 10541 ins_encode %{ 10542 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10543 emit_cmpfp_fixup(_masm); 10544 %} 10545 ins_pipe(pipe_slow); 10546 %} 10547 10548 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10549 match(Set cr (CmpD src1 (LoadD src2))); 10550 10551 ins_cost(100); 10552 format %{ "ucomisd $src1, $src2" %} 10553 ins_encode %{ 10554 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10555 %} 10556 ins_pipe(pipe_slow); 10557 %} 10558 10559 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10560 match(Set cr (CmpD src con)); 10561 10562 ins_cost(145); 10563 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10564 "jnp,s exit\n\t" 10565 "pushfq\t# saw NaN, set CF\n\t" 10566 "andq [rsp], #0xffffff2b\n\t" 10567 "popfq\n" 10568 "exit:" %} 10569 ins_encode %{ 10570 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10571 emit_cmpfp_fixup(_masm); 10572 %} 10573 ins_pipe(pipe_slow); 10574 %} 10575 10576 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10577 match(Set cr (CmpD src con)); 10578 ins_cost(100); 10579 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10580 ins_encode %{ 10581 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10582 %} 10583 ins_pipe(pipe_slow); 10584 %} 10585 10586 // Compare into -1,0,1 10587 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10588 %{ 10589 match(Set dst (CmpF3 src1 src2)); 10590 effect(KILL cr); 10591 10592 ins_cost(275); 10593 format %{ "ucomiss $src1, $src2\n\t" 10594 "movl $dst, #-1\n\t" 10595 "jp,s done\n\t" 10596 "jb,s done\n\t" 10597 "setne $dst\n\t" 10598 "movzbl $dst, $dst\n" 10599 "done:" %} 10600 ins_encode %{ 10601 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10602 emit_cmpfp3(_masm, $dst$$Register); 10603 %} 10604 ins_pipe(pipe_slow); 10605 %} 10606 10607 // Compare into -1,0,1 10608 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10609 %{ 10610 match(Set dst (CmpF3 src1 (LoadF src2))); 10611 effect(KILL cr); 10612 10613 ins_cost(275); 10614 format %{ "ucomiss $src1, $src2\n\t" 10615 "movl $dst, #-1\n\t" 10616 "jp,s done\n\t" 10617 "jb,s done\n\t" 10618 "setne $dst\n\t" 10619 "movzbl $dst, $dst\n" 10620 "done:" %} 10621 ins_encode %{ 10622 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10623 emit_cmpfp3(_masm, $dst$$Register); 10624 %} 10625 ins_pipe(pipe_slow); 10626 %} 10627 10628 // Compare into -1,0,1 10629 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10630 match(Set dst (CmpF3 src con)); 10631 effect(KILL cr); 10632 10633 ins_cost(275); 10634 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10635 "movl $dst, #-1\n\t" 10636 "jp,s done\n\t" 10637 "jb,s done\n\t" 10638 "setne $dst\n\t" 10639 "movzbl $dst, $dst\n" 10640 "done:" %} 10641 ins_encode %{ 10642 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10643 emit_cmpfp3(_masm, $dst$$Register); 10644 %} 10645 ins_pipe(pipe_slow); 10646 %} 10647 10648 // Compare into -1,0,1 10649 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10650 %{ 10651 match(Set dst (CmpD3 src1 src2)); 10652 effect(KILL cr); 10653 10654 ins_cost(275); 10655 format %{ "ucomisd $src1, $src2\n\t" 10656 "movl $dst, #-1\n\t" 10657 "jp,s done\n\t" 10658 "jb,s done\n\t" 10659 "setne $dst\n\t" 10660 "movzbl $dst, $dst\n" 10661 "done:" %} 10662 ins_encode %{ 10663 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10664 emit_cmpfp3(_masm, $dst$$Register); 10665 %} 10666 ins_pipe(pipe_slow); 10667 %} 10668 10669 // Compare into -1,0,1 10670 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10671 %{ 10672 match(Set dst (CmpD3 src1 (LoadD src2))); 10673 effect(KILL cr); 10674 10675 ins_cost(275); 10676 format %{ "ucomisd $src1, $src2\n\t" 10677 "movl $dst, #-1\n\t" 10678 "jp,s done\n\t" 10679 "jb,s done\n\t" 10680 "setne $dst\n\t" 10681 "movzbl $dst, $dst\n" 10682 "done:" %} 10683 ins_encode %{ 10684 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10685 emit_cmpfp3(_masm, $dst$$Register); 10686 %} 10687 ins_pipe(pipe_slow); 10688 %} 10689 10690 // Compare into -1,0,1 10691 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10692 match(Set dst (CmpD3 src con)); 10693 effect(KILL cr); 10694 10695 ins_cost(275); 10696 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10697 "movl $dst, #-1\n\t" 10698 "jp,s done\n\t" 10699 "jb,s done\n\t" 10700 "setne $dst\n\t" 10701 "movzbl $dst, $dst\n" 10702 "done:" %} 10703 ins_encode %{ 10704 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10705 emit_cmpfp3(_masm, $dst$$Register); 10706 %} 10707 ins_pipe(pipe_slow); 10708 %} 10709 10710 //----------Arithmetic Conversion Instructions--------------------------------- 10711 10712 instruct roundFloat_nop(regF dst) 10713 %{ 10714 match(Set dst (RoundFloat dst)); 10715 10716 ins_cost(0); 10717 ins_encode(); 10718 ins_pipe(empty); 10719 %} 10720 10721 instruct roundDouble_nop(regD dst) 10722 %{ 10723 match(Set dst (RoundDouble dst)); 10724 10725 ins_cost(0); 10726 ins_encode(); 10727 ins_pipe(empty); 10728 %} 10729 10730 instruct convF2D_reg_reg(regD dst, regF src) 10731 %{ 10732 match(Set dst (ConvF2D src)); 10733 10734 format %{ "cvtss2sd $dst, $src" %} 10735 ins_encode %{ 10736 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10737 %} 10738 ins_pipe(pipe_slow); // XXX 10739 %} 10740 10741 instruct convF2D_reg_mem(regD dst, memory src) 10742 %{ 10743 match(Set dst (ConvF2D (LoadF src))); 10744 10745 format %{ "cvtss2sd $dst, $src" %} 10746 ins_encode %{ 10747 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10748 %} 10749 ins_pipe(pipe_slow); // XXX 10750 %} 10751 10752 instruct convD2F_reg_reg(regF dst, regD src) 10753 %{ 10754 match(Set dst (ConvD2F src)); 10755 10756 format %{ "cvtsd2ss $dst, $src" %} 10757 ins_encode %{ 10758 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10759 %} 10760 ins_pipe(pipe_slow); // XXX 10761 %} 10762 10763 instruct convD2F_reg_mem(regF dst, memory src) 10764 %{ 10765 match(Set dst (ConvD2F (LoadD src))); 10766 10767 format %{ "cvtsd2ss $dst, $src" %} 10768 ins_encode %{ 10769 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10770 %} 10771 ins_pipe(pipe_slow); // XXX 10772 %} 10773 10774 // XXX do mem variants 10775 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10776 %{ 10777 match(Set dst (ConvF2I src)); 10778 effect(KILL cr); 10779 10780 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10781 "cmpl $dst, #0x80000000\n\t" 10782 "jne,s done\n\t" 10783 "subq rsp, #8\n\t" 10784 "movss [rsp], $src\n\t" 10785 "call f2i_fixup\n\t" 10786 "popq $dst\n" 10787 "done: "%} 10788 ins_encode %{ 10789 Label done; 10790 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10791 __ cmpl($dst$$Register, 0x80000000); 10792 __ jccb(Assembler::notEqual, done); 10793 __ subptr(rsp, 8); 10794 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10795 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10796 __ pop($dst$$Register); 10797 __ bind(done); 10798 %} 10799 ins_pipe(pipe_slow); 10800 %} 10801 10802 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10803 %{ 10804 match(Set dst (ConvF2L src)); 10805 effect(KILL cr); 10806 10807 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10808 "cmpq $dst, [0x8000000000000000]\n\t" 10809 "jne,s done\n\t" 10810 "subq rsp, #8\n\t" 10811 "movss [rsp], $src\n\t" 10812 "call f2l_fixup\n\t" 10813 "popq $dst\n" 10814 "done: "%} 10815 ins_encode %{ 10816 Label done; 10817 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10818 __ cmp64($dst$$Register, 10819 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10820 __ jccb(Assembler::notEqual, done); 10821 __ subptr(rsp, 8); 10822 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10823 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10824 __ pop($dst$$Register); 10825 __ bind(done); 10826 %} 10827 ins_pipe(pipe_slow); 10828 %} 10829 10830 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10831 %{ 10832 match(Set dst (ConvD2I src)); 10833 effect(KILL cr); 10834 10835 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10836 "cmpl $dst, #0x80000000\n\t" 10837 "jne,s done\n\t" 10838 "subq rsp, #8\n\t" 10839 "movsd [rsp], $src\n\t" 10840 "call d2i_fixup\n\t" 10841 "popq $dst\n" 10842 "done: "%} 10843 ins_encode %{ 10844 Label done; 10845 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10846 __ cmpl($dst$$Register, 0x80000000); 10847 __ jccb(Assembler::notEqual, done); 10848 __ subptr(rsp, 8); 10849 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10850 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10851 __ pop($dst$$Register); 10852 __ bind(done); 10853 %} 10854 ins_pipe(pipe_slow); 10855 %} 10856 10857 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10858 %{ 10859 match(Set dst (ConvD2L src)); 10860 effect(KILL cr); 10861 10862 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10863 "cmpq $dst, [0x8000000000000000]\n\t" 10864 "jne,s done\n\t" 10865 "subq rsp, #8\n\t" 10866 "movsd [rsp], $src\n\t" 10867 "call d2l_fixup\n\t" 10868 "popq $dst\n" 10869 "done: "%} 10870 ins_encode %{ 10871 Label done; 10872 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10873 __ cmp64($dst$$Register, 10874 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10875 __ jccb(Assembler::notEqual, done); 10876 __ subptr(rsp, 8); 10877 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10878 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10879 __ pop($dst$$Register); 10880 __ bind(done); 10881 %} 10882 ins_pipe(pipe_slow); 10883 %} 10884 10885 instruct convI2F_reg_reg(regF dst, rRegI src) 10886 %{ 10887 predicate(!UseXmmI2F); 10888 match(Set dst (ConvI2F src)); 10889 10890 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10891 ins_encode %{ 10892 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10893 %} 10894 ins_pipe(pipe_slow); // XXX 10895 %} 10896 10897 instruct convI2F_reg_mem(regF dst, memory src) 10898 %{ 10899 match(Set dst (ConvI2F (LoadI src))); 10900 10901 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10902 ins_encode %{ 10903 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10904 %} 10905 ins_pipe(pipe_slow); // XXX 10906 %} 10907 10908 instruct convI2D_reg_reg(regD dst, rRegI src) 10909 %{ 10910 predicate(!UseXmmI2D); 10911 match(Set dst (ConvI2D src)); 10912 10913 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10914 ins_encode %{ 10915 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10916 %} 10917 ins_pipe(pipe_slow); // XXX 10918 %} 10919 10920 instruct convI2D_reg_mem(regD dst, memory src) 10921 %{ 10922 match(Set dst (ConvI2D (LoadI src))); 10923 10924 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10925 ins_encode %{ 10926 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10927 %} 10928 ins_pipe(pipe_slow); // XXX 10929 %} 10930 10931 instruct convXI2F_reg(regF dst, rRegI src) 10932 %{ 10933 predicate(UseXmmI2F); 10934 match(Set dst (ConvI2F src)); 10935 10936 format %{ "movdl $dst, $src\n\t" 10937 "cvtdq2psl $dst, $dst\t# i2f" %} 10938 ins_encode %{ 10939 __ movdl($dst$$XMMRegister, $src$$Register); 10940 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10941 %} 10942 ins_pipe(pipe_slow); // XXX 10943 %} 10944 10945 instruct convXI2D_reg(regD dst, rRegI src) 10946 %{ 10947 predicate(UseXmmI2D); 10948 match(Set dst (ConvI2D src)); 10949 10950 format %{ "movdl $dst, $src\n\t" 10951 "cvtdq2pdl $dst, $dst\t# i2d" %} 10952 ins_encode %{ 10953 __ movdl($dst$$XMMRegister, $src$$Register); 10954 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10955 %} 10956 ins_pipe(pipe_slow); // XXX 10957 %} 10958 10959 instruct convL2F_reg_reg(regF dst, rRegL src) 10960 %{ 10961 match(Set dst (ConvL2F src)); 10962 10963 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10964 ins_encode %{ 10965 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10966 %} 10967 ins_pipe(pipe_slow); // XXX 10968 %} 10969 10970 instruct convL2F_reg_mem(regF dst, memory src) 10971 %{ 10972 match(Set dst (ConvL2F (LoadL src))); 10973 10974 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10975 ins_encode %{ 10976 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10977 %} 10978 ins_pipe(pipe_slow); // XXX 10979 %} 10980 10981 instruct convL2D_reg_reg(regD dst, rRegL src) 10982 %{ 10983 match(Set dst (ConvL2D src)); 10984 10985 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10986 ins_encode %{ 10987 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10988 %} 10989 ins_pipe(pipe_slow); // XXX 10990 %} 10991 10992 instruct convL2D_reg_mem(regD dst, memory src) 10993 %{ 10994 match(Set dst (ConvL2D (LoadL src))); 10995 10996 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10997 ins_encode %{ 10998 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10999 %} 11000 ins_pipe(pipe_slow); // XXX 11001 %} 11002 11003 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11004 %{ 11005 match(Set dst (ConvI2L src)); 11006 11007 ins_cost(125); 11008 format %{ "movslq $dst, $src\t# i2l" %} 11009 ins_encode %{ 11010 __ movslq($dst$$Register, $src$$Register); 11011 %} 11012 ins_pipe(ialu_reg_reg); 11013 %} 11014 11015 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 11016 // %{ 11017 // match(Set dst (ConvI2L src)); 11018 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 11019 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 11020 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 11021 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 11022 // ((const TypeNode*) n)->type()->is_long()->_lo == 11023 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 11024 11025 // format %{ "movl $dst, $src\t# unsigned i2l" %} 11026 // ins_encode(enc_copy(dst, src)); 11027 // // opcode(0x63); // needs REX.W 11028 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 11029 // ins_pipe(ialu_reg_reg); 11030 // %} 11031 11032 // Zero-extend convert int to long 11033 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 11034 %{ 11035 match(Set dst (AndL (ConvI2L src) mask)); 11036 11037 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11038 ins_encode %{ 11039 if ($dst$$reg != $src$$reg) { 11040 __ movl($dst$$Register, $src$$Register); 11041 } 11042 %} 11043 ins_pipe(ialu_reg_reg); 11044 %} 11045 11046 // Zero-extend convert int to long 11047 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11048 %{ 11049 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11050 11051 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11052 ins_encode %{ 11053 __ movl($dst$$Register, $src$$Address); 11054 %} 11055 ins_pipe(ialu_reg_mem); 11056 %} 11057 11058 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 11059 %{ 11060 match(Set dst (AndL src mask)); 11061 11062 format %{ "movl $dst, $src\t# zero-extend long" %} 11063 ins_encode %{ 11064 __ movl($dst$$Register, $src$$Register); 11065 %} 11066 ins_pipe(ialu_reg_reg); 11067 %} 11068 11069 instruct convL2I_reg_reg(rRegI dst, rRegL src) 11070 %{ 11071 match(Set dst (ConvL2I src)); 11072 11073 format %{ "movl $dst, $src\t# l2i" %} 11074 ins_encode %{ 11075 __ movl($dst$$Register, $src$$Register); 11076 %} 11077 ins_pipe(ialu_reg_reg); 11078 %} 11079 11080 11081 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 11082 match(Set dst (MoveF2I src)); 11083 effect(DEF dst, USE src); 11084 11085 ins_cost(125); 11086 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 11087 ins_encode %{ 11088 __ movl($dst$$Register, Address(rsp, $src$$disp)); 11089 %} 11090 ins_pipe(ialu_reg_mem); 11091 %} 11092 11093 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 11094 match(Set dst (MoveI2F src)); 11095 effect(DEF dst, USE src); 11096 11097 ins_cost(125); 11098 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 11099 ins_encode %{ 11100 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 11101 %} 11102 ins_pipe(pipe_slow); 11103 %} 11104 11105 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 11106 match(Set dst (MoveD2L src)); 11107 effect(DEF dst, USE src); 11108 11109 ins_cost(125); 11110 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 11111 ins_encode %{ 11112 __ movq($dst$$Register, Address(rsp, $src$$disp)); 11113 %} 11114 ins_pipe(ialu_reg_mem); 11115 %} 11116 11117 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 11118 predicate(!UseXmmLoadAndClearUpper); 11119 match(Set dst (MoveL2D src)); 11120 effect(DEF dst, USE src); 11121 11122 ins_cost(125); 11123 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 11124 ins_encode %{ 11125 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11126 %} 11127 ins_pipe(pipe_slow); 11128 %} 11129 11130 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 11131 predicate(UseXmmLoadAndClearUpper); 11132 match(Set dst (MoveL2D src)); 11133 effect(DEF dst, USE src); 11134 11135 ins_cost(125); 11136 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 11137 ins_encode %{ 11138 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11139 %} 11140 ins_pipe(pipe_slow); 11141 %} 11142 11143 11144 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 11145 match(Set dst (MoveF2I src)); 11146 effect(DEF dst, USE src); 11147 11148 ins_cost(95); // XXX 11149 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 11150 ins_encode %{ 11151 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 11152 %} 11153 ins_pipe(pipe_slow); 11154 %} 11155 11156 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 11157 match(Set dst (MoveI2F src)); 11158 effect(DEF dst, USE src); 11159 11160 ins_cost(100); 11161 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 11162 ins_encode %{ 11163 __ movl(Address(rsp, $dst$$disp), $src$$Register); 11164 %} 11165 ins_pipe( ialu_mem_reg ); 11166 %} 11167 11168 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 11169 match(Set dst (MoveD2L src)); 11170 effect(DEF dst, USE src); 11171 11172 ins_cost(95); // XXX 11173 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 11174 ins_encode %{ 11175 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 11176 %} 11177 ins_pipe(pipe_slow); 11178 %} 11179 11180 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 11181 match(Set dst (MoveL2D src)); 11182 effect(DEF dst, USE src); 11183 11184 ins_cost(100); 11185 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 11186 ins_encode %{ 11187 __ movq(Address(rsp, $dst$$disp), $src$$Register); 11188 %} 11189 ins_pipe(ialu_mem_reg); 11190 %} 11191 11192 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 11193 match(Set dst (MoveF2I src)); 11194 effect(DEF dst, USE src); 11195 ins_cost(85); 11196 format %{ "movd $dst,$src\t# MoveF2I" %} 11197 ins_encode %{ 11198 __ movdl($dst$$Register, $src$$XMMRegister); 11199 %} 11200 ins_pipe( pipe_slow ); 11201 %} 11202 11203 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 11204 match(Set dst (MoveD2L src)); 11205 effect(DEF dst, USE src); 11206 ins_cost(85); 11207 format %{ "movd $dst,$src\t# MoveD2L" %} 11208 ins_encode %{ 11209 __ movdq($dst$$Register, $src$$XMMRegister); 11210 %} 11211 ins_pipe( pipe_slow ); 11212 %} 11213 11214 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 11215 match(Set dst (MoveI2F src)); 11216 effect(DEF dst, USE src); 11217 ins_cost(100); 11218 format %{ "movd $dst,$src\t# MoveI2F" %} 11219 ins_encode %{ 11220 __ movdl($dst$$XMMRegister, $src$$Register); 11221 %} 11222 ins_pipe( pipe_slow ); 11223 %} 11224 11225 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 11226 match(Set dst (MoveL2D src)); 11227 effect(DEF dst, USE src); 11228 ins_cost(100); 11229 format %{ "movd $dst,$src\t# MoveL2D" %} 11230 ins_encode %{ 11231 __ movdq($dst$$XMMRegister, $src$$Register); 11232 %} 11233 ins_pipe( pipe_slow ); 11234 %} 11235 11236 11237 // ======================================================================= 11238 // fast clearing of an array 11239 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11240 Universe dummy, rFlagsReg cr) 11241 %{ 11242 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only()); 11243 match(Set dummy (ClearArray (Binary cnt base) val)); 11244 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11245 11246 format %{ $$template 11247 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11248 $$emit$$"jg LARGE\n\t" 11249 $$emit$$"dec rcx\n\t" 11250 $$emit$$"js DONE\t# Zero length\n\t" 11251 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11252 $$emit$$"dec rcx\n\t" 11253 $$emit$$"jge LOOP\n\t" 11254 $$emit$$"jmp DONE\n\t" 11255 $$emit$$"# LARGE:\n\t" 11256 if (UseFastStosb) { 11257 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11258 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 11259 } else if (UseXMMForObjInit) { 11260 $$emit$$"movdq $tmp, $val\n\t" 11261 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11262 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11263 $$emit$$"jmpq L_zero_64_bytes\n\t" 11264 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11265 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11266 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11267 $$emit$$"add 0x40,rax\n\t" 11268 $$emit$$"# L_zero_64_bytes:\n\t" 11269 $$emit$$"sub 0x8,rcx\n\t" 11270 $$emit$$"jge L_loop\n\t" 11271 $$emit$$"add 0x4,rcx\n\t" 11272 $$emit$$"jl L_tail\n\t" 11273 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11274 $$emit$$"add 0x20,rax\n\t" 11275 $$emit$$"sub 0x4,rcx\n\t" 11276 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11277 $$emit$$"add 0x4,rcx\n\t" 11278 $$emit$$"jle L_end\n\t" 11279 $$emit$$"dec rcx\n\t" 11280 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11281 $$emit$$"vmovq xmm0,(rax)\n\t" 11282 $$emit$$"add 0x8,rax\n\t" 11283 $$emit$$"dec rcx\n\t" 11284 $$emit$$"jge L_sloop\n\t" 11285 $$emit$$"# L_end:\n\t" 11286 } else { 11287 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11288 } 11289 $$emit$$"# DONE" 11290 %} 11291 ins_encode %{ 11292 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11293 $tmp$$XMMRegister, false, false); 11294 %} 11295 ins_pipe(pipe_slow); 11296 %} 11297 11298 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11299 Universe dummy, rFlagsReg cr) 11300 %{ 11301 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only()); 11302 match(Set dummy (ClearArray (Binary cnt base) val)); 11303 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11304 11305 format %{ $$template 11306 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11307 $$emit$$"jg LARGE\n\t" 11308 $$emit$$"dec rcx\n\t" 11309 $$emit$$"js DONE\t# Zero length\n\t" 11310 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11311 $$emit$$"dec rcx\n\t" 11312 $$emit$$"jge LOOP\n\t" 11313 $$emit$$"jmp DONE\n\t" 11314 $$emit$$"# LARGE:\n\t" 11315 if (UseXMMForObjInit) { 11316 $$emit$$"movdq $tmp, $val\n\t" 11317 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11318 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11319 $$emit$$"jmpq L_zero_64_bytes\n\t" 11320 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11321 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11322 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11323 $$emit$$"add 0x40,rax\n\t" 11324 $$emit$$"# L_zero_64_bytes:\n\t" 11325 $$emit$$"sub 0x8,rcx\n\t" 11326 $$emit$$"jge L_loop\n\t" 11327 $$emit$$"add 0x4,rcx\n\t" 11328 $$emit$$"jl L_tail\n\t" 11329 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11330 $$emit$$"add 0x20,rax\n\t" 11331 $$emit$$"sub 0x4,rcx\n\t" 11332 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11333 $$emit$$"add 0x4,rcx\n\t" 11334 $$emit$$"jle L_end\n\t" 11335 $$emit$$"dec rcx\n\t" 11336 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11337 $$emit$$"vmovq xmm0,(rax)\n\t" 11338 $$emit$$"add 0x8,rax\n\t" 11339 $$emit$$"dec rcx\n\t" 11340 $$emit$$"jge L_sloop\n\t" 11341 $$emit$$"# L_end:\n\t" 11342 } else { 11343 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11344 } 11345 $$emit$$"# DONE" 11346 %} 11347 ins_encode %{ 11348 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11349 $tmp$$XMMRegister, false, true); 11350 %} 11351 ins_pipe(pipe_slow); 11352 %} 11353 11354 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11355 Universe dummy, rFlagsReg cr) 11356 %{ 11357 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only()); 11358 match(Set dummy (ClearArray (Binary cnt base) val)); 11359 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11360 11361 format %{ $$template 11362 if (UseFastStosb) { 11363 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11364 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11365 } else if (UseXMMForObjInit) { 11366 $$emit$$"movdq $tmp, $val\n\t" 11367 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11368 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11369 $$emit$$"jmpq L_zero_64_bytes\n\t" 11370 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11371 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11372 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11373 $$emit$$"add 0x40,rax\n\t" 11374 $$emit$$"# L_zero_64_bytes:\n\t" 11375 $$emit$$"sub 0x8,rcx\n\t" 11376 $$emit$$"jge L_loop\n\t" 11377 $$emit$$"add 0x4,rcx\n\t" 11378 $$emit$$"jl L_tail\n\t" 11379 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11380 $$emit$$"add 0x20,rax\n\t" 11381 $$emit$$"sub 0x4,rcx\n\t" 11382 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11383 $$emit$$"add 0x4,rcx\n\t" 11384 $$emit$$"jle L_end\n\t" 11385 $$emit$$"dec rcx\n\t" 11386 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11387 $$emit$$"vmovq xmm0,(rax)\n\t" 11388 $$emit$$"add 0x8,rax\n\t" 11389 $$emit$$"dec rcx\n\t" 11390 $$emit$$"jge L_sloop\n\t" 11391 $$emit$$"# L_end:\n\t" 11392 } else { 11393 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11394 } 11395 %} 11396 ins_encode %{ 11397 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11398 $tmp$$XMMRegister, true, false); 11399 %} 11400 ins_pipe(pipe_slow); 11401 %} 11402 11403 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 11404 Universe dummy, rFlagsReg cr) 11405 %{ 11406 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only()); 11407 match(Set dummy (ClearArray (Binary cnt base) val)); 11408 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 11409 11410 format %{ $$template 11411 if (UseXMMForObjInit) { 11412 $$emit$$"movdq $tmp, $val\n\t" 11413 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 11414 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 11415 $$emit$$"jmpq L_zero_64_bytes\n\t" 11416 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11417 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11418 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 11419 $$emit$$"add 0x40,rax\n\t" 11420 $$emit$$"# L_zero_64_bytes:\n\t" 11421 $$emit$$"sub 0x8,rcx\n\t" 11422 $$emit$$"jge L_loop\n\t" 11423 $$emit$$"add 0x4,rcx\n\t" 11424 $$emit$$"jl L_tail\n\t" 11425 $$emit$$"vmovdqu $tmp,(rax)\n\t" 11426 $$emit$$"add 0x20,rax\n\t" 11427 $$emit$$"sub 0x4,rcx\n\t" 11428 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11429 $$emit$$"add 0x4,rcx\n\t" 11430 $$emit$$"jle L_end\n\t" 11431 $$emit$$"dec rcx\n\t" 11432 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11433 $$emit$$"vmovq xmm0,(rax)\n\t" 11434 $$emit$$"add 0x8,rax\n\t" 11435 $$emit$$"dec rcx\n\t" 11436 $$emit$$"jge L_sloop\n\t" 11437 $$emit$$"# L_end:\n\t" 11438 } else { 11439 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11440 } 11441 %} 11442 ins_encode %{ 11443 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11444 $tmp$$XMMRegister, true, true); 11445 %} 11446 ins_pipe(pipe_slow); 11447 %} 11448 11449 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11450 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11451 %{ 11452 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11453 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11454 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11455 11456 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11457 ins_encode %{ 11458 __ string_compare($str1$$Register, $str2$$Register, 11459 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11460 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11461 %} 11462 ins_pipe( pipe_slow ); 11463 %} 11464 11465 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11466 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11467 %{ 11468 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11469 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11470 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11471 11472 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11473 ins_encode %{ 11474 __ string_compare($str1$$Register, $str2$$Register, 11475 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11476 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11477 %} 11478 ins_pipe( pipe_slow ); 11479 %} 11480 11481 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11482 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11483 %{ 11484 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11485 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11486 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11487 11488 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11489 ins_encode %{ 11490 __ string_compare($str1$$Register, $str2$$Register, 11491 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11492 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11493 %} 11494 ins_pipe( pipe_slow ); 11495 %} 11496 11497 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11498 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11499 %{ 11500 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11501 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11502 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11503 11504 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11505 ins_encode %{ 11506 __ string_compare($str2$$Register, $str1$$Register, 11507 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11508 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11509 %} 11510 ins_pipe( pipe_slow ); 11511 %} 11512 11513 // fast search of substring with known size. 11514 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11515 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11516 %{ 11517 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11518 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11519 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11520 11521 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11522 ins_encode %{ 11523 int icnt2 = (int)$int_cnt2$$constant; 11524 if (icnt2 >= 16) { 11525 // IndexOf for constant substrings with size >= 16 elements 11526 // which don't need to be loaded through stack. 11527 __ string_indexofC8($str1$$Register, $str2$$Register, 11528 $cnt1$$Register, $cnt2$$Register, 11529 icnt2, $result$$Register, 11530 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11531 } else { 11532 // Small strings are loaded through stack if they cross page boundary. 11533 __ string_indexof($str1$$Register, $str2$$Register, 11534 $cnt1$$Register, $cnt2$$Register, 11535 icnt2, $result$$Register, 11536 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11537 } 11538 %} 11539 ins_pipe( pipe_slow ); 11540 %} 11541 11542 // fast search of substring with known size. 11543 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11544 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11545 %{ 11546 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11547 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11548 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11549 11550 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11551 ins_encode %{ 11552 int icnt2 = (int)$int_cnt2$$constant; 11553 if (icnt2 >= 8) { 11554 // IndexOf for constant substrings with size >= 8 elements 11555 // which don't need to be loaded through stack. 11556 __ string_indexofC8($str1$$Register, $str2$$Register, 11557 $cnt1$$Register, $cnt2$$Register, 11558 icnt2, $result$$Register, 11559 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11560 } else { 11561 // Small strings are loaded through stack if they cross page boundary. 11562 __ string_indexof($str1$$Register, $str2$$Register, 11563 $cnt1$$Register, $cnt2$$Register, 11564 icnt2, $result$$Register, 11565 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11566 } 11567 %} 11568 ins_pipe( pipe_slow ); 11569 %} 11570 11571 // fast search of substring with known size. 11572 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11573 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11574 %{ 11575 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11576 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11577 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11578 11579 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11580 ins_encode %{ 11581 int icnt2 = (int)$int_cnt2$$constant; 11582 if (icnt2 >= 8) { 11583 // IndexOf for constant substrings with size >= 8 elements 11584 // which don't need to be loaded through stack. 11585 __ string_indexofC8($str1$$Register, $str2$$Register, 11586 $cnt1$$Register, $cnt2$$Register, 11587 icnt2, $result$$Register, 11588 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11589 } else { 11590 // Small strings are loaded through stack if they cross page boundary. 11591 __ string_indexof($str1$$Register, $str2$$Register, 11592 $cnt1$$Register, $cnt2$$Register, 11593 icnt2, $result$$Register, 11594 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11595 } 11596 %} 11597 ins_pipe( pipe_slow ); 11598 %} 11599 11600 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11601 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11602 %{ 11603 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11604 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11605 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11606 11607 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11608 ins_encode %{ 11609 __ string_indexof($str1$$Register, $str2$$Register, 11610 $cnt1$$Register, $cnt2$$Register, 11611 (-1), $result$$Register, 11612 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11613 %} 11614 ins_pipe( pipe_slow ); 11615 %} 11616 11617 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11618 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11619 %{ 11620 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11621 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11622 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11623 11624 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11625 ins_encode %{ 11626 __ string_indexof($str1$$Register, $str2$$Register, 11627 $cnt1$$Register, $cnt2$$Register, 11628 (-1), $result$$Register, 11629 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11630 %} 11631 ins_pipe( pipe_slow ); 11632 %} 11633 11634 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11635 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11636 %{ 11637 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11638 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11639 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11640 11641 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11642 ins_encode %{ 11643 __ string_indexof($str1$$Register, $str2$$Register, 11644 $cnt1$$Register, $cnt2$$Register, 11645 (-1), $result$$Register, 11646 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11647 %} 11648 ins_pipe( pipe_slow ); 11649 %} 11650 11651 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11652 rbx_RegI result, legVecS vec1, legVecS vec2, legVecS vec3, rcx_RegI tmp, rFlagsReg cr) 11653 %{ 11654 predicate(UseSSE42Intrinsics); 11655 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11656 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11657 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11658 ins_encode %{ 11659 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11660 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11661 %} 11662 ins_pipe( pipe_slow ); 11663 %} 11664 11665 // fast string equals 11666 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11667 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11668 %{ 11669 match(Set result (StrEquals (Binary str1 str2) cnt)); 11670 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11671 11672 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11673 ins_encode %{ 11674 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11675 $cnt$$Register, $result$$Register, $tmp3$$Register, 11676 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11677 %} 11678 ins_pipe( pipe_slow ); 11679 %} 11680 11681 // fast array equals 11682 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11683 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11684 %{ 11685 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11686 match(Set result (AryEq ary1 ary2)); 11687 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11688 11689 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11690 ins_encode %{ 11691 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11692 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11693 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11694 %} 11695 ins_pipe( pipe_slow ); 11696 %} 11697 11698 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11699 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11700 %{ 11701 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11702 match(Set result (AryEq ary1 ary2)); 11703 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11704 11705 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11706 ins_encode %{ 11707 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11708 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11709 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11710 %} 11711 ins_pipe( pipe_slow ); 11712 %} 11713 11714 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11715 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11716 %{ 11717 match(Set result (HasNegatives ary1 len)); 11718 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11719 11720 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11721 ins_encode %{ 11722 __ has_negatives($ary1$$Register, $len$$Register, 11723 $result$$Register, $tmp3$$Register, 11724 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11725 %} 11726 ins_pipe( pipe_slow ); 11727 %} 11728 11729 // fast char[] to byte[] compression 11730 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11731 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11732 match(Set result (StrCompressedCopy src (Binary dst len))); 11733 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11734 11735 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11736 ins_encode %{ 11737 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11738 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11739 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11740 %} 11741 ins_pipe( pipe_slow ); 11742 %} 11743 11744 // fast byte[] to char[] inflation 11745 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11746 legVecS tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11747 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11748 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11749 11750 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11751 ins_encode %{ 11752 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11753 $tmp1$$XMMRegister, $tmp2$$Register); 11754 %} 11755 ins_pipe( pipe_slow ); 11756 %} 11757 11758 // encode char[] to byte[] in ISO_8859_1 11759 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11760 legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11761 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11762 match(Set result (EncodeISOArray src (Binary dst len))); 11763 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11764 11765 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11766 ins_encode %{ 11767 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11768 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11769 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11770 %} 11771 ins_pipe( pipe_slow ); 11772 %} 11773 11774 //----------Overflow Math Instructions----------------------------------------- 11775 11776 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11777 %{ 11778 match(Set cr (OverflowAddI op1 op2)); 11779 effect(DEF cr, USE_KILL op1, USE op2); 11780 11781 format %{ "addl $op1, $op2\t# overflow check int" %} 11782 11783 ins_encode %{ 11784 __ addl($op1$$Register, $op2$$Register); 11785 %} 11786 ins_pipe(ialu_reg_reg); 11787 %} 11788 11789 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11790 %{ 11791 match(Set cr (OverflowAddI op1 op2)); 11792 effect(DEF cr, USE_KILL op1, USE op2); 11793 11794 format %{ "addl $op1, $op2\t# overflow check int" %} 11795 11796 ins_encode %{ 11797 __ addl($op1$$Register, $op2$$constant); 11798 %} 11799 ins_pipe(ialu_reg_reg); 11800 %} 11801 11802 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11803 %{ 11804 match(Set cr (OverflowAddL op1 op2)); 11805 effect(DEF cr, USE_KILL op1, USE op2); 11806 11807 format %{ "addq $op1, $op2\t# overflow check long" %} 11808 ins_encode %{ 11809 __ addq($op1$$Register, $op2$$Register); 11810 %} 11811 ins_pipe(ialu_reg_reg); 11812 %} 11813 11814 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11815 %{ 11816 match(Set cr (OverflowAddL op1 op2)); 11817 effect(DEF cr, USE_KILL op1, USE op2); 11818 11819 format %{ "addq $op1, $op2\t# overflow check long" %} 11820 ins_encode %{ 11821 __ addq($op1$$Register, $op2$$constant); 11822 %} 11823 ins_pipe(ialu_reg_reg); 11824 %} 11825 11826 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11827 %{ 11828 match(Set cr (OverflowSubI op1 op2)); 11829 11830 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11831 ins_encode %{ 11832 __ cmpl($op1$$Register, $op2$$Register); 11833 %} 11834 ins_pipe(ialu_reg_reg); 11835 %} 11836 11837 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11838 %{ 11839 match(Set cr (OverflowSubI op1 op2)); 11840 11841 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11842 ins_encode %{ 11843 __ cmpl($op1$$Register, $op2$$constant); 11844 %} 11845 ins_pipe(ialu_reg_reg); 11846 %} 11847 11848 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11849 %{ 11850 match(Set cr (OverflowSubL op1 op2)); 11851 11852 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11853 ins_encode %{ 11854 __ cmpq($op1$$Register, $op2$$Register); 11855 %} 11856 ins_pipe(ialu_reg_reg); 11857 %} 11858 11859 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11860 %{ 11861 match(Set cr (OverflowSubL op1 op2)); 11862 11863 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11864 ins_encode %{ 11865 __ cmpq($op1$$Register, $op2$$constant); 11866 %} 11867 ins_pipe(ialu_reg_reg); 11868 %} 11869 11870 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11871 %{ 11872 match(Set cr (OverflowSubI zero op2)); 11873 effect(DEF cr, USE_KILL op2); 11874 11875 format %{ "negl $op2\t# overflow check int" %} 11876 ins_encode %{ 11877 __ negl($op2$$Register); 11878 %} 11879 ins_pipe(ialu_reg_reg); 11880 %} 11881 11882 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11883 %{ 11884 match(Set cr (OverflowSubL zero op2)); 11885 effect(DEF cr, USE_KILL op2); 11886 11887 format %{ "negq $op2\t# overflow check long" %} 11888 ins_encode %{ 11889 __ negq($op2$$Register); 11890 %} 11891 ins_pipe(ialu_reg_reg); 11892 %} 11893 11894 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11895 %{ 11896 match(Set cr (OverflowMulI op1 op2)); 11897 effect(DEF cr, USE_KILL op1, USE op2); 11898 11899 format %{ "imull $op1, $op2\t# overflow check int" %} 11900 ins_encode %{ 11901 __ imull($op1$$Register, $op2$$Register); 11902 %} 11903 ins_pipe(ialu_reg_reg_alu0); 11904 %} 11905 11906 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11907 %{ 11908 match(Set cr (OverflowMulI op1 op2)); 11909 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11910 11911 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11912 ins_encode %{ 11913 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11914 %} 11915 ins_pipe(ialu_reg_reg_alu0); 11916 %} 11917 11918 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11919 %{ 11920 match(Set cr (OverflowMulL op1 op2)); 11921 effect(DEF cr, USE_KILL op1, USE op2); 11922 11923 format %{ "imulq $op1, $op2\t# overflow check long" %} 11924 ins_encode %{ 11925 __ imulq($op1$$Register, $op2$$Register); 11926 %} 11927 ins_pipe(ialu_reg_reg_alu0); 11928 %} 11929 11930 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11931 %{ 11932 match(Set cr (OverflowMulL op1 op2)); 11933 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11934 11935 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11936 ins_encode %{ 11937 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11938 %} 11939 ins_pipe(ialu_reg_reg_alu0); 11940 %} 11941 11942 11943 //----------Control Flow Instructions------------------------------------------ 11944 // Signed compare Instructions 11945 11946 // XXX more variants!! 11947 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11948 %{ 11949 match(Set cr (CmpI op1 op2)); 11950 effect(DEF cr, USE op1, USE op2); 11951 11952 format %{ "cmpl $op1, $op2" %} 11953 opcode(0x3B); /* Opcode 3B /r */ 11954 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11955 ins_pipe(ialu_cr_reg_reg); 11956 %} 11957 11958 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11959 %{ 11960 match(Set cr (CmpI op1 op2)); 11961 11962 format %{ "cmpl $op1, $op2" %} 11963 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11964 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11965 ins_pipe(ialu_cr_reg_imm); 11966 %} 11967 11968 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11969 %{ 11970 match(Set cr (CmpI op1 (LoadI op2))); 11971 11972 ins_cost(500); // XXX 11973 format %{ "cmpl $op1, $op2" %} 11974 opcode(0x3B); /* Opcode 3B /r */ 11975 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11976 ins_pipe(ialu_cr_reg_mem); 11977 %} 11978 11979 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11980 %{ 11981 match(Set cr (CmpI src zero)); 11982 11983 format %{ "testl $src, $src" %} 11984 opcode(0x85); 11985 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11986 ins_pipe(ialu_cr_reg_imm); 11987 %} 11988 11989 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11990 %{ 11991 match(Set cr (CmpI (AndI src con) zero)); 11992 11993 format %{ "testl $src, $con" %} 11994 opcode(0xF7, 0x00); 11995 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11996 ins_pipe(ialu_cr_reg_imm); 11997 %} 11998 11999 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 12000 %{ 12001 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 12002 12003 format %{ "testl $src, $mem" %} 12004 opcode(0x85); 12005 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 12006 ins_pipe(ialu_cr_reg_mem); 12007 %} 12008 12009 // Fold array properties check 12010 instruct testI_mem_imm(rFlagsReg cr, memory mem, immI con, immI0 zero) 12011 %{ 12012 match(Set cr (CmpI (AndI (CastN2I (LoadNKlass mem)) con) zero)); 12013 12014 format %{ "testl $mem, $con" %} 12015 opcode(0xF7, 0x00); 12016 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(con)); 12017 ins_pipe(ialu_mem_imm); 12018 %} 12019 12020 // Unsigned compare Instructions; really, same as signed except they 12021 // produce an rFlagsRegU instead of rFlagsReg. 12022 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 12023 %{ 12024 match(Set cr (CmpU op1 op2)); 12025 12026 format %{ "cmpl $op1, $op2\t# unsigned" %} 12027 opcode(0x3B); /* Opcode 3B /r */ 12028 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 12029 ins_pipe(ialu_cr_reg_reg); 12030 %} 12031 12032 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 12033 %{ 12034 match(Set cr (CmpU op1 op2)); 12035 12036 format %{ "cmpl $op1, $op2\t# unsigned" %} 12037 opcode(0x81,0x07); /* Opcode 81 /7 */ 12038 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 12039 ins_pipe(ialu_cr_reg_imm); 12040 %} 12041 12042 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 12043 %{ 12044 match(Set cr (CmpU op1 (LoadI op2))); 12045 12046 ins_cost(500); // XXX 12047 format %{ "cmpl $op1, $op2\t# unsigned" %} 12048 opcode(0x3B); /* Opcode 3B /r */ 12049 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 12050 ins_pipe(ialu_cr_reg_mem); 12051 %} 12052 12053 // // // Cisc-spilled version of cmpU_rReg 12054 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 12055 // //%{ 12056 // // match(Set cr (CmpU (LoadI op1) op2)); 12057 // // 12058 // // format %{ "CMPu $op1,$op2" %} 12059 // // ins_cost(500); 12060 // // opcode(0x39); /* Opcode 39 /r */ 12061 // // ins_encode( OpcP, reg_mem( op1, op2) ); 12062 // //%} 12063 12064 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 12065 %{ 12066 match(Set cr (CmpU src zero)); 12067 12068 format %{ "testl $src, $src\t# unsigned" %} 12069 opcode(0x85); 12070 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 12071 ins_pipe(ialu_cr_reg_imm); 12072 %} 12073 12074 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 12075 %{ 12076 match(Set cr (CmpP op1 op2)); 12077 12078 format %{ "cmpq $op1, $op2\t# ptr" %} 12079 opcode(0x3B); /* Opcode 3B /r */ 12080 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12081 ins_pipe(ialu_cr_reg_reg); 12082 %} 12083 12084 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 12085 %{ 12086 match(Set cr (CmpP op1 (LoadP op2))); 12087 12088 ins_cost(500); // XXX 12089 format %{ "cmpq $op1, $op2\t# ptr" %} 12090 opcode(0x3B); /* Opcode 3B /r */ 12091 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12092 ins_pipe(ialu_cr_reg_mem); 12093 %} 12094 12095 // // // Cisc-spilled version of cmpP_rReg 12096 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 12097 // //%{ 12098 // // match(Set cr (CmpP (LoadP op1) op2)); 12099 // // 12100 // // format %{ "CMPu $op1,$op2" %} 12101 // // ins_cost(500); 12102 // // opcode(0x39); /* Opcode 39 /r */ 12103 // // ins_encode( OpcP, reg_mem( op1, op2) ); 12104 // //%} 12105 12106 // XXX this is generalized by compP_rReg_mem??? 12107 // Compare raw pointer (used in out-of-heap check). 12108 // Only works because non-oop pointers must be raw pointers 12109 // and raw pointers have no anti-dependencies. 12110 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 12111 %{ 12112 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 12113 match(Set cr (CmpP op1 (LoadP op2))); 12114 12115 format %{ "cmpq $op1, $op2\t# raw ptr" %} 12116 opcode(0x3B); /* Opcode 3B /r */ 12117 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12118 ins_pipe(ialu_cr_reg_mem); 12119 %} 12120 12121 // This will generate a signed flags result. This should be OK since 12122 // any compare to a zero should be eq/neq. 12123 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 12124 %{ 12125 match(Set cr (CmpP src zero)); 12126 12127 format %{ "testq $src, $src\t# ptr" %} 12128 opcode(0x85); 12129 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12130 ins_pipe(ialu_cr_reg_imm); 12131 %} 12132 12133 // This will generate a signed flags result. This should be OK since 12134 // any compare to a zero should be eq/neq. 12135 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 12136 %{ 12137 predicate(!UseCompressedOops || (CompressedOops::base() != NULL)); 12138 match(Set cr (CmpP (LoadP op) zero)); 12139 12140 ins_cost(500); // XXX 12141 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 12142 opcode(0xF7); /* Opcode F7 /0 */ 12143 ins_encode(REX_mem_wide(op), 12144 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 12145 ins_pipe(ialu_cr_reg_imm); 12146 %} 12147 12148 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 12149 %{ 12150 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 12151 match(Set cr (CmpP (LoadP mem) zero)); 12152 12153 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 12154 ins_encode %{ 12155 __ cmpq(r12, $mem$$Address); 12156 %} 12157 ins_pipe(ialu_cr_reg_mem); 12158 %} 12159 12160 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 12161 %{ 12162 match(Set cr (CmpN op1 op2)); 12163 12164 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12165 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 12166 ins_pipe(ialu_cr_reg_reg); 12167 %} 12168 12169 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 12170 %{ 12171 match(Set cr (CmpN src (LoadN mem))); 12172 12173 format %{ "cmpl $src, $mem\t# compressed ptr" %} 12174 ins_encode %{ 12175 __ cmpl($src$$Register, $mem$$Address); 12176 %} 12177 ins_pipe(ialu_cr_reg_mem); 12178 %} 12179 12180 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 12181 match(Set cr (CmpN op1 op2)); 12182 12183 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12184 ins_encode %{ 12185 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 12186 %} 12187 ins_pipe(ialu_cr_reg_imm); 12188 %} 12189 12190 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 12191 %{ 12192 match(Set cr (CmpN src (LoadN mem))); 12193 12194 format %{ "cmpl $mem, $src\t# compressed ptr" %} 12195 ins_encode %{ 12196 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 12197 %} 12198 ins_pipe(ialu_cr_reg_mem); 12199 %} 12200 12201 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 12202 match(Set cr (CmpN op1 op2)); 12203 12204 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 12205 ins_encode %{ 12206 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 12207 %} 12208 ins_pipe(ialu_cr_reg_imm); 12209 %} 12210 12211 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 12212 %{ 12213 match(Set cr (CmpN src (LoadNKlass mem))); 12214 12215 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 12216 ins_encode %{ 12217 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 12218 %} 12219 ins_pipe(ialu_cr_reg_mem); 12220 %} 12221 12222 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 12223 match(Set cr (CmpN src zero)); 12224 12225 format %{ "testl $src, $src\t# compressed ptr" %} 12226 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 12227 ins_pipe(ialu_cr_reg_imm); 12228 %} 12229 12230 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 12231 %{ 12232 predicate(CompressedOops::base() != NULL); 12233 match(Set cr (CmpN (LoadN mem) zero)); 12234 12235 ins_cost(500); // XXX 12236 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 12237 ins_encode %{ 12238 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 12239 %} 12240 ins_pipe(ialu_cr_reg_mem); 12241 %} 12242 12243 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 12244 %{ 12245 predicate(CompressedOops::base() == NULL && (CompressedKlassPointers::base() == NULL)); 12246 match(Set cr (CmpN (LoadN mem) zero)); 12247 12248 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 12249 ins_encode %{ 12250 __ cmpl(r12, $mem$$Address); 12251 %} 12252 ins_pipe(ialu_cr_reg_mem); 12253 %} 12254 12255 // Yanked all unsigned pointer compare operations. 12256 // Pointer compares are done with CmpP which is already unsigned. 12257 12258 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 12259 %{ 12260 match(Set cr (CmpL op1 op2)); 12261 12262 format %{ "cmpq $op1, $op2" %} 12263 opcode(0x3B); /* Opcode 3B /r */ 12264 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12265 ins_pipe(ialu_cr_reg_reg); 12266 %} 12267 12268 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 12269 %{ 12270 match(Set cr (CmpL op1 op2)); 12271 12272 format %{ "cmpq $op1, $op2" %} 12273 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12274 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12275 ins_pipe(ialu_cr_reg_imm); 12276 %} 12277 12278 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 12279 %{ 12280 match(Set cr (CmpL op1 (LoadL op2))); 12281 12282 format %{ "cmpq $op1, $op2" %} 12283 opcode(0x3B); /* Opcode 3B /r */ 12284 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12285 ins_pipe(ialu_cr_reg_mem); 12286 %} 12287 12288 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12289 %{ 12290 match(Set cr (CmpL src zero)); 12291 12292 format %{ "testq $src, $src" %} 12293 opcode(0x85); 12294 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12295 ins_pipe(ialu_cr_reg_imm); 12296 %} 12297 12298 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12299 %{ 12300 match(Set cr (CmpL (AndL src con) zero)); 12301 12302 format %{ "testq $src, $con\t# long" %} 12303 opcode(0xF7, 0x00); 12304 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 12305 ins_pipe(ialu_cr_reg_imm); 12306 %} 12307 12308 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12309 %{ 12310 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12311 12312 format %{ "testq $src, $mem" %} 12313 opcode(0x85); 12314 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12315 ins_pipe(ialu_cr_reg_mem); 12316 %} 12317 12318 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12319 %{ 12320 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12321 12322 format %{ "testq $src, $mem" %} 12323 opcode(0x85); 12324 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12325 ins_pipe(ialu_cr_reg_mem); 12326 %} 12327 12328 // Fold array properties check 12329 instruct testL_reg_mem3(rFlagsReg cr, memory mem, rRegL src, immL0 zero) 12330 %{ 12331 match(Set cr (CmpL (AndL (CastP2X (LoadKlass mem)) src) zero)); 12332 12333 format %{ "testq $src, $mem" %} 12334 opcode(0x85); 12335 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12336 ins_pipe(ialu_cr_reg_mem); 12337 %} 12338 12339 // Manifest a CmpL result in an integer register. Very painful. 12340 // This is the test to avoid. 12341 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12342 %{ 12343 match(Set dst (CmpL3 src1 src2)); 12344 effect(KILL flags); 12345 12346 ins_cost(275); // XXX 12347 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12348 "movl $dst, -1\n\t" 12349 "jl,s done\n\t" 12350 "setne $dst\n\t" 12351 "movzbl $dst, $dst\n\t" 12352 "done:" %} 12353 ins_encode(cmpl3_flag(src1, src2, dst)); 12354 ins_pipe(pipe_slow); 12355 %} 12356 12357 // Unsigned long compare Instructions; really, same as signed long except they 12358 // produce an rFlagsRegU instead of rFlagsReg. 12359 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12360 %{ 12361 match(Set cr (CmpUL op1 op2)); 12362 12363 format %{ "cmpq $op1, $op2\t# unsigned" %} 12364 opcode(0x3B); /* Opcode 3B /r */ 12365 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12366 ins_pipe(ialu_cr_reg_reg); 12367 %} 12368 12369 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12370 %{ 12371 match(Set cr (CmpUL op1 op2)); 12372 12373 format %{ "cmpq $op1, $op2\t# unsigned" %} 12374 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12375 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12376 ins_pipe(ialu_cr_reg_imm); 12377 %} 12378 12379 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12380 %{ 12381 match(Set cr (CmpUL op1 (LoadL op2))); 12382 12383 format %{ "cmpq $op1, $op2\t# unsigned" %} 12384 opcode(0x3B); /* Opcode 3B /r */ 12385 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12386 ins_pipe(ialu_cr_reg_mem); 12387 %} 12388 12389 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12390 %{ 12391 match(Set cr (CmpUL src zero)); 12392 12393 format %{ "testq $src, $src\t# unsigned" %} 12394 opcode(0x85); 12395 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12396 ins_pipe(ialu_cr_reg_imm); 12397 %} 12398 12399 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12400 %{ 12401 match(Set cr (CmpI (LoadB mem) imm)); 12402 12403 ins_cost(125); 12404 format %{ "cmpb $mem, $imm" %} 12405 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12406 ins_pipe(ialu_cr_reg_mem); 12407 %} 12408 12409 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 12410 %{ 12411 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12412 12413 ins_cost(125); 12414 format %{ "testb $mem, $imm\t# ubyte" %} 12415 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12416 ins_pipe(ialu_cr_reg_mem); 12417 %} 12418 12419 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 12420 %{ 12421 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12422 12423 ins_cost(125); 12424 format %{ "testb $mem, $imm\t# byte" %} 12425 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12426 ins_pipe(ialu_cr_reg_mem); 12427 %} 12428 12429 //----------Max and Min-------------------------------------------------------- 12430 // Min Instructions 12431 12432 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12433 %{ 12434 effect(USE_DEF dst, USE src, USE cr); 12435 12436 format %{ "cmovlgt $dst, $src\t# min" %} 12437 opcode(0x0F, 0x4F); 12438 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12439 ins_pipe(pipe_cmov_reg); 12440 %} 12441 12442 12443 instruct minI_rReg(rRegI dst, rRegI src) 12444 %{ 12445 match(Set dst (MinI dst src)); 12446 12447 ins_cost(200); 12448 expand %{ 12449 rFlagsReg cr; 12450 compI_rReg(cr, dst, src); 12451 cmovI_reg_g(dst, src, cr); 12452 %} 12453 %} 12454 12455 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12456 %{ 12457 effect(USE_DEF dst, USE src, USE cr); 12458 12459 format %{ "cmovllt $dst, $src\t# max" %} 12460 opcode(0x0F, 0x4C); 12461 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12462 ins_pipe(pipe_cmov_reg); 12463 %} 12464 12465 12466 instruct maxI_rReg(rRegI dst, rRegI src) 12467 %{ 12468 match(Set dst (MaxI dst src)); 12469 12470 ins_cost(200); 12471 expand %{ 12472 rFlagsReg cr; 12473 compI_rReg(cr, dst, src); 12474 cmovI_reg_l(dst, src, cr); 12475 %} 12476 %} 12477 12478 // ============================================================================ 12479 // Branch Instructions 12480 12481 // Jump Direct - Label defines a relative address from JMP+1 12482 instruct jmpDir(label labl) 12483 %{ 12484 match(Goto); 12485 effect(USE labl); 12486 12487 ins_cost(300); 12488 format %{ "jmp $labl" %} 12489 size(5); 12490 ins_encode %{ 12491 Label* L = $labl$$label; 12492 __ jmp(*L, false); // Always long jump 12493 %} 12494 ins_pipe(pipe_jmp); 12495 %} 12496 12497 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12498 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12499 %{ 12500 match(If cop cr); 12501 effect(USE labl); 12502 12503 ins_cost(300); 12504 format %{ "j$cop $labl" %} 12505 size(6); 12506 ins_encode %{ 12507 Label* L = $labl$$label; 12508 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12509 %} 12510 ins_pipe(pipe_jcc); 12511 %} 12512 12513 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12514 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12515 %{ 12516 predicate(!n->has_vector_mask_set()); 12517 match(CountedLoopEnd cop cr); 12518 effect(USE labl); 12519 12520 ins_cost(300); 12521 format %{ "j$cop $labl\t# loop end" %} 12522 size(6); 12523 ins_encode %{ 12524 Label* L = $labl$$label; 12525 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12526 %} 12527 ins_pipe(pipe_jcc); 12528 %} 12529 12530 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12531 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12532 predicate(!n->has_vector_mask_set()); 12533 match(CountedLoopEnd cop cmp); 12534 effect(USE labl); 12535 12536 ins_cost(300); 12537 format %{ "j$cop,u $labl\t# loop end" %} 12538 size(6); 12539 ins_encode %{ 12540 Label* L = $labl$$label; 12541 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12542 %} 12543 ins_pipe(pipe_jcc); 12544 %} 12545 12546 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12547 predicate(!n->has_vector_mask_set()); 12548 match(CountedLoopEnd cop cmp); 12549 effect(USE labl); 12550 12551 ins_cost(200); 12552 format %{ "j$cop,u $labl\t# loop end" %} 12553 size(6); 12554 ins_encode %{ 12555 Label* L = $labl$$label; 12556 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12557 %} 12558 ins_pipe(pipe_jcc); 12559 %} 12560 12561 // mask version 12562 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12563 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12564 %{ 12565 predicate(n->has_vector_mask_set()); 12566 match(CountedLoopEnd cop cr); 12567 effect(USE labl); 12568 12569 ins_cost(400); 12570 format %{ "j$cop $labl\t# loop end\n\t" 12571 "restorevectmask \t# vector mask restore for loops" %} 12572 size(10); 12573 ins_encode %{ 12574 Label* L = $labl$$label; 12575 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12576 __ restorevectmask(); 12577 %} 12578 ins_pipe(pipe_jcc); 12579 %} 12580 12581 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12582 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12583 predicate(n->has_vector_mask_set()); 12584 match(CountedLoopEnd cop cmp); 12585 effect(USE labl); 12586 12587 ins_cost(400); 12588 format %{ "j$cop,u $labl\t# loop end\n\t" 12589 "restorevectmask \t# vector mask restore for loops" %} 12590 size(10); 12591 ins_encode %{ 12592 Label* L = $labl$$label; 12593 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12594 __ restorevectmask(); 12595 %} 12596 ins_pipe(pipe_jcc); 12597 %} 12598 12599 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12600 predicate(n->has_vector_mask_set()); 12601 match(CountedLoopEnd cop cmp); 12602 effect(USE labl); 12603 12604 ins_cost(300); 12605 format %{ "j$cop,u $labl\t# loop end\n\t" 12606 "restorevectmask \t# vector mask restore for loops" %} 12607 size(10); 12608 ins_encode %{ 12609 Label* L = $labl$$label; 12610 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12611 __ restorevectmask(); 12612 %} 12613 ins_pipe(pipe_jcc); 12614 %} 12615 12616 // Jump Direct Conditional - using unsigned comparison 12617 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12618 match(If cop cmp); 12619 effect(USE labl); 12620 12621 ins_cost(300); 12622 format %{ "j$cop,u $labl" %} 12623 size(6); 12624 ins_encode %{ 12625 Label* L = $labl$$label; 12626 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12627 %} 12628 ins_pipe(pipe_jcc); 12629 %} 12630 12631 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12632 match(If cop cmp); 12633 effect(USE labl); 12634 12635 ins_cost(200); 12636 format %{ "j$cop,u $labl" %} 12637 size(6); 12638 ins_encode %{ 12639 Label* L = $labl$$label; 12640 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12641 %} 12642 ins_pipe(pipe_jcc); 12643 %} 12644 12645 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12646 match(If cop cmp); 12647 effect(USE labl); 12648 12649 ins_cost(200); 12650 format %{ $$template 12651 if ($cop$$cmpcode == Assembler::notEqual) { 12652 $$emit$$"jp,u $labl\n\t" 12653 $$emit$$"j$cop,u $labl" 12654 } else { 12655 $$emit$$"jp,u done\n\t" 12656 $$emit$$"j$cop,u $labl\n\t" 12657 $$emit$$"done:" 12658 } 12659 %} 12660 ins_encode %{ 12661 Label* l = $labl$$label; 12662 if ($cop$$cmpcode == Assembler::notEqual) { 12663 __ jcc(Assembler::parity, *l, false); 12664 __ jcc(Assembler::notEqual, *l, false); 12665 } else if ($cop$$cmpcode == Assembler::equal) { 12666 Label done; 12667 __ jccb(Assembler::parity, done); 12668 __ jcc(Assembler::equal, *l, false); 12669 __ bind(done); 12670 } else { 12671 ShouldNotReachHere(); 12672 } 12673 %} 12674 ins_pipe(pipe_jcc); 12675 %} 12676 12677 // ============================================================================ 12678 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12679 // superklass array for an instance of the superklass. Set a hidden 12680 // internal cache on a hit (cache is checked with exposed code in 12681 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12682 // encoding ALSO sets flags. 12683 12684 instruct partialSubtypeCheck(rdi_RegP result, 12685 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12686 rFlagsReg cr) 12687 %{ 12688 match(Set result (PartialSubtypeCheck sub super)); 12689 effect(KILL rcx, KILL cr); 12690 12691 ins_cost(1100); // slightly larger than the next version 12692 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12693 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12694 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12695 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12696 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12697 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12698 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12699 "miss:\t" %} 12700 12701 opcode(0x1); // Force a XOR of RDI 12702 ins_encode(enc_PartialSubtypeCheck()); 12703 ins_pipe(pipe_slow); 12704 %} 12705 12706 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12707 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12708 immP0 zero, 12709 rdi_RegP result) 12710 %{ 12711 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12712 effect(KILL rcx, KILL result); 12713 12714 ins_cost(1000); 12715 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12716 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12717 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12718 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12719 "jne,s miss\t\t# Missed: flags nz\n\t" 12720 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12721 "miss:\t" %} 12722 12723 opcode(0x0); // No need to XOR RDI 12724 ins_encode(enc_PartialSubtypeCheck()); 12725 ins_pipe(pipe_slow); 12726 %} 12727 12728 // ============================================================================ 12729 // Branch Instructions -- short offset versions 12730 // 12731 // These instructions are used to replace jumps of a long offset (the default 12732 // match) with jumps of a shorter offset. These instructions are all tagged 12733 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12734 // match rules in general matching. Instead, the ADLC generates a conversion 12735 // method in the MachNode which can be used to do in-place replacement of the 12736 // long variant with the shorter variant. The compiler will determine if a 12737 // branch can be taken by the is_short_branch_offset() predicate in the machine 12738 // specific code section of the file. 12739 12740 // Jump Direct - Label defines a relative address from JMP+1 12741 instruct jmpDir_short(label labl) %{ 12742 match(Goto); 12743 effect(USE labl); 12744 12745 ins_cost(300); 12746 format %{ "jmp,s $labl" %} 12747 size(2); 12748 ins_encode %{ 12749 Label* L = $labl$$label; 12750 __ jmpb(*L); 12751 %} 12752 ins_pipe(pipe_jmp); 12753 ins_short_branch(1); 12754 %} 12755 12756 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12757 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12758 match(If cop cr); 12759 effect(USE labl); 12760 12761 ins_cost(300); 12762 format %{ "j$cop,s $labl" %} 12763 size(2); 12764 ins_encode %{ 12765 Label* L = $labl$$label; 12766 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12767 %} 12768 ins_pipe(pipe_jcc); 12769 ins_short_branch(1); 12770 %} 12771 12772 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12773 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12774 match(CountedLoopEnd cop cr); 12775 effect(USE labl); 12776 12777 ins_cost(300); 12778 format %{ "j$cop,s $labl\t# loop end" %} 12779 size(2); 12780 ins_encode %{ 12781 Label* L = $labl$$label; 12782 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12783 %} 12784 ins_pipe(pipe_jcc); 12785 ins_short_branch(1); 12786 %} 12787 12788 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12789 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12790 match(CountedLoopEnd cop cmp); 12791 effect(USE labl); 12792 12793 ins_cost(300); 12794 format %{ "j$cop,us $labl\t# loop end" %} 12795 size(2); 12796 ins_encode %{ 12797 Label* L = $labl$$label; 12798 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12799 %} 12800 ins_pipe(pipe_jcc); 12801 ins_short_branch(1); 12802 %} 12803 12804 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12805 match(CountedLoopEnd cop cmp); 12806 effect(USE labl); 12807 12808 ins_cost(300); 12809 format %{ "j$cop,us $labl\t# loop end" %} 12810 size(2); 12811 ins_encode %{ 12812 Label* L = $labl$$label; 12813 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12814 %} 12815 ins_pipe(pipe_jcc); 12816 ins_short_branch(1); 12817 %} 12818 12819 // Jump Direct Conditional - using unsigned comparison 12820 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12821 match(If cop cmp); 12822 effect(USE labl); 12823 12824 ins_cost(300); 12825 format %{ "j$cop,us $labl" %} 12826 size(2); 12827 ins_encode %{ 12828 Label* L = $labl$$label; 12829 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12830 %} 12831 ins_pipe(pipe_jcc); 12832 ins_short_branch(1); 12833 %} 12834 12835 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12836 match(If cop cmp); 12837 effect(USE labl); 12838 12839 ins_cost(300); 12840 format %{ "j$cop,us $labl" %} 12841 size(2); 12842 ins_encode %{ 12843 Label* L = $labl$$label; 12844 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12845 %} 12846 ins_pipe(pipe_jcc); 12847 ins_short_branch(1); 12848 %} 12849 12850 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12851 match(If cop cmp); 12852 effect(USE labl); 12853 12854 ins_cost(300); 12855 format %{ $$template 12856 if ($cop$$cmpcode == Assembler::notEqual) { 12857 $$emit$$"jp,u,s $labl\n\t" 12858 $$emit$$"j$cop,u,s $labl" 12859 } else { 12860 $$emit$$"jp,u,s done\n\t" 12861 $$emit$$"j$cop,u,s $labl\n\t" 12862 $$emit$$"done:" 12863 } 12864 %} 12865 size(4); 12866 ins_encode %{ 12867 Label* l = $labl$$label; 12868 if ($cop$$cmpcode == Assembler::notEqual) { 12869 __ jccb(Assembler::parity, *l); 12870 __ jccb(Assembler::notEqual, *l); 12871 } else if ($cop$$cmpcode == Assembler::equal) { 12872 Label done; 12873 __ jccb(Assembler::parity, done); 12874 __ jccb(Assembler::equal, *l); 12875 __ bind(done); 12876 } else { 12877 ShouldNotReachHere(); 12878 } 12879 %} 12880 ins_pipe(pipe_jcc); 12881 ins_short_branch(1); 12882 %} 12883 12884 // ============================================================================ 12885 // inlined locking and unlocking 12886 12887 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12888 predicate(Compile::current()->use_rtm()); 12889 match(Set cr (FastLock object box)); 12890 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12891 ins_cost(300); 12892 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12893 ins_encode %{ 12894 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12895 $scr$$Register, $cx1$$Register, $cx2$$Register, 12896 _counters, _rtm_counters, _stack_rtm_counters, 12897 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12898 true, ra_->C->profile_rtm()); 12899 %} 12900 ins_pipe(pipe_slow); 12901 %} 12902 12903 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12904 predicate(!Compile::current()->use_rtm()); 12905 match(Set cr (FastLock object box)); 12906 effect(TEMP tmp, TEMP scr, USE_KILL box); 12907 ins_cost(300); 12908 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12909 ins_encode %{ 12910 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12911 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12912 %} 12913 ins_pipe(pipe_slow); 12914 %} 12915 12916 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12917 match(Set cr (FastUnlock object box)); 12918 effect(TEMP tmp, USE_KILL box); 12919 ins_cost(300); 12920 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12921 ins_encode %{ 12922 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12923 %} 12924 ins_pipe(pipe_slow); 12925 %} 12926 12927 12928 // ============================================================================ 12929 // Safepoint Instructions 12930 instruct safePoint_poll(rFlagsReg cr) 12931 %{ 12932 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12933 match(SafePoint); 12934 effect(KILL cr); 12935 12936 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12937 "# Safepoint: poll for GC" %} 12938 ins_cost(125); 12939 ins_encode %{ 12940 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12941 __ testl(rax, addr); 12942 %} 12943 ins_pipe(ialu_reg_mem); 12944 %} 12945 12946 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12947 %{ 12948 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12949 match(SafePoint poll); 12950 effect(KILL cr, USE poll); 12951 12952 format %{ "testl rax, [$poll]\t" 12953 "# Safepoint: poll for GC" %} 12954 ins_cost(125); 12955 ins_encode %{ 12956 __ relocate(relocInfo::poll_type); 12957 __ testl(rax, Address($poll$$Register, 0)); 12958 %} 12959 ins_pipe(ialu_reg_mem); 12960 %} 12961 12962 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12963 %{ 12964 predicate(SafepointMechanism::uses_thread_local_poll()); 12965 match(SafePoint poll); 12966 effect(KILL cr, USE poll); 12967 12968 format %{ "testl rax, [$poll]\t" 12969 "# Safepoint: poll for GC" %} 12970 ins_cost(125); 12971 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12972 ins_encode %{ 12973 __ relocate(relocInfo::poll_type); 12974 address pre_pc = __ pc(); 12975 __ testl(rax, Address($poll$$Register, 0)); 12976 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12977 %} 12978 ins_pipe(ialu_reg_mem); 12979 %} 12980 12981 // ============================================================================ 12982 // Procedure Call/Return Instructions 12983 // Call Java Static Instruction 12984 // Note: If this code changes, the corresponding ret_addr_offset() and 12985 // compute_padding() functions will have to be adjusted. 12986 instruct CallStaticJavaDirect(method meth) %{ 12987 match(CallStaticJava); 12988 effect(USE meth); 12989 12990 ins_cost(300); 12991 format %{ "call,static " %} 12992 opcode(0xE8); /* E8 cd */ 12993 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12994 ins_pipe(pipe_slow); 12995 ins_alignment(4); 12996 %} 12997 12998 // Call Java Dynamic Instruction 12999 // Note: If this code changes, the corresponding ret_addr_offset() and 13000 // compute_padding() functions will have to be adjusted. 13001 instruct CallDynamicJavaDirect(method meth) 13002 %{ 13003 match(CallDynamicJava); 13004 effect(USE meth); 13005 13006 ins_cost(300); 13007 format %{ "movq rax, #Universe::non_oop_word()\n\t" 13008 "call,dynamic " %} 13009 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 13010 ins_pipe(pipe_slow); 13011 ins_alignment(4); 13012 %} 13013 13014 // Call Runtime Instruction 13015 instruct CallRuntimeDirect(method meth) 13016 %{ 13017 match(CallRuntime); 13018 effect(USE meth); 13019 13020 ins_cost(300); 13021 format %{ "call,runtime " %} 13022 ins_encode(clear_avx, Java_To_Runtime(meth)); 13023 ins_pipe(pipe_slow); 13024 %} 13025 13026 // Call runtime without safepoint 13027 instruct CallLeafDirect(method meth) 13028 %{ 13029 match(CallLeaf); 13030 effect(USE meth); 13031 13032 ins_cost(300); 13033 format %{ "call_leaf,runtime " %} 13034 ins_encode(clear_avx, Java_To_Runtime(meth)); 13035 ins_pipe(pipe_slow); 13036 %} 13037 13038 // Call runtime without safepoint 13039 // entry point is null, target holds the address to call 13040 instruct CallLeafNoFPInDirect(rRegP target) 13041 %{ 13042 predicate(n->as_Call()->entry_point() == NULL); 13043 match(CallLeafNoFP target); 13044 13045 ins_cost(300); 13046 format %{ "call_leaf_nofp,runtime indirect " %} 13047 ins_encode %{ 13048 __ call($target$$Register); 13049 %} 13050 13051 ins_pipe(pipe_slow); 13052 %} 13053 13054 instruct CallLeafNoFPDirect(method meth) 13055 %{ 13056 predicate(n->as_Call()->entry_point() != NULL); 13057 match(CallLeafNoFP); 13058 effect(USE meth); 13059 13060 ins_cost(300); 13061 format %{ "call_leaf_nofp,runtime " %} 13062 ins_encode(clear_avx, Java_To_Runtime(meth)); 13063 ins_pipe(pipe_slow); 13064 %} 13065 13066 // Return Instruction 13067 // Remove the return address & jump to it. 13068 // Notice: We always emit a nop after a ret to make sure there is room 13069 // for safepoint patching 13070 instruct Ret() 13071 %{ 13072 match(Return); 13073 13074 format %{ "ret" %} 13075 opcode(0xC3); 13076 ins_encode(OpcP); 13077 ins_pipe(pipe_jmp); 13078 %} 13079 13080 // Tail Call; Jump from runtime stub to Java code. 13081 // Also known as an 'interprocedural jump'. 13082 // Target of jump will eventually return to caller. 13083 // TailJump below removes the return address. 13084 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 13085 %{ 13086 match(TailCall jump_target method_oop); 13087 13088 ins_cost(300); 13089 format %{ "jmp $jump_target\t# rbx holds method oop" %} 13090 opcode(0xFF, 0x4); /* Opcode FF /4 */ 13091 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 13092 ins_pipe(pipe_jmp); 13093 %} 13094 13095 // Tail Jump; remove the return address; jump to target. 13096 // TailCall above leaves the return address around. 13097 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 13098 %{ 13099 match(TailJump jump_target ex_oop); 13100 13101 ins_cost(300); 13102 format %{ "popq rdx\t# pop return address\n\t" 13103 "jmp $jump_target" %} 13104 opcode(0xFF, 0x4); /* Opcode FF /4 */ 13105 ins_encode(Opcode(0x5a), // popq rdx 13106 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 13107 ins_pipe(pipe_jmp); 13108 %} 13109 13110 // Create exception oop: created by stack-crawling runtime code. 13111 // Created exception is now available to this handler, and is setup 13112 // just prior to jumping to this handler. No code emitted. 13113 instruct CreateException(rax_RegP ex_oop) 13114 %{ 13115 match(Set ex_oop (CreateEx)); 13116 13117 size(0); 13118 // use the following format syntax 13119 format %{ "# exception oop is in rax; no code emitted" %} 13120 ins_encode(); 13121 ins_pipe(empty); 13122 %} 13123 13124 // Rethrow exception: 13125 // The exception oop will come in the first argument position. 13126 // Then JUMP (not call) to the rethrow stub code. 13127 instruct RethrowException() 13128 %{ 13129 match(Rethrow); 13130 13131 // use the following format syntax 13132 format %{ "jmp rethrow_stub" %} 13133 ins_encode(enc_rethrow); 13134 ins_pipe(pipe_jmp); 13135 %} 13136 13137 // ============================================================================ 13138 // This name is KNOWN by the ADLC and cannot be changed. 13139 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 13140 // for this guy. 13141 instruct tlsLoadP(r15_RegP dst) %{ 13142 match(Set dst (ThreadLocal)); 13143 effect(DEF dst); 13144 13145 size(0); 13146 format %{ "# TLS is in R15" %} 13147 ins_encode( /*empty encoding*/ ); 13148 ins_pipe(ialu_reg_reg); 13149 %} 13150 13151 13152 //----------PEEPHOLE RULES----------------------------------------------------- 13153 // These must follow all instruction definitions as they use the names 13154 // defined in the instructions definitions. 13155 // 13156 // peepmatch ( root_instr_name [preceding_instruction]* ); 13157 // 13158 // peepconstraint %{ 13159 // (instruction_number.operand_name relational_op instruction_number.operand_name 13160 // [, ...] ); 13161 // // instruction numbers are zero-based using left to right order in peepmatch 13162 // 13163 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13164 // // provide an instruction_number.operand_name for each operand that appears 13165 // // in the replacement instruction's match rule 13166 // 13167 // ---------VM FLAGS--------------------------------------------------------- 13168 // 13169 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13170 // 13171 // Each peephole rule is given an identifying number starting with zero and 13172 // increasing by one in the order seen by the parser. An individual peephole 13173 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13174 // on the command-line. 13175 // 13176 // ---------CURRENT LIMITATIONS---------------------------------------------- 13177 // 13178 // Only match adjacent instructions in same basic block 13179 // Only equality constraints 13180 // Only constraints between operands, not (0.dest_reg == RAX_enc) 13181 // Only one replacement instruction 13182 // 13183 // ---------EXAMPLE---------------------------------------------------------- 13184 // 13185 // // pertinent parts of existing instructions in architecture description 13186 // instruct movI(rRegI dst, rRegI src) 13187 // %{ 13188 // match(Set dst (CopyI src)); 13189 // %} 13190 // 13191 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 13192 // %{ 13193 // match(Set dst (AddI dst src)); 13194 // effect(KILL cr); 13195 // %} 13196 // 13197 // // Change (inc mov) to lea 13198 // peephole %{ 13199 // // increment preceeded by register-register move 13200 // peepmatch ( incI_rReg movI ); 13201 // // require that the destination register of the increment 13202 // // match the destination register of the move 13203 // peepconstraint ( 0.dst == 1.dst ); 13204 // // construct a replacement instruction that sets 13205 // // the destination to ( move's source register + one ) 13206 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 13207 // %} 13208 // 13209 13210 // Implementation no longer uses movX instructions since 13211 // machine-independent system no longer uses CopyX nodes. 13212 // 13213 // peephole 13214 // %{ 13215 // peepmatch (incI_rReg movI); 13216 // peepconstraint (0.dst == 1.dst); 13217 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13218 // %} 13219 13220 // peephole 13221 // %{ 13222 // peepmatch (decI_rReg movI); 13223 // peepconstraint (0.dst == 1.dst); 13224 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13225 // %} 13226 13227 // peephole 13228 // %{ 13229 // peepmatch (addI_rReg_imm movI); 13230 // peepconstraint (0.dst == 1.dst); 13231 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13232 // %} 13233 13234 // peephole 13235 // %{ 13236 // peepmatch (incL_rReg movL); 13237 // peepconstraint (0.dst == 1.dst); 13238 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13239 // %} 13240 13241 // peephole 13242 // %{ 13243 // peepmatch (decL_rReg movL); 13244 // peepconstraint (0.dst == 1.dst); 13245 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13246 // %} 13247 13248 // peephole 13249 // %{ 13250 // peepmatch (addL_rReg_imm movL); 13251 // peepconstraint (0.dst == 1.dst); 13252 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13253 // %} 13254 13255 // peephole 13256 // %{ 13257 // peepmatch (addP_rReg_imm movP); 13258 // peepconstraint (0.dst == 1.dst); 13259 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13260 // %} 13261 13262 // // Change load of spilled value to only a spill 13263 // instruct storeI(memory mem, rRegI src) 13264 // %{ 13265 // match(Set mem (StoreI mem src)); 13266 // %} 13267 // 13268 // instruct loadI(rRegI dst, memory mem) 13269 // %{ 13270 // match(Set dst (LoadI mem)); 13271 // %} 13272 // 13273 13274 peephole 13275 %{ 13276 peepmatch (loadI storeI); 13277 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13278 peepreplace (storeI(1.mem 1.mem 1.src)); 13279 %} 13280 13281 peephole 13282 %{ 13283 peepmatch (loadL storeL); 13284 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13285 peepreplace (storeL(1.mem 1.mem 1.src)); 13286 %} 13287 13288 //----------SMARTSPILL RULES--------------------------------------------------- 13289 // These must follow all instruction definitions as they use the names 13290 // defined in the instructions definitions.