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 RBP pointer register 271 reg_class ptr_rbp_reg(RBP, RBP_H); 272 273 // Singleton class for RDI pointer register 274 reg_class ptr_rdi_reg(RDI, RDI_H); 275 276 // Singleton class for stack pointer 277 reg_class ptr_rsp_reg(RSP, RSP_H); 278 279 // Singleton class for TLS pointer 280 reg_class ptr_r15_reg(R15, R15_H); 281 282 // Singleton class for RAX long register 283 reg_class long_rax_reg(RAX, RAX_H); 284 285 // Singleton class for RCX long register 286 reg_class long_rcx_reg(RCX, RCX_H); 287 288 // Singleton class for RDX long register 289 reg_class long_rdx_reg(RDX, RDX_H); 290 291 // Singleton class for RAX int register 292 reg_class int_rax_reg(RAX); 293 294 // Singleton class for RBX int register 295 reg_class int_rbx_reg(RBX); 296 297 // Singleton class for RCX int register 298 reg_class int_rcx_reg(RCX); 299 300 // Singleton class for RCX int register 301 reg_class int_rdx_reg(RDX); 302 303 // Singleton class for RCX int register 304 reg_class int_rdi_reg(RDI); 305 306 // Singleton class for instruction pointer 307 // reg_class ip_reg(RIP); 308 309 %} 310 311 //----------SOURCE BLOCK------------------------------------------------------- 312 // This is a block of C++ code which provides values, functions, and 313 // definitions necessary in the rest of the architecture description 314 source_hpp %{ 315 316 extern RegMask _ANY_REG_mask; 317 extern RegMask _PTR_REG_mask; 318 extern RegMask _PTR_REG_NO_RBP_mask; 319 extern RegMask _PTR_NO_RAX_REG_mask; 320 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 321 extern RegMask _LONG_REG_mask; 322 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 323 extern RegMask _LONG_NO_RCX_REG_mask; 324 extern RegMask _INT_REG_mask; 325 extern RegMask _INT_NO_RAX_RDX_REG_mask; 326 extern RegMask _INT_NO_RCX_REG_mask; 327 328 extern RegMask _STACK_OR_PTR_REG_mask; 329 extern RegMask _STACK_OR_LONG_REG_mask; 330 extern RegMask _STACK_OR_INT_REG_mask; 331 332 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 333 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 334 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 335 336 %} 337 338 source %{ 339 #define RELOC_IMM64 Assembler::imm_operand 340 #define RELOC_DISP32 Assembler::disp32_operand 341 342 #define __ _masm. 343 344 RegMask _ANY_REG_mask; 345 RegMask _PTR_REG_mask; 346 RegMask _PTR_REG_NO_RBP_mask; 347 RegMask _PTR_NO_RAX_REG_mask; 348 RegMask _PTR_NO_RAX_RBX_REG_mask; 349 RegMask _LONG_REG_mask; 350 RegMask _LONG_NO_RAX_RDX_REG_mask; 351 RegMask _LONG_NO_RCX_REG_mask; 352 RegMask _INT_REG_mask; 353 RegMask _INT_NO_RAX_RDX_REG_mask; 354 RegMask _INT_NO_RCX_REG_mask; 355 RegMask _STACK_OR_PTR_REG_mask; 356 RegMask _STACK_OR_LONG_REG_mask; 357 RegMask _STACK_OR_INT_REG_mask; 358 359 static bool need_r12_heapbase() { 360 return UseCompressedOops || UseCompressedClassPointers; 361 } 362 363 void reg_mask_init() { 364 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 365 // We derive a number of subsets from it. 366 _ANY_REG_mask = _ALL_REG_mask; 367 368 if (PreserveFramePointer) { 369 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 370 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 371 } 372 if (need_r12_heapbase()) { 373 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 374 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 375 } 376 377 _PTR_REG_mask = _ANY_REG_mask; 378 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 379 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 380 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 381 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 382 383 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 384 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 385 386 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 387 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 388 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 389 390 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 391 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 392 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 393 394 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 395 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 396 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 397 398 _LONG_REG_mask = _PTR_REG_mask; 399 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 400 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 401 402 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 403 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 404 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 405 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 406 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 407 408 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 409 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 410 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 411 412 _INT_REG_mask = _ALL_INT_REG_mask; 413 if (PreserveFramePointer) { 414 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 415 } 416 if (need_r12_heapbase()) { 417 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 418 } 419 420 _STACK_OR_INT_REG_mask = _INT_REG_mask; 421 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 422 423 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 424 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 425 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 426 427 _INT_NO_RCX_REG_mask = _INT_REG_mask; 428 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 429 } 430 431 static bool generate_vzeroupper(Compile* C) { 432 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 433 } 434 435 static int clear_avx_size() { 436 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 437 } 438 439 // !!!!! Special hack to get all types of calls to specify the byte offset 440 // from the start of the call to the point where the return address 441 // will point. 442 int MachCallStaticJavaNode::ret_addr_offset() 443 { 444 int offset = 5; // 5 bytes from start of call to where return address points 445 offset += clear_avx_size(); 446 return offset; 447 } 448 449 int MachCallDynamicJavaNode::ret_addr_offset() 450 { 451 int offset = 15; // 15 bytes from start of call to where return address points 452 offset += clear_avx_size(); 453 return offset; 454 } 455 456 int MachCallRuntimeNode::ret_addr_offset() { 457 int offset = 13; // movq r10,#addr; callq (r10) 458 offset += clear_avx_size(); 459 return offset; 460 } 461 462 // Indicate if the safepoint node needs the polling page as an input, 463 // it does if the polling page is more than disp32 away. 464 bool SafePointNode::needs_polling_address_input() 465 { 466 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 467 } 468 469 // 470 // Compute padding required for nodes which need alignment 471 // 472 473 // The address of the call instruction needs to be 4-byte aligned to 474 // ensure that it does not span a cache line so that it can be patched. 475 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 476 { 477 current_offset += clear_avx_size(); // skip vzeroupper 478 current_offset += 1; // skip call opcode byte 479 return align_up(current_offset, alignment_required()) - current_offset; 480 } 481 482 // The address of the call instruction needs to be 4-byte aligned to 483 // ensure that it does not span a cache line so that it can be patched. 484 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 485 { 486 current_offset += clear_avx_size(); // skip vzeroupper 487 current_offset += 11; // skip movq instruction + call opcode byte 488 return align_up(current_offset, alignment_required()) - current_offset; 489 } 490 491 // EMIT_RM() 492 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 493 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 494 cbuf.insts()->emit_int8(c); 495 } 496 497 // EMIT_CC() 498 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 499 unsigned char c = (unsigned char) (f1 | f2); 500 cbuf.insts()->emit_int8(c); 501 } 502 503 // EMIT_OPCODE() 504 void emit_opcode(CodeBuffer &cbuf, int code) { 505 cbuf.insts()->emit_int8((unsigned char) code); 506 } 507 508 // EMIT_OPCODE() w/ relocation information 509 void emit_opcode(CodeBuffer &cbuf, 510 int code, relocInfo::relocType reloc, int offset, int format) 511 { 512 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 513 emit_opcode(cbuf, code); 514 } 515 516 // EMIT_D8() 517 void emit_d8(CodeBuffer &cbuf, int d8) { 518 cbuf.insts()->emit_int8((unsigned char) d8); 519 } 520 521 // EMIT_D16() 522 void emit_d16(CodeBuffer &cbuf, int d16) { 523 cbuf.insts()->emit_int16(d16); 524 } 525 526 // EMIT_D32() 527 void emit_d32(CodeBuffer &cbuf, int d32) { 528 cbuf.insts()->emit_int32(d32); 529 } 530 531 // EMIT_D64() 532 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 533 cbuf.insts()->emit_int64(d64); 534 } 535 536 // emit 32 bit value and construct relocation entry from relocInfo::relocType 537 void emit_d32_reloc(CodeBuffer& cbuf, 538 int d32, 539 relocInfo::relocType reloc, 540 int format) 541 { 542 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 543 cbuf.relocate(cbuf.insts_mark(), reloc, format); 544 cbuf.insts()->emit_int32(d32); 545 } 546 547 // emit 32 bit value and construct relocation entry from RelocationHolder 548 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 549 #ifdef ASSERT 550 if (rspec.reloc()->type() == relocInfo::oop_type && 551 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 552 assert(Universe::heap()->is_in((address)(intptr_t)d32), "should be real oop"); 553 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)), "cannot embed broken oops in code"); 554 } 555 #endif 556 cbuf.relocate(cbuf.insts_mark(), rspec, format); 557 cbuf.insts()->emit_int32(d32); 558 } 559 560 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 561 address next_ip = cbuf.insts_end() + 4; 562 emit_d32_reloc(cbuf, (int) (addr - next_ip), 563 external_word_Relocation::spec(addr), 564 RELOC_DISP32); 565 } 566 567 568 // emit 64 bit value and construct relocation entry from relocInfo::relocType 569 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 570 cbuf.relocate(cbuf.insts_mark(), reloc, format); 571 cbuf.insts()->emit_int64(d64); 572 } 573 574 // emit 64 bit value and construct relocation entry from RelocationHolder 575 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 576 #ifdef ASSERT 577 if (rspec.reloc()->type() == relocInfo::oop_type && 578 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 579 assert(Universe::heap()->is_in((address)d64), "should be real oop"); 580 assert(oopDesc::is_oop(cast_to_oop(d64)), "cannot embed broken oops in code"); 581 } 582 #endif 583 cbuf.relocate(cbuf.insts_mark(), rspec, format); 584 cbuf.insts()->emit_int64(d64); 585 } 586 587 // Access stack slot for load or store 588 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 589 { 590 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 591 if (-0x80 <= disp && disp < 0x80) { 592 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 593 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 594 emit_d8(cbuf, disp); // Displacement // R/M byte 595 } else { 596 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 597 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 598 emit_d32(cbuf, disp); // Displacement // R/M byte 599 } 600 } 601 602 // rRegI ereg, memory mem) %{ // emit_reg_mem 603 void encode_RegMem(CodeBuffer &cbuf, 604 int reg, 605 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 606 { 607 assert(disp_reloc == relocInfo::none, "cannot have disp"); 608 int regenc = reg & 7; 609 int baseenc = base & 7; 610 int indexenc = index & 7; 611 612 // There is no index & no scale, use form without SIB byte 613 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 614 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 615 if (disp == 0 && base != RBP_enc && base != R13_enc) { 616 emit_rm(cbuf, 0x0, regenc, baseenc); // * 617 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 618 // If 8-bit displacement, mode 0x1 619 emit_rm(cbuf, 0x1, regenc, baseenc); // * 620 emit_d8(cbuf, disp); 621 } else { 622 // If 32-bit displacement 623 if (base == -1) { // Special flag for absolute address 624 emit_rm(cbuf, 0x0, regenc, 0x5); // * 625 if (disp_reloc != relocInfo::none) { 626 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 627 } else { 628 emit_d32(cbuf, disp); 629 } 630 } else { 631 // Normal base + offset 632 emit_rm(cbuf, 0x2, regenc, baseenc); // * 633 if (disp_reloc != relocInfo::none) { 634 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 635 } else { 636 emit_d32(cbuf, disp); 637 } 638 } 639 } 640 } else { 641 // Else, encode with the SIB byte 642 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 643 if (disp == 0 && base != RBP_enc && base != R13_enc) { 644 // If no displacement 645 emit_rm(cbuf, 0x0, regenc, 0x4); // * 646 emit_rm(cbuf, scale, indexenc, baseenc); 647 } else { 648 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 649 // If 8-bit displacement, mode 0x1 650 emit_rm(cbuf, 0x1, regenc, 0x4); // * 651 emit_rm(cbuf, scale, indexenc, baseenc); 652 emit_d8(cbuf, disp); 653 } else { 654 // If 32-bit displacement 655 if (base == 0x04 ) { 656 emit_rm(cbuf, 0x2, regenc, 0x4); 657 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 658 } else { 659 emit_rm(cbuf, 0x2, regenc, 0x4); 660 emit_rm(cbuf, scale, indexenc, baseenc); // * 661 } 662 if (disp_reloc != relocInfo::none) { 663 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 664 } else { 665 emit_d32(cbuf, disp); 666 } 667 } 668 } 669 } 670 } 671 672 // This could be in MacroAssembler but it's fairly C2 specific 673 void emit_cmpfp_fixup(MacroAssembler& _masm) { 674 Label exit; 675 __ jccb(Assembler::noParity, exit); 676 __ pushf(); 677 // 678 // comiss/ucomiss instructions set ZF,PF,CF flags and 679 // zero OF,AF,SF for NaN values. 680 // Fixup flags by zeroing ZF,PF so that compare of NaN 681 // values returns 'less than' result (CF is set). 682 // Leave the rest of flags unchanged. 683 // 684 // 7 6 5 4 3 2 1 0 685 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 686 // 0 0 1 0 1 0 1 1 (0x2B) 687 // 688 __ andq(Address(rsp, 0), 0xffffff2b); 689 __ popf(); 690 __ bind(exit); 691 } 692 693 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 694 Label done; 695 __ movl(dst, -1); 696 __ jcc(Assembler::parity, done); 697 __ jcc(Assembler::below, done); 698 __ setb(Assembler::notEqual, dst); 699 __ movzbl(dst, dst); 700 __ bind(done); 701 } 702 703 // Math.min() # Math.max() 704 // -------------------------- 705 // ucomis[s/d] # 706 // ja -> b # a 707 // jp -> NaN # NaN 708 // jb -> a # b 709 // je # 710 // |-jz -> a | b # a & b 711 // | -> a # 712 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst, 713 XMMRegister a, XMMRegister b, 714 XMMRegister xmmt, Register rt, 715 bool min, bool single) { 716 717 Label nan, zero, below, above, done; 718 719 if (single) 720 __ ucomiss(a, b); 721 else 722 __ ucomisd(a, b); 723 724 if (dst->encoding() != (min ? b : a)->encoding()) 725 __ jccb(Assembler::above, above); // CF=0 & ZF=0 726 else 727 __ jccb(Assembler::above, done); 728 729 __ jccb(Assembler::parity, nan); // PF=1 730 __ jccb(Assembler::below, below); // CF=1 731 732 // equal 733 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 734 if (single) { 735 __ ucomiss(a, xmmt); 736 __ jccb(Assembler::equal, zero); 737 738 __ movflt(dst, a); 739 __ jmp(done); 740 } 741 else { 742 __ ucomisd(a, xmmt); 743 __ jccb(Assembler::equal, zero); 744 745 __ movdbl(dst, a); 746 __ jmp(done); 747 } 748 749 __ bind(zero); 750 if (min) 751 __ vpor(dst, a, b, Assembler::AVX_128bit); 752 else 753 __ vpand(dst, a, b, Assembler::AVX_128bit); 754 755 __ jmp(done); 756 757 __ bind(above); 758 if (single) 759 __ movflt(dst, min ? b : a); 760 else 761 __ movdbl(dst, min ? b : a); 762 763 __ jmp(done); 764 765 __ bind(nan); 766 if (single) { 767 __ movl(rt, 0x7fc00000); // Float.NaN 768 __ movdl(dst, rt); 769 } 770 else { 771 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 772 __ movdq(dst, rt); 773 } 774 __ jmp(done); 775 776 __ bind(below); 777 if (single) 778 __ movflt(dst, min ? a : b); 779 else 780 __ movdbl(dst, min ? a : b); 781 782 __ bind(done); 783 } 784 785 //============================================================================= 786 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 787 788 int Compile::ConstantTable::calculate_table_base_offset() const { 789 return 0; // absolute addressing, no offset 790 } 791 792 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 793 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 794 ShouldNotReachHere(); 795 } 796 797 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 798 // Empty encoding 799 } 800 801 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 802 return 0; 803 } 804 805 #ifndef PRODUCT 806 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 807 st->print("# MachConstantBaseNode (empty encoding)"); 808 } 809 #endif 810 811 812 //============================================================================= 813 #ifndef PRODUCT 814 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 815 Compile* C = ra_->C; 816 817 int framesize = C->frame_size_in_bytes(); 818 int bangsize = C->bang_size_in_bytes(); 819 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 820 // Remove wordSize for return addr which is already pushed. 821 framesize -= wordSize; 822 823 if (C->need_stack_bang(bangsize)) { 824 framesize -= wordSize; 825 st->print("# stack bang (%d bytes)", bangsize); 826 st->print("\n\t"); 827 st->print("pushq rbp\t# Save rbp"); 828 if (PreserveFramePointer) { 829 st->print("\n\t"); 830 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 831 } 832 if (framesize) { 833 st->print("\n\t"); 834 st->print("subq rsp, #%d\t# Create frame",framesize); 835 } 836 } else { 837 st->print("subq rsp, #%d\t# Create frame",framesize); 838 st->print("\n\t"); 839 framesize -= wordSize; 840 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 841 if (PreserveFramePointer) { 842 st->print("\n\t"); 843 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 844 if (framesize > 0) { 845 st->print("\n\t"); 846 st->print("addq rbp, #%d", framesize); 847 } 848 } 849 } 850 851 if (VerifyStackAtCalls) { 852 st->print("\n\t"); 853 framesize -= wordSize; 854 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 855 #ifdef ASSERT 856 st->print("\n\t"); 857 st->print("# stack alignment check"); 858 #endif 859 } 860 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 861 st->print("\n\t"); 862 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t"); 863 st->print("\n\t"); 864 st->print("je fast_entry\t"); 865 st->print("\n\t"); 866 st->print("call #nmethod_entry_barrier_stub\t"); 867 st->print("\n\tfast_entry:"); 868 } 869 st->cr(); 870 } 871 #endif 872 873 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 874 Compile* C = ra_->C; 875 MacroAssembler _masm(&cbuf); 876 877 int framesize = C->frame_size_in_bytes(); 878 int bangsize = C->bang_size_in_bytes(); 879 880 if (C->clinit_barrier_on_entry()) { 881 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 882 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 883 884 Label L_skip_barrier; 885 Register klass = rscratch1; 886 887 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 888 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 889 890 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 891 892 __ bind(L_skip_barrier); 893 } 894 895 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != NULL); 896 897 C->set_frame_complete(cbuf.insts_size()); 898 899 if (C->has_mach_constant_base_node()) { 900 // NOTE: We set the table base offset here because users might be 901 // emitted before MachConstantBaseNode. 902 Compile::ConstantTable& constant_table = C->constant_table(); 903 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 904 } 905 } 906 907 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 908 { 909 return MachNode::size(ra_); // too many variables; just compute it 910 // the hard way 911 } 912 913 int MachPrologNode::reloc() const 914 { 915 return 0; // a large enough number 916 } 917 918 //============================================================================= 919 #ifndef PRODUCT 920 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 921 { 922 Compile* C = ra_->C; 923 if (generate_vzeroupper(C)) { 924 st->print("vzeroupper"); 925 st->cr(); st->print("\t"); 926 } 927 928 int framesize = C->frame_size_in_bytes(); 929 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 930 // Remove word for return adr already pushed 931 // and RBP 932 framesize -= 2*wordSize; 933 934 if (framesize) { 935 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 936 st->print("\t"); 937 } 938 939 st->print_cr("popq rbp"); 940 if (do_polling() && C->is_method_compilation()) { 941 st->print("\t"); 942 if (SafepointMechanism::uses_thread_local_poll()) { 943 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 944 "testl rax, [rscratch1]\t" 945 "# Safepoint: poll for GC"); 946 } else if (Assembler::is_polling_page_far()) { 947 st->print_cr("movq rscratch1, #polling_page_address\n\t" 948 "testl rax, [rscratch1]\t" 949 "# Safepoint: poll for GC"); 950 } else { 951 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 952 "# Safepoint: poll for GC"); 953 } 954 } 955 } 956 #endif 957 958 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 959 { 960 Compile* C = ra_->C; 961 MacroAssembler _masm(&cbuf); 962 963 if (generate_vzeroupper(C)) { 964 // Clear upper bits of YMM registers when current compiled code uses 965 // wide vectors to avoid AVX <-> SSE transition penalty during call. 966 __ vzeroupper(); 967 } 968 969 int framesize = C->frame_size_in_bytes(); 970 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 971 // Remove word for return adr already pushed 972 // and RBP 973 framesize -= 2*wordSize; 974 975 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 976 977 if (framesize) { 978 emit_opcode(cbuf, Assembler::REX_W); 979 if (framesize < 0x80) { 980 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 981 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 982 emit_d8(cbuf, framesize); 983 } else { 984 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 985 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 986 emit_d32(cbuf, framesize); 987 } 988 } 989 990 // popq rbp 991 emit_opcode(cbuf, 0x58 | RBP_enc); 992 993 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 994 __ reserved_stack_check(); 995 } 996 997 if (do_polling() && C->is_method_compilation()) { 998 MacroAssembler _masm(&cbuf); 999 if (SafepointMechanism::uses_thread_local_poll()) { 1000 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1001 __ relocate(relocInfo::poll_return_type); 1002 __ testl(rax, Address(rscratch1, 0)); 1003 } else { 1004 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1005 if (Assembler::is_polling_page_far()) { 1006 __ lea(rscratch1, polling_page); 1007 __ relocate(relocInfo::poll_return_type); 1008 __ testl(rax, Address(rscratch1, 0)); 1009 } else { 1010 __ testl(rax, polling_page); 1011 } 1012 } 1013 } 1014 } 1015 1016 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1017 { 1018 return MachNode::size(ra_); // too many variables; just compute it 1019 // the hard way 1020 } 1021 1022 int MachEpilogNode::reloc() const 1023 { 1024 return 2; // a large enough number 1025 } 1026 1027 const Pipeline* MachEpilogNode::pipeline() const 1028 { 1029 return MachNode::pipeline_class(); 1030 } 1031 1032 int MachEpilogNode::safepoint_offset() const 1033 { 1034 return 0; 1035 } 1036 1037 //============================================================================= 1038 1039 enum RC { 1040 rc_bad, 1041 rc_int, 1042 rc_float, 1043 rc_stack 1044 }; 1045 1046 static enum RC rc_class(OptoReg::Name reg) 1047 { 1048 if( !OptoReg::is_valid(reg) ) return rc_bad; 1049 1050 if (OptoReg::is_stack(reg)) return rc_stack; 1051 1052 VMReg r = OptoReg::as_VMReg(reg); 1053 1054 if (r->is_Register()) return rc_int; 1055 1056 assert(r->is_XMMRegister(), "must be"); 1057 return rc_float; 1058 } 1059 1060 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1061 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1062 int src_hi, int dst_hi, uint ireg, outputStream* st); 1063 1064 int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1065 int stack_offset, int reg, uint ireg, outputStream* st); 1066 1067 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1068 int dst_offset, uint ireg, outputStream* st) { 1069 if (cbuf) { 1070 MacroAssembler _masm(cbuf); 1071 switch (ireg) { 1072 case Op_VecS: 1073 __ movq(Address(rsp, -8), rax); 1074 __ movl(rax, Address(rsp, src_offset)); 1075 __ movl(Address(rsp, dst_offset), rax); 1076 __ movq(rax, Address(rsp, -8)); 1077 break; 1078 case Op_VecD: 1079 __ pushq(Address(rsp, src_offset)); 1080 __ popq (Address(rsp, dst_offset)); 1081 break; 1082 case Op_VecX: 1083 __ pushq(Address(rsp, src_offset)); 1084 __ popq (Address(rsp, dst_offset)); 1085 __ pushq(Address(rsp, src_offset+8)); 1086 __ popq (Address(rsp, dst_offset+8)); 1087 break; 1088 case Op_VecY: 1089 __ vmovdqu(Address(rsp, -32), xmm0); 1090 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1091 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1092 __ vmovdqu(xmm0, Address(rsp, -32)); 1093 break; 1094 case Op_VecZ: 1095 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1096 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1097 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1098 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1099 break; 1100 default: 1101 ShouldNotReachHere(); 1102 } 1103 #ifndef PRODUCT 1104 } else { 1105 switch (ireg) { 1106 case Op_VecS: 1107 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1108 "movl rax, [rsp + #%d]\n\t" 1109 "movl [rsp + #%d], rax\n\t" 1110 "movq rax, [rsp - #8]", 1111 src_offset, dst_offset); 1112 break; 1113 case Op_VecD: 1114 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1115 "popq [rsp + #%d]", 1116 src_offset, dst_offset); 1117 break; 1118 case Op_VecX: 1119 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1120 "popq [rsp + #%d]\n\t" 1121 "pushq [rsp + #%d]\n\t" 1122 "popq [rsp + #%d]", 1123 src_offset, dst_offset, src_offset+8, dst_offset+8); 1124 break; 1125 case Op_VecY: 1126 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1127 "vmovdqu xmm0, [rsp + #%d]\n\t" 1128 "vmovdqu [rsp + #%d], xmm0\n\t" 1129 "vmovdqu xmm0, [rsp - #32]", 1130 src_offset, dst_offset); 1131 break; 1132 case Op_VecZ: 1133 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1134 "vmovdqu xmm0, [rsp + #%d]\n\t" 1135 "vmovdqu [rsp + #%d], xmm0\n\t" 1136 "vmovdqu xmm0, [rsp - #64]", 1137 src_offset, dst_offset); 1138 break; 1139 default: 1140 ShouldNotReachHere(); 1141 } 1142 #endif 1143 } 1144 } 1145 1146 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1147 PhaseRegAlloc* ra_, 1148 bool do_size, 1149 outputStream* st) const { 1150 assert(cbuf != NULL || st != NULL, "sanity"); 1151 // Get registers to move 1152 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1153 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1154 OptoReg::Name dst_second = ra_->get_reg_second(this); 1155 OptoReg::Name dst_first = ra_->get_reg_first(this); 1156 1157 enum RC src_second_rc = rc_class(src_second); 1158 enum RC src_first_rc = rc_class(src_first); 1159 enum RC dst_second_rc = rc_class(dst_second); 1160 enum RC dst_first_rc = rc_class(dst_first); 1161 1162 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1163 "must move at least 1 register" ); 1164 1165 if (src_first == dst_first && src_second == dst_second) { 1166 // Self copy, no move 1167 return 0; 1168 } 1169 if (bottom_type()->isa_vect() != NULL) { 1170 uint ireg = ideal_reg(); 1171 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1172 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1173 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1174 // mem -> mem 1175 int src_offset = ra_->reg2offset(src_first); 1176 int dst_offset = ra_->reg2offset(dst_first); 1177 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1178 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1179 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1180 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1181 int stack_offset = ra_->reg2offset(dst_first); 1182 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1183 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1184 int stack_offset = ra_->reg2offset(src_first); 1185 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1186 } else { 1187 ShouldNotReachHere(); 1188 } 1189 return 0; 1190 } 1191 if (src_first_rc == rc_stack) { 1192 // mem -> 1193 if (dst_first_rc == rc_stack) { 1194 // mem -> mem 1195 assert(src_second != dst_first, "overlap"); 1196 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1197 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1198 // 64-bit 1199 int src_offset = ra_->reg2offset(src_first); 1200 int dst_offset = ra_->reg2offset(dst_first); 1201 if (cbuf) { 1202 MacroAssembler _masm(cbuf); 1203 __ pushq(Address(rsp, src_offset)); 1204 __ popq (Address(rsp, dst_offset)); 1205 #ifndef PRODUCT 1206 } else { 1207 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1208 "popq [rsp + #%d]", 1209 src_offset, dst_offset); 1210 #endif 1211 } 1212 } else { 1213 // 32-bit 1214 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1215 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1216 // No pushl/popl, so: 1217 int src_offset = ra_->reg2offset(src_first); 1218 int dst_offset = ra_->reg2offset(dst_first); 1219 if (cbuf) { 1220 MacroAssembler _masm(cbuf); 1221 __ movq(Address(rsp, -8), rax); 1222 __ movl(rax, Address(rsp, src_offset)); 1223 __ movl(Address(rsp, dst_offset), rax); 1224 __ movq(rax, Address(rsp, -8)); 1225 #ifndef PRODUCT 1226 } else { 1227 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1228 "movl rax, [rsp + #%d]\n\t" 1229 "movl [rsp + #%d], rax\n\t" 1230 "movq rax, [rsp - #8]", 1231 src_offset, dst_offset); 1232 #endif 1233 } 1234 } 1235 return 0; 1236 } else if (dst_first_rc == rc_int) { 1237 // mem -> gpr 1238 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1239 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1240 // 64-bit 1241 int offset = ra_->reg2offset(src_first); 1242 if (cbuf) { 1243 MacroAssembler _masm(cbuf); 1244 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1245 #ifndef PRODUCT 1246 } else { 1247 st->print("movq %s, [rsp + #%d]\t# spill", 1248 Matcher::regName[dst_first], 1249 offset); 1250 #endif 1251 } 1252 } else { 1253 // 32-bit 1254 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1255 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1256 int offset = ra_->reg2offset(src_first); 1257 if (cbuf) { 1258 MacroAssembler _masm(cbuf); 1259 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1260 #ifndef PRODUCT 1261 } else { 1262 st->print("movl %s, [rsp + #%d]\t# spill", 1263 Matcher::regName[dst_first], 1264 offset); 1265 #endif 1266 } 1267 } 1268 return 0; 1269 } else if (dst_first_rc == rc_float) { 1270 // mem-> xmm 1271 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1272 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1273 // 64-bit 1274 int offset = ra_->reg2offset(src_first); 1275 if (cbuf) { 1276 MacroAssembler _masm(cbuf); 1277 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1278 #ifndef PRODUCT 1279 } else { 1280 st->print("%s %s, [rsp + #%d]\t# spill", 1281 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1282 Matcher::regName[dst_first], 1283 offset); 1284 #endif 1285 } 1286 } else { 1287 // 32-bit 1288 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1289 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1290 int offset = ra_->reg2offset(src_first); 1291 if (cbuf) { 1292 MacroAssembler _masm(cbuf); 1293 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1294 #ifndef PRODUCT 1295 } else { 1296 st->print("movss %s, [rsp + #%d]\t# spill", 1297 Matcher::regName[dst_first], 1298 offset); 1299 #endif 1300 } 1301 } 1302 return 0; 1303 } 1304 } else if (src_first_rc == rc_int) { 1305 // gpr -> 1306 if (dst_first_rc == rc_stack) { 1307 // gpr -> mem 1308 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1309 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1310 // 64-bit 1311 int offset = ra_->reg2offset(dst_first); 1312 if (cbuf) { 1313 MacroAssembler _masm(cbuf); 1314 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1315 #ifndef PRODUCT 1316 } else { 1317 st->print("movq [rsp + #%d], %s\t# spill", 1318 offset, 1319 Matcher::regName[src_first]); 1320 #endif 1321 } 1322 } else { 1323 // 32-bit 1324 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1325 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1326 int offset = ra_->reg2offset(dst_first); 1327 if (cbuf) { 1328 MacroAssembler _masm(cbuf); 1329 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1330 #ifndef PRODUCT 1331 } else { 1332 st->print("movl [rsp + #%d], %s\t# spill", 1333 offset, 1334 Matcher::regName[src_first]); 1335 #endif 1336 } 1337 } 1338 return 0; 1339 } else if (dst_first_rc == rc_int) { 1340 // gpr -> gpr 1341 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1342 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1343 // 64-bit 1344 if (cbuf) { 1345 MacroAssembler _masm(cbuf); 1346 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1347 as_Register(Matcher::_regEncode[src_first])); 1348 #ifndef PRODUCT 1349 } else { 1350 st->print("movq %s, %s\t# spill", 1351 Matcher::regName[dst_first], 1352 Matcher::regName[src_first]); 1353 #endif 1354 } 1355 return 0; 1356 } else { 1357 // 32-bit 1358 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1359 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1360 if (cbuf) { 1361 MacroAssembler _masm(cbuf); 1362 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1363 as_Register(Matcher::_regEncode[src_first])); 1364 #ifndef PRODUCT 1365 } else { 1366 st->print("movl %s, %s\t# spill", 1367 Matcher::regName[dst_first], 1368 Matcher::regName[src_first]); 1369 #endif 1370 } 1371 return 0; 1372 } 1373 } else if (dst_first_rc == rc_float) { 1374 // gpr -> xmm 1375 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1376 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1377 // 64-bit 1378 if (cbuf) { 1379 MacroAssembler _masm(cbuf); 1380 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1381 #ifndef PRODUCT 1382 } else { 1383 st->print("movdq %s, %s\t# spill", 1384 Matcher::regName[dst_first], 1385 Matcher::regName[src_first]); 1386 #endif 1387 } 1388 } else { 1389 // 32-bit 1390 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1391 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1392 if (cbuf) { 1393 MacroAssembler _masm(cbuf); 1394 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1395 #ifndef PRODUCT 1396 } else { 1397 st->print("movdl %s, %s\t# spill", 1398 Matcher::regName[dst_first], 1399 Matcher::regName[src_first]); 1400 #endif 1401 } 1402 } 1403 return 0; 1404 } 1405 } else if (src_first_rc == rc_float) { 1406 // xmm -> 1407 if (dst_first_rc == rc_stack) { 1408 // xmm -> mem 1409 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1410 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1411 // 64-bit 1412 int offset = ra_->reg2offset(dst_first); 1413 if (cbuf) { 1414 MacroAssembler _masm(cbuf); 1415 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1416 #ifndef PRODUCT 1417 } else { 1418 st->print("movsd [rsp + #%d], %s\t# spill", 1419 offset, 1420 Matcher::regName[src_first]); 1421 #endif 1422 } 1423 } else { 1424 // 32-bit 1425 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1426 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1427 int offset = ra_->reg2offset(dst_first); 1428 if (cbuf) { 1429 MacroAssembler _masm(cbuf); 1430 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1431 #ifndef PRODUCT 1432 } else { 1433 st->print("movss [rsp + #%d], %s\t# spill", 1434 offset, 1435 Matcher::regName[src_first]); 1436 #endif 1437 } 1438 } 1439 return 0; 1440 } else if (dst_first_rc == rc_int) { 1441 // xmm -> gpr 1442 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1443 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1444 // 64-bit 1445 if (cbuf) { 1446 MacroAssembler _masm(cbuf); 1447 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1448 #ifndef PRODUCT 1449 } else { 1450 st->print("movdq %s, %s\t# spill", 1451 Matcher::regName[dst_first], 1452 Matcher::regName[src_first]); 1453 #endif 1454 } 1455 } else { 1456 // 32-bit 1457 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1458 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1459 if (cbuf) { 1460 MacroAssembler _masm(cbuf); 1461 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1462 #ifndef PRODUCT 1463 } else { 1464 st->print("movdl %s, %s\t# spill", 1465 Matcher::regName[dst_first], 1466 Matcher::regName[src_first]); 1467 #endif 1468 } 1469 } 1470 return 0; 1471 } else if (dst_first_rc == rc_float) { 1472 // xmm -> xmm 1473 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1474 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1475 // 64-bit 1476 if (cbuf) { 1477 MacroAssembler _masm(cbuf); 1478 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1479 #ifndef PRODUCT 1480 } else { 1481 st->print("%s %s, %s\t# spill", 1482 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1483 Matcher::regName[dst_first], 1484 Matcher::regName[src_first]); 1485 #endif 1486 } 1487 } else { 1488 // 32-bit 1489 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1490 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1491 if (cbuf) { 1492 MacroAssembler _masm(cbuf); 1493 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1494 #ifndef PRODUCT 1495 } else { 1496 st->print("%s %s, %s\t# spill", 1497 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1498 Matcher::regName[dst_first], 1499 Matcher::regName[src_first]); 1500 #endif 1501 } 1502 } 1503 return 0; 1504 } 1505 } 1506 1507 assert(0," foo "); 1508 Unimplemented(); 1509 return 0; 1510 } 1511 1512 #ifndef PRODUCT 1513 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1514 implementation(NULL, ra_, false, st); 1515 } 1516 #endif 1517 1518 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1519 implementation(&cbuf, ra_, false, NULL); 1520 } 1521 1522 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1523 return MachNode::size(ra_); 1524 } 1525 1526 //============================================================================= 1527 #ifndef PRODUCT 1528 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1529 { 1530 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1531 int reg = ra_->get_reg_first(this); 1532 st->print("leaq %s, [rsp + #%d]\t# box lock", 1533 Matcher::regName[reg], offset); 1534 } 1535 #endif 1536 1537 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1538 { 1539 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1540 int reg = ra_->get_encode(this); 1541 if (offset >= 0x80) { 1542 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1543 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1544 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1545 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1546 emit_d32(cbuf, offset); 1547 } else { 1548 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1549 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1550 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1551 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1552 emit_d8(cbuf, offset); 1553 } 1554 } 1555 1556 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1557 { 1558 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1559 return (offset < 0x80) ? 5 : 8; // REX 1560 } 1561 1562 //============================================================================= 1563 #ifndef PRODUCT 1564 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1565 { 1566 if (UseCompressedClassPointers) { 1567 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1568 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1569 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1570 } else { 1571 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1572 "# Inline cache check"); 1573 } 1574 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1575 st->print_cr("\tnop\t# nops to align entry point"); 1576 } 1577 #endif 1578 1579 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1580 { 1581 MacroAssembler masm(&cbuf); 1582 uint insts_size = cbuf.insts_size(); 1583 if (UseCompressedClassPointers) { 1584 masm.load_klass(rscratch1, j_rarg0); 1585 masm.cmpptr(rax, rscratch1); 1586 } else { 1587 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1588 } 1589 1590 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1591 1592 /* WARNING these NOPs are critical so that verified entry point is properly 1593 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1594 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1595 if (OptoBreakpoint) { 1596 // Leave space for int3 1597 nops_cnt -= 1; 1598 } 1599 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1600 if (nops_cnt > 0) 1601 masm.nop(nops_cnt); 1602 } 1603 1604 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1605 { 1606 return MachNode::size(ra_); // too many variables; just compute it 1607 // the hard way 1608 } 1609 1610 1611 //============================================================================= 1612 1613 int Matcher::regnum_to_fpu_offset(int regnum) 1614 { 1615 return regnum - 32; // The FP registers are in the second chunk 1616 } 1617 1618 // This is UltraSparc specific, true just means we have fast l2f conversion 1619 const bool Matcher::convL2FSupported(void) { 1620 return true; 1621 } 1622 1623 // Is this branch offset short enough that a short branch can be used? 1624 // 1625 // NOTE: If the platform does not provide any short branch variants, then 1626 // this method should return false for offset 0. 1627 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1628 // The passed offset is relative to address of the branch. 1629 // On 86 a branch displacement is calculated relative to address 1630 // of a next instruction. 1631 offset -= br_size; 1632 1633 // the short version of jmpConUCF2 contains multiple branches, 1634 // making the reach slightly less 1635 if (rule == jmpConUCF2_rule) 1636 return (-126 <= offset && offset <= 125); 1637 return (-128 <= offset && offset <= 127); 1638 } 1639 1640 const bool Matcher::isSimpleConstant64(jlong value) { 1641 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1642 //return value == (int) value; // Cf. storeImmL and immL32. 1643 1644 // Probably always true, even if a temp register is required. 1645 return true; 1646 } 1647 1648 // The ecx parameter to rep stosq for the ClearArray node is in words. 1649 const bool Matcher::init_array_count_is_in_bytes = false; 1650 1651 // No additional cost for CMOVL. 1652 const int Matcher::long_cmove_cost() { return 0; } 1653 1654 // No CMOVF/CMOVD with SSE2 1655 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1656 1657 // Does the CPU require late expand (see block.cpp for description of late expand)? 1658 const bool Matcher::require_postalloc_expand = false; 1659 1660 // Do we need to mask the count passed to shift instructions or does 1661 // the cpu only look at the lower 5/6 bits anyway? 1662 const bool Matcher::need_masked_shift_count = false; 1663 1664 bool Matcher::narrow_oop_use_complex_address() { 1665 assert(UseCompressedOops, "only for compressed oops code"); 1666 return (LogMinObjAlignmentInBytes <= 3); 1667 } 1668 1669 bool Matcher::narrow_klass_use_complex_address() { 1670 assert(UseCompressedClassPointers, "only for compressed klass code"); 1671 return (LogKlassAlignmentInBytes <= 3); 1672 } 1673 1674 bool Matcher::const_oop_prefer_decode() { 1675 // Prefer ConN+DecodeN over ConP. 1676 return true; 1677 } 1678 1679 bool Matcher::const_klass_prefer_decode() { 1680 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1681 // or condisider the following: 1682 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1683 //return CompressedKlassPointers::base() == NULL; 1684 return true; 1685 } 1686 1687 // Is it better to copy float constants, or load them directly from 1688 // memory? Intel can load a float constant from a direct address, 1689 // requiring no extra registers. Most RISCs will have to materialize 1690 // an address into a register first, so they would do better to copy 1691 // the constant from stack. 1692 const bool Matcher::rematerialize_float_constants = true; // XXX 1693 1694 // If CPU can load and store mis-aligned doubles directly then no 1695 // fixup is needed. Else we split the double into 2 integer pieces 1696 // and move it piece-by-piece. Only happens when passing doubles into 1697 // C code as the Java calling convention forces doubles to be aligned. 1698 const bool Matcher::misaligned_doubles_ok = true; 1699 1700 // No-op on amd64 1701 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1702 1703 // Advertise here if the CPU requires explicit rounding operations to 1704 // implement the UseStrictFP mode. 1705 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1706 1707 // Are floats conerted to double when stored to stack during deoptimization? 1708 // On x64 it is stored without convertion so we can use normal access. 1709 bool Matcher::float_in_double() { return false; } 1710 1711 // Do ints take an entire long register or just half? 1712 const bool Matcher::int_in_long = true; 1713 1714 // Return whether or not this register is ever used as an argument. 1715 // This function is used on startup to build the trampoline stubs in 1716 // generateOptoStub. Registers not mentioned will be killed by the VM 1717 // call in the trampoline, and arguments in those registers not be 1718 // available to the callee. 1719 bool Matcher::can_be_java_arg(int reg) 1720 { 1721 return 1722 reg == RDI_num || reg == RDI_H_num || 1723 reg == RSI_num || reg == RSI_H_num || 1724 reg == RDX_num || reg == RDX_H_num || 1725 reg == RCX_num || reg == RCX_H_num || 1726 reg == R8_num || reg == R8_H_num || 1727 reg == R9_num || reg == R9_H_num || 1728 reg == R12_num || reg == R12_H_num || 1729 reg == XMM0_num || reg == XMM0b_num || 1730 reg == XMM1_num || reg == XMM1b_num || 1731 reg == XMM2_num || reg == XMM2b_num || 1732 reg == XMM3_num || reg == XMM3b_num || 1733 reg == XMM4_num || reg == XMM4b_num || 1734 reg == XMM5_num || reg == XMM5b_num || 1735 reg == XMM6_num || reg == XMM6b_num || 1736 reg == XMM7_num || reg == XMM7b_num; 1737 } 1738 1739 bool Matcher::is_spillable_arg(int reg) 1740 { 1741 return can_be_java_arg(reg); 1742 } 1743 1744 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1745 // In 64 bit mode a code which use multiply when 1746 // devisor is constant is faster than hardware 1747 // DIV instruction (it uses MulHiL). 1748 return false; 1749 } 1750 1751 // Register for DIVI projection of divmodI 1752 RegMask Matcher::divI_proj_mask() { 1753 return INT_RAX_REG_mask(); 1754 } 1755 1756 // Register for MODI projection of divmodI 1757 RegMask Matcher::modI_proj_mask() { 1758 return INT_RDX_REG_mask(); 1759 } 1760 1761 // Register for DIVL projection of divmodL 1762 RegMask Matcher::divL_proj_mask() { 1763 return LONG_RAX_REG_mask(); 1764 } 1765 1766 // Register for MODL projection of divmodL 1767 RegMask Matcher::modL_proj_mask() { 1768 return LONG_RDX_REG_mask(); 1769 } 1770 1771 // Register for saving SP into on method handle invokes. Not used on x86_64. 1772 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1773 return NO_REG_mask(); 1774 } 1775 1776 %} 1777 1778 //----------ENCODING BLOCK----------------------------------------------------- 1779 // This block specifies the encoding classes used by the compiler to 1780 // output byte streams. Encoding classes are parameterized macros 1781 // used by Machine Instruction Nodes in order to generate the bit 1782 // encoding of the instruction. Operands specify their base encoding 1783 // interface with the interface keyword. There are currently 1784 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1785 // COND_INTER. REG_INTER causes an operand to generate a function 1786 // which returns its register number when queried. CONST_INTER causes 1787 // an operand to generate a function which returns the value of the 1788 // constant when queried. MEMORY_INTER causes an operand to generate 1789 // four functions which return the Base Register, the Index Register, 1790 // the Scale Value, and the Offset Value of the operand when queried. 1791 // COND_INTER causes an operand to generate six functions which return 1792 // the encoding code (ie - encoding bits for the instruction) 1793 // associated with each basic boolean condition for a conditional 1794 // instruction. 1795 // 1796 // Instructions specify two basic values for encoding. Again, a 1797 // function is available to check if the constant displacement is an 1798 // oop. They use the ins_encode keyword to specify their encoding 1799 // classes (which must be a sequence of enc_class names, and their 1800 // parameters, specified in the encoding block), and they use the 1801 // opcode keyword to specify, in order, their primary, secondary, and 1802 // tertiary opcode. Only the opcode sections which a particular 1803 // instruction needs for encoding need to be specified. 1804 encode %{ 1805 // Build emit functions for each basic byte or larger field in the 1806 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1807 // from C++ code in the enc_class source block. Emit functions will 1808 // live in the main source block for now. In future, we can 1809 // generalize this by adding a syntax that specifies the sizes of 1810 // fields in an order, so that the adlc can build the emit functions 1811 // automagically 1812 1813 // Emit primary opcode 1814 enc_class OpcP 1815 %{ 1816 emit_opcode(cbuf, $primary); 1817 %} 1818 1819 // Emit secondary opcode 1820 enc_class OpcS 1821 %{ 1822 emit_opcode(cbuf, $secondary); 1823 %} 1824 1825 // Emit tertiary opcode 1826 enc_class OpcT 1827 %{ 1828 emit_opcode(cbuf, $tertiary); 1829 %} 1830 1831 // Emit opcode directly 1832 enc_class Opcode(immI d8) 1833 %{ 1834 emit_opcode(cbuf, $d8$$constant); 1835 %} 1836 1837 // Emit size prefix 1838 enc_class SizePrefix 1839 %{ 1840 emit_opcode(cbuf, 0x66); 1841 %} 1842 1843 enc_class reg(rRegI reg) 1844 %{ 1845 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1846 %} 1847 1848 enc_class reg_reg(rRegI dst, rRegI src) 1849 %{ 1850 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1851 %} 1852 1853 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1854 %{ 1855 emit_opcode(cbuf, $opcode$$constant); 1856 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1857 %} 1858 1859 enc_class cdql_enc(no_rax_rdx_RegI div) 1860 %{ 1861 // Full implementation of Java idiv and irem; checks for 1862 // special case as described in JVM spec., p.243 & p.271. 1863 // 1864 // normal case special case 1865 // 1866 // input : rax: dividend min_int 1867 // reg: divisor -1 1868 // 1869 // output: rax: quotient (= rax idiv reg) min_int 1870 // rdx: remainder (= rax irem reg) 0 1871 // 1872 // Code sequnce: 1873 // 1874 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1875 // 5: 75 07/08 jne e <normal> 1876 // 7: 33 d2 xor %edx,%edx 1877 // [div >= 8 -> offset + 1] 1878 // [REX_B] 1879 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1880 // c: 74 03/04 je 11 <done> 1881 // 000000000000000e <normal>: 1882 // e: 99 cltd 1883 // [div >= 8 -> offset + 1] 1884 // [REX_B] 1885 // f: f7 f9 idiv $div 1886 // 0000000000000011 <done>: 1887 1888 // cmp $0x80000000,%eax 1889 emit_opcode(cbuf, 0x3d); 1890 emit_d8(cbuf, 0x00); 1891 emit_d8(cbuf, 0x00); 1892 emit_d8(cbuf, 0x00); 1893 emit_d8(cbuf, 0x80); 1894 1895 // jne e <normal> 1896 emit_opcode(cbuf, 0x75); 1897 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1898 1899 // xor %edx,%edx 1900 emit_opcode(cbuf, 0x33); 1901 emit_d8(cbuf, 0xD2); 1902 1903 // cmp $0xffffffffffffffff,%ecx 1904 if ($div$$reg >= 8) { 1905 emit_opcode(cbuf, Assembler::REX_B); 1906 } 1907 emit_opcode(cbuf, 0x83); 1908 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1909 emit_d8(cbuf, 0xFF); 1910 1911 // je 11 <done> 1912 emit_opcode(cbuf, 0x74); 1913 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1914 1915 // <normal> 1916 // cltd 1917 emit_opcode(cbuf, 0x99); 1918 1919 // idivl (note: must be emitted by the user of this rule) 1920 // <done> 1921 %} 1922 1923 enc_class cdqq_enc(no_rax_rdx_RegL div) 1924 %{ 1925 // Full implementation of Java ldiv and lrem; checks for 1926 // special case as described in JVM spec., p.243 & p.271. 1927 // 1928 // normal case special case 1929 // 1930 // input : rax: dividend min_long 1931 // reg: divisor -1 1932 // 1933 // output: rax: quotient (= rax idiv reg) min_long 1934 // rdx: remainder (= rax irem reg) 0 1935 // 1936 // Code sequnce: 1937 // 1938 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1939 // 7: 00 00 80 1940 // a: 48 39 d0 cmp %rdx,%rax 1941 // d: 75 08 jne 17 <normal> 1942 // f: 33 d2 xor %edx,%edx 1943 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1944 // 15: 74 05 je 1c <done> 1945 // 0000000000000017 <normal>: 1946 // 17: 48 99 cqto 1947 // 19: 48 f7 f9 idiv $div 1948 // 000000000000001c <done>: 1949 1950 // mov $0x8000000000000000,%rdx 1951 emit_opcode(cbuf, Assembler::REX_W); 1952 emit_opcode(cbuf, 0xBA); 1953 emit_d8(cbuf, 0x00); 1954 emit_d8(cbuf, 0x00); 1955 emit_d8(cbuf, 0x00); 1956 emit_d8(cbuf, 0x00); 1957 emit_d8(cbuf, 0x00); 1958 emit_d8(cbuf, 0x00); 1959 emit_d8(cbuf, 0x00); 1960 emit_d8(cbuf, 0x80); 1961 1962 // cmp %rdx,%rax 1963 emit_opcode(cbuf, Assembler::REX_W); 1964 emit_opcode(cbuf, 0x39); 1965 emit_d8(cbuf, 0xD0); 1966 1967 // jne 17 <normal> 1968 emit_opcode(cbuf, 0x75); 1969 emit_d8(cbuf, 0x08); 1970 1971 // xor %edx,%edx 1972 emit_opcode(cbuf, 0x33); 1973 emit_d8(cbuf, 0xD2); 1974 1975 // cmp $0xffffffffffffffff,$div 1976 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1977 emit_opcode(cbuf, 0x83); 1978 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1979 emit_d8(cbuf, 0xFF); 1980 1981 // je 1e <done> 1982 emit_opcode(cbuf, 0x74); 1983 emit_d8(cbuf, 0x05); 1984 1985 // <normal> 1986 // cqto 1987 emit_opcode(cbuf, Assembler::REX_W); 1988 emit_opcode(cbuf, 0x99); 1989 1990 // idivq (note: must be emitted by the user of this rule) 1991 // <done> 1992 %} 1993 1994 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1995 enc_class OpcSE(immI imm) 1996 %{ 1997 // Emit primary opcode and set sign-extend bit 1998 // Check for 8-bit immediate, and set sign extend bit in opcode 1999 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2000 emit_opcode(cbuf, $primary | 0x02); 2001 } else { 2002 // 32-bit immediate 2003 emit_opcode(cbuf, $primary); 2004 } 2005 %} 2006 2007 enc_class OpcSErm(rRegI dst, immI imm) 2008 %{ 2009 // OpcSEr/m 2010 int dstenc = $dst$$reg; 2011 if (dstenc >= 8) { 2012 emit_opcode(cbuf, Assembler::REX_B); 2013 dstenc -= 8; 2014 } 2015 // Emit primary opcode and set sign-extend bit 2016 // Check for 8-bit immediate, and set sign extend bit in opcode 2017 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2018 emit_opcode(cbuf, $primary | 0x02); 2019 } else { 2020 // 32-bit immediate 2021 emit_opcode(cbuf, $primary); 2022 } 2023 // Emit r/m byte with secondary opcode, after primary opcode. 2024 emit_rm(cbuf, 0x3, $secondary, dstenc); 2025 %} 2026 2027 enc_class OpcSErm_wide(rRegL dst, immI imm) 2028 %{ 2029 // OpcSEr/m 2030 int dstenc = $dst$$reg; 2031 if (dstenc < 8) { 2032 emit_opcode(cbuf, Assembler::REX_W); 2033 } else { 2034 emit_opcode(cbuf, Assembler::REX_WB); 2035 dstenc -= 8; 2036 } 2037 // Emit primary opcode and set sign-extend bit 2038 // Check for 8-bit immediate, and set sign extend bit in opcode 2039 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2040 emit_opcode(cbuf, $primary | 0x02); 2041 } else { 2042 // 32-bit immediate 2043 emit_opcode(cbuf, $primary); 2044 } 2045 // Emit r/m byte with secondary opcode, after primary opcode. 2046 emit_rm(cbuf, 0x3, $secondary, dstenc); 2047 %} 2048 2049 enc_class Con8or32(immI imm) 2050 %{ 2051 // Check for 8-bit immediate, and set sign extend bit in opcode 2052 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2053 $$$emit8$imm$$constant; 2054 } else { 2055 // 32-bit immediate 2056 $$$emit32$imm$$constant; 2057 } 2058 %} 2059 2060 enc_class opc2_reg(rRegI dst) 2061 %{ 2062 // BSWAP 2063 emit_cc(cbuf, $secondary, $dst$$reg); 2064 %} 2065 2066 enc_class opc3_reg(rRegI dst) 2067 %{ 2068 // BSWAP 2069 emit_cc(cbuf, $tertiary, $dst$$reg); 2070 %} 2071 2072 enc_class reg_opc(rRegI div) 2073 %{ 2074 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2075 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2076 %} 2077 2078 enc_class enc_cmov(cmpOp cop) 2079 %{ 2080 // CMOV 2081 $$$emit8$primary; 2082 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2083 %} 2084 2085 enc_class enc_PartialSubtypeCheck() 2086 %{ 2087 Register Rrdi = as_Register(RDI_enc); // result register 2088 Register Rrax = as_Register(RAX_enc); // super class 2089 Register Rrcx = as_Register(RCX_enc); // killed 2090 Register Rrsi = as_Register(RSI_enc); // sub class 2091 Label miss; 2092 const bool set_cond_codes = true; 2093 2094 MacroAssembler _masm(&cbuf); 2095 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2096 NULL, &miss, 2097 /*set_cond_codes:*/ true); 2098 if ($primary) { 2099 __ xorptr(Rrdi, Rrdi); 2100 } 2101 __ bind(miss); 2102 %} 2103 2104 enc_class clear_avx %{ 2105 debug_only(int off0 = cbuf.insts_size()); 2106 if (generate_vzeroupper(Compile::current())) { 2107 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2108 // Clear upper bits of YMM registers when current compiled code uses 2109 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2110 MacroAssembler _masm(&cbuf); 2111 __ vzeroupper(); 2112 } 2113 debug_only(int off1 = cbuf.insts_size()); 2114 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2115 %} 2116 2117 enc_class Java_To_Runtime(method meth) %{ 2118 // No relocation needed 2119 MacroAssembler _masm(&cbuf); 2120 __ mov64(r10, (int64_t) $meth$$method); 2121 __ call(r10); 2122 %} 2123 2124 enc_class Java_To_Interpreter(method meth) 2125 %{ 2126 // CALL Java_To_Interpreter 2127 // This is the instruction starting address for relocation info. 2128 cbuf.set_insts_mark(); 2129 $$$emit8$primary; 2130 // CALL directly to the runtime 2131 emit_d32_reloc(cbuf, 2132 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2133 runtime_call_Relocation::spec(), 2134 RELOC_DISP32); 2135 %} 2136 2137 enc_class Java_Static_Call(method meth) 2138 %{ 2139 // JAVA STATIC CALL 2140 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2141 // determine who we intended to call. 2142 cbuf.set_insts_mark(); 2143 $$$emit8$primary; 2144 2145 if (!_method) { 2146 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2147 runtime_call_Relocation::spec(), 2148 RELOC_DISP32); 2149 } else { 2150 int method_index = resolved_method_index(cbuf); 2151 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2152 : static_call_Relocation::spec(method_index); 2153 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2154 rspec, RELOC_DISP32); 2155 // Emit stubs for static call. 2156 address mark = cbuf.insts_mark(); 2157 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2158 if (stub == NULL) { 2159 ciEnv::current()->record_failure("CodeCache is full"); 2160 return; 2161 } 2162 #if INCLUDE_AOT 2163 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2164 #endif 2165 } 2166 %} 2167 2168 enc_class Java_Dynamic_Call(method meth) %{ 2169 MacroAssembler _masm(&cbuf); 2170 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2171 %} 2172 2173 enc_class Java_Compiled_Call(method meth) 2174 %{ 2175 // JAVA COMPILED CALL 2176 int disp = in_bytes(Method:: from_compiled_offset()); 2177 2178 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2179 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2180 2181 // callq *disp(%rax) 2182 cbuf.set_insts_mark(); 2183 $$$emit8$primary; 2184 if (disp < 0x80) { 2185 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2186 emit_d8(cbuf, disp); // Displacement 2187 } else { 2188 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2189 emit_d32(cbuf, disp); // Displacement 2190 } 2191 %} 2192 2193 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2194 %{ 2195 // SAL, SAR, SHR 2196 int dstenc = $dst$$reg; 2197 if (dstenc >= 8) { 2198 emit_opcode(cbuf, Assembler::REX_B); 2199 dstenc -= 8; 2200 } 2201 $$$emit8$primary; 2202 emit_rm(cbuf, 0x3, $secondary, dstenc); 2203 $$$emit8$shift$$constant; 2204 %} 2205 2206 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2207 %{ 2208 // SAL, SAR, SHR 2209 int dstenc = $dst$$reg; 2210 if (dstenc < 8) { 2211 emit_opcode(cbuf, Assembler::REX_W); 2212 } else { 2213 emit_opcode(cbuf, Assembler::REX_WB); 2214 dstenc -= 8; 2215 } 2216 $$$emit8$primary; 2217 emit_rm(cbuf, 0x3, $secondary, dstenc); 2218 $$$emit8$shift$$constant; 2219 %} 2220 2221 enc_class load_immI(rRegI dst, immI src) 2222 %{ 2223 int dstenc = $dst$$reg; 2224 if (dstenc >= 8) { 2225 emit_opcode(cbuf, Assembler::REX_B); 2226 dstenc -= 8; 2227 } 2228 emit_opcode(cbuf, 0xB8 | dstenc); 2229 $$$emit32$src$$constant; 2230 %} 2231 2232 enc_class load_immL(rRegL dst, immL src) 2233 %{ 2234 int dstenc = $dst$$reg; 2235 if (dstenc < 8) { 2236 emit_opcode(cbuf, Assembler::REX_W); 2237 } else { 2238 emit_opcode(cbuf, Assembler::REX_WB); 2239 dstenc -= 8; 2240 } 2241 emit_opcode(cbuf, 0xB8 | dstenc); 2242 emit_d64(cbuf, $src$$constant); 2243 %} 2244 2245 enc_class load_immUL32(rRegL dst, immUL32 src) 2246 %{ 2247 // same as load_immI, but this time we care about zeroes in the high word 2248 int dstenc = $dst$$reg; 2249 if (dstenc >= 8) { 2250 emit_opcode(cbuf, Assembler::REX_B); 2251 dstenc -= 8; 2252 } 2253 emit_opcode(cbuf, 0xB8 | dstenc); 2254 $$$emit32$src$$constant; 2255 %} 2256 2257 enc_class load_immL32(rRegL dst, immL32 src) 2258 %{ 2259 int dstenc = $dst$$reg; 2260 if (dstenc < 8) { 2261 emit_opcode(cbuf, Assembler::REX_W); 2262 } else { 2263 emit_opcode(cbuf, Assembler::REX_WB); 2264 dstenc -= 8; 2265 } 2266 emit_opcode(cbuf, 0xC7); 2267 emit_rm(cbuf, 0x03, 0x00, dstenc); 2268 $$$emit32$src$$constant; 2269 %} 2270 2271 enc_class load_immP31(rRegP dst, immP32 src) 2272 %{ 2273 // same as load_immI, but this time we care about zeroes in the high word 2274 int dstenc = $dst$$reg; 2275 if (dstenc >= 8) { 2276 emit_opcode(cbuf, Assembler::REX_B); 2277 dstenc -= 8; 2278 } 2279 emit_opcode(cbuf, 0xB8 | dstenc); 2280 $$$emit32$src$$constant; 2281 %} 2282 2283 enc_class load_immP(rRegP dst, immP src) 2284 %{ 2285 int dstenc = $dst$$reg; 2286 if (dstenc < 8) { 2287 emit_opcode(cbuf, Assembler::REX_W); 2288 } else { 2289 emit_opcode(cbuf, Assembler::REX_WB); 2290 dstenc -= 8; 2291 } 2292 emit_opcode(cbuf, 0xB8 | dstenc); 2293 // This next line should be generated from ADLC 2294 if ($src->constant_reloc() != relocInfo::none) { 2295 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2296 } else { 2297 emit_d64(cbuf, $src$$constant); 2298 } 2299 %} 2300 2301 enc_class Con32(immI src) 2302 %{ 2303 // Output immediate 2304 $$$emit32$src$$constant; 2305 %} 2306 2307 enc_class Con32F_as_bits(immF src) 2308 %{ 2309 // Output Float immediate bits 2310 jfloat jf = $src$$constant; 2311 jint jf_as_bits = jint_cast(jf); 2312 emit_d32(cbuf, jf_as_bits); 2313 %} 2314 2315 enc_class Con16(immI src) 2316 %{ 2317 // Output immediate 2318 $$$emit16$src$$constant; 2319 %} 2320 2321 // How is this different from Con32??? XXX 2322 enc_class Con_d32(immI src) 2323 %{ 2324 emit_d32(cbuf,$src$$constant); 2325 %} 2326 2327 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2328 // Output immediate memory reference 2329 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2330 emit_d32(cbuf, 0x00); 2331 %} 2332 2333 enc_class lock_prefix() 2334 %{ 2335 emit_opcode(cbuf, 0xF0); // lock 2336 %} 2337 2338 enc_class REX_mem(memory mem) 2339 %{ 2340 if ($mem$$base >= 8) { 2341 if ($mem$$index < 8) { 2342 emit_opcode(cbuf, Assembler::REX_B); 2343 } else { 2344 emit_opcode(cbuf, Assembler::REX_XB); 2345 } 2346 } else { 2347 if ($mem$$index >= 8) { 2348 emit_opcode(cbuf, Assembler::REX_X); 2349 } 2350 } 2351 %} 2352 2353 enc_class REX_mem_wide(memory mem) 2354 %{ 2355 if ($mem$$base >= 8) { 2356 if ($mem$$index < 8) { 2357 emit_opcode(cbuf, Assembler::REX_WB); 2358 } else { 2359 emit_opcode(cbuf, Assembler::REX_WXB); 2360 } 2361 } else { 2362 if ($mem$$index < 8) { 2363 emit_opcode(cbuf, Assembler::REX_W); 2364 } else { 2365 emit_opcode(cbuf, Assembler::REX_WX); 2366 } 2367 } 2368 %} 2369 2370 // for byte regs 2371 enc_class REX_breg(rRegI reg) 2372 %{ 2373 if ($reg$$reg >= 4) { 2374 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2375 } 2376 %} 2377 2378 // for byte regs 2379 enc_class REX_reg_breg(rRegI dst, rRegI src) 2380 %{ 2381 if ($dst$$reg < 8) { 2382 if ($src$$reg >= 4) { 2383 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2384 } 2385 } else { 2386 if ($src$$reg < 8) { 2387 emit_opcode(cbuf, Assembler::REX_R); 2388 } else { 2389 emit_opcode(cbuf, Assembler::REX_RB); 2390 } 2391 } 2392 %} 2393 2394 // for byte regs 2395 enc_class REX_breg_mem(rRegI reg, memory mem) 2396 %{ 2397 if ($reg$$reg < 8) { 2398 if ($mem$$base < 8) { 2399 if ($mem$$index >= 8) { 2400 emit_opcode(cbuf, Assembler::REX_X); 2401 } else if ($reg$$reg >= 4) { 2402 emit_opcode(cbuf, Assembler::REX); 2403 } 2404 } else { 2405 if ($mem$$index < 8) { 2406 emit_opcode(cbuf, Assembler::REX_B); 2407 } else { 2408 emit_opcode(cbuf, Assembler::REX_XB); 2409 } 2410 } 2411 } else { 2412 if ($mem$$base < 8) { 2413 if ($mem$$index < 8) { 2414 emit_opcode(cbuf, Assembler::REX_R); 2415 } else { 2416 emit_opcode(cbuf, Assembler::REX_RX); 2417 } 2418 } else { 2419 if ($mem$$index < 8) { 2420 emit_opcode(cbuf, Assembler::REX_RB); 2421 } else { 2422 emit_opcode(cbuf, Assembler::REX_RXB); 2423 } 2424 } 2425 } 2426 %} 2427 2428 enc_class REX_reg(rRegI reg) 2429 %{ 2430 if ($reg$$reg >= 8) { 2431 emit_opcode(cbuf, Assembler::REX_B); 2432 } 2433 %} 2434 2435 enc_class REX_reg_wide(rRegI reg) 2436 %{ 2437 if ($reg$$reg < 8) { 2438 emit_opcode(cbuf, Assembler::REX_W); 2439 } else { 2440 emit_opcode(cbuf, Assembler::REX_WB); 2441 } 2442 %} 2443 2444 enc_class REX_reg_reg(rRegI dst, rRegI src) 2445 %{ 2446 if ($dst$$reg < 8) { 2447 if ($src$$reg >= 8) { 2448 emit_opcode(cbuf, Assembler::REX_B); 2449 } 2450 } else { 2451 if ($src$$reg < 8) { 2452 emit_opcode(cbuf, Assembler::REX_R); 2453 } else { 2454 emit_opcode(cbuf, Assembler::REX_RB); 2455 } 2456 } 2457 %} 2458 2459 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2460 %{ 2461 if ($dst$$reg < 8) { 2462 if ($src$$reg < 8) { 2463 emit_opcode(cbuf, Assembler::REX_W); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_WB); 2466 } 2467 } else { 2468 if ($src$$reg < 8) { 2469 emit_opcode(cbuf, Assembler::REX_WR); 2470 } else { 2471 emit_opcode(cbuf, Assembler::REX_WRB); 2472 } 2473 } 2474 %} 2475 2476 enc_class REX_reg_mem(rRegI reg, memory mem) 2477 %{ 2478 if ($reg$$reg < 8) { 2479 if ($mem$$base < 8) { 2480 if ($mem$$index >= 8) { 2481 emit_opcode(cbuf, Assembler::REX_X); 2482 } 2483 } else { 2484 if ($mem$$index < 8) { 2485 emit_opcode(cbuf, Assembler::REX_B); 2486 } else { 2487 emit_opcode(cbuf, Assembler::REX_XB); 2488 } 2489 } 2490 } else { 2491 if ($mem$$base < 8) { 2492 if ($mem$$index < 8) { 2493 emit_opcode(cbuf, Assembler::REX_R); 2494 } else { 2495 emit_opcode(cbuf, Assembler::REX_RX); 2496 } 2497 } else { 2498 if ($mem$$index < 8) { 2499 emit_opcode(cbuf, Assembler::REX_RB); 2500 } else { 2501 emit_opcode(cbuf, Assembler::REX_RXB); 2502 } 2503 } 2504 } 2505 %} 2506 2507 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2508 %{ 2509 if ($reg$$reg < 8) { 2510 if ($mem$$base < 8) { 2511 if ($mem$$index < 8) { 2512 emit_opcode(cbuf, Assembler::REX_W); 2513 } else { 2514 emit_opcode(cbuf, Assembler::REX_WX); 2515 } 2516 } else { 2517 if ($mem$$index < 8) { 2518 emit_opcode(cbuf, Assembler::REX_WB); 2519 } else { 2520 emit_opcode(cbuf, Assembler::REX_WXB); 2521 } 2522 } 2523 } else { 2524 if ($mem$$base < 8) { 2525 if ($mem$$index < 8) { 2526 emit_opcode(cbuf, Assembler::REX_WR); 2527 } else { 2528 emit_opcode(cbuf, Assembler::REX_WRX); 2529 } 2530 } else { 2531 if ($mem$$index < 8) { 2532 emit_opcode(cbuf, Assembler::REX_WRB); 2533 } else { 2534 emit_opcode(cbuf, Assembler::REX_WRXB); 2535 } 2536 } 2537 } 2538 %} 2539 2540 enc_class reg_mem(rRegI ereg, memory mem) 2541 %{ 2542 // High registers handle in encode_RegMem 2543 int reg = $ereg$$reg; 2544 int base = $mem$$base; 2545 int index = $mem$$index; 2546 int scale = $mem$$scale; 2547 int disp = $mem$$disp; 2548 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2549 2550 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2551 %} 2552 2553 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2554 %{ 2555 int rm_byte_opcode = $rm_opcode$$constant; 2556 2557 // High registers handle in encode_RegMem 2558 int base = $mem$$base; 2559 int index = $mem$$index; 2560 int scale = $mem$$scale; 2561 int displace = $mem$$disp; 2562 2563 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2564 // working with static 2565 // globals 2566 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2567 disp_reloc); 2568 %} 2569 2570 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2571 %{ 2572 int reg_encoding = $dst$$reg; 2573 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2574 int index = 0x04; // 0x04 indicates no index 2575 int scale = 0x00; // 0x00 indicates no scale 2576 int displace = $src1$$constant; // 0x00 indicates no displacement 2577 relocInfo::relocType disp_reloc = relocInfo::none; 2578 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2579 disp_reloc); 2580 %} 2581 2582 enc_class neg_reg(rRegI dst) 2583 %{ 2584 int dstenc = $dst$$reg; 2585 if (dstenc >= 8) { 2586 emit_opcode(cbuf, Assembler::REX_B); 2587 dstenc -= 8; 2588 } 2589 // NEG $dst 2590 emit_opcode(cbuf, 0xF7); 2591 emit_rm(cbuf, 0x3, 0x03, dstenc); 2592 %} 2593 2594 enc_class neg_reg_wide(rRegI dst) 2595 %{ 2596 int dstenc = $dst$$reg; 2597 if (dstenc < 8) { 2598 emit_opcode(cbuf, Assembler::REX_W); 2599 } else { 2600 emit_opcode(cbuf, Assembler::REX_WB); 2601 dstenc -= 8; 2602 } 2603 // NEG $dst 2604 emit_opcode(cbuf, 0xF7); 2605 emit_rm(cbuf, 0x3, 0x03, dstenc); 2606 %} 2607 2608 enc_class setLT_reg(rRegI dst) 2609 %{ 2610 int dstenc = $dst$$reg; 2611 if (dstenc >= 8) { 2612 emit_opcode(cbuf, Assembler::REX_B); 2613 dstenc -= 8; 2614 } else if (dstenc >= 4) { 2615 emit_opcode(cbuf, Assembler::REX); 2616 } 2617 // SETLT $dst 2618 emit_opcode(cbuf, 0x0F); 2619 emit_opcode(cbuf, 0x9C); 2620 emit_rm(cbuf, 0x3, 0x0, dstenc); 2621 %} 2622 2623 enc_class setNZ_reg(rRegI dst) 2624 %{ 2625 int dstenc = $dst$$reg; 2626 if (dstenc >= 8) { 2627 emit_opcode(cbuf, Assembler::REX_B); 2628 dstenc -= 8; 2629 } else if (dstenc >= 4) { 2630 emit_opcode(cbuf, Assembler::REX); 2631 } 2632 // SETNZ $dst 2633 emit_opcode(cbuf, 0x0F); 2634 emit_opcode(cbuf, 0x95); 2635 emit_rm(cbuf, 0x3, 0x0, dstenc); 2636 %} 2637 2638 2639 // Compare the lonogs and set -1, 0, or 1 into dst 2640 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2641 %{ 2642 int src1enc = $src1$$reg; 2643 int src2enc = $src2$$reg; 2644 int dstenc = $dst$$reg; 2645 2646 // cmpq $src1, $src2 2647 if (src1enc < 8) { 2648 if (src2enc < 8) { 2649 emit_opcode(cbuf, Assembler::REX_W); 2650 } else { 2651 emit_opcode(cbuf, Assembler::REX_WB); 2652 } 2653 } else { 2654 if (src2enc < 8) { 2655 emit_opcode(cbuf, Assembler::REX_WR); 2656 } else { 2657 emit_opcode(cbuf, Assembler::REX_WRB); 2658 } 2659 } 2660 emit_opcode(cbuf, 0x3B); 2661 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2662 2663 // movl $dst, -1 2664 if (dstenc >= 8) { 2665 emit_opcode(cbuf, Assembler::REX_B); 2666 } 2667 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2668 emit_d32(cbuf, -1); 2669 2670 // jl,s done 2671 emit_opcode(cbuf, 0x7C); 2672 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2673 2674 // setne $dst 2675 if (dstenc >= 4) { 2676 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2677 } 2678 emit_opcode(cbuf, 0x0F); 2679 emit_opcode(cbuf, 0x95); 2680 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2681 2682 // movzbl $dst, $dst 2683 if (dstenc >= 4) { 2684 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2685 } 2686 emit_opcode(cbuf, 0x0F); 2687 emit_opcode(cbuf, 0xB6); 2688 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2689 %} 2690 2691 enc_class Push_ResultXD(regD dst) %{ 2692 MacroAssembler _masm(&cbuf); 2693 __ fstp_d(Address(rsp, 0)); 2694 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2695 __ addptr(rsp, 8); 2696 %} 2697 2698 enc_class Push_SrcXD(regD src) %{ 2699 MacroAssembler _masm(&cbuf); 2700 __ subptr(rsp, 8); 2701 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2702 __ fld_d(Address(rsp, 0)); 2703 %} 2704 2705 2706 enc_class enc_rethrow() 2707 %{ 2708 cbuf.set_insts_mark(); 2709 emit_opcode(cbuf, 0xE9); // jmp entry 2710 emit_d32_reloc(cbuf, 2711 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2712 runtime_call_Relocation::spec(), 2713 RELOC_DISP32); 2714 %} 2715 2716 %} 2717 2718 2719 2720 //----------FRAME-------------------------------------------------------------- 2721 // Definition of frame structure and management information. 2722 // 2723 // S T A C K L A Y O U T Allocators stack-slot number 2724 // | (to get allocators register number 2725 // G Owned by | | v add OptoReg::stack0()) 2726 // r CALLER | | 2727 // o | +--------+ pad to even-align allocators stack-slot 2728 // w V | pad0 | numbers; owned by CALLER 2729 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2730 // h ^ | in | 5 2731 // | | args | 4 Holes in incoming args owned by SELF 2732 // | | | | 3 2733 // | | +--------+ 2734 // V | | old out| Empty on Intel, window on Sparc 2735 // | old |preserve| Must be even aligned. 2736 // | SP-+--------+----> Matcher::_old_SP, even aligned 2737 // | | in | 3 area for Intel ret address 2738 // Owned by |preserve| Empty on Sparc. 2739 // SELF +--------+ 2740 // | | pad2 | 2 pad to align old SP 2741 // | +--------+ 1 2742 // | | locks | 0 2743 // | +--------+----> OptoReg::stack0(), even aligned 2744 // | | pad1 | 11 pad to align new SP 2745 // | +--------+ 2746 // | | | 10 2747 // | | spills | 9 spills 2748 // V | | 8 (pad0 slot for callee) 2749 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2750 // ^ | out | 7 2751 // | | args | 6 Holes in outgoing args owned by CALLEE 2752 // Owned by +--------+ 2753 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2754 // | new |preserve| Must be even-aligned. 2755 // | SP-+--------+----> Matcher::_new_SP, even aligned 2756 // | | | 2757 // 2758 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2759 // known from SELF's arguments and the Java calling convention. 2760 // Region 6-7 is determined per call site. 2761 // Note 2: If the calling convention leaves holes in the incoming argument 2762 // area, those holes are owned by SELF. Holes in the outgoing area 2763 // are owned by the CALLEE. Holes should not be nessecary in the 2764 // incoming area, as the Java calling convention is completely under 2765 // the control of the AD file. Doubles can be sorted and packed to 2766 // avoid holes. Holes in the outgoing arguments may be nessecary for 2767 // varargs C calling conventions. 2768 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2769 // even aligned with pad0 as needed. 2770 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2771 // region 6-11 is even aligned; it may be padded out more so that 2772 // the region from SP to FP meets the minimum stack alignment. 2773 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2774 // alignment. Region 11, pad1, may be dynamically extended so that 2775 // SP meets the minimum alignment. 2776 2777 frame 2778 %{ 2779 // What direction does stack grow in (assumed to be same for C & Java) 2780 stack_direction(TOWARDS_LOW); 2781 2782 // These three registers define part of the calling convention 2783 // between compiled code and the interpreter. 2784 inline_cache_reg(RAX); // Inline Cache Register 2785 interpreter_method_oop_reg(RBX); // Method Oop Register when 2786 // calling interpreter 2787 2788 // Optional: name the operand used by cisc-spilling to access 2789 // [stack_pointer + offset] 2790 cisc_spilling_operand_name(indOffset32); 2791 2792 // Number of stack slots consumed by locking an object 2793 sync_stack_slots(2); 2794 2795 // Compiled code's Frame Pointer 2796 frame_pointer(RSP); 2797 2798 // Interpreter stores its frame pointer in a register which is 2799 // stored to the stack by I2CAdaptors. 2800 // I2CAdaptors convert from interpreted java to compiled java. 2801 interpreter_frame_pointer(RBP); 2802 2803 // Stack alignment requirement 2804 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2805 2806 // Number of stack slots between incoming argument block and the start of 2807 // a new frame. The PROLOG must add this many slots to the stack. The 2808 // EPILOG must remove this many slots. amd64 needs two slots for 2809 // return address. 2810 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2811 2812 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2813 // for calls to C. Supports the var-args backing area for register parms. 2814 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2815 2816 // The after-PROLOG location of the return address. Location of 2817 // return address specifies a type (REG or STACK) and a number 2818 // representing the register number (i.e. - use a register name) or 2819 // stack slot. 2820 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2821 // Otherwise, it is above the locks and verification slot and alignment word 2822 return_addr(STACK - 2 + 2823 align_up((Compile::current()->in_preserve_stack_slots() + 2824 Compile::current()->fixed_slots()), 2825 stack_alignment_in_slots())); 2826 2827 // Body of function which returns an integer array locating 2828 // arguments either in registers or in stack slots. Passed an array 2829 // of ideal registers called "sig" and a "length" count. Stack-slot 2830 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2831 // arguments for a CALLEE. Incoming stack arguments are 2832 // automatically biased by the preserve_stack_slots field above. 2833 2834 calling_convention 2835 %{ 2836 // No difference between ingoing/outgoing just pass false 2837 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2838 %} 2839 2840 c_calling_convention 2841 %{ 2842 // This is obviously always outgoing 2843 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2844 %} 2845 2846 // Location of compiled Java return values. Same as C for now. 2847 return_value 2848 %{ 2849 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2850 "only return normal values"); 2851 2852 static const int lo[Op_RegL + 1] = { 2853 0, 2854 0, 2855 RAX_num, // Op_RegN 2856 RAX_num, // Op_RegI 2857 RAX_num, // Op_RegP 2858 XMM0_num, // Op_RegF 2859 XMM0_num, // Op_RegD 2860 RAX_num // Op_RegL 2861 }; 2862 static const int hi[Op_RegL + 1] = { 2863 0, 2864 0, 2865 OptoReg::Bad, // Op_RegN 2866 OptoReg::Bad, // Op_RegI 2867 RAX_H_num, // Op_RegP 2868 OptoReg::Bad, // Op_RegF 2869 XMM0b_num, // Op_RegD 2870 RAX_H_num // Op_RegL 2871 }; 2872 // Excluded flags and vector registers. 2873 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2874 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2875 %} 2876 %} 2877 2878 //----------ATTRIBUTES--------------------------------------------------------- 2879 //----------Operand Attributes------------------------------------------------- 2880 op_attrib op_cost(0); // Required cost attribute 2881 2882 //----------Instruction Attributes--------------------------------------------- 2883 ins_attrib ins_cost(100); // Required cost attribute 2884 ins_attrib ins_size(8); // Required size attribute (in bits) 2885 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2886 // a non-matching short branch variant 2887 // of some long branch? 2888 ins_attrib ins_alignment(1); // Required alignment attribute (must 2889 // be a power of 2) specifies the 2890 // alignment that some part of the 2891 // instruction (not necessarily the 2892 // start) requires. If > 1, a 2893 // compute_padding() function must be 2894 // provided for the instruction 2895 2896 //----------OPERANDS----------------------------------------------------------- 2897 // Operand definitions must precede instruction definitions for correct parsing 2898 // in the ADLC because operands constitute user defined types which are used in 2899 // instruction definitions. 2900 2901 //----------Simple Operands---------------------------------------------------- 2902 // Immediate Operands 2903 // Integer Immediate 2904 operand immI() 2905 %{ 2906 match(ConI); 2907 2908 op_cost(10); 2909 format %{ %} 2910 interface(CONST_INTER); 2911 %} 2912 2913 // Constant for test vs zero 2914 operand immI0() 2915 %{ 2916 predicate(n->get_int() == 0); 2917 match(ConI); 2918 2919 op_cost(0); 2920 format %{ %} 2921 interface(CONST_INTER); 2922 %} 2923 2924 // Constant for increment 2925 operand immI1() 2926 %{ 2927 predicate(n->get_int() == 1); 2928 match(ConI); 2929 2930 op_cost(0); 2931 format %{ %} 2932 interface(CONST_INTER); 2933 %} 2934 2935 // Constant for decrement 2936 operand immI_M1() 2937 %{ 2938 predicate(n->get_int() == -1); 2939 match(ConI); 2940 2941 op_cost(0); 2942 format %{ %} 2943 interface(CONST_INTER); 2944 %} 2945 2946 // Valid scale values for addressing modes 2947 operand immI2() 2948 %{ 2949 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2950 match(ConI); 2951 2952 format %{ %} 2953 interface(CONST_INTER); 2954 %} 2955 2956 operand immI8() 2957 %{ 2958 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2959 match(ConI); 2960 2961 op_cost(5); 2962 format %{ %} 2963 interface(CONST_INTER); 2964 %} 2965 2966 operand immU8() 2967 %{ 2968 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2969 match(ConI); 2970 2971 op_cost(5); 2972 format %{ %} 2973 interface(CONST_INTER); 2974 %} 2975 2976 operand immI16() 2977 %{ 2978 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2979 match(ConI); 2980 2981 op_cost(10); 2982 format %{ %} 2983 interface(CONST_INTER); 2984 %} 2985 2986 // Int Immediate non-negative 2987 operand immU31() 2988 %{ 2989 predicate(n->get_int() >= 0); 2990 match(ConI); 2991 2992 op_cost(0); 2993 format %{ %} 2994 interface(CONST_INTER); 2995 %} 2996 2997 // Constant for long shifts 2998 operand immI_32() 2999 %{ 3000 predicate( n->get_int() == 32 ); 3001 match(ConI); 3002 3003 op_cost(0); 3004 format %{ %} 3005 interface(CONST_INTER); 3006 %} 3007 3008 // Constant for long shifts 3009 operand immI_64() 3010 %{ 3011 predicate( n->get_int() == 64 ); 3012 match(ConI); 3013 3014 op_cost(0); 3015 format %{ %} 3016 interface(CONST_INTER); 3017 %} 3018 3019 // Pointer Immediate 3020 operand immP() 3021 %{ 3022 match(ConP); 3023 3024 op_cost(10); 3025 format %{ %} 3026 interface(CONST_INTER); 3027 %} 3028 3029 // NULL Pointer Immediate 3030 operand immP0() 3031 %{ 3032 predicate(n->get_ptr() == 0); 3033 match(ConP); 3034 3035 op_cost(5); 3036 format %{ %} 3037 interface(CONST_INTER); 3038 %} 3039 3040 // Pointer Immediate 3041 operand immN() %{ 3042 match(ConN); 3043 3044 op_cost(10); 3045 format %{ %} 3046 interface(CONST_INTER); 3047 %} 3048 3049 operand immNKlass() %{ 3050 match(ConNKlass); 3051 3052 op_cost(10); 3053 format %{ %} 3054 interface(CONST_INTER); 3055 %} 3056 3057 // NULL Pointer Immediate 3058 operand immN0() %{ 3059 predicate(n->get_narrowcon() == 0); 3060 match(ConN); 3061 3062 op_cost(5); 3063 format %{ %} 3064 interface(CONST_INTER); 3065 %} 3066 3067 operand immP31() 3068 %{ 3069 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3070 && (n->get_ptr() >> 31) == 0); 3071 match(ConP); 3072 3073 op_cost(5); 3074 format %{ %} 3075 interface(CONST_INTER); 3076 %} 3077 3078 3079 // Long Immediate 3080 operand immL() 3081 %{ 3082 match(ConL); 3083 3084 op_cost(20); 3085 format %{ %} 3086 interface(CONST_INTER); 3087 %} 3088 3089 // Long Immediate 8-bit 3090 operand immL8() 3091 %{ 3092 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3093 match(ConL); 3094 3095 op_cost(5); 3096 format %{ %} 3097 interface(CONST_INTER); 3098 %} 3099 3100 // Long Immediate 32-bit unsigned 3101 operand immUL32() 3102 %{ 3103 predicate(n->get_long() == (unsigned int) (n->get_long())); 3104 match(ConL); 3105 3106 op_cost(10); 3107 format %{ %} 3108 interface(CONST_INTER); 3109 %} 3110 3111 // Long Immediate 32-bit signed 3112 operand immL32() 3113 %{ 3114 predicate(n->get_long() == (int) (n->get_long())); 3115 match(ConL); 3116 3117 op_cost(15); 3118 format %{ %} 3119 interface(CONST_INTER); 3120 %} 3121 3122 operand immL_Pow2() 3123 %{ 3124 predicate(is_power_of_2_long(n->get_long())); 3125 match(ConL); 3126 3127 op_cost(15); 3128 format %{ %} 3129 interface(CONST_INTER); 3130 %} 3131 3132 operand immL_NotPow2() 3133 %{ 3134 predicate(is_power_of_2_long(~n->get_long())); 3135 match(ConL); 3136 3137 op_cost(15); 3138 format %{ %} 3139 interface(CONST_INTER); 3140 %} 3141 3142 // Long Immediate zero 3143 operand immL0() 3144 %{ 3145 predicate(n->get_long() == 0L); 3146 match(ConL); 3147 3148 op_cost(10); 3149 format %{ %} 3150 interface(CONST_INTER); 3151 %} 3152 3153 // Constant for increment 3154 operand immL1() 3155 %{ 3156 predicate(n->get_long() == 1); 3157 match(ConL); 3158 3159 format %{ %} 3160 interface(CONST_INTER); 3161 %} 3162 3163 // Constant for decrement 3164 operand immL_M1() 3165 %{ 3166 predicate(n->get_long() == -1); 3167 match(ConL); 3168 3169 format %{ %} 3170 interface(CONST_INTER); 3171 %} 3172 3173 // Long Immediate: the value 10 3174 operand immL10() 3175 %{ 3176 predicate(n->get_long() == 10); 3177 match(ConL); 3178 3179 format %{ %} 3180 interface(CONST_INTER); 3181 %} 3182 3183 // Long immediate from 0 to 127. 3184 // Used for a shorter form of long mul by 10. 3185 operand immL_127() 3186 %{ 3187 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3188 match(ConL); 3189 3190 op_cost(10); 3191 format %{ %} 3192 interface(CONST_INTER); 3193 %} 3194 3195 // Long Immediate: low 32-bit mask 3196 operand immL_32bits() 3197 %{ 3198 predicate(n->get_long() == 0xFFFFFFFFL); 3199 match(ConL); 3200 op_cost(20); 3201 3202 format %{ %} 3203 interface(CONST_INTER); 3204 %} 3205 3206 // Float Immediate zero 3207 operand immF0() 3208 %{ 3209 predicate(jint_cast(n->getf()) == 0); 3210 match(ConF); 3211 3212 op_cost(5); 3213 format %{ %} 3214 interface(CONST_INTER); 3215 %} 3216 3217 // Float Immediate 3218 operand immF() 3219 %{ 3220 match(ConF); 3221 3222 op_cost(15); 3223 format %{ %} 3224 interface(CONST_INTER); 3225 %} 3226 3227 // Double Immediate zero 3228 operand immD0() 3229 %{ 3230 predicate(jlong_cast(n->getd()) == 0); 3231 match(ConD); 3232 3233 op_cost(5); 3234 format %{ %} 3235 interface(CONST_INTER); 3236 %} 3237 3238 // Double Immediate 3239 operand immD() 3240 %{ 3241 match(ConD); 3242 3243 op_cost(15); 3244 format %{ %} 3245 interface(CONST_INTER); 3246 %} 3247 3248 // Immediates for special shifts (sign extend) 3249 3250 // Constants for increment 3251 operand immI_16() 3252 %{ 3253 predicate(n->get_int() == 16); 3254 match(ConI); 3255 3256 format %{ %} 3257 interface(CONST_INTER); 3258 %} 3259 3260 operand immI_24() 3261 %{ 3262 predicate(n->get_int() == 24); 3263 match(ConI); 3264 3265 format %{ %} 3266 interface(CONST_INTER); 3267 %} 3268 3269 // Constant for byte-wide masking 3270 operand immI_255() 3271 %{ 3272 predicate(n->get_int() == 255); 3273 match(ConI); 3274 3275 format %{ %} 3276 interface(CONST_INTER); 3277 %} 3278 3279 // Constant for short-wide masking 3280 operand immI_65535() 3281 %{ 3282 predicate(n->get_int() == 65535); 3283 match(ConI); 3284 3285 format %{ %} 3286 interface(CONST_INTER); 3287 %} 3288 3289 // Constant for byte-wide masking 3290 operand immL_255() 3291 %{ 3292 predicate(n->get_long() == 255); 3293 match(ConL); 3294 3295 format %{ %} 3296 interface(CONST_INTER); 3297 %} 3298 3299 // Constant for short-wide masking 3300 operand immL_65535() 3301 %{ 3302 predicate(n->get_long() == 65535); 3303 match(ConL); 3304 3305 format %{ %} 3306 interface(CONST_INTER); 3307 %} 3308 3309 // Register Operands 3310 // Integer Register 3311 operand rRegI() 3312 %{ 3313 constraint(ALLOC_IN_RC(int_reg)); 3314 match(RegI); 3315 3316 match(rax_RegI); 3317 match(rbx_RegI); 3318 match(rcx_RegI); 3319 match(rdx_RegI); 3320 match(rdi_RegI); 3321 3322 format %{ %} 3323 interface(REG_INTER); 3324 %} 3325 3326 // Special Registers 3327 operand rax_RegI() 3328 %{ 3329 constraint(ALLOC_IN_RC(int_rax_reg)); 3330 match(RegI); 3331 match(rRegI); 3332 3333 format %{ "RAX" %} 3334 interface(REG_INTER); 3335 %} 3336 3337 // Special Registers 3338 operand rbx_RegI() 3339 %{ 3340 constraint(ALLOC_IN_RC(int_rbx_reg)); 3341 match(RegI); 3342 match(rRegI); 3343 3344 format %{ "RBX" %} 3345 interface(REG_INTER); 3346 %} 3347 3348 operand rcx_RegI() 3349 %{ 3350 constraint(ALLOC_IN_RC(int_rcx_reg)); 3351 match(RegI); 3352 match(rRegI); 3353 3354 format %{ "RCX" %} 3355 interface(REG_INTER); 3356 %} 3357 3358 operand rdx_RegI() 3359 %{ 3360 constraint(ALLOC_IN_RC(int_rdx_reg)); 3361 match(RegI); 3362 match(rRegI); 3363 3364 format %{ "RDX" %} 3365 interface(REG_INTER); 3366 %} 3367 3368 operand rdi_RegI() 3369 %{ 3370 constraint(ALLOC_IN_RC(int_rdi_reg)); 3371 match(RegI); 3372 match(rRegI); 3373 3374 format %{ "RDI" %} 3375 interface(REG_INTER); 3376 %} 3377 3378 operand no_rcx_RegI() 3379 %{ 3380 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3381 match(RegI); 3382 match(rax_RegI); 3383 match(rbx_RegI); 3384 match(rdx_RegI); 3385 match(rdi_RegI); 3386 3387 format %{ %} 3388 interface(REG_INTER); 3389 %} 3390 3391 operand no_rax_rdx_RegI() 3392 %{ 3393 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3394 match(RegI); 3395 match(rbx_RegI); 3396 match(rcx_RegI); 3397 match(rdi_RegI); 3398 3399 format %{ %} 3400 interface(REG_INTER); 3401 %} 3402 3403 // Pointer Register 3404 operand any_RegP() 3405 %{ 3406 constraint(ALLOC_IN_RC(any_reg)); 3407 match(RegP); 3408 match(rax_RegP); 3409 match(rbx_RegP); 3410 match(rdi_RegP); 3411 match(rsi_RegP); 3412 match(rbp_RegP); 3413 match(r15_RegP); 3414 match(rRegP); 3415 3416 format %{ %} 3417 interface(REG_INTER); 3418 %} 3419 3420 operand rRegP() 3421 %{ 3422 constraint(ALLOC_IN_RC(ptr_reg)); 3423 match(RegP); 3424 match(rax_RegP); 3425 match(rbx_RegP); 3426 match(rdi_RegP); 3427 match(rsi_RegP); 3428 match(rbp_RegP); // See Q&A below about 3429 match(r15_RegP); // r15_RegP and rbp_RegP. 3430 3431 format %{ %} 3432 interface(REG_INTER); 3433 %} 3434 3435 operand rRegN() %{ 3436 constraint(ALLOC_IN_RC(int_reg)); 3437 match(RegN); 3438 3439 format %{ %} 3440 interface(REG_INTER); 3441 %} 3442 3443 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3444 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3445 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3446 // The output of an instruction is controlled by the allocator, which respects 3447 // register class masks, not match rules. Unless an instruction mentions 3448 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3449 // by the allocator as an input. 3450 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3451 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3452 // result, RBP is not included in the output of the instruction either. 3453 3454 operand no_rax_RegP() 3455 %{ 3456 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3457 match(RegP); 3458 match(rbx_RegP); 3459 match(rsi_RegP); 3460 match(rdi_RegP); 3461 3462 format %{ %} 3463 interface(REG_INTER); 3464 %} 3465 3466 // This operand is not allowed to use RBP even if 3467 // RBP is not used to hold the frame pointer. 3468 operand no_rbp_RegP() 3469 %{ 3470 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3471 match(RegP); 3472 match(rbx_RegP); 3473 match(rsi_RegP); 3474 match(rdi_RegP); 3475 3476 format %{ %} 3477 interface(REG_INTER); 3478 %} 3479 3480 operand no_rax_rbx_RegP() 3481 %{ 3482 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3483 match(RegP); 3484 match(rsi_RegP); 3485 match(rdi_RegP); 3486 3487 format %{ %} 3488 interface(REG_INTER); 3489 %} 3490 3491 // Special Registers 3492 // Return a pointer value 3493 operand rax_RegP() 3494 %{ 3495 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3496 match(RegP); 3497 match(rRegP); 3498 3499 format %{ %} 3500 interface(REG_INTER); 3501 %} 3502 3503 // Special Registers 3504 // Return a compressed pointer value 3505 operand rax_RegN() 3506 %{ 3507 constraint(ALLOC_IN_RC(int_rax_reg)); 3508 match(RegN); 3509 match(rRegN); 3510 3511 format %{ %} 3512 interface(REG_INTER); 3513 %} 3514 3515 // Used in AtomicAdd 3516 operand rbx_RegP() 3517 %{ 3518 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3519 match(RegP); 3520 match(rRegP); 3521 3522 format %{ %} 3523 interface(REG_INTER); 3524 %} 3525 3526 operand rsi_RegP() 3527 %{ 3528 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3529 match(RegP); 3530 match(rRegP); 3531 3532 format %{ %} 3533 interface(REG_INTER); 3534 %} 3535 3536 operand rbp_RegP() 3537 %{ 3538 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3539 match(RegP); 3540 match(rRegP); 3541 3542 format %{ %} 3543 interface(REG_INTER); 3544 %} 3545 3546 // Used in rep stosq 3547 operand rdi_RegP() 3548 %{ 3549 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3550 match(RegP); 3551 match(rRegP); 3552 3553 format %{ %} 3554 interface(REG_INTER); 3555 %} 3556 3557 operand r15_RegP() 3558 %{ 3559 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3560 match(RegP); 3561 match(rRegP); 3562 3563 format %{ %} 3564 interface(REG_INTER); 3565 %} 3566 3567 operand rRegL() 3568 %{ 3569 constraint(ALLOC_IN_RC(long_reg)); 3570 match(RegL); 3571 match(rax_RegL); 3572 match(rdx_RegL); 3573 3574 format %{ %} 3575 interface(REG_INTER); 3576 %} 3577 3578 // Special Registers 3579 operand no_rax_rdx_RegL() 3580 %{ 3581 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3582 match(RegL); 3583 match(rRegL); 3584 3585 format %{ %} 3586 interface(REG_INTER); 3587 %} 3588 3589 operand no_rax_RegL() 3590 %{ 3591 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3592 match(RegL); 3593 match(rRegL); 3594 match(rdx_RegL); 3595 3596 format %{ %} 3597 interface(REG_INTER); 3598 %} 3599 3600 operand no_rcx_RegL() 3601 %{ 3602 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3603 match(RegL); 3604 match(rRegL); 3605 3606 format %{ %} 3607 interface(REG_INTER); 3608 %} 3609 3610 operand rax_RegL() 3611 %{ 3612 constraint(ALLOC_IN_RC(long_rax_reg)); 3613 match(RegL); 3614 match(rRegL); 3615 3616 format %{ "RAX" %} 3617 interface(REG_INTER); 3618 %} 3619 3620 operand rcx_RegL() 3621 %{ 3622 constraint(ALLOC_IN_RC(long_rcx_reg)); 3623 match(RegL); 3624 match(rRegL); 3625 3626 format %{ %} 3627 interface(REG_INTER); 3628 %} 3629 3630 operand rdx_RegL() 3631 %{ 3632 constraint(ALLOC_IN_RC(long_rdx_reg)); 3633 match(RegL); 3634 match(rRegL); 3635 3636 format %{ %} 3637 interface(REG_INTER); 3638 %} 3639 3640 // Flags register, used as output of compare instructions 3641 operand rFlagsReg() 3642 %{ 3643 constraint(ALLOC_IN_RC(int_flags)); 3644 match(RegFlags); 3645 3646 format %{ "RFLAGS" %} 3647 interface(REG_INTER); 3648 %} 3649 3650 // Flags register, used as output of FLOATING POINT compare instructions 3651 operand rFlagsRegU() 3652 %{ 3653 constraint(ALLOC_IN_RC(int_flags)); 3654 match(RegFlags); 3655 3656 format %{ "RFLAGS_U" %} 3657 interface(REG_INTER); 3658 %} 3659 3660 operand rFlagsRegUCF() %{ 3661 constraint(ALLOC_IN_RC(int_flags)); 3662 match(RegFlags); 3663 predicate(false); 3664 3665 format %{ "RFLAGS_U_CF" %} 3666 interface(REG_INTER); 3667 %} 3668 3669 // Float register operands 3670 operand regF() %{ 3671 constraint(ALLOC_IN_RC(float_reg)); 3672 match(RegF); 3673 3674 format %{ %} 3675 interface(REG_INTER); 3676 %} 3677 3678 // Float register operands 3679 operand legRegF() %{ 3680 constraint(ALLOC_IN_RC(float_reg_legacy)); 3681 match(RegF); 3682 3683 format %{ %} 3684 interface(REG_INTER); 3685 %} 3686 3687 // Float register operands 3688 operand vlRegF() %{ 3689 constraint(ALLOC_IN_RC(float_reg_vl)); 3690 match(RegF); 3691 3692 format %{ %} 3693 interface(REG_INTER); 3694 %} 3695 3696 // Double register operands 3697 operand regD() %{ 3698 constraint(ALLOC_IN_RC(double_reg)); 3699 match(RegD); 3700 3701 format %{ %} 3702 interface(REG_INTER); 3703 %} 3704 3705 // Double register operands 3706 operand legRegD() %{ 3707 constraint(ALLOC_IN_RC(double_reg_legacy)); 3708 match(RegD); 3709 3710 format %{ %} 3711 interface(REG_INTER); 3712 %} 3713 3714 // Double register operands 3715 operand vlRegD() %{ 3716 constraint(ALLOC_IN_RC(double_reg_vl)); 3717 match(RegD); 3718 3719 format %{ %} 3720 interface(REG_INTER); 3721 %} 3722 3723 //----------Memory Operands---------------------------------------------------- 3724 // Direct Memory Operand 3725 // operand direct(immP addr) 3726 // %{ 3727 // match(addr); 3728 3729 // format %{ "[$addr]" %} 3730 // interface(MEMORY_INTER) %{ 3731 // base(0xFFFFFFFF); 3732 // index(0x4); 3733 // scale(0x0); 3734 // disp($addr); 3735 // %} 3736 // %} 3737 3738 // Indirect Memory Operand 3739 operand indirect(any_RegP reg) 3740 %{ 3741 constraint(ALLOC_IN_RC(ptr_reg)); 3742 match(reg); 3743 3744 format %{ "[$reg]" %} 3745 interface(MEMORY_INTER) %{ 3746 base($reg); 3747 index(0x4); 3748 scale(0x0); 3749 disp(0x0); 3750 %} 3751 %} 3752 3753 // Indirect Memory Plus Short Offset Operand 3754 operand indOffset8(any_RegP reg, immL8 off) 3755 %{ 3756 constraint(ALLOC_IN_RC(ptr_reg)); 3757 match(AddP reg off); 3758 3759 format %{ "[$reg + $off (8-bit)]" %} 3760 interface(MEMORY_INTER) %{ 3761 base($reg); 3762 index(0x4); 3763 scale(0x0); 3764 disp($off); 3765 %} 3766 %} 3767 3768 // Indirect Memory Plus Long Offset Operand 3769 operand indOffset32(any_RegP reg, immL32 off) 3770 %{ 3771 constraint(ALLOC_IN_RC(ptr_reg)); 3772 match(AddP reg off); 3773 3774 format %{ "[$reg + $off (32-bit)]" %} 3775 interface(MEMORY_INTER) %{ 3776 base($reg); 3777 index(0x4); 3778 scale(0x0); 3779 disp($off); 3780 %} 3781 %} 3782 3783 // Indirect Memory Plus Index Register Plus Offset Operand 3784 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3785 %{ 3786 constraint(ALLOC_IN_RC(ptr_reg)); 3787 match(AddP (AddP reg lreg) off); 3788 3789 op_cost(10); 3790 format %{"[$reg + $off + $lreg]" %} 3791 interface(MEMORY_INTER) %{ 3792 base($reg); 3793 index($lreg); 3794 scale(0x0); 3795 disp($off); 3796 %} 3797 %} 3798 3799 // Indirect Memory Plus Index Register Plus Offset Operand 3800 operand indIndex(any_RegP reg, rRegL lreg) 3801 %{ 3802 constraint(ALLOC_IN_RC(ptr_reg)); 3803 match(AddP reg lreg); 3804 3805 op_cost(10); 3806 format %{"[$reg + $lreg]" %} 3807 interface(MEMORY_INTER) %{ 3808 base($reg); 3809 index($lreg); 3810 scale(0x0); 3811 disp(0x0); 3812 %} 3813 %} 3814 3815 // Indirect Memory Times Scale Plus Index Register 3816 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3817 %{ 3818 constraint(ALLOC_IN_RC(ptr_reg)); 3819 match(AddP reg (LShiftL lreg scale)); 3820 3821 op_cost(10); 3822 format %{"[$reg + $lreg << $scale]" %} 3823 interface(MEMORY_INTER) %{ 3824 base($reg); 3825 index($lreg); 3826 scale($scale); 3827 disp(0x0); 3828 %} 3829 %} 3830 3831 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3832 %{ 3833 constraint(ALLOC_IN_RC(ptr_reg)); 3834 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3835 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3836 3837 op_cost(10); 3838 format %{"[$reg + pos $idx << $scale]" %} 3839 interface(MEMORY_INTER) %{ 3840 base($reg); 3841 index($idx); 3842 scale($scale); 3843 disp(0x0); 3844 %} 3845 %} 3846 3847 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3848 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3849 %{ 3850 constraint(ALLOC_IN_RC(ptr_reg)); 3851 match(AddP (AddP reg (LShiftL lreg scale)) off); 3852 3853 op_cost(10); 3854 format %{"[$reg + $off + $lreg << $scale]" %} 3855 interface(MEMORY_INTER) %{ 3856 base($reg); 3857 index($lreg); 3858 scale($scale); 3859 disp($off); 3860 %} 3861 %} 3862 3863 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3864 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3865 %{ 3866 constraint(ALLOC_IN_RC(ptr_reg)); 3867 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3868 match(AddP (AddP reg (ConvI2L idx)) off); 3869 3870 op_cost(10); 3871 format %{"[$reg + $off + $idx]" %} 3872 interface(MEMORY_INTER) %{ 3873 base($reg); 3874 index($idx); 3875 scale(0x0); 3876 disp($off); 3877 %} 3878 %} 3879 3880 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3881 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3882 %{ 3883 constraint(ALLOC_IN_RC(ptr_reg)); 3884 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3885 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3886 3887 op_cost(10); 3888 format %{"[$reg + $off + $idx << $scale]" %} 3889 interface(MEMORY_INTER) %{ 3890 base($reg); 3891 index($idx); 3892 scale($scale); 3893 disp($off); 3894 %} 3895 %} 3896 3897 // Indirect Narrow Oop Plus Offset Operand 3898 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3899 // we can't free r12 even with CompressedOops::base() == NULL. 3900 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3901 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3902 constraint(ALLOC_IN_RC(ptr_reg)); 3903 match(AddP (DecodeN reg) off); 3904 3905 op_cost(10); 3906 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3907 interface(MEMORY_INTER) %{ 3908 base(0xc); // R12 3909 index($reg); 3910 scale(0x3); 3911 disp($off); 3912 %} 3913 %} 3914 3915 // Indirect Memory Operand 3916 operand indirectNarrow(rRegN reg) 3917 %{ 3918 predicate(CompressedOops::shift() == 0); 3919 constraint(ALLOC_IN_RC(ptr_reg)); 3920 match(DecodeN reg); 3921 3922 format %{ "[$reg]" %} 3923 interface(MEMORY_INTER) %{ 3924 base($reg); 3925 index(0x4); 3926 scale(0x0); 3927 disp(0x0); 3928 %} 3929 %} 3930 3931 // Indirect Memory Plus Short Offset Operand 3932 operand indOffset8Narrow(rRegN reg, immL8 off) 3933 %{ 3934 predicate(CompressedOops::shift() == 0); 3935 constraint(ALLOC_IN_RC(ptr_reg)); 3936 match(AddP (DecodeN reg) off); 3937 3938 format %{ "[$reg + $off (8-bit)]" %} 3939 interface(MEMORY_INTER) %{ 3940 base($reg); 3941 index(0x4); 3942 scale(0x0); 3943 disp($off); 3944 %} 3945 %} 3946 3947 // Indirect Memory Plus Long Offset Operand 3948 operand indOffset32Narrow(rRegN reg, immL32 off) 3949 %{ 3950 predicate(CompressedOops::shift() == 0); 3951 constraint(ALLOC_IN_RC(ptr_reg)); 3952 match(AddP (DecodeN reg) off); 3953 3954 format %{ "[$reg + $off (32-bit)]" %} 3955 interface(MEMORY_INTER) %{ 3956 base($reg); 3957 index(0x4); 3958 scale(0x0); 3959 disp($off); 3960 %} 3961 %} 3962 3963 // Indirect Memory Plus Index Register Plus Offset Operand 3964 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3965 %{ 3966 predicate(CompressedOops::shift() == 0); 3967 constraint(ALLOC_IN_RC(ptr_reg)); 3968 match(AddP (AddP (DecodeN reg) lreg) off); 3969 3970 op_cost(10); 3971 format %{"[$reg + $off + $lreg]" %} 3972 interface(MEMORY_INTER) %{ 3973 base($reg); 3974 index($lreg); 3975 scale(0x0); 3976 disp($off); 3977 %} 3978 %} 3979 3980 // Indirect Memory Plus Index Register Plus Offset Operand 3981 operand indIndexNarrow(rRegN reg, rRegL lreg) 3982 %{ 3983 predicate(CompressedOops::shift() == 0); 3984 constraint(ALLOC_IN_RC(ptr_reg)); 3985 match(AddP (DecodeN reg) lreg); 3986 3987 op_cost(10); 3988 format %{"[$reg + $lreg]" %} 3989 interface(MEMORY_INTER) %{ 3990 base($reg); 3991 index($lreg); 3992 scale(0x0); 3993 disp(0x0); 3994 %} 3995 %} 3996 3997 // Indirect Memory Times Scale Plus Index Register 3998 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3999 %{ 4000 predicate(CompressedOops::shift() == 0); 4001 constraint(ALLOC_IN_RC(ptr_reg)); 4002 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4003 4004 op_cost(10); 4005 format %{"[$reg + $lreg << $scale]" %} 4006 interface(MEMORY_INTER) %{ 4007 base($reg); 4008 index($lreg); 4009 scale($scale); 4010 disp(0x0); 4011 %} 4012 %} 4013 4014 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4015 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4016 %{ 4017 predicate(CompressedOops::shift() == 0); 4018 constraint(ALLOC_IN_RC(ptr_reg)); 4019 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4020 4021 op_cost(10); 4022 format %{"[$reg + $off + $lreg << $scale]" %} 4023 interface(MEMORY_INTER) %{ 4024 base($reg); 4025 index($lreg); 4026 scale($scale); 4027 disp($off); 4028 %} 4029 %} 4030 4031 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4032 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4033 %{ 4034 constraint(ALLOC_IN_RC(ptr_reg)); 4035 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4036 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4037 4038 op_cost(10); 4039 format %{"[$reg + $off + $idx]" %} 4040 interface(MEMORY_INTER) %{ 4041 base($reg); 4042 index($idx); 4043 scale(0x0); 4044 disp($off); 4045 %} 4046 %} 4047 4048 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4049 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4050 %{ 4051 constraint(ALLOC_IN_RC(ptr_reg)); 4052 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4053 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4054 4055 op_cost(10); 4056 format %{"[$reg + $off + $idx << $scale]" %} 4057 interface(MEMORY_INTER) %{ 4058 base($reg); 4059 index($idx); 4060 scale($scale); 4061 disp($off); 4062 %} 4063 %} 4064 4065 //----------Special Memory Operands-------------------------------------------- 4066 // Stack Slot Operand - This operand is used for loading and storing temporary 4067 // values on the stack where a match requires a value to 4068 // flow through memory. 4069 operand stackSlotP(sRegP reg) 4070 %{ 4071 constraint(ALLOC_IN_RC(stack_slots)); 4072 // No match rule because this operand is only generated in matching 4073 4074 format %{ "[$reg]" %} 4075 interface(MEMORY_INTER) %{ 4076 base(0x4); // RSP 4077 index(0x4); // No Index 4078 scale(0x0); // No Scale 4079 disp($reg); // Stack Offset 4080 %} 4081 %} 4082 4083 operand stackSlotI(sRegI reg) 4084 %{ 4085 constraint(ALLOC_IN_RC(stack_slots)); 4086 // No match rule because this operand is only generated in matching 4087 4088 format %{ "[$reg]" %} 4089 interface(MEMORY_INTER) %{ 4090 base(0x4); // RSP 4091 index(0x4); // No Index 4092 scale(0x0); // No Scale 4093 disp($reg); // Stack Offset 4094 %} 4095 %} 4096 4097 operand stackSlotF(sRegF reg) 4098 %{ 4099 constraint(ALLOC_IN_RC(stack_slots)); 4100 // No match rule because this operand is only generated in matching 4101 4102 format %{ "[$reg]" %} 4103 interface(MEMORY_INTER) %{ 4104 base(0x4); // RSP 4105 index(0x4); // No Index 4106 scale(0x0); // No Scale 4107 disp($reg); // Stack Offset 4108 %} 4109 %} 4110 4111 operand stackSlotD(sRegD reg) 4112 %{ 4113 constraint(ALLOC_IN_RC(stack_slots)); 4114 // No match rule because this operand is only generated in matching 4115 4116 format %{ "[$reg]" %} 4117 interface(MEMORY_INTER) %{ 4118 base(0x4); // RSP 4119 index(0x4); // No Index 4120 scale(0x0); // No Scale 4121 disp($reg); // Stack Offset 4122 %} 4123 %} 4124 operand stackSlotL(sRegL reg) 4125 %{ 4126 constraint(ALLOC_IN_RC(stack_slots)); 4127 // No match rule because this operand is only generated in matching 4128 4129 format %{ "[$reg]" %} 4130 interface(MEMORY_INTER) %{ 4131 base(0x4); // RSP 4132 index(0x4); // No Index 4133 scale(0x0); // No Scale 4134 disp($reg); // Stack Offset 4135 %} 4136 %} 4137 4138 //----------Conditional Branch Operands---------------------------------------- 4139 // Comparison Op - This is the operation of the comparison, and is limited to 4140 // the following set of codes: 4141 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4142 // 4143 // Other attributes of the comparison, such as unsignedness, are specified 4144 // by the comparison instruction that sets a condition code flags register. 4145 // That result is represented by a flags operand whose subtype is appropriate 4146 // to the unsignedness (etc.) of the comparison. 4147 // 4148 // Later, the instruction which matches both the Comparison Op (a Bool) and 4149 // the flags (produced by the Cmp) specifies the coding of the comparison op 4150 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4151 4152 // Comparision Code 4153 operand cmpOp() 4154 %{ 4155 match(Bool); 4156 4157 format %{ "" %} 4158 interface(COND_INTER) %{ 4159 equal(0x4, "e"); 4160 not_equal(0x5, "ne"); 4161 less(0xC, "l"); 4162 greater_equal(0xD, "ge"); 4163 less_equal(0xE, "le"); 4164 greater(0xF, "g"); 4165 overflow(0x0, "o"); 4166 no_overflow(0x1, "no"); 4167 %} 4168 %} 4169 4170 // Comparison Code, unsigned compare. Used by FP also, with 4171 // C2 (unordered) turned into GT or LT already. The other bits 4172 // C0 and C3 are turned into Carry & Zero flags. 4173 operand cmpOpU() 4174 %{ 4175 match(Bool); 4176 4177 format %{ "" %} 4178 interface(COND_INTER) %{ 4179 equal(0x4, "e"); 4180 not_equal(0x5, "ne"); 4181 less(0x2, "b"); 4182 greater_equal(0x3, "nb"); 4183 less_equal(0x6, "be"); 4184 greater(0x7, "nbe"); 4185 overflow(0x0, "o"); 4186 no_overflow(0x1, "no"); 4187 %} 4188 %} 4189 4190 4191 // Floating comparisons that don't require any fixup for the unordered case 4192 operand cmpOpUCF() %{ 4193 match(Bool); 4194 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4195 n->as_Bool()->_test._test == BoolTest::ge || 4196 n->as_Bool()->_test._test == BoolTest::le || 4197 n->as_Bool()->_test._test == BoolTest::gt); 4198 format %{ "" %} 4199 interface(COND_INTER) %{ 4200 equal(0x4, "e"); 4201 not_equal(0x5, "ne"); 4202 less(0x2, "b"); 4203 greater_equal(0x3, "nb"); 4204 less_equal(0x6, "be"); 4205 greater(0x7, "nbe"); 4206 overflow(0x0, "o"); 4207 no_overflow(0x1, "no"); 4208 %} 4209 %} 4210 4211 4212 // Floating comparisons that can be fixed up with extra conditional jumps 4213 operand cmpOpUCF2() %{ 4214 match(Bool); 4215 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4216 n->as_Bool()->_test._test == BoolTest::eq); 4217 format %{ "" %} 4218 interface(COND_INTER) %{ 4219 equal(0x4, "e"); 4220 not_equal(0x5, "ne"); 4221 less(0x2, "b"); 4222 greater_equal(0x3, "nb"); 4223 less_equal(0x6, "be"); 4224 greater(0x7, "nbe"); 4225 overflow(0x0, "o"); 4226 no_overflow(0x1, "no"); 4227 %} 4228 %} 4229 4230 //----------OPERAND CLASSES---------------------------------------------------- 4231 // Operand Classes are groups of operands that are used as to simplify 4232 // instruction definitions by not requiring the AD writer to specify separate 4233 // instructions for every form of operand when the instruction accepts 4234 // multiple operand types with the same basic encoding and format. The classic 4235 // case of this is memory operands. 4236 4237 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4238 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4239 indCompressedOopOffset, 4240 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4241 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4242 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4243 4244 //----------PIPELINE----------------------------------------------------------- 4245 // Rules which define the behavior of the target architectures pipeline. 4246 pipeline %{ 4247 4248 //----------ATTRIBUTES--------------------------------------------------------- 4249 attributes %{ 4250 variable_size_instructions; // Fixed size instructions 4251 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4252 instruction_unit_size = 1; // An instruction is 1 bytes long 4253 instruction_fetch_unit_size = 16; // The processor fetches one line 4254 instruction_fetch_units = 1; // of 16 bytes 4255 4256 // List of nop instructions 4257 nops( MachNop ); 4258 %} 4259 4260 //----------RESOURCES---------------------------------------------------------- 4261 // Resources are the functional units available to the machine 4262 4263 // Generic P2/P3 pipeline 4264 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4265 // 3 instructions decoded per cycle. 4266 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4267 // 3 ALU op, only ALU0 handles mul instructions. 4268 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4269 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4270 BR, FPU, 4271 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4272 4273 //----------PIPELINE DESCRIPTION----------------------------------------------- 4274 // Pipeline Description specifies the stages in the machine's pipeline 4275 4276 // Generic P2/P3 pipeline 4277 pipe_desc(S0, S1, S2, S3, S4, S5); 4278 4279 //----------PIPELINE CLASSES--------------------------------------------------- 4280 // Pipeline Classes describe the stages in which input and output are 4281 // referenced by the hardware pipeline. 4282 4283 // Naming convention: ialu or fpu 4284 // Then: _reg 4285 // Then: _reg if there is a 2nd register 4286 // Then: _long if it's a pair of instructions implementing a long 4287 // Then: _fat if it requires the big decoder 4288 // Or: _mem if it requires the big decoder and a memory unit. 4289 4290 // Integer ALU reg operation 4291 pipe_class ialu_reg(rRegI dst) 4292 %{ 4293 single_instruction; 4294 dst : S4(write); 4295 dst : S3(read); 4296 DECODE : S0; // any decoder 4297 ALU : S3; // any alu 4298 %} 4299 4300 // Long ALU reg operation 4301 pipe_class ialu_reg_long(rRegL dst) 4302 %{ 4303 instruction_count(2); 4304 dst : S4(write); 4305 dst : S3(read); 4306 DECODE : S0(2); // any 2 decoders 4307 ALU : S3(2); // both alus 4308 %} 4309 4310 // Integer ALU reg operation using big decoder 4311 pipe_class ialu_reg_fat(rRegI dst) 4312 %{ 4313 single_instruction; 4314 dst : S4(write); 4315 dst : S3(read); 4316 D0 : S0; // big decoder only 4317 ALU : S3; // any alu 4318 %} 4319 4320 // Long ALU reg operation using big decoder 4321 pipe_class ialu_reg_long_fat(rRegL dst) 4322 %{ 4323 instruction_count(2); 4324 dst : S4(write); 4325 dst : S3(read); 4326 D0 : S0(2); // big decoder only; twice 4327 ALU : S3(2); // any 2 alus 4328 %} 4329 4330 // Integer ALU reg-reg operation 4331 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4332 %{ 4333 single_instruction; 4334 dst : S4(write); 4335 src : S3(read); 4336 DECODE : S0; // any decoder 4337 ALU : S3; // any alu 4338 %} 4339 4340 // Long ALU reg-reg operation 4341 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4342 %{ 4343 instruction_count(2); 4344 dst : S4(write); 4345 src : S3(read); 4346 DECODE : S0(2); // any 2 decoders 4347 ALU : S3(2); // both alus 4348 %} 4349 4350 // Integer ALU reg-reg operation 4351 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4352 %{ 4353 single_instruction; 4354 dst : S4(write); 4355 src : S3(read); 4356 D0 : S0; // big decoder only 4357 ALU : S3; // any alu 4358 %} 4359 4360 // Long ALU reg-reg operation 4361 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4362 %{ 4363 instruction_count(2); 4364 dst : S4(write); 4365 src : S3(read); 4366 D0 : S0(2); // big decoder only; twice 4367 ALU : S3(2); // both alus 4368 %} 4369 4370 // Integer ALU reg-mem operation 4371 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4372 %{ 4373 single_instruction; 4374 dst : S5(write); 4375 mem : S3(read); 4376 D0 : S0; // big decoder only 4377 ALU : S4; // any alu 4378 MEM : S3; // any mem 4379 %} 4380 4381 // Integer mem operation (prefetch) 4382 pipe_class ialu_mem(memory mem) 4383 %{ 4384 single_instruction; 4385 mem : S3(read); 4386 D0 : S0; // big decoder only 4387 MEM : S3; // any mem 4388 %} 4389 4390 // Integer Store to Memory 4391 pipe_class ialu_mem_reg(memory mem, rRegI src) 4392 %{ 4393 single_instruction; 4394 mem : S3(read); 4395 src : S5(read); 4396 D0 : S0; // big decoder only 4397 ALU : S4; // any alu 4398 MEM : S3; 4399 %} 4400 4401 // // Long Store to Memory 4402 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4403 // %{ 4404 // instruction_count(2); 4405 // mem : S3(read); 4406 // src : S5(read); 4407 // D0 : S0(2); // big decoder only; twice 4408 // ALU : S4(2); // any 2 alus 4409 // MEM : S3(2); // Both mems 4410 // %} 4411 4412 // Integer Store to Memory 4413 pipe_class ialu_mem_imm(memory mem) 4414 %{ 4415 single_instruction; 4416 mem : S3(read); 4417 D0 : S0; // big decoder only 4418 ALU : S4; // any alu 4419 MEM : S3; 4420 %} 4421 4422 // Integer ALU0 reg-reg operation 4423 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4424 %{ 4425 single_instruction; 4426 dst : S4(write); 4427 src : S3(read); 4428 D0 : S0; // Big decoder only 4429 ALU0 : S3; // only alu0 4430 %} 4431 4432 // Integer ALU0 reg-mem operation 4433 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4434 %{ 4435 single_instruction; 4436 dst : S5(write); 4437 mem : S3(read); 4438 D0 : S0; // big decoder only 4439 ALU0 : S4; // ALU0 only 4440 MEM : S3; // any mem 4441 %} 4442 4443 // Integer ALU reg-reg operation 4444 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4445 %{ 4446 single_instruction; 4447 cr : S4(write); 4448 src1 : S3(read); 4449 src2 : S3(read); 4450 DECODE : S0; // any decoder 4451 ALU : S3; // any alu 4452 %} 4453 4454 // Integer ALU reg-imm operation 4455 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4456 %{ 4457 single_instruction; 4458 cr : S4(write); 4459 src1 : S3(read); 4460 DECODE : S0; // any decoder 4461 ALU : S3; // any alu 4462 %} 4463 4464 // Integer ALU reg-mem operation 4465 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4466 %{ 4467 single_instruction; 4468 cr : S4(write); 4469 src1 : S3(read); 4470 src2 : S3(read); 4471 D0 : S0; // big decoder only 4472 ALU : S4; // any alu 4473 MEM : S3; 4474 %} 4475 4476 // Conditional move reg-reg 4477 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4478 %{ 4479 instruction_count(4); 4480 y : S4(read); 4481 q : S3(read); 4482 p : S3(read); 4483 DECODE : S0(4); // any decoder 4484 %} 4485 4486 // Conditional move reg-reg 4487 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4488 %{ 4489 single_instruction; 4490 dst : S4(write); 4491 src : S3(read); 4492 cr : S3(read); 4493 DECODE : S0; // any decoder 4494 %} 4495 4496 // Conditional move reg-mem 4497 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4498 %{ 4499 single_instruction; 4500 dst : S4(write); 4501 src : S3(read); 4502 cr : S3(read); 4503 DECODE : S0; // any decoder 4504 MEM : S3; 4505 %} 4506 4507 // Conditional move reg-reg long 4508 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4509 %{ 4510 single_instruction; 4511 dst : S4(write); 4512 src : S3(read); 4513 cr : S3(read); 4514 DECODE : S0(2); // any 2 decoders 4515 %} 4516 4517 // XXX 4518 // // Conditional move double reg-reg 4519 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4520 // %{ 4521 // single_instruction; 4522 // dst : S4(write); 4523 // src : S3(read); 4524 // cr : S3(read); 4525 // DECODE : S0; // any decoder 4526 // %} 4527 4528 // Float reg-reg operation 4529 pipe_class fpu_reg(regD dst) 4530 %{ 4531 instruction_count(2); 4532 dst : S3(read); 4533 DECODE : S0(2); // any 2 decoders 4534 FPU : S3; 4535 %} 4536 4537 // Float reg-reg operation 4538 pipe_class fpu_reg_reg(regD dst, regD src) 4539 %{ 4540 instruction_count(2); 4541 dst : S4(write); 4542 src : S3(read); 4543 DECODE : S0(2); // any 2 decoders 4544 FPU : S3; 4545 %} 4546 4547 // Float reg-reg operation 4548 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4549 %{ 4550 instruction_count(3); 4551 dst : S4(write); 4552 src1 : S3(read); 4553 src2 : S3(read); 4554 DECODE : S0(3); // any 3 decoders 4555 FPU : S3(2); 4556 %} 4557 4558 // Float reg-reg operation 4559 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4560 %{ 4561 instruction_count(4); 4562 dst : S4(write); 4563 src1 : S3(read); 4564 src2 : S3(read); 4565 src3 : S3(read); 4566 DECODE : S0(4); // any 3 decoders 4567 FPU : S3(2); 4568 %} 4569 4570 // Float reg-reg operation 4571 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4572 %{ 4573 instruction_count(4); 4574 dst : S4(write); 4575 src1 : S3(read); 4576 src2 : S3(read); 4577 src3 : S3(read); 4578 DECODE : S1(3); // any 3 decoders 4579 D0 : S0; // Big decoder only 4580 FPU : S3(2); 4581 MEM : S3; 4582 %} 4583 4584 // Float reg-mem operation 4585 pipe_class fpu_reg_mem(regD dst, memory mem) 4586 %{ 4587 instruction_count(2); 4588 dst : S5(write); 4589 mem : S3(read); 4590 D0 : S0; // big decoder only 4591 DECODE : S1; // any decoder for FPU POP 4592 FPU : S4; 4593 MEM : S3; // any mem 4594 %} 4595 4596 // Float reg-mem operation 4597 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4598 %{ 4599 instruction_count(3); 4600 dst : S5(write); 4601 src1 : S3(read); 4602 mem : S3(read); 4603 D0 : S0; // big decoder only 4604 DECODE : S1(2); // any decoder for FPU POP 4605 FPU : S4; 4606 MEM : S3; // any mem 4607 %} 4608 4609 // Float mem-reg operation 4610 pipe_class fpu_mem_reg(memory mem, regD src) 4611 %{ 4612 instruction_count(2); 4613 src : S5(read); 4614 mem : S3(read); 4615 DECODE : S0; // any decoder for FPU PUSH 4616 D0 : S1; // big decoder only 4617 FPU : S4; 4618 MEM : S3; // any mem 4619 %} 4620 4621 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4622 %{ 4623 instruction_count(3); 4624 src1 : S3(read); 4625 src2 : S3(read); 4626 mem : S3(read); 4627 DECODE : S0(2); // any decoder for FPU PUSH 4628 D0 : S1; // big decoder only 4629 FPU : S4; 4630 MEM : S3; // any mem 4631 %} 4632 4633 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4634 %{ 4635 instruction_count(3); 4636 src1 : S3(read); 4637 src2 : S3(read); 4638 mem : S4(read); 4639 DECODE : S0; // any decoder for FPU PUSH 4640 D0 : S0(2); // big decoder only 4641 FPU : S4; 4642 MEM : S3(2); // any mem 4643 %} 4644 4645 pipe_class fpu_mem_mem(memory dst, memory src1) 4646 %{ 4647 instruction_count(2); 4648 src1 : S3(read); 4649 dst : S4(read); 4650 D0 : S0(2); // big decoder only 4651 MEM : S3(2); // any mem 4652 %} 4653 4654 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4655 %{ 4656 instruction_count(3); 4657 src1 : S3(read); 4658 src2 : S3(read); 4659 dst : S4(read); 4660 D0 : S0(3); // big decoder only 4661 FPU : S4; 4662 MEM : S3(3); // any mem 4663 %} 4664 4665 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4666 %{ 4667 instruction_count(3); 4668 src1 : S4(read); 4669 mem : S4(read); 4670 DECODE : S0; // any decoder for FPU PUSH 4671 D0 : S0(2); // big decoder only 4672 FPU : S4; 4673 MEM : S3(2); // any mem 4674 %} 4675 4676 // Float load constant 4677 pipe_class fpu_reg_con(regD dst) 4678 %{ 4679 instruction_count(2); 4680 dst : S5(write); 4681 D0 : S0; // big decoder only for the load 4682 DECODE : S1; // any decoder for FPU POP 4683 FPU : S4; 4684 MEM : S3; // any mem 4685 %} 4686 4687 // Float load constant 4688 pipe_class fpu_reg_reg_con(regD dst, regD src) 4689 %{ 4690 instruction_count(3); 4691 dst : S5(write); 4692 src : S3(read); 4693 D0 : S0; // big decoder only for the load 4694 DECODE : S1(2); // any decoder for FPU POP 4695 FPU : S4; 4696 MEM : S3; // any mem 4697 %} 4698 4699 // UnConditional branch 4700 pipe_class pipe_jmp(label labl) 4701 %{ 4702 single_instruction; 4703 BR : S3; 4704 %} 4705 4706 // Conditional branch 4707 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4708 %{ 4709 single_instruction; 4710 cr : S1(read); 4711 BR : S3; 4712 %} 4713 4714 // Allocation idiom 4715 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4716 %{ 4717 instruction_count(1); force_serialization; 4718 fixed_latency(6); 4719 heap_ptr : S3(read); 4720 DECODE : S0(3); 4721 D0 : S2; 4722 MEM : S3; 4723 ALU : S3(2); 4724 dst : S5(write); 4725 BR : S5; 4726 %} 4727 4728 // Generic big/slow expanded idiom 4729 pipe_class pipe_slow() 4730 %{ 4731 instruction_count(10); multiple_bundles; force_serialization; 4732 fixed_latency(100); 4733 D0 : S0(2); 4734 MEM : S3(2); 4735 %} 4736 4737 // The real do-nothing guy 4738 pipe_class empty() 4739 %{ 4740 instruction_count(0); 4741 %} 4742 4743 // Define the class for the Nop node 4744 define 4745 %{ 4746 MachNop = empty; 4747 %} 4748 4749 %} 4750 4751 //----------INSTRUCTIONS------------------------------------------------------- 4752 // 4753 // match -- States which machine-independent subtree may be replaced 4754 // by this instruction. 4755 // ins_cost -- The estimated cost of this instruction is used by instruction 4756 // selection to identify a minimum cost tree of machine 4757 // instructions that matches a tree of machine-independent 4758 // instructions. 4759 // format -- A string providing the disassembly for this instruction. 4760 // The value of an instruction's operand may be inserted 4761 // by referring to it with a '$' prefix. 4762 // opcode -- Three instruction opcodes may be provided. These are referred 4763 // to within an encode class as $primary, $secondary, and $tertiary 4764 // rrspectively. The primary opcode is commonly used to 4765 // indicate the type of machine instruction, while secondary 4766 // and tertiary are often used for prefix options or addressing 4767 // modes. 4768 // ins_encode -- A list of encode classes with parameters. The encode class 4769 // name must have been defined in an 'enc_class' specification 4770 // in the encode section of the architecture description. 4771 4772 4773 //----------Load/Store/Move Instructions--------------------------------------- 4774 //----------Load Instructions-------------------------------------------------- 4775 4776 // Load Byte (8 bit signed) 4777 instruct loadB(rRegI dst, memory mem) 4778 %{ 4779 match(Set dst (LoadB mem)); 4780 4781 ins_cost(125); 4782 format %{ "movsbl $dst, $mem\t# byte" %} 4783 4784 ins_encode %{ 4785 __ movsbl($dst$$Register, $mem$$Address); 4786 %} 4787 4788 ins_pipe(ialu_reg_mem); 4789 %} 4790 4791 // Load Byte (8 bit signed) into Long Register 4792 instruct loadB2L(rRegL dst, memory mem) 4793 %{ 4794 match(Set dst (ConvI2L (LoadB mem))); 4795 4796 ins_cost(125); 4797 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4798 4799 ins_encode %{ 4800 __ movsbq($dst$$Register, $mem$$Address); 4801 %} 4802 4803 ins_pipe(ialu_reg_mem); 4804 %} 4805 4806 // Load Unsigned Byte (8 bit UNsigned) 4807 instruct loadUB(rRegI dst, memory mem) 4808 %{ 4809 match(Set dst (LoadUB mem)); 4810 4811 ins_cost(125); 4812 format %{ "movzbl $dst, $mem\t# ubyte" %} 4813 4814 ins_encode %{ 4815 __ movzbl($dst$$Register, $mem$$Address); 4816 %} 4817 4818 ins_pipe(ialu_reg_mem); 4819 %} 4820 4821 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4822 instruct loadUB2L(rRegL dst, memory mem) 4823 %{ 4824 match(Set dst (ConvI2L (LoadUB mem))); 4825 4826 ins_cost(125); 4827 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4828 4829 ins_encode %{ 4830 __ movzbq($dst$$Register, $mem$$Address); 4831 %} 4832 4833 ins_pipe(ialu_reg_mem); 4834 %} 4835 4836 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4837 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4838 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4839 effect(KILL cr); 4840 4841 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4842 "andl $dst, right_n_bits($mask, 8)" %} 4843 ins_encode %{ 4844 Register Rdst = $dst$$Register; 4845 __ movzbq(Rdst, $mem$$Address); 4846 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4847 %} 4848 ins_pipe(ialu_reg_mem); 4849 %} 4850 4851 // Load Short (16 bit signed) 4852 instruct loadS(rRegI dst, memory mem) 4853 %{ 4854 match(Set dst (LoadS mem)); 4855 4856 ins_cost(125); 4857 format %{ "movswl $dst, $mem\t# short" %} 4858 4859 ins_encode %{ 4860 __ movswl($dst$$Register, $mem$$Address); 4861 %} 4862 4863 ins_pipe(ialu_reg_mem); 4864 %} 4865 4866 // Load Short (16 bit signed) to Byte (8 bit signed) 4867 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4868 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4869 4870 ins_cost(125); 4871 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4872 ins_encode %{ 4873 __ movsbl($dst$$Register, $mem$$Address); 4874 %} 4875 ins_pipe(ialu_reg_mem); 4876 %} 4877 4878 // Load Short (16 bit signed) into Long Register 4879 instruct loadS2L(rRegL dst, memory mem) 4880 %{ 4881 match(Set dst (ConvI2L (LoadS mem))); 4882 4883 ins_cost(125); 4884 format %{ "movswq $dst, $mem\t# short -> long" %} 4885 4886 ins_encode %{ 4887 __ movswq($dst$$Register, $mem$$Address); 4888 %} 4889 4890 ins_pipe(ialu_reg_mem); 4891 %} 4892 4893 // Load Unsigned Short/Char (16 bit UNsigned) 4894 instruct loadUS(rRegI dst, memory mem) 4895 %{ 4896 match(Set dst (LoadUS mem)); 4897 4898 ins_cost(125); 4899 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4900 4901 ins_encode %{ 4902 __ movzwl($dst$$Register, $mem$$Address); 4903 %} 4904 4905 ins_pipe(ialu_reg_mem); 4906 %} 4907 4908 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4909 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4910 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4911 4912 ins_cost(125); 4913 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4914 ins_encode %{ 4915 __ movsbl($dst$$Register, $mem$$Address); 4916 %} 4917 ins_pipe(ialu_reg_mem); 4918 %} 4919 4920 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4921 instruct loadUS2L(rRegL dst, memory mem) 4922 %{ 4923 match(Set dst (ConvI2L (LoadUS mem))); 4924 4925 ins_cost(125); 4926 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4927 4928 ins_encode %{ 4929 __ movzwq($dst$$Register, $mem$$Address); 4930 %} 4931 4932 ins_pipe(ialu_reg_mem); 4933 %} 4934 4935 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4936 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4937 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4938 4939 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4940 ins_encode %{ 4941 __ movzbq($dst$$Register, $mem$$Address); 4942 %} 4943 ins_pipe(ialu_reg_mem); 4944 %} 4945 4946 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4947 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4948 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4949 effect(KILL cr); 4950 4951 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4952 "andl $dst, right_n_bits($mask, 16)" %} 4953 ins_encode %{ 4954 Register Rdst = $dst$$Register; 4955 __ movzwq(Rdst, $mem$$Address); 4956 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4957 %} 4958 ins_pipe(ialu_reg_mem); 4959 %} 4960 4961 // Load Integer 4962 instruct loadI(rRegI dst, memory mem) 4963 %{ 4964 match(Set dst (LoadI mem)); 4965 4966 ins_cost(125); 4967 format %{ "movl $dst, $mem\t# int" %} 4968 4969 ins_encode %{ 4970 __ movl($dst$$Register, $mem$$Address); 4971 %} 4972 4973 ins_pipe(ialu_reg_mem); 4974 %} 4975 4976 // Load Integer (32 bit signed) to Byte (8 bit signed) 4977 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4978 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4979 4980 ins_cost(125); 4981 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4982 ins_encode %{ 4983 __ movsbl($dst$$Register, $mem$$Address); 4984 %} 4985 ins_pipe(ialu_reg_mem); 4986 %} 4987 4988 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4989 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4990 match(Set dst (AndI (LoadI mem) mask)); 4991 4992 ins_cost(125); 4993 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4994 ins_encode %{ 4995 __ movzbl($dst$$Register, $mem$$Address); 4996 %} 4997 ins_pipe(ialu_reg_mem); 4998 %} 4999 5000 // Load Integer (32 bit signed) to Short (16 bit signed) 5001 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5002 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5003 5004 ins_cost(125); 5005 format %{ "movswl $dst, $mem\t# int -> short" %} 5006 ins_encode %{ 5007 __ movswl($dst$$Register, $mem$$Address); 5008 %} 5009 ins_pipe(ialu_reg_mem); 5010 %} 5011 5012 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5013 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5014 match(Set dst (AndI (LoadI mem) mask)); 5015 5016 ins_cost(125); 5017 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5018 ins_encode %{ 5019 __ movzwl($dst$$Register, $mem$$Address); 5020 %} 5021 ins_pipe(ialu_reg_mem); 5022 %} 5023 5024 // Load Integer into Long Register 5025 instruct loadI2L(rRegL dst, memory mem) 5026 %{ 5027 match(Set dst (ConvI2L (LoadI mem))); 5028 5029 ins_cost(125); 5030 format %{ "movslq $dst, $mem\t# int -> long" %} 5031 5032 ins_encode %{ 5033 __ movslq($dst$$Register, $mem$$Address); 5034 %} 5035 5036 ins_pipe(ialu_reg_mem); 5037 %} 5038 5039 // Load Integer with mask 0xFF into Long Register 5040 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5041 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5042 5043 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5044 ins_encode %{ 5045 __ movzbq($dst$$Register, $mem$$Address); 5046 %} 5047 ins_pipe(ialu_reg_mem); 5048 %} 5049 5050 // Load Integer with mask 0xFFFF into Long Register 5051 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5052 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5053 5054 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5055 ins_encode %{ 5056 __ movzwq($dst$$Register, $mem$$Address); 5057 %} 5058 ins_pipe(ialu_reg_mem); 5059 %} 5060 5061 // Load Integer with a 31-bit mask into Long Register 5062 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5063 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5064 effect(KILL cr); 5065 5066 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5067 "andl $dst, $mask" %} 5068 ins_encode %{ 5069 Register Rdst = $dst$$Register; 5070 __ movl(Rdst, $mem$$Address); 5071 __ andl(Rdst, $mask$$constant); 5072 %} 5073 ins_pipe(ialu_reg_mem); 5074 %} 5075 5076 // Load Unsigned Integer into Long Register 5077 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5078 %{ 5079 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5080 5081 ins_cost(125); 5082 format %{ "movl $dst, $mem\t# uint -> long" %} 5083 5084 ins_encode %{ 5085 __ movl($dst$$Register, $mem$$Address); 5086 %} 5087 5088 ins_pipe(ialu_reg_mem); 5089 %} 5090 5091 // Load Long 5092 instruct loadL(rRegL dst, memory mem) 5093 %{ 5094 match(Set dst (LoadL mem)); 5095 5096 ins_cost(125); 5097 format %{ "movq $dst, $mem\t# long" %} 5098 5099 ins_encode %{ 5100 __ movq($dst$$Register, $mem$$Address); 5101 %} 5102 5103 ins_pipe(ialu_reg_mem); // XXX 5104 %} 5105 5106 // Load Range 5107 instruct loadRange(rRegI dst, memory mem) 5108 %{ 5109 match(Set dst (LoadRange mem)); 5110 5111 ins_cost(125); // XXX 5112 format %{ "movl $dst, $mem\t# range" %} 5113 opcode(0x8B); 5114 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5115 ins_pipe(ialu_reg_mem); 5116 %} 5117 5118 // Load Pointer 5119 instruct loadP(rRegP dst, memory mem) 5120 %{ 5121 match(Set dst (LoadP mem)); 5122 predicate(n->as_Load()->barrier_data() == 0); 5123 5124 ins_cost(125); // XXX 5125 format %{ "movq $dst, $mem\t# ptr" %} 5126 opcode(0x8B); 5127 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5128 ins_pipe(ialu_reg_mem); // XXX 5129 %} 5130 5131 // Load Compressed Pointer 5132 instruct loadN(rRegN dst, memory mem) 5133 %{ 5134 match(Set dst (LoadN mem)); 5135 5136 ins_cost(125); // XXX 5137 format %{ "movl $dst, $mem\t# compressed ptr" %} 5138 ins_encode %{ 5139 __ movl($dst$$Register, $mem$$Address); 5140 %} 5141 ins_pipe(ialu_reg_mem); // XXX 5142 %} 5143 5144 5145 // Load Klass Pointer 5146 instruct loadKlass(rRegP dst, memory mem) 5147 %{ 5148 match(Set dst (LoadKlass mem)); 5149 5150 ins_cost(125); // XXX 5151 format %{ "movq $dst, $mem\t# class" %} 5152 opcode(0x8B); 5153 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5154 ins_pipe(ialu_reg_mem); // XXX 5155 %} 5156 5157 // Load narrow Klass Pointer 5158 instruct loadNKlass(rRegN dst, memory mem) 5159 %{ 5160 match(Set dst (LoadNKlass mem)); 5161 5162 ins_cost(125); // XXX 5163 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5164 ins_encode %{ 5165 __ movl($dst$$Register, $mem$$Address); 5166 %} 5167 ins_pipe(ialu_reg_mem); // XXX 5168 %} 5169 5170 // Load Float 5171 instruct loadF(regF dst, memory mem) 5172 %{ 5173 match(Set dst (LoadF mem)); 5174 5175 ins_cost(145); // XXX 5176 format %{ "movss $dst, $mem\t# float" %} 5177 ins_encode %{ 5178 __ movflt($dst$$XMMRegister, $mem$$Address); 5179 %} 5180 ins_pipe(pipe_slow); // XXX 5181 %} 5182 5183 // Load Float 5184 instruct MoveF2VL(vlRegF dst, regF src) %{ 5185 match(Set dst src); 5186 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5187 ins_encode %{ 5188 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5189 %} 5190 ins_pipe( fpu_reg_reg ); 5191 %} 5192 5193 // Load Float 5194 instruct MoveF2LEG(legRegF dst, regF src) %{ 5195 match(Set dst src); 5196 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5197 ins_encode %{ 5198 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5199 %} 5200 ins_pipe( fpu_reg_reg ); 5201 %} 5202 5203 // Load Float 5204 instruct MoveVL2F(regF dst, vlRegF src) %{ 5205 match(Set dst src); 5206 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5207 ins_encode %{ 5208 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5209 %} 5210 ins_pipe( fpu_reg_reg ); 5211 %} 5212 5213 // Load Float 5214 instruct MoveLEG2F(regF dst, legRegF src) %{ 5215 match(Set dst src); 5216 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5217 ins_encode %{ 5218 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5219 %} 5220 ins_pipe( fpu_reg_reg ); 5221 %} 5222 5223 // Load Double 5224 instruct loadD_partial(regD dst, memory mem) 5225 %{ 5226 predicate(!UseXmmLoadAndClearUpper); 5227 match(Set dst (LoadD mem)); 5228 5229 ins_cost(145); // XXX 5230 format %{ "movlpd $dst, $mem\t# double" %} 5231 ins_encode %{ 5232 __ movdbl($dst$$XMMRegister, $mem$$Address); 5233 %} 5234 ins_pipe(pipe_slow); // XXX 5235 %} 5236 5237 instruct loadD(regD dst, memory mem) 5238 %{ 5239 predicate(UseXmmLoadAndClearUpper); 5240 match(Set dst (LoadD mem)); 5241 5242 ins_cost(145); // XXX 5243 format %{ "movsd $dst, $mem\t# double" %} 5244 ins_encode %{ 5245 __ movdbl($dst$$XMMRegister, $mem$$Address); 5246 %} 5247 ins_pipe(pipe_slow); // XXX 5248 %} 5249 5250 // Load Double 5251 instruct MoveD2VL(vlRegD dst, regD src) %{ 5252 match(Set dst src); 5253 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5254 ins_encode %{ 5255 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5256 %} 5257 ins_pipe( fpu_reg_reg ); 5258 %} 5259 5260 // Load Double 5261 instruct MoveD2LEG(legRegD dst, regD src) %{ 5262 match(Set dst src); 5263 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5264 ins_encode %{ 5265 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5266 %} 5267 ins_pipe( fpu_reg_reg ); 5268 %} 5269 5270 // Load Double 5271 instruct MoveVL2D(regD dst, vlRegD src) %{ 5272 match(Set dst src); 5273 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5274 ins_encode %{ 5275 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5276 %} 5277 ins_pipe( fpu_reg_reg ); 5278 %} 5279 5280 // Load Double 5281 instruct MoveLEG2D(regD dst, legRegD src) %{ 5282 match(Set dst src); 5283 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5284 ins_encode %{ 5285 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5286 %} 5287 ins_pipe( fpu_reg_reg ); 5288 %} 5289 5290 // Following pseudo code describes the algorithm for max[FD]: 5291 // Min algorithm is on similar lines 5292 // btmp = (b < +0.0) ? a : b 5293 // atmp = (b < +0.0) ? b : a 5294 // Tmp = Max_Float(atmp , btmp) 5295 // Res = (atmp == NaN) ? atmp : Tmp 5296 5297 // max = java.lang.Math.max(float a, float b) 5298 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5299 predicate(UseAVX > 0 && !n->is_reduction()); 5300 match(Set dst (MaxF a b)); 5301 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5302 format %{ 5303 "blendvps $btmp,$b,$a,$b \n\t" 5304 "blendvps $atmp,$a,$b,$b \n\t" 5305 "vmaxss $tmp,$atmp,$btmp \n\t" 5306 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5307 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5308 %} 5309 ins_encode %{ 5310 int vector_len = Assembler::AVX_128bit; 5311 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5312 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5313 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5314 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5315 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5316 %} 5317 ins_pipe( pipe_slow ); 5318 %} 5319 5320 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 5321 predicate(UseAVX > 0 && n->is_reduction()); 5322 match(Set dst (MaxF a b)); 5323 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5324 5325 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 5326 ins_encode %{ 5327 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5328 false /*min*/, true /*single*/); 5329 %} 5330 ins_pipe( pipe_slow ); 5331 %} 5332 5333 // max = java.lang.Math.max(double a, double b) 5334 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5335 predicate(UseAVX > 0 && !n->is_reduction()); 5336 match(Set dst (MaxD a b)); 5337 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 5338 format %{ 5339 "blendvpd $btmp,$b,$a,$b \n\t" 5340 "blendvpd $atmp,$a,$b,$b \n\t" 5341 "vmaxsd $tmp,$atmp,$btmp \n\t" 5342 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5343 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5344 %} 5345 ins_encode %{ 5346 int vector_len = Assembler::AVX_128bit; 5347 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5348 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5349 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5350 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5351 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5352 %} 5353 ins_pipe( pipe_slow ); 5354 %} 5355 5356 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 5357 predicate(UseAVX > 0 && n->is_reduction()); 5358 match(Set dst (MaxD a b)); 5359 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5360 5361 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 5362 ins_encode %{ 5363 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5364 false /*min*/, false /*single*/); 5365 %} 5366 ins_pipe( pipe_slow ); 5367 %} 5368 5369 // min = java.lang.Math.min(float a, float b) 5370 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5371 predicate(UseAVX > 0 && !n->is_reduction()); 5372 match(Set dst (MinF a b)); 5373 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5374 format %{ 5375 "blendvps $atmp,$a,$b,$a \n\t" 5376 "blendvps $btmp,$b,$a,$a \n\t" 5377 "vminss $tmp,$atmp,$btmp \n\t" 5378 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5379 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5380 %} 5381 ins_encode %{ 5382 int vector_len = Assembler::AVX_128bit; 5383 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5384 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5385 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5386 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5387 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5388 %} 5389 ins_pipe( pipe_slow ); 5390 %} 5391 5392 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 5393 predicate(UseAVX > 0 && n->is_reduction()); 5394 match(Set dst (MinF a b)); 5395 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5396 5397 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 5398 ins_encode %{ 5399 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5400 true /*min*/, true /*single*/); 5401 %} 5402 ins_pipe( pipe_slow ); 5403 %} 5404 5405 // min = java.lang.Math.min(double a, double b) 5406 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5407 predicate(UseAVX > 0 && !n->is_reduction()); 5408 match(Set dst (MinD a b)); 5409 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5410 format %{ 5411 "blendvpd $atmp,$a,$b,$a \n\t" 5412 "blendvpd $btmp,$b,$a,$a \n\t" 5413 "vminsd $tmp,$atmp,$btmp \n\t" 5414 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5415 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5416 %} 5417 ins_encode %{ 5418 int vector_len = Assembler::AVX_128bit; 5419 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5420 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5421 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5422 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5423 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5424 %} 5425 ins_pipe( pipe_slow ); 5426 %} 5427 5428 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 5429 predicate(UseAVX > 0 && n->is_reduction()); 5430 match(Set dst (MinD a b)); 5431 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5432 5433 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 5434 ins_encode %{ 5435 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5436 true /*min*/, false /*single*/); 5437 %} 5438 ins_pipe( pipe_slow ); 5439 %} 5440 5441 // Load Effective Address 5442 instruct leaP8(rRegP dst, indOffset8 mem) 5443 %{ 5444 match(Set dst mem); 5445 5446 ins_cost(110); // XXX 5447 format %{ "leaq $dst, $mem\t# ptr 8" %} 5448 opcode(0x8D); 5449 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5450 ins_pipe(ialu_reg_reg_fat); 5451 %} 5452 5453 instruct leaP32(rRegP dst, indOffset32 mem) 5454 %{ 5455 match(Set dst mem); 5456 5457 ins_cost(110); 5458 format %{ "leaq $dst, $mem\t# ptr 32" %} 5459 opcode(0x8D); 5460 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5461 ins_pipe(ialu_reg_reg_fat); 5462 %} 5463 5464 // instruct leaPIdx(rRegP dst, indIndex mem) 5465 // %{ 5466 // match(Set dst mem); 5467 5468 // ins_cost(110); 5469 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5470 // opcode(0x8D); 5471 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5472 // ins_pipe(ialu_reg_reg_fat); 5473 // %} 5474 5475 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5476 %{ 5477 match(Set dst mem); 5478 5479 ins_cost(110); 5480 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5481 opcode(0x8D); 5482 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5483 ins_pipe(ialu_reg_reg_fat); 5484 %} 5485 5486 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5487 %{ 5488 match(Set dst mem); 5489 5490 ins_cost(110); 5491 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5492 opcode(0x8D); 5493 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5494 ins_pipe(ialu_reg_reg_fat); 5495 %} 5496 5497 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5498 %{ 5499 match(Set dst mem); 5500 5501 ins_cost(110); 5502 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5503 opcode(0x8D); 5504 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5505 ins_pipe(ialu_reg_reg_fat); 5506 %} 5507 5508 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5509 %{ 5510 match(Set dst mem); 5511 5512 ins_cost(110); 5513 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5514 opcode(0x8D); 5515 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5516 ins_pipe(ialu_reg_reg_fat); 5517 %} 5518 5519 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5520 %{ 5521 match(Set dst mem); 5522 5523 ins_cost(110); 5524 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5525 opcode(0x8D); 5526 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5527 ins_pipe(ialu_reg_reg_fat); 5528 %} 5529 5530 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5531 %{ 5532 match(Set dst mem); 5533 5534 ins_cost(110); 5535 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5536 opcode(0x8D); 5537 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5538 ins_pipe(ialu_reg_reg_fat); 5539 %} 5540 5541 // Load Effective Address which uses Narrow (32-bits) oop 5542 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5543 %{ 5544 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 5545 match(Set dst mem); 5546 5547 ins_cost(110); 5548 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5549 opcode(0x8D); 5550 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5551 ins_pipe(ialu_reg_reg_fat); 5552 %} 5553 5554 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5555 %{ 5556 predicate(CompressedOops::shift() == 0); 5557 match(Set dst mem); 5558 5559 ins_cost(110); // XXX 5560 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5561 opcode(0x8D); 5562 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5563 ins_pipe(ialu_reg_reg_fat); 5564 %} 5565 5566 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5567 %{ 5568 predicate(CompressedOops::shift() == 0); 5569 match(Set dst mem); 5570 5571 ins_cost(110); 5572 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5573 opcode(0x8D); 5574 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5575 ins_pipe(ialu_reg_reg_fat); 5576 %} 5577 5578 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5579 %{ 5580 predicate(CompressedOops::shift() == 0); 5581 match(Set dst mem); 5582 5583 ins_cost(110); 5584 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5585 opcode(0x8D); 5586 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5587 ins_pipe(ialu_reg_reg_fat); 5588 %} 5589 5590 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5591 %{ 5592 predicate(CompressedOops::shift() == 0); 5593 match(Set dst mem); 5594 5595 ins_cost(110); 5596 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5597 opcode(0x8D); 5598 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5599 ins_pipe(ialu_reg_reg_fat); 5600 %} 5601 5602 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5603 %{ 5604 predicate(CompressedOops::shift() == 0); 5605 match(Set dst mem); 5606 5607 ins_cost(110); 5608 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5609 opcode(0x8D); 5610 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5611 ins_pipe(ialu_reg_reg_fat); 5612 %} 5613 5614 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5615 %{ 5616 predicate(CompressedOops::shift() == 0); 5617 match(Set dst mem); 5618 5619 ins_cost(110); 5620 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5621 opcode(0x8D); 5622 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5623 ins_pipe(ialu_reg_reg_fat); 5624 %} 5625 5626 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5627 %{ 5628 predicate(CompressedOops::shift() == 0); 5629 match(Set dst mem); 5630 5631 ins_cost(110); 5632 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5633 opcode(0x8D); 5634 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5635 ins_pipe(ialu_reg_reg_fat); 5636 %} 5637 5638 instruct loadConI(rRegI dst, immI src) 5639 %{ 5640 match(Set dst src); 5641 5642 format %{ "movl $dst, $src\t# int" %} 5643 ins_encode(load_immI(dst, src)); 5644 ins_pipe(ialu_reg_fat); // XXX 5645 %} 5646 5647 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5648 %{ 5649 match(Set dst src); 5650 effect(KILL cr); 5651 5652 ins_cost(50); 5653 format %{ "xorl $dst, $dst\t# int" %} 5654 opcode(0x33); /* + rd */ 5655 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5656 ins_pipe(ialu_reg); 5657 %} 5658 5659 instruct loadConL(rRegL dst, immL src) 5660 %{ 5661 match(Set dst src); 5662 5663 ins_cost(150); 5664 format %{ "movq $dst, $src\t# long" %} 5665 ins_encode(load_immL(dst, src)); 5666 ins_pipe(ialu_reg); 5667 %} 5668 5669 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5670 %{ 5671 match(Set dst src); 5672 effect(KILL cr); 5673 5674 ins_cost(50); 5675 format %{ "xorl $dst, $dst\t# long" %} 5676 opcode(0x33); /* + rd */ 5677 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5678 ins_pipe(ialu_reg); // XXX 5679 %} 5680 5681 instruct loadConUL32(rRegL dst, immUL32 src) 5682 %{ 5683 match(Set dst src); 5684 5685 ins_cost(60); 5686 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5687 ins_encode(load_immUL32(dst, src)); 5688 ins_pipe(ialu_reg); 5689 %} 5690 5691 instruct loadConL32(rRegL dst, immL32 src) 5692 %{ 5693 match(Set dst src); 5694 5695 ins_cost(70); 5696 format %{ "movq $dst, $src\t# long (32-bit)" %} 5697 ins_encode(load_immL32(dst, src)); 5698 ins_pipe(ialu_reg); 5699 %} 5700 5701 instruct loadConP(rRegP dst, immP con) %{ 5702 match(Set dst con); 5703 5704 format %{ "movq $dst, $con\t# ptr" %} 5705 ins_encode(load_immP(dst, con)); 5706 ins_pipe(ialu_reg_fat); // XXX 5707 %} 5708 5709 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5710 %{ 5711 match(Set dst src); 5712 effect(KILL cr); 5713 5714 ins_cost(50); 5715 format %{ "xorl $dst, $dst\t# ptr" %} 5716 opcode(0x33); /* + rd */ 5717 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5718 ins_pipe(ialu_reg); 5719 %} 5720 5721 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5722 %{ 5723 match(Set dst src); 5724 effect(KILL cr); 5725 5726 ins_cost(60); 5727 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5728 ins_encode(load_immP31(dst, src)); 5729 ins_pipe(ialu_reg); 5730 %} 5731 5732 instruct loadConF(regF dst, immF con) %{ 5733 match(Set dst con); 5734 ins_cost(125); 5735 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5736 ins_encode %{ 5737 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5738 %} 5739 ins_pipe(pipe_slow); 5740 %} 5741 5742 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5743 match(Set dst src); 5744 effect(KILL cr); 5745 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5746 ins_encode %{ 5747 __ xorq($dst$$Register, $dst$$Register); 5748 %} 5749 ins_pipe(ialu_reg); 5750 %} 5751 5752 instruct loadConN(rRegN dst, immN src) %{ 5753 match(Set dst src); 5754 5755 ins_cost(125); 5756 format %{ "movl $dst, $src\t# compressed ptr" %} 5757 ins_encode %{ 5758 address con = (address)$src$$constant; 5759 if (con == NULL) { 5760 ShouldNotReachHere(); 5761 } else { 5762 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5763 } 5764 %} 5765 ins_pipe(ialu_reg_fat); // XXX 5766 %} 5767 5768 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5769 match(Set dst src); 5770 5771 ins_cost(125); 5772 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5773 ins_encode %{ 5774 address con = (address)$src$$constant; 5775 if (con == NULL) { 5776 ShouldNotReachHere(); 5777 } else { 5778 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5779 } 5780 %} 5781 ins_pipe(ialu_reg_fat); // XXX 5782 %} 5783 5784 instruct loadConF0(regF dst, immF0 src) 5785 %{ 5786 match(Set dst src); 5787 ins_cost(100); 5788 5789 format %{ "xorps $dst, $dst\t# float 0.0" %} 5790 ins_encode %{ 5791 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5792 %} 5793 ins_pipe(pipe_slow); 5794 %} 5795 5796 // Use the same format since predicate() can not be used here. 5797 instruct loadConD(regD dst, immD con) %{ 5798 match(Set dst con); 5799 ins_cost(125); 5800 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5801 ins_encode %{ 5802 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5803 %} 5804 ins_pipe(pipe_slow); 5805 %} 5806 5807 instruct loadConD0(regD dst, immD0 src) 5808 %{ 5809 match(Set dst src); 5810 ins_cost(100); 5811 5812 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5813 ins_encode %{ 5814 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5815 %} 5816 ins_pipe(pipe_slow); 5817 %} 5818 5819 instruct loadSSI(rRegI dst, stackSlotI src) 5820 %{ 5821 match(Set dst src); 5822 5823 ins_cost(125); 5824 format %{ "movl $dst, $src\t# int stk" %} 5825 opcode(0x8B); 5826 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5827 ins_pipe(ialu_reg_mem); 5828 %} 5829 5830 instruct loadSSL(rRegL dst, stackSlotL src) 5831 %{ 5832 match(Set dst src); 5833 5834 ins_cost(125); 5835 format %{ "movq $dst, $src\t# long stk" %} 5836 opcode(0x8B); 5837 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5838 ins_pipe(ialu_reg_mem); 5839 %} 5840 5841 instruct loadSSP(rRegP dst, stackSlotP src) 5842 %{ 5843 match(Set dst src); 5844 5845 ins_cost(125); 5846 format %{ "movq $dst, $src\t# ptr stk" %} 5847 opcode(0x8B); 5848 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5849 ins_pipe(ialu_reg_mem); 5850 %} 5851 5852 instruct loadSSF(regF dst, stackSlotF src) 5853 %{ 5854 match(Set dst src); 5855 5856 ins_cost(125); 5857 format %{ "movss $dst, $src\t# float stk" %} 5858 ins_encode %{ 5859 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5860 %} 5861 ins_pipe(pipe_slow); // XXX 5862 %} 5863 5864 // Use the same format since predicate() can not be used here. 5865 instruct loadSSD(regD dst, stackSlotD src) 5866 %{ 5867 match(Set dst src); 5868 5869 ins_cost(125); 5870 format %{ "movsd $dst, $src\t# double stk" %} 5871 ins_encode %{ 5872 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5873 %} 5874 ins_pipe(pipe_slow); // XXX 5875 %} 5876 5877 // Prefetch instructions for allocation. 5878 // Must be safe to execute with invalid address (cannot fault). 5879 5880 instruct prefetchAlloc( memory mem ) %{ 5881 predicate(AllocatePrefetchInstr==3); 5882 match(PrefetchAllocation mem); 5883 ins_cost(125); 5884 5885 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5886 ins_encode %{ 5887 __ prefetchw($mem$$Address); 5888 %} 5889 ins_pipe(ialu_mem); 5890 %} 5891 5892 instruct prefetchAllocNTA( memory mem ) %{ 5893 predicate(AllocatePrefetchInstr==0); 5894 match(PrefetchAllocation mem); 5895 ins_cost(125); 5896 5897 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5898 ins_encode %{ 5899 __ prefetchnta($mem$$Address); 5900 %} 5901 ins_pipe(ialu_mem); 5902 %} 5903 5904 instruct prefetchAllocT0( memory mem ) %{ 5905 predicate(AllocatePrefetchInstr==1); 5906 match(PrefetchAllocation mem); 5907 ins_cost(125); 5908 5909 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5910 ins_encode %{ 5911 __ prefetcht0($mem$$Address); 5912 %} 5913 ins_pipe(ialu_mem); 5914 %} 5915 5916 instruct prefetchAllocT2( memory mem ) %{ 5917 predicate(AllocatePrefetchInstr==2); 5918 match(PrefetchAllocation mem); 5919 ins_cost(125); 5920 5921 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5922 ins_encode %{ 5923 __ prefetcht2($mem$$Address); 5924 %} 5925 ins_pipe(ialu_mem); 5926 %} 5927 5928 //----------Store Instructions------------------------------------------------- 5929 5930 // Store Byte 5931 instruct storeB(memory mem, rRegI src) 5932 %{ 5933 match(Set mem (StoreB mem src)); 5934 5935 ins_cost(125); // XXX 5936 format %{ "movb $mem, $src\t# byte" %} 5937 opcode(0x88); 5938 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5939 ins_pipe(ialu_mem_reg); 5940 %} 5941 5942 // Store Char/Short 5943 instruct storeC(memory mem, rRegI src) 5944 %{ 5945 match(Set mem (StoreC mem src)); 5946 5947 ins_cost(125); // XXX 5948 format %{ "movw $mem, $src\t# char/short" %} 5949 opcode(0x89); 5950 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5951 ins_pipe(ialu_mem_reg); 5952 %} 5953 5954 // Store Integer 5955 instruct storeI(memory mem, rRegI src) 5956 %{ 5957 match(Set mem (StoreI mem src)); 5958 5959 ins_cost(125); // XXX 5960 format %{ "movl $mem, $src\t# int" %} 5961 opcode(0x89); 5962 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5963 ins_pipe(ialu_mem_reg); 5964 %} 5965 5966 // Store Long 5967 instruct storeL(memory mem, rRegL src) 5968 %{ 5969 match(Set mem (StoreL mem src)); 5970 5971 ins_cost(125); // XXX 5972 format %{ "movq $mem, $src\t# long" %} 5973 opcode(0x89); 5974 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5975 ins_pipe(ialu_mem_reg); // XXX 5976 %} 5977 5978 // Store Pointer 5979 instruct storeP(memory mem, any_RegP src) 5980 %{ 5981 match(Set mem (StoreP mem src)); 5982 5983 ins_cost(125); // XXX 5984 format %{ "movq $mem, $src\t# ptr" %} 5985 opcode(0x89); 5986 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5987 ins_pipe(ialu_mem_reg); 5988 %} 5989 5990 instruct storeImmP0(memory mem, immP0 zero) 5991 %{ 5992 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 5993 match(Set mem (StoreP mem zero)); 5994 5995 ins_cost(125); // XXX 5996 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5997 ins_encode %{ 5998 __ movq($mem$$Address, r12); 5999 %} 6000 ins_pipe(ialu_mem_reg); 6001 %} 6002 6003 // Store NULL Pointer, mark word, or other simple pointer constant. 6004 instruct storeImmP(memory mem, immP31 src) 6005 %{ 6006 match(Set mem (StoreP mem src)); 6007 6008 ins_cost(150); // XXX 6009 format %{ "movq $mem, $src\t# ptr" %} 6010 opcode(0xC7); /* C7 /0 */ 6011 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6012 ins_pipe(ialu_mem_imm); 6013 %} 6014 6015 // Store Compressed Pointer 6016 instruct storeN(memory mem, rRegN src) 6017 %{ 6018 match(Set mem (StoreN mem src)); 6019 6020 ins_cost(125); // XXX 6021 format %{ "movl $mem, $src\t# compressed ptr" %} 6022 ins_encode %{ 6023 __ movl($mem$$Address, $src$$Register); 6024 %} 6025 ins_pipe(ialu_mem_reg); 6026 %} 6027 6028 instruct storeNKlass(memory mem, rRegN src) 6029 %{ 6030 match(Set mem (StoreNKlass mem src)); 6031 6032 ins_cost(125); // XXX 6033 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6034 ins_encode %{ 6035 __ movl($mem$$Address, $src$$Register); 6036 %} 6037 ins_pipe(ialu_mem_reg); 6038 %} 6039 6040 instruct storeImmN0(memory mem, immN0 zero) 6041 %{ 6042 predicate(CompressedOops::base() == NULL && CompressedKlassPointers::base() == NULL); 6043 match(Set mem (StoreN mem zero)); 6044 6045 ins_cost(125); // XXX 6046 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6047 ins_encode %{ 6048 __ movl($mem$$Address, r12); 6049 %} 6050 ins_pipe(ialu_mem_reg); 6051 %} 6052 6053 instruct storeImmN(memory mem, immN src) 6054 %{ 6055 match(Set mem (StoreN mem src)); 6056 6057 ins_cost(150); // XXX 6058 format %{ "movl $mem, $src\t# compressed ptr" %} 6059 ins_encode %{ 6060 address con = (address)$src$$constant; 6061 if (con == NULL) { 6062 __ movl($mem$$Address, (int32_t)0); 6063 } else { 6064 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6065 } 6066 %} 6067 ins_pipe(ialu_mem_imm); 6068 %} 6069 6070 instruct storeImmNKlass(memory mem, immNKlass src) 6071 %{ 6072 match(Set mem (StoreNKlass mem src)); 6073 6074 ins_cost(150); // XXX 6075 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6076 ins_encode %{ 6077 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6078 %} 6079 ins_pipe(ialu_mem_imm); 6080 %} 6081 6082 // Store Integer Immediate 6083 instruct storeImmI0(memory mem, immI0 zero) 6084 %{ 6085 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6086 match(Set mem (StoreI mem zero)); 6087 6088 ins_cost(125); // XXX 6089 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6090 ins_encode %{ 6091 __ movl($mem$$Address, r12); 6092 %} 6093 ins_pipe(ialu_mem_reg); 6094 %} 6095 6096 instruct storeImmI(memory mem, immI src) 6097 %{ 6098 match(Set mem (StoreI mem src)); 6099 6100 ins_cost(150); 6101 format %{ "movl $mem, $src\t# int" %} 6102 opcode(0xC7); /* C7 /0 */ 6103 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6104 ins_pipe(ialu_mem_imm); 6105 %} 6106 6107 // Store Long Immediate 6108 instruct storeImmL0(memory mem, immL0 zero) 6109 %{ 6110 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6111 match(Set mem (StoreL mem zero)); 6112 6113 ins_cost(125); // XXX 6114 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6115 ins_encode %{ 6116 __ movq($mem$$Address, r12); 6117 %} 6118 ins_pipe(ialu_mem_reg); 6119 %} 6120 6121 instruct storeImmL(memory mem, immL32 src) 6122 %{ 6123 match(Set mem (StoreL mem src)); 6124 6125 ins_cost(150); 6126 format %{ "movq $mem, $src\t# long" %} 6127 opcode(0xC7); /* C7 /0 */ 6128 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6129 ins_pipe(ialu_mem_imm); 6130 %} 6131 6132 // Store Short/Char Immediate 6133 instruct storeImmC0(memory mem, immI0 zero) 6134 %{ 6135 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6136 match(Set mem (StoreC mem zero)); 6137 6138 ins_cost(125); // XXX 6139 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6140 ins_encode %{ 6141 __ movw($mem$$Address, r12); 6142 %} 6143 ins_pipe(ialu_mem_reg); 6144 %} 6145 6146 instruct storeImmI16(memory mem, immI16 src) 6147 %{ 6148 predicate(UseStoreImmI16); 6149 match(Set mem (StoreC mem src)); 6150 6151 ins_cost(150); 6152 format %{ "movw $mem, $src\t# short/char" %} 6153 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6154 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6155 ins_pipe(ialu_mem_imm); 6156 %} 6157 6158 // Store Byte Immediate 6159 instruct storeImmB0(memory mem, immI0 zero) 6160 %{ 6161 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6162 match(Set mem (StoreB mem zero)); 6163 6164 ins_cost(125); // XXX 6165 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6166 ins_encode %{ 6167 __ movb($mem$$Address, r12); 6168 %} 6169 ins_pipe(ialu_mem_reg); 6170 %} 6171 6172 instruct storeImmB(memory mem, immI8 src) 6173 %{ 6174 match(Set mem (StoreB mem src)); 6175 6176 ins_cost(150); // XXX 6177 format %{ "movb $mem, $src\t# byte" %} 6178 opcode(0xC6); /* C6 /0 */ 6179 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6180 ins_pipe(ialu_mem_imm); 6181 %} 6182 6183 // Store CMS card-mark Immediate 6184 instruct storeImmCM0_reg(memory mem, immI0 zero) 6185 %{ 6186 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6187 match(Set mem (StoreCM mem zero)); 6188 6189 ins_cost(125); // XXX 6190 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6191 ins_encode %{ 6192 __ movb($mem$$Address, r12); 6193 %} 6194 ins_pipe(ialu_mem_reg); 6195 %} 6196 6197 instruct storeImmCM0(memory mem, immI0 src) 6198 %{ 6199 match(Set mem (StoreCM mem src)); 6200 6201 ins_cost(150); // XXX 6202 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6203 opcode(0xC6); /* C6 /0 */ 6204 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6205 ins_pipe(ialu_mem_imm); 6206 %} 6207 6208 // Store Float 6209 instruct storeF(memory mem, regF src) 6210 %{ 6211 match(Set mem (StoreF mem src)); 6212 6213 ins_cost(95); // XXX 6214 format %{ "movss $mem, $src\t# float" %} 6215 ins_encode %{ 6216 __ movflt($mem$$Address, $src$$XMMRegister); 6217 %} 6218 ins_pipe(pipe_slow); // XXX 6219 %} 6220 6221 // Store immediate Float value (it is faster than store from XMM register) 6222 instruct storeF0(memory mem, immF0 zero) 6223 %{ 6224 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6225 match(Set mem (StoreF mem zero)); 6226 6227 ins_cost(25); // XXX 6228 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6229 ins_encode %{ 6230 __ movl($mem$$Address, r12); 6231 %} 6232 ins_pipe(ialu_mem_reg); 6233 %} 6234 6235 instruct storeF_imm(memory mem, immF src) 6236 %{ 6237 match(Set mem (StoreF mem src)); 6238 6239 ins_cost(50); 6240 format %{ "movl $mem, $src\t# float" %} 6241 opcode(0xC7); /* C7 /0 */ 6242 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6243 ins_pipe(ialu_mem_imm); 6244 %} 6245 6246 // Store Double 6247 instruct storeD(memory mem, regD src) 6248 %{ 6249 match(Set mem (StoreD mem src)); 6250 6251 ins_cost(95); // XXX 6252 format %{ "movsd $mem, $src\t# double" %} 6253 ins_encode %{ 6254 __ movdbl($mem$$Address, $src$$XMMRegister); 6255 %} 6256 ins_pipe(pipe_slow); // XXX 6257 %} 6258 6259 // Store immediate double 0.0 (it is faster than store from XMM register) 6260 instruct storeD0_imm(memory mem, immD0 src) 6261 %{ 6262 predicate(!UseCompressedOops || (CompressedOops::base() != NULL)); 6263 match(Set mem (StoreD mem src)); 6264 6265 ins_cost(50); 6266 format %{ "movq $mem, $src\t# double 0." %} 6267 opcode(0xC7); /* C7 /0 */ 6268 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6269 ins_pipe(ialu_mem_imm); 6270 %} 6271 6272 instruct storeD0(memory mem, immD0 zero) 6273 %{ 6274 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL)); 6275 match(Set mem (StoreD mem zero)); 6276 6277 ins_cost(25); // XXX 6278 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6279 ins_encode %{ 6280 __ movq($mem$$Address, r12); 6281 %} 6282 ins_pipe(ialu_mem_reg); 6283 %} 6284 6285 instruct storeSSI(stackSlotI dst, rRegI src) 6286 %{ 6287 match(Set dst src); 6288 6289 ins_cost(100); 6290 format %{ "movl $dst, $src\t# int stk" %} 6291 opcode(0x89); 6292 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6293 ins_pipe( ialu_mem_reg ); 6294 %} 6295 6296 instruct storeSSL(stackSlotL dst, rRegL src) 6297 %{ 6298 match(Set dst src); 6299 6300 ins_cost(100); 6301 format %{ "movq $dst, $src\t# long stk" %} 6302 opcode(0x89); 6303 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6304 ins_pipe(ialu_mem_reg); 6305 %} 6306 6307 instruct storeSSP(stackSlotP dst, rRegP src) 6308 %{ 6309 match(Set dst src); 6310 6311 ins_cost(100); 6312 format %{ "movq $dst, $src\t# ptr stk" %} 6313 opcode(0x89); 6314 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6315 ins_pipe(ialu_mem_reg); 6316 %} 6317 6318 instruct storeSSF(stackSlotF dst, regF src) 6319 %{ 6320 match(Set dst src); 6321 6322 ins_cost(95); // XXX 6323 format %{ "movss $dst, $src\t# float stk" %} 6324 ins_encode %{ 6325 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6326 %} 6327 ins_pipe(pipe_slow); // XXX 6328 %} 6329 6330 instruct storeSSD(stackSlotD dst, regD src) 6331 %{ 6332 match(Set dst src); 6333 6334 ins_cost(95); // XXX 6335 format %{ "movsd $dst, $src\t# double stk" %} 6336 ins_encode %{ 6337 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6338 %} 6339 ins_pipe(pipe_slow); // XXX 6340 %} 6341 6342 instruct cacheWB(indirect addr) 6343 %{ 6344 predicate(VM_Version::supports_data_cache_line_flush()); 6345 match(CacheWB addr); 6346 6347 ins_cost(100); 6348 format %{"cache wb $addr" %} 6349 ins_encode %{ 6350 assert($addr->index_position() < 0, "should be"); 6351 assert($addr$$disp == 0, "should be"); 6352 __ cache_wb(Address($addr$$base$$Register, 0)); 6353 %} 6354 ins_pipe(pipe_slow); // XXX 6355 %} 6356 6357 instruct cacheWBPreSync() 6358 %{ 6359 predicate(VM_Version::supports_data_cache_line_flush()); 6360 match(CacheWBPreSync); 6361 6362 ins_cost(100); 6363 format %{"cache wb presync" %} 6364 ins_encode %{ 6365 __ cache_wbsync(true); 6366 %} 6367 ins_pipe(pipe_slow); // XXX 6368 %} 6369 6370 instruct cacheWBPostSync() 6371 %{ 6372 predicate(VM_Version::supports_data_cache_line_flush()); 6373 match(CacheWBPostSync); 6374 6375 ins_cost(100); 6376 format %{"cache wb postsync" %} 6377 ins_encode %{ 6378 __ cache_wbsync(false); 6379 %} 6380 ins_pipe(pipe_slow); // XXX 6381 %} 6382 6383 //----------BSWAP Instructions------------------------------------------------- 6384 instruct bytes_reverse_int(rRegI dst) %{ 6385 match(Set dst (ReverseBytesI dst)); 6386 6387 format %{ "bswapl $dst" %} 6388 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6389 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6390 ins_pipe( ialu_reg ); 6391 %} 6392 6393 instruct bytes_reverse_long(rRegL dst) %{ 6394 match(Set dst (ReverseBytesL dst)); 6395 6396 format %{ "bswapq $dst" %} 6397 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6398 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6399 ins_pipe( ialu_reg); 6400 %} 6401 6402 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6403 match(Set dst (ReverseBytesUS dst)); 6404 effect(KILL cr); 6405 6406 format %{ "bswapl $dst\n\t" 6407 "shrl $dst,16\n\t" %} 6408 ins_encode %{ 6409 __ bswapl($dst$$Register); 6410 __ shrl($dst$$Register, 16); 6411 %} 6412 ins_pipe( ialu_reg ); 6413 %} 6414 6415 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6416 match(Set dst (ReverseBytesS dst)); 6417 effect(KILL cr); 6418 6419 format %{ "bswapl $dst\n\t" 6420 "sar $dst,16\n\t" %} 6421 ins_encode %{ 6422 __ bswapl($dst$$Register); 6423 __ sarl($dst$$Register, 16); 6424 %} 6425 ins_pipe( ialu_reg ); 6426 %} 6427 6428 //---------- Zeros Count Instructions ------------------------------------------ 6429 6430 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6431 predicate(UseCountLeadingZerosInstruction); 6432 match(Set dst (CountLeadingZerosI src)); 6433 effect(KILL cr); 6434 6435 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6436 ins_encode %{ 6437 __ lzcntl($dst$$Register, $src$$Register); 6438 %} 6439 ins_pipe(ialu_reg); 6440 %} 6441 6442 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6443 predicate(!UseCountLeadingZerosInstruction); 6444 match(Set dst (CountLeadingZerosI src)); 6445 effect(KILL cr); 6446 6447 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6448 "jnz skip\n\t" 6449 "movl $dst, -1\n" 6450 "skip:\n\t" 6451 "negl $dst\n\t" 6452 "addl $dst, 31" %} 6453 ins_encode %{ 6454 Register Rdst = $dst$$Register; 6455 Register Rsrc = $src$$Register; 6456 Label skip; 6457 __ bsrl(Rdst, Rsrc); 6458 __ jccb(Assembler::notZero, skip); 6459 __ movl(Rdst, -1); 6460 __ bind(skip); 6461 __ negl(Rdst); 6462 __ addl(Rdst, BitsPerInt - 1); 6463 %} 6464 ins_pipe(ialu_reg); 6465 %} 6466 6467 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6468 predicate(UseCountLeadingZerosInstruction); 6469 match(Set dst (CountLeadingZerosL src)); 6470 effect(KILL cr); 6471 6472 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6473 ins_encode %{ 6474 __ lzcntq($dst$$Register, $src$$Register); 6475 %} 6476 ins_pipe(ialu_reg); 6477 %} 6478 6479 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6480 predicate(!UseCountLeadingZerosInstruction); 6481 match(Set dst (CountLeadingZerosL src)); 6482 effect(KILL cr); 6483 6484 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6485 "jnz skip\n\t" 6486 "movl $dst, -1\n" 6487 "skip:\n\t" 6488 "negl $dst\n\t" 6489 "addl $dst, 63" %} 6490 ins_encode %{ 6491 Register Rdst = $dst$$Register; 6492 Register Rsrc = $src$$Register; 6493 Label skip; 6494 __ bsrq(Rdst, Rsrc); 6495 __ jccb(Assembler::notZero, skip); 6496 __ movl(Rdst, -1); 6497 __ bind(skip); 6498 __ negl(Rdst); 6499 __ addl(Rdst, BitsPerLong - 1); 6500 %} 6501 ins_pipe(ialu_reg); 6502 %} 6503 6504 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6505 predicate(UseCountTrailingZerosInstruction); 6506 match(Set dst (CountTrailingZerosI src)); 6507 effect(KILL cr); 6508 6509 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6510 ins_encode %{ 6511 __ tzcntl($dst$$Register, $src$$Register); 6512 %} 6513 ins_pipe(ialu_reg); 6514 %} 6515 6516 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6517 predicate(!UseCountTrailingZerosInstruction); 6518 match(Set dst (CountTrailingZerosI src)); 6519 effect(KILL cr); 6520 6521 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6522 "jnz done\n\t" 6523 "movl $dst, 32\n" 6524 "done:" %} 6525 ins_encode %{ 6526 Register Rdst = $dst$$Register; 6527 Label done; 6528 __ bsfl(Rdst, $src$$Register); 6529 __ jccb(Assembler::notZero, done); 6530 __ movl(Rdst, BitsPerInt); 6531 __ bind(done); 6532 %} 6533 ins_pipe(ialu_reg); 6534 %} 6535 6536 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6537 predicate(UseCountTrailingZerosInstruction); 6538 match(Set dst (CountTrailingZerosL src)); 6539 effect(KILL cr); 6540 6541 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6542 ins_encode %{ 6543 __ tzcntq($dst$$Register, $src$$Register); 6544 %} 6545 ins_pipe(ialu_reg); 6546 %} 6547 6548 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6549 predicate(!UseCountTrailingZerosInstruction); 6550 match(Set dst (CountTrailingZerosL src)); 6551 effect(KILL cr); 6552 6553 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6554 "jnz done\n\t" 6555 "movl $dst, 64\n" 6556 "done:" %} 6557 ins_encode %{ 6558 Register Rdst = $dst$$Register; 6559 Label done; 6560 __ bsfq(Rdst, $src$$Register); 6561 __ jccb(Assembler::notZero, done); 6562 __ movl(Rdst, BitsPerLong); 6563 __ bind(done); 6564 %} 6565 ins_pipe(ialu_reg); 6566 %} 6567 6568 6569 //---------- Population Count Instructions ------------------------------------- 6570 6571 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6572 predicate(UsePopCountInstruction); 6573 match(Set dst (PopCountI src)); 6574 effect(KILL cr); 6575 6576 format %{ "popcnt $dst, $src" %} 6577 ins_encode %{ 6578 __ popcntl($dst$$Register, $src$$Register); 6579 %} 6580 ins_pipe(ialu_reg); 6581 %} 6582 6583 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6584 predicate(UsePopCountInstruction); 6585 match(Set dst (PopCountI (LoadI mem))); 6586 effect(KILL cr); 6587 6588 format %{ "popcnt $dst, $mem" %} 6589 ins_encode %{ 6590 __ popcntl($dst$$Register, $mem$$Address); 6591 %} 6592 ins_pipe(ialu_reg); 6593 %} 6594 6595 // Note: Long.bitCount(long) returns an int. 6596 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6597 predicate(UsePopCountInstruction); 6598 match(Set dst (PopCountL src)); 6599 effect(KILL cr); 6600 6601 format %{ "popcnt $dst, $src" %} 6602 ins_encode %{ 6603 __ popcntq($dst$$Register, $src$$Register); 6604 %} 6605 ins_pipe(ialu_reg); 6606 %} 6607 6608 // Note: Long.bitCount(long) returns an int. 6609 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6610 predicate(UsePopCountInstruction); 6611 match(Set dst (PopCountL (LoadL mem))); 6612 effect(KILL cr); 6613 6614 format %{ "popcnt $dst, $mem" %} 6615 ins_encode %{ 6616 __ popcntq($dst$$Register, $mem$$Address); 6617 %} 6618 ins_pipe(ialu_reg); 6619 %} 6620 6621 6622 //----------MemBar Instructions----------------------------------------------- 6623 // Memory barrier flavors 6624 6625 instruct membar_acquire() 6626 %{ 6627 match(MemBarAcquire); 6628 match(LoadFence); 6629 ins_cost(0); 6630 6631 size(0); 6632 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6633 ins_encode(); 6634 ins_pipe(empty); 6635 %} 6636 6637 instruct membar_acquire_lock() 6638 %{ 6639 match(MemBarAcquireLock); 6640 ins_cost(0); 6641 6642 size(0); 6643 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6644 ins_encode(); 6645 ins_pipe(empty); 6646 %} 6647 6648 instruct membar_release() 6649 %{ 6650 match(MemBarRelease); 6651 match(StoreFence); 6652 ins_cost(0); 6653 6654 size(0); 6655 format %{ "MEMBAR-release ! (empty encoding)" %} 6656 ins_encode(); 6657 ins_pipe(empty); 6658 %} 6659 6660 instruct membar_release_lock() 6661 %{ 6662 match(MemBarReleaseLock); 6663 ins_cost(0); 6664 6665 size(0); 6666 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6667 ins_encode(); 6668 ins_pipe(empty); 6669 %} 6670 6671 instruct membar_volatile(rFlagsReg cr) %{ 6672 match(MemBarVolatile); 6673 effect(KILL cr); 6674 ins_cost(400); 6675 6676 format %{ 6677 $$template 6678 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6679 %} 6680 ins_encode %{ 6681 __ membar(Assembler::StoreLoad); 6682 %} 6683 ins_pipe(pipe_slow); 6684 %} 6685 6686 instruct unnecessary_membar_volatile() 6687 %{ 6688 match(MemBarVolatile); 6689 predicate(Matcher::post_store_load_barrier(n)); 6690 ins_cost(0); 6691 6692 size(0); 6693 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6694 ins_encode(); 6695 ins_pipe(empty); 6696 %} 6697 6698 instruct membar_storestore() %{ 6699 match(MemBarStoreStore); 6700 ins_cost(0); 6701 6702 size(0); 6703 format %{ "MEMBAR-storestore (empty encoding)" %} 6704 ins_encode( ); 6705 ins_pipe(empty); 6706 %} 6707 6708 //----------Move Instructions-------------------------------------------------- 6709 6710 instruct castX2P(rRegP dst, rRegL src) 6711 %{ 6712 match(Set dst (CastX2P src)); 6713 6714 format %{ "movq $dst, $src\t# long->ptr" %} 6715 ins_encode %{ 6716 if ($dst$$reg != $src$$reg) { 6717 __ movptr($dst$$Register, $src$$Register); 6718 } 6719 %} 6720 ins_pipe(ialu_reg_reg); // XXX 6721 %} 6722 6723 instruct castP2X(rRegL dst, rRegP src) 6724 %{ 6725 match(Set dst (CastP2X src)); 6726 6727 format %{ "movq $dst, $src\t# ptr -> long" %} 6728 ins_encode %{ 6729 if ($dst$$reg != $src$$reg) { 6730 __ movptr($dst$$Register, $src$$Register); 6731 } 6732 %} 6733 ins_pipe(ialu_reg_reg); // XXX 6734 %} 6735 6736 // Convert oop into int for vectors alignment masking 6737 instruct convP2I(rRegI dst, rRegP src) 6738 %{ 6739 match(Set dst (ConvL2I (CastP2X src))); 6740 6741 format %{ "movl $dst, $src\t# ptr -> int" %} 6742 ins_encode %{ 6743 __ movl($dst$$Register, $src$$Register); 6744 %} 6745 ins_pipe(ialu_reg_reg); // XXX 6746 %} 6747 6748 // Convert compressed oop into int for vectors alignment masking 6749 // in case of 32bit oops (heap < 4Gb). 6750 instruct convN2I(rRegI dst, rRegN src) 6751 %{ 6752 predicate(CompressedOops::shift() == 0); 6753 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6754 6755 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6756 ins_encode %{ 6757 __ movl($dst$$Register, $src$$Register); 6758 %} 6759 ins_pipe(ialu_reg_reg); // XXX 6760 %} 6761 6762 // Convert oop pointer into compressed form 6763 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6764 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6765 match(Set dst (EncodeP src)); 6766 effect(KILL cr); 6767 format %{ "encode_heap_oop $dst,$src" %} 6768 ins_encode %{ 6769 Register s = $src$$Register; 6770 Register d = $dst$$Register; 6771 if (s != d) { 6772 __ movq(d, s); 6773 } 6774 __ encode_heap_oop(d); 6775 %} 6776 ins_pipe(ialu_reg_long); 6777 %} 6778 6779 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6780 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6781 match(Set dst (EncodeP src)); 6782 effect(KILL cr); 6783 format %{ "encode_heap_oop_not_null $dst,$src" %} 6784 ins_encode %{ 6785 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6786 %} 6787 ins_pipe(ialu_reg_long); 6788 %} 6789 6790 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6791 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6792 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6793 match(Set dst (DecodeN src)); 6794 effect(KILL cr); 6795 format %{ "decode_heap_oop $dst,$src" %} 6796 ins_encode %{ 6797 Register s = $src$$Register; 6798 Register d = $dst$$Register; 6799 if (s != d) { 6800 __ movq(d, s); 6801 } 6802 __ decode_heap_oop(d); 6803 %} 6804 ins_pipe(ialu_reg_long); 6805 %} 6806 6807 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6808 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6809 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6810 match(Set dst (DecodeN src)); 6811 effect(KILL cr); 6812 format %{ "decode_heap_oop_not_null $dst,$src" %} 6813 ins_encode %{ 6814 Register s = $src$$Register; 6815 Register d = $dst$$Register; 6816 if (s != d) { 6817 __ decode_heap_oop_not_null(d, s); 6818 } else { 6819 __ decode_heap_oop_not_null(d); 6820 } 6821 %} 6822 ins_pipe(ialu_reg_long); 6823 %} 6824 6825 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6826 match(Set dst (EncodePKlass src)); 6827 effect(KILL cr); 6828 format %{ "encode_klass_not_null $dst,$src" %} 6829 ins_encode %{ 6830 __ encode_klass_not_null($dst$$Register, $src$$Register); 6831 %} 6832 ins_pipe(ialu_reg_long); 6833 %} 6834 6835 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6836 match(Set dst (DecodeNKlass src)); 6837 effect(KILL cr); 6838 format %{ "decode_klass_not_null $dst,$src" %} 6839 ins_encode %{ 6840 Register s = $src$$Register; 6841 Register d = $dst$$Register; 6842 if (s != d) { 6843 __ decode_klass_not_null(d, s); 6844 } else { 6845 __ decode_klass_not_null(d); 6846 } 6847 %} 6848 ins_pipe(ialu_reg_long); 6849 %} 6850 6851 6852 //----------Conditional Move--------------------------------------------------- 6853 // Jump 6854 // dummy instruction for generating temp registers 6855 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6856 match(Jump (LShiftL switch_val shift)); 6857 ins_cost(350); 6858 predicate(false); 6859 effect(TEMP dest); 6860 6861 format %{ "leaq $dest, [$constantaddress]\n\t" 6862 "jmp [$dest + $switch_val << $shift]\n\t" %} 6863 ins_encode %{ 6864 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6865 // to do that and the compiler is using that register as one it can allocate. 6866 // So we build it all by hand. 6867 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6868 // ArrayAddress dispatch(table, index); 6869 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6870 __ lea($dest$$Register, $constantaddress); 6871 __ jmp(dispatch); 6872 %} 6873 ins_pipe(pipe_jmp); 6874 %} 6875 6876 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6877 match(Jump (AddL (LShiftL switch_val shift) offset)); 6878 ins_cost(350); 6879 effect(TEMP dest); 6880 6881 format %{ "leaq $dest, [$constantaddress]\n\t" 6882 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6883 ins_encode %{ 6884 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6885 // to do that and the compiler is using that register as one it can allocate. 6886 // So we build it all by hand. 6887 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6888 // ArrayAddress dispatch(table, index); 6889 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6890 __ lea($dest$$Register, $constantaddress); 6891 __ jmp(dispatch); 6892 %} 6893 ins_pipe(pipe_jmp); 6894 %} 6895 6896 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6897 match(Jump switch_val); 6898 ins_cost(350); 6899 effect(TEMP dest); 6900 6901 format %{ "leaq $dest, [$constantaddress]\n\t" 6902 "jmp [$dest + $switch_val]\n\t" %} 6903 ins_encode %{ 6904 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6905 // to do that and the compiler is using that register as one it can allocate. 6906 // So we build it all by hand. 6907 // Address index(noreg, switch_reg, Address::times_1); 6908 // ArrayAddress dispatch(table, index); 6909 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6910 __ lea($dest$$Register, $constantaddress); 6911 __ jmp(dispatch); 6912 %} 6913 ins_pipe(pipe_jmp); 6914 %} 6915 6916 // Conditional move 6917 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6918 %{ 6919 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6920 6921 ins_cost(200); // XXX 6922 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6923 opcode(0x0F, 0x40); 6924 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6925 ins_pipe(pipe_cmov_reg); 6926 %} 6927 6928 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6929 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6930 6931 ins_cost(200); // XXX 6932 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6933 opcode(0x0F, 0x40); 6934 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6935 ins_pipe(pipe_cmov_reg); 6936 %} 6937 6938 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6939 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6940 ins_cost(200); 6941 expand %{ 6942 cmovI_regU(cop, cr, dst, src); 6943 %} 6944 %} 6945 6946 // Conditional move 6947 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6948 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6949 6950 ins_cost(250); // XXX 6951 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6952 opcode(0x0F, 0x40); 6953 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6954 ins_pipe(pipe_cmov_mem); 6955 %} 6956 6957 // Conditional move 6958 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6959 %{ 6960 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6961 6962 ins_cost(250); // XXX 6963 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6964 opcode(0x0F, 0x40); 6965 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6966 ins_pipe(pipe_cmov_mem); 6967 %} 6968 6969 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6970 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6971 ins_cost(250); 6972 expand %{ 6973 cmovI_memU(cop, cr, dst, src); 6974 %} 6975 %} 6976 6977 // Conditional move 6978 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6979 %{ 6980 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6981 6982 ins_cost(200); // XXX 6983 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6984 opcode(0x0F, 0x40); 6985 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6986 ins_pipe(pipe_cmov_reg); 6987 %} 6988 6989 // Conditional move 6990 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6991 %{ 6992 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6993 6994 ins_cost(200); // XXX 6995 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6996 opcode(0x0F, 0x40); 6997 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6998 ins_pipe(pipe_cmov_reg); 6999 %} 7000 7001 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7002 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7003 ins_cost(200); 7004 expand %{ 7005 cmovN_regU(cop, cr, dst, src); 7006 %} 7007 %} 7008 7009 // Conditional move 7010 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7011 %{ 7012 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7013 7014 ins_cost(200); // XXX 7015 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7016 opcode(0x0F, 0x40); 7017 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7018 ins_pipe(pipe_cmov_reg); // XXX 7019 %} 7020 7021 // Conditional move 7022 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7023 %{ 7024 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7025 7026 ins_cost(200); // XXX 7027 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7028 opcode(0x0F, 0x40); 7029 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7030 ins_pipe(pipe_cmov_reg); // XXX 7031 %} 7032 7033 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7034 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7035 ins_cost(200); 7036 expand %{ 7037 cmovP_regU(cop, cr, dst, src); 7038 %} 7039 %} 7040 7041 // DISABLED: Requires the ADLC to emit a bottom_type call that 7042 // correctly meets the two pointer arguments; one is an incoming 7043 // register but the other is a memory operand. ALSO appears to 7044 // be buggy with implicit null checks. 7045 // 7046 //// Conditional move 7047 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7048 //%{ 7049 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7050 // ins_cost(250); 7051 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7052 // opcode(0x0F,0x40); 7053 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7054 // ins_pipe( pipe_cmov_mem ); 7055 //%} 7056 // 7057 //// Conditional move 7058 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7059 //%{ 7060 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7061 // ins_cost(250); 7062 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7063 // opcode(0x0F,0x40); 7064 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7065 // ins_pipe( pipe_cmov_mem ); 7066 //%} 7067 7068 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7069 %{ 7070 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7071 7072 ins_cost(200); // XXX 7073 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7074 opcode(0x0F, 0x40); 7075 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7076 ins_pipe(pipe_cmov_reg); // XXX 7077 %} 7078 7079 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7080 %{ 7081 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7082 7083 ins_cost(200); // XXX 7084 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7085 opcode(0x0F, 0x40); 7086 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7087 ins_pipe(pipe_cmov_mem); // XXX 7088 %} 7089 7090 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7091 %{ 7092 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7093 7094 ins_cost(200); // XXX 7095 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7096 opcode(0x0F, 0x40); 7097 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7098 ins_pipe(pipe_cmov_reg); // XXX 7099 %} 7100 7101 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7102 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7103 ins_cost(200); 7104 expand %{ 7105 cmovL_regU(cop, cr, dst, src); 7106 %} 7107 %} 7108 7109 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7110 %{ 7111 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7112 7113 ins_cost(200); // XXX 7114 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7115 opcode(0x0F, 0x40); 7116 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7117 ins_pipe(pipe_cmov_mem); // XXX 7118 %} 7119 7120 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7121 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7122 ins_cost(200); 7123 expand %{ 7124 cmovL_memU(cop, cr, dst, src); 7125 %} 7126 %} 7127 7128 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7129 %{ 7130 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7131 7132 ins_cost(200); // XXX 7133 format %{ "jn$cop skip\t# signed cmove float\n\t" 7134 "movss $dst, $src\n" 7135 "skip:" %} 7136 ins_encode %{ 7137 Label Lskip; 7138 // Invert sense of branch from sense of CMOV 7139 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7140 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7141 __ bind(Lskip); 7142 %} 7143 ins_pipe(pipe_slow); 7144 %} 7145 7146 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7147 // %{ 7148 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7149 7150 // ins_cost(200); // XXX 7151 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7152 // "movss $dst, $src\n" 7153 // "skip:" %} 7154 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7155 // ins_pipe(pipe_slow); 7156 // %} 7157 7158 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7159 %{ 7160 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7161 7162 ins_cost(200); // XXX 7163 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7164 "movss $dst, $src\n" 7165 "skip:" %} 7166 ins_encode %{ 7167 Label Lskip; 7168 // Invert sense of branch from sense of CMOV 7169 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7170 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7171 __ bind(Lskip); 7172 %} 7173 ins_pipe(pipe_slow); 7174 %} 7175 7176 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7177 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7178 ins_cost(200); 7179 expand %{ 7180 cmovF_regU(cop, cr, dst, src); 7181 %} 7182 %} 7183 7184 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7185 %{ 7186 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7187 7188 ins_cost(200); // XXX 7189 format %{ "jn$cop skip\t# signed cmove double\n\t" 7190 "movsd $dst, $src\n" 7191 "skip:" %} 7192 ins_encode %{ 7193 Label Lskip; 7194 // Invert sense of branch from sense of CMOV 7195 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7196 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7197 __ bind(Lskip); 7198 %} 7199 ins_pipe(pipe_slow); 7200 %} 7201 7202 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7203 %{ 7204 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7205 7206 ins_cost(200); // XXX 7207 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7208 "movsd $dst, $src\n" 7209 "skip:" %} 7210 ins_encode %{ 7211 Label Lskip; 7212 // Invert sense of branch from sense of CMOV 7213 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7214 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7215 __ bind(Lskip); 7216 %} 7217 ins_pipe(pipe_slow); 7218 %} 7219 7220 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7221 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7222 ins_cost(200); 7223 expand %{ 7224 cmovD_regU(cop, cr, dst, src); 7225 %} 7226 %} 7227 7228 //----------Arithmetic Instructions-------------------------------------------- 7229 //----------Addition Instructions---------------------------------------------- 7230 7231 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7232 %{ 7233 match(Set dst (AddI dst src)); 7234 effect(KILL cr); 7235 7236 format %{ "addl $dst, $src\t# int" %} 7237 opcode(0x03); 7238 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7239 ins_pipe(ialu_reg_reg); 7240 %} 7241 7242 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7243 %{ 7244 match(Set dst (AddI dst src)); 7245 effect(KILL cr); 7246 7247 format %{ "addl $dst, $src\t# int" %} 7248 opcode(0x81, 0x00); /* /0 id */ 7249 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7250 ins_pipe( ialu_reg ); 7251 %} 7252 7253 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7254 %{ 7255 match(Set dst (AddI dst (LoadI src))); 7256 effect(KILL cr); 7257 7258 ins_cost(125); // XXX 7259 format %{ "addl $dst, $src\t# int" %} 7260 opcode(0x03); 7261 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7262 ins_pipe(ialu_reg_mem); 7263 %} 7264 7265 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7266 %{ 7267 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7268 effect(KILL cr); 7269 7270 ins_cost(150); // XXX 7271 format %{ "addl $dst, $src\t# int" %} 7272 opcode(0x01); /* Opcode 01 /r */ 7273 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7274 ins_pipe(ialu_mem_reg); 7275 %} 7276 7277 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7278 %{ 7279 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7280 effect(KILL cr); 7281 7282 ins_cost(125); // XXX 7283 format %{ "addl $dst, $src\t# int" %} 7284 opcode(0x81); /* Opcode 81 /0 id */ 7285 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7286 ins_pipe(ialu_mem_imm); 7287 %} 7288 7289 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7290 %{ 7291 predicate(UseIncDec); 7292 match(Set dst (AddI dst src)); 7293 effect(KILL cr); 7294 7295 format %{ "incl $dst\t# int" %} 7296 opcode(0xFF, 0x00); // FF /0 7297 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7298 ins_pipe(ialu_reg); 7299 %} 7300 7301 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7302 %{ 7303 predicate(UseIncDec); 7304 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7305 effect(KILL cr); 7306 7307 ins_cost(125); // XXX 7308 format %{ "incl $dst\t# int" %} 7309 opcode(0xFF); /* Opcode FF /0 */ 7310 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7311 ins_pipe(ialu_mem_imm); 7312 %} 7313 7314 // XXX why does that use AddI 7315 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7316 %{ 7317 predicate(UseIncDec); 7318 match(Set dst (AddI dst src)); 7319 effect(KILL cr); 7320 7321 format %{ "decl $dst\t# int" %} 7322 opcode(0xFF, 0x01); // FF /1 7323 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7324 ins_pipe(ialu_reg); 7325 %} 7326 7327 // XXX why does that use AddI 7328 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7329 %{ 7330 predicate(UseIncDec); 7331 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7332 effect(KILL cr); 7333 7334 ins_cost(125); // XXX 7335 format %{ "decl $dst\t# int" %} 7336 opcode(0xFF); /* Opcode FF /1 */ 7337 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7338 ins_pipe(ialu_mem_imm); 7339 %} 7340 7341 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7342 %{ 7343 match(Set dst (AddI src0 src1)); 7344 7345 ins_cost(110); 7346 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7347 opcode(0x8D); /* 0x8D /r */ 7348 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7349 ins_pipe(ialu_reg_reg); 7350 %} 7351 7352 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7353 %{ 7354 match(Set dst (AddL dst src)); 7355 effect(KILL cr); 7356 7357 format %{ "addq $dst, $src\t# long" %} 7358 opcode(0x03); 7359 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7360 ins_pipe(ialu_reg_reg); 7361 %} 7362 7363 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7364 %{ 7365 match(Set dst (AddL dst src)); 7366 effect(KILL cr); 7367 7368 format %{ "addq $dst, $src\t# long" %} 7369 opcode(0x81, 0x00); /* /0 id */ 7370 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7371 ins_pipe( ialu_reg ); 7372 %} 7373 7374 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7375 %{ 7376 match(Set dst (AddL dst (LoadL src))); 7377 effect(KILL cr); 7378 7379 ins_cost(125); // XXX 7380 format %{ "addq $dst, $src\t# long" %} 7381 opcode(0x03); 7382 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7383 ins_pipe(ialu_reg_mem); 7384 %} 7385 7386 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7387 %{ 7388 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7389 effect(KILL cr); 7390 7391 ins_cost(150); // XXX 7392 format %{ "addq $dst, $src\t# long" %} 7393 opcode(0x01); /* Opcode 01 /r */ 7394 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7395 ins_pipe(ialu_mem_reg); 7396 %} 7397 7398 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7399 %{ 7400 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7401 effect(KILL cr); 7402 7403 ins_cost(125); // XXX 7404 format %{ "addq $dst, $src\t# long" %} 7405 opcode(0x81); /* Opcode 81 /0 id */ 7406 ins_encode(REX_mem_wide(dst), 7407 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7408 ins_pipe(ialu_mem_imm); 7409 %} 7410 7411 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7412 %{ 7413 predicate(UseIncDec); 7414 match(Set dst (AddL dst src)); 7415 effect(KILL cr); 7416 7417 format %{ "incq $dst\t# long" %} 7418 opcode(0xFF, 0x00); // FF /0 7419 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7420 ins_pipe(ialu_reg); 7421 %} 7422 7423 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7424 %{ 7425 predicate(UseIncDec); 7426 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7427 effect(KILL cr); 7428 7429 ins_cost(125); // XXX 7430 format %{ "incq $dst\t# long" %} 7431 opcode(0xFF); /* Opcode FF /0 */ 7432 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7433 ins_pipe(ialu_mem_imm); 7434 %} 7435 7436 // XXX why does that use AddL 7437 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7438 %{ 7439 predicate(UseIncDec); 7440 match(Set dst (AddL dst src)); 7441 effect(KILL cr); 7442 7443 format %{ "decq $dst\t# long" %} 7444 opcode(0xFF, 0x01); // FF /1 7445 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7446 ins_pipe(ialu_reg); 7447 %} 7448 7449 // XXX why does that use AddL 7450 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7451 %{ 7452 predicate(UseIncDec); 7453 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7454 effect(KILL cr); 7455 7456 ins_cost(125); // XXX 7457 format %{ "decq $dst\t# long" %} 7458 opcode(0xFF); /* Opcode FF /1 */ 7459 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7460 ins_pipe(ialu_mem_imm); 7461 %} 7462 7463 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7464 %{ 7465 match(Set dst (AddL src0 src1)); 7466 7467 ins_cost(110); 7468 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7469 opcode(0x8D); /* 0x8D /r */ 7470 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7471 ins_pipe(ialu_reg_reg); 7472 %} 7473 7474 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7475 %{ 7476 match(Set dst (AddP dst src)); 7477 effect(KILL cr); 7478 7479 format %{ "addq $dst, $src\t# ptr" %} 7480 opcode(0x03); 7481 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7482 ins_pipe(ialu_reg_reg); 7483 %} 7484 7485 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7486 %{ 7487 match(Set dst (AddP dst src)); 7488 effect(KILL cr); 7489 7490 format %{ "addq $dst, $src\t# ptr" %} 7491 opcode(0x81, 0x00); /* /0 id */ 7492 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7493 ins_pipe( ialu_reg ); 7494 %} 7495 7496 // XXX addP mem ops ???? 7497 7498 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7499 %{ 7500 match(Set dst (AddP src0 src1)); 7501 7502 ins_cost(110); 7503 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7504 opcode(0x8D); /* 0x8D /r */ 7505 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7506 ins_pipe(ialu_reg_reg); 7507 %} 7508 7509 instruct checkCastPP(rRegP dst) 7510 %{ 7511 match(Set dst (CheckCastPP dst)); 7512 7513 size(0); 7514 format %{ "# checkcastPP of $dst" %} 7515 ins_encode(/* empty encoding */); 7516 ins_pipe(empty); 7517 %} 7518 7519 instruct castPP(rRegP dst) 7520 %{ 7521 match(Set dst (CastPP dst)); 7522 7523 size(0); 7524 format %{ "# castPP of $dst" %} 7525 ins_encode(/* empty encoding */); 7526 ins_pipe(empty); 7527 %} 7528 7529 instruct castII(rRegI dst) 7530 %{ 7531 match(Set dst (CastII dst)); 7532 7533 size(0); 7534 format %{ "# castII of $dst" %} 7535 ins_encode(/* empty encoding */); 7536 ins_cost(0); 7537 ins_pipe(empty); 7538 %} 7539 7540 instruct castLL(rRegL dst) 7541 %{ 7542 match(Set dst (CastLL dst)); 7543 7544 size(0); 7545 format %{ "# castLL of $dst" %} 7546 ins_encode(/* empty encoding */); 7547 ins_cost(0); 7548 ins_pipe(empty); 7549 %} 7550 7551 // LoadP-locked same as a regular LoadP when used with compare-swap 7552 instruct loadPLocked(rRegP dst, memory mem) 7553 %{ 7554 match(Set dst (LoadPLocked mem)); 7555 7556 ins_cost(125); // XXX 7557 format %{ "movq $dst, $mem\t# ptr locked" %} 7558 opcode(0x8B); 7559 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7560 ins_pipe(ialu_reg_mem); // XXX 7561 %} 7562 7563 // Conditional-store of the updated heap-top. 7564 // Used during allocation of the shared heap. 7565 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7566 7567 instruct storePConditional(memory heap_top_ptr, 7568 rax_RegP oldval, rRegP newval, 7569 rFlagsReg cr) 7570 %{ 7571 predicate(n->as_LoadStore()->barrier_data() == 0); 7572 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7573 7574 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7575 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7576 opcode(0x0F, 0xB1); 7577 ins_encode(lock_prefix, 7578 REX_reg_mem_wide(newval, heap_top_ptr), 7579 OpcP, OpcS, 7580 reg_mem(newval, heap_top_ptr)); 7581 ins_pipe(pipe_cmpxchg); 7582 %} 7583 7584 // Conditional-store of an int value. 7585 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7586 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7587 %{ 7588 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7589 effect(KILL oldval); 7590 7591 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7592 opcode(0x0F, 0xB1); 7593 ins_encode(lock_prefix, 7594 REX_reg_mem(newval, mem), 7595 OpcP, OpcS, 7596 reg_mem(newval, mem)); 7597 ins_pipe(pipe_cmpxchg); 7598 %} 7599 7600 // Conditional-store of a long value. 7601 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7602 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7603 %{ 7604 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7605 effect(KILL oldval); 7606 7607 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7608 opcode(0x0F, 0xB1); 7609 ins_encode(lock_prefix, 7610 REX_reg_mem_wide(newval, mem), 7611 OpcP, OpcS, 7612 reg_mem(newval, mem)); 7613 ins_pipe(pipe_cmpxchg); 7614 %} 7615 7616 7617 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7618 instruct compareAndSwapP(rRegI res, 7619 memory mem_ptr, 7620 rax_RegP oldval, rRegP newval, 7621 rFlagsReg cr) 7622 %{ 7623 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0); 7624 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7625 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7626 effect(KILL cr, KILL oldval); 7627 7628 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7629 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7630 "sete $res\n\t" 7631 "movzbl $res, $res" %} 7632 opcode(0x0F, 0xB1); 7633 ins_encode(lock_prefix, 7634 REX_reg_mem_wide(newval, mem_ptr), 7635 OpcP, OpcS, 7636 reg_mem(newval, mem_ptr), 7637 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7638 REX_reg_breg(res, res), // movzbl 7639 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7640 ins_pipe( pipe_cmpxchg ); 7641 %} 7642 7643 instruct compareAndSwapL(rRegI res, 7644 memory mem_ptr, 7645 rax_RegL oldval, rRegL newval, 7646 rFlagsReg cr) 7647 %{ 7648 predicate(VM_Version::supports_cx8()); 7649 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7650 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7651 effect(KILL cr, KILL oldval); 7652 7653 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7654 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7655 "sete $res\n\t" 7656 "movzbl $res, $res" %} 7657 opcode(0x0F, 0xB1); 7658 ins_encode(lock_prefix, 7659 REX_reg_mem_wide(newval, mem_ptr), 7660 OpcP, OpcS, 7661 reg_mem(newval, mem_ptr), 7662 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7663 REX_reg_breg(res, res), // movzbl 7664 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7665 ins_pipe( pipe_cmpxchg ); 7666 %} 7667 7668 instruct compareAndSwapI(rRegI res, 7669 memory mem_ptr, 7670 rax_RegI oldval, rRegI newval, 7671 rFlagsReg cr) 7672 %{ 7673 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7674 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7675 effect(KILL cr, KILL oldval); 7676 7677 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7678 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7679 "sete $res\n\t" 7680 "movzbl $res, $res" %} 7681 opcode(0x0F, 0xB1); 7682 ins_encode(lock_prefix, 7683 REX_reg_mem(newval, mem_ptr), 7684 OpcP, OpcS, 7685 reg_mem(newval, mem_ptr), 7686 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7687 REX_reg_breg(res, res), // movzbl 7688 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7689 ins_pipe( pipe_cmpxchg ); 7690 %} 7691 7692 instruct compareAndSwapB(rRegI res, 7693 memory mem_ptr, 7694 rax_RegI oldval, rRegI newval, 7695 rFlagsReg cr) 7696 %{ 7697 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7698 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7699 effect(KILL cr, KILL oldval); 7700 7701 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7702 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7703 "sete $res\n\t" 7704 "movzbl $res, $res" %} 7705 opcode(0x0F, 0xB0); 7706 ins_encode(lock_prefix, 7707 REX_breg_mem(newval, mem_ptr), 7708 OpcP, OpcS, 7709 reg_mem(newval, mem_ptr), 7710 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7711 REX_reg_breg(res, res), // movzbl 7712 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7713 ins_pipe( pipe_cmpxchg ); 7714 %} 7715 7716 instruct compareAndSwapS(rRegI res, 7717 memory mem_ptr, 7718 rax_RegI oldval, rRegI newval, 7719 rFlagsReg cr) 7720 %{ 7721 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7722 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7723 effect(KILL cr, KILL oldval); 7724 7725 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7726 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7727 "sete $res\n\t" 7728 "movzbl $res, $res" %} 7729 opcode(0x0F, 0xB1); 7730 ins_encode(lock_prefix, 7731 SizePrefix, 7732 REX_reg_mem(newval, mem_ptr), 7733 OpcP, OpcS, 7734 reg_mem(newval, mem_ptr), 7735 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7736 REX_reg_breg(res, res), // movzbl 7737 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7738 ins_pipe( pipe_cmpxchg ); 7739 %} 7740 7741 instruct compareAndSwapN(rRegI res, 7742 memory mem_ptr, 7743 rax_RegN oldval, rRegN newval, 7744 rFlagsReg cr) %{ 7745 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7746 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7747 effect(KILL cr, KILL oldval); 7748 7749 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7750 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7751 "sete $res\n\t" 7752 "movzbl $res, $res" %} 7753 opcode(0x0F, 0xB1); 7754 ins_encode(lock_prefix, 7755 REX_reg_mem(newval, mem_ptr), 7756 OpcP, OpcS, 7757 reg_mem(newval, mem_ptr), 7758 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7759 REX_reg_breg(res, res), // movzbl 7760 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7761 ins_pipe( pipe_cmpxchg ); 7762 %} 7763 7764 instruct compareAndExchangeB( 7765 memory mem_ptr, 7766 rax_RegI oldval, rRegI newval, 7767 rFlagsReg cr) 7768 %{ 7769 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7770 effect(KILL cr); 7771 7772 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7773 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7774 opcode(0x0F, 0xB0); 7775 ins_encode(lock_prefix, 7776 REX_breg_mem(newval, mem_ptr), 7777 OpcP, OpcS, 7778 reg_mem(newval, mem_ptr) // lock cmpxchg 7779 ); 7780 ins_pipe( pipe_cmpxchg ); 7781 %} 7782 7783 instruct compareAndExchangeS( 7784 memory mem_ptr, 7785 rax_RegI oldval, rRegI newval, 7786 rFlagsReg cr) 7787 %{ 7788 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7789 effect(KILL cr); 7790 7791 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7792 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7793 opcode(0x0F, 0xB1); 7794 ins_encode(lock_prefix, 7795 SizePrefix, 7796 REX_reg_mem(newval, mem_ptr), 7797 OpcP, OpcS, 7798 reg_mem(newval, mem_ptr) // lock cmpxchg 7799 ); 7800 ins_pipe( pipe_cmpxchg ); 7801 %} 7802 7803 instruct compareAndExchangeI( 7804 memory mem_ptr, 7805 rax_RegI oldval, rRegI newval, 7806 rFlagsReg cr) 7807 %{ 7808 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7809 effect(KILL cr); 7810 7811 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7812 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7813 opcode(0x0F, 0xB1); 7814 ins_encode(lock_prefix, 7815 REX_reg_mem(newval, mem_ptr), 7816 OpcP, OpcS, 7817 reg_mem(newval, mem_ptr) // lock cmpxchg 7818 ); 7819 ins_pipe( pipe_cmpxchg ); 7820 %} 7821 7822 instruct compareAndExchangeL( 7823 memory mem_ptr, 7824 rax_RegL oldval, rRegL newval, 7825 rFlagsReg cr) 7826 %{ 7827 predicate(VM_Version::supports_cx8()); 7828 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7829 effect(KILL cr); 7830 7831 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7832 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7833 opcode(0x0F, 0xB1); 7834 ins_encode(lock_prefix, 7835 REX_reg_mem_wide(newval, mem_ptr), 7836 OpcP, OpcS, 7837 reg_mem(newval, mem_ptr) // lock cmpxchg 7838 ); 7839 ins_pipe( pipe_cmpxchg ); 7840 %} 7841 7842 instruct compareAndExchangeN( 7843 memory mem_ptr, 7844 rax_RegN oldval, rRegN newval, 7845 rFlagsReg cr) %{ 7846 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7847 effect(KILL cr); 7848 7849 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7850 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7851 opcode(0x0F, 0xB1); 7852 ins_encode(lock_prefix, 7853 REX_reg_mem(newval, mem_ptr), 7854 OpcP, OpcS, 7855 reg_mem(newval, mem_ptr) // lock cmpxchg 7856 ); 7857 ins_pipe( pipe_cmpxchg ); 7858 %} 7859 7860 instruct compareAndExchangeP( 7861 memory mem_ptr, 7862 rax_RegP oldval, rRegP newval, 7863 rFlagsReg cr) 7864 %{ 7865 predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0); 7866 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7867 effect(KILL cr); 7868 7869 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7870 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7871 opcode(0x0F, 0xB1); 7872 ins_encode(lock_prefix, 7873 REX_reg_mem_wide(newval, mem_ptr), 7874 OpcP, OpcS, 7875 reg_mem(newval, mem_ptr) // lock cmpxchg 7876 ); 7877 ins_pipe( pipe_cmpxchg ); 7878 %} 7879 7880 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7881 predicate(n->as_LoadStore()->result_not_used()); 7882 match(Set dummy (GetAndAddB mem add)); 7883 effect(KILL cr); 7884 format %{ "ADDB [$mem],$add" %} 7885 ins_encode %{ 7886 __ lock(); 7887 __ addb($mem$$Address, $add$$constant); 7888 %} 7889 ins_pipe( pipe_cmpxchg ); 7890 %} 7891 7892 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7893 match(Set newval (GetAndAddB mem newval)); 7894 effect(KILL cr); 7895 format %{ "XADDB [$mem],$newval" %} 7896 ins_encode %{ 7897 __ lock(); 7898 __ xaddb($mem$$Address, $newval$$Register); 7899 %} 7900 ins_pipe( pipe_cmpxchg ); 7901 %} 7902 7903 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7904 predicate(n->as_LoadStore()->result_not_used()); 7905 match(Set dummy (GetAndAddS mem add)); 7906 effect(KILL cr); 7907 format %{ "ADDW [$mem],$add" %} 7908 ins_encode %{ 7909 __ lock(); 7910 __ addw($mem$$Address, $add$$constant); 7911 %} 7912 ins_pipe( pipe_cmpxchg ); 7913 %} 7914 7915 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7916 match(Set newval (GetAndAddS mem newval)); 7917 effect(KILL cr); 7918 format %{ "XADDW [$mem],$newval" %} 7919 ins_encode %{ 7920 __ lock(); 7921 __ xaddw($mem$$Address, $newval$$Register); 7922 %} 7923 ins_pipe( pipe_cmpxchg ); 7924 %} 7925 7926 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7927 predicate(n->as_LoadStore()->result_not_used()); 7928 match(Set dummy (GetAndAddI mem add)); 7929 effect(KILL cr); 7930 format %{ "ADDL [$mem],$add" %} 7931 ins_encode %{ 7932 __ lock(); 7933 __ addl($mem$$Address, $add$$constant); 7934 %} 7935 ins_pipe( pipe_cmpxchg ); 7936 %} 7937 7938 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7939 match(Set newval (GetAndAddI mem newval)); 7940 effect(KILL cr); 7941 format %{ "XADDL [$mem],$newval" %} 7942 ins_encode %{ 7943 __ lock(); 7944 __ xaddl($mem$$Address, $newval$$Register); 7945 %} 7946 ins_pipe( pipe_cmpxchg ); 7947 %} 7948 7949 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7950 predicate(n->as_LoadStore()->result_not_used()); 7951 match(Set dummy (GetAndAddL mem add)); 7952 effect(KILL cr); 7953 format %{ "ADDQ [$mem],$add" %} 7954 ins_encode %{ 7955 __ lock(); 7956 __ addq($mem$$Address, $add$$constant); 7957 %} 7958 ins_pipe( pipe_cmpxchg ); 7959 %} 7960 7961 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7962 match(Set newval (GetAndAddL mem newval)); 7963 effect(KILL cr); 7964 format %{ "XADDQ [$mem],$newval" %} 7965 ins_encode %{ 7966 __ lock(); 7967 __ xaddq($mem$$Address, $newval$$Register); 7968 %} 7969 ins_pipe( pipe_cmpxchg ); 7970 %} 7971 7972 instruct xchgB( memory mem, rRegI newval) %{ 7973 match(Set newval (GetAndSetB mem newval)); 7974 format %{ "XCHGB $newval,[$mem]" %} 7975 ins_encode %{ 7976 __ xchgb($newval$$Register, $mem$$Address); 7977 %} 7978 ins_pipe( pipe_cmpxchg ); 7979 %} 7980 7981 instruct xchgS( memory mem, rRegI newval) %{ 7982 match(Set newval (GetAndSetS mem newval)); 7983 format %{ "XCHGW $newval,[$mem]" %} 7984 ins_encode %{ 7985 __ xchgw($newval$$Register, $mem$$Address); 7986 %} 7987 ins_pipe( pipe_cmpxchg ); 7988 %} 7989 7990 instruct xchgI( memory mem, rRegI newval) %{ 7991 match(Set newval (GetAndSetI mem newval)); 7992 format %{ "XCHGL $newval,[$mem]" %} 7993 ins_encode %{ 7994 __ xchgl($newval$$Register, $mem$$Address); 7995 %} 7996 ins_pipe( pipe_cmpxchg ); 7997 %} 7998 7999 instruct xchgL( memory mem, rRegL newval) %{ 8000 match(Set newval (GetAndSetL mem newval)); 8001 format %{ "XCHGL $newval,[$mem]" %} 8002 ins_encode %{ 8003 __ xchgq($newval$$Register, $mem$$Address); 8004 %} 8005 ins_pipe( pipe_cmpxchg ); 8006 %} 8007 8008 instruct xchgP( memory mem, rRegP newval) %{ 8009 match(Set newval (GetAndSetP mem newval)); 8010 predicate(n->as_LoadStore()->barrier_data() == 0); 8011 format %{ "XCHGQ $newval,[$mem]" %} 8012 ins_encode %{ 8013 __ xchgq($newval$$Register, $mem$$Address); 8014 %} 8015 ins_pipe( pipe_cmpxchg ); 8016 %} 8017 8018 instruct xchgN( memory mem, rRegN newval) %{ 8019 match(Set newval (GetAndSetN mem newval)); 8020 format %{ "XCHGL $newval,$mem]" %} 8021 ins_encode %{ 8022 __ xchgl($newval$$Register, $mem$$Address); 8023 %} 8024 ins_pipe( pipe_cmpxchg ); 8025 %} 8026 8027 //----------Abs Instructions------------------------------------------- 8028 8029 // Integer Absolute Instructions 8030 instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr) 8031 %{ 8032 match(Set dst (AbsI src)); 8033 effect(TEMP dst, TEMP tmp, KILL cr); 8034 format %{ "movl $tmp, $src\n\t" 8035 "sarl $tmp, 31\n\t" 8036 "movl $dst, $src\n\t" 8037 "xorl $dst, $tmp\n\t" 8038 "subl $dst, $tmp\n" 8039 %} 8040 ins_encode %{ 8041 __ movl($tmp$$Register, $src$$Register); 8042 __ sarl($tmp$$Register, 31); 8043 __ movl($dst$$Register, $src$$Register); 8044 __ xorl($dst$$Register, $tmp$$Register); 8045 __ subl($dst$$Register, $tmp$$Register); 8046 %} 8047 8048 ins_pipe(ialu_reg_reg); 8049 %} 8050 8051 // Long Absolute Instructions 8052 instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr) 8053 %{ 8054 match(Set dst (AbsL src)); 8055 effect(TEMP dst, TEMP tmp, KILL cr); 8056 format %{ "movq $tmp, $src\n\t" 8057 "sarq $tmp, 63\n\t" 8058 "movq $dst, $src\n\t" 8059 "xorq $dst, $tmp\n\t" 8060 "subq $dst, $tmp\n" 8061 %} 8062 ins_encode %{ 8063 __ movq($tmp$$Register, $src$$Register); 8064 __ sarq($tmp$$Register, 63); 8065 __ movq($dst$$Register, $src$$Register); 8066 __ xorq($dst$$Register, $tmp$$Register); 8067 __ subq($dst$$Register, $tmp$$Register); 8068 %} 8069 8070 ins_pipe(ialu_reg_reg); 8071 %} 8072 8073 //----------Subtraction Instructions------------------------------------------- 8074 8075 // Integer Subtraction Instructions 8076 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8077 %{ 8078 match(Set dst (SubI dst src)); 8079 effect(KILL cr); 8080 8081 format %{ "subl $dst, $src\t# int" %} 8082 opcode(0x2B); 8083 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8084 ins_pipe(ialu_reg_reg); 8085 %} 8086 8087 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8088 %{ 8089 match(Set dst (SubI dst src)); 8090 effect(KILL cr); 8091 8092 format %{ "subl $dst, $src\t# int" %} 8093 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8094 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8095 ins_pipe(ialu_reg); 8096 %} 8097 8098 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8099 %{ 8100 match(Set dst (SubI dst (LoadI src))); 8101 effect(KILL cr); 8102 8103 ins_cost(125); 8104 format %{ "subl $dst, $src\t# int" %} 8105 opcode(0x2B); 8106 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8107 ins_pipe(ialu_reg_mem); 8108 %} 8109 8110 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8111 %{ 8112 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8113 effect(KILL cr); 8114 8115 ins_cost(150); 8116 format %{ "subl $dst, $src\t# int" %} 8117 opcode(0x29); /* Opcode 29 /r */ 8118 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8119 ins_pipe(ialu_mem_reg); 8120 %} 8121 8122 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8123 %{ 8124 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8125 effect(KILL cr); 8126 8127 ins_cost(125); // XXX 8128 format %{ "subl $dst, $src\t# int" %} 8129 opcode(0x81); /* Opcode 81 /5 id */ 8130 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8131 ins_pipe(ialu_mem_imm); 8132 %} 8133 8134 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8135 %{ 8136 match(Set dst (SubL dst src)); 8137 effect(KILL cr); 8138 8139 format %{ "subq $dst, $src\t# long" %} 8140 opcode(0x2B); 8141 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8142 ins_pipe(ialu_reg_reg); 8143 %} 8144 8145 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8146 %{ 8147 match(Set dst (SubL dst src)); 8148 effect(KILL cr); 8149 8150 format %{ "subq $dst, $src\t# long" %} 8151 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8152 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8153 ins_pipe(ialu_reg); 8154 %} 8155 8156 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8157 %{ 8158 match(Set dst (SubL dst (LoadL src))); 8159 effect(KILL cr); 8160 8161 ins_cost(125); 8162 format %{ "subq $dst, $src\t# long" %} 8163 opcode(0x2B); 8164 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8165 ins_pipe(ialu_reg_mem); 8166 %} 8167 8168 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8169 %{ 8170 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8171 effect(KILL cr); 8172 8173 ins_cost(150); 8174 format %{ "subq $dst, $src\t# long" %} 8175 opcode(0x29); /* Opcode 29 /r */ 8176 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8177 ins_pipe(ialu_mem_reg); 8178 %} 8179 8180 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8181 %{ 8182 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8183 effect(KILL cr); 8184 8185 ins_cost(125); // XXX 8186 format %{ "subq $dst, $src\t# long" %} 8187 opcode(0x81); /* Opcode 81 /5 id */ 8188 ins_encode(REX_mem_wide(dst), 8189 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8190 ins_pipe(ialu_mem_imm); 8191 %} 8192 8193 // Subtract from a pointer 8194 // XXX hmpf??? 8195 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8196 %{ 8197 match(Set dst (AddP dst (SubI zero src))); 8198 effect(KILL cr); 8199 8200 format %{ "subq $dst, $src\t# ptr - int" %} 8201 opcode(0x2B); 8202 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8203 ins_pipe(ialu_reg_reg); 8204 %} 8205 8206 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8207 %{ 8208 match(Set dst (SubI zero dst)); 8209 effect(KILL cr); 8210 8211 format %{ "negl $dst\t# int" %} 8212 opcode(0xF7, 0x03); // Opcode F7 /3 8213 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8214 ins_pipe(ialu_reg); 8215 %} 8216 8217 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8218 %{ 8219 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8220 effect(KILL cr); 8221 8222 format %{ "negl $dst\t# int" %} 8223 opcode(0xF7, 0x03); // Opcode F7 /3 8224 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8225 ins_pipe(ialu_reg); 8226 %} 8227 8228 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8229 %{ 8230 match(Set dst (SubL zero dst)); 8231 effect(KILL cr); 8232 8233 format %{ "negq $dst\t# long" %} 8234 opcode(0xF7, 0x03); // Opcode F7 /3 8235 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8236 ins_pipe(ialu_reg); 8237 %} 8238 8239 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8240 %{ 8241 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8242 effect(KILL cr); 8243 8244 format %{ "negq $dst\t# long" %} 8245 opcode(0xF7, 0x03); // Opcode F7 /3 8246 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8247 ins_pipe(ialu_reg); 8248 %} 8249 8250 //----------Multiplication/Division Instructions------------------------------- 8251 // Integer Multiplication Instructions 8252 // Multiply Register 8253 8254 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8255 %{ 8256 match(Set dst (MulI dst src)); 8257 effect(KILL cr); 8258 8259 ins_cost(300); 8260 format %{ "imull $dst, $src\t# int" %} 8261 opcode(0x0F, 0xAF); 8262 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8263 ins_pipe(ialu_reg_reg_alu0); 8264 %} 8265 8266 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8267 %{ 8268 match(Set dst (MulI src imm)); 8269 effect(KILL cr); 8270 8271 ins_cost(300); 8272 format %{ "imull $dst, $src, $imm\t# int" %} 8273 opcode(0x69); /* 69 /r id */ 8274 ins_encode(REX_reg_reg(dst, src), 8275 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8276 ins_pipe(ialu_reg_reg_alu0); 8277 %} 8278 8279 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8280 %{ 8281 match(Set dst (MulI dst (LoadI src))); 8282 effect(KILL cr); 8283 8284 ins_cost(350); 8285 format %{ "imull $dst, $src\t# int" %} 8286 opcode(0x0F, 0xAF); 8287 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8288 ins_pipe(ialu_reg_mem_alu0); 8289 %} 8290 8291 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8292 %{ 8293 match(Set dst (MulI (LoadI src) imm)); 8294 effect(KILL cr); 8295 8296 ins_cost(300); 8297 format %{ "imull $dst, $src, $imm\t# int" %} 8298 opcode(0x69); /* 69 /r id */ 8299 ins_encode(REX_reg_mem(dst, src), 8300 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8301 ins_pipe(ialu_reg_mem_alu0); 8302 %} 8303 8304 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8305 %{ 8306 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8307 effect(KILL cr, KILL src2); 8308 8309 expand %{ mulI_rReg(dst, src1, cr); 8310 mulI_rReg(src2, src3, cr); 8311 addI_rReg(dst, src2, cr); %} 8312 %} 8313 8314 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8315 %{ 8316 match(Set dst (MulL dst src)); 8317 effect(KILL cr); 8318 8319 ins_cost(300); 8320 format %{ "imulq $dst, $src\t# long" %} 8321 opcode(0x0F, 0xAF); 8322 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8323 ins_pipe(ialu_reg_reg_alu0); 8324 %} 8325 8326 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8327 %{ 8328 match(Set dst (MulL src imm)); 8329 effect(KILL cr); 8330 8331 ins_cost(300); 8332 format %{ "imulq $dst, $src, $imm\t# long" %} 8333 opcode(0x69); /* 69 /r id */ 8334 ins_encode(REX_reg_reg_wide(dst, src), 8335 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8336 ins_pipe(ialu_reg_reg_alu0); 8337 %} 8338 8339 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8340 %{ 8341 match(Set dst (MulL dst (LoadL src))); 8342 effect(KILL cr); 8343 8344 ins_cost(350); 8345 format %{ "imulq $dst, $src\t# long" %} 8346 opcode(0x0F, 0xAF); 8347 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8348 ins_pipe(ialu_reg_mem_alu0); 8349 %} 8350 8351 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8352 %{ 8353 match(Set dst (MulL (LoadL src) imm)); 8354 effect(KILL cr); 8355 8356 ins_cost(300); 8357 format %{ "imulq $dst, $src, $imm\t# long" %} 8358 opcode(0x69); /* 69 /r id */ 8359 ins_encode(REX_reg_mem_wide(dst, src), 8360 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8361 ins_pipe(ialu_reg_mem_alu0); 8362 %} 8363 8364 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8365 %{ 8366 match(Set dst (MulHiL src rax)); 8367 effect(USE_KILL rax, KILL cr); 8368 8369 ins_cost(300); 8370 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8371 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8372 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8373 ins_pipe(ialu_reg_reg_alu0); 8374 %} 8375 8376 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8377 rFlagsReg cr) 8378 %{ 8379 match(Set rax (DivI rax div)); 8380 effect(KILL rdx, KILL cr); 8381 8382 ins_cost(30*100+10*100); // XXX 8383 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8384 "jne,s normal\n\t" 8385 "xorl rdx, rdx\n\t" 8386 "cmpl $div, -1\n\t" 8387 "je,s done\n" 8388 "normal: cdql\n\t" 8389 "idivl $div\n" 8390 "done:" %} 8391 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8392 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8393 ins_pipe(ialu_reg_reg_alu0); 8394 %} 8395 8396 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8397 rFlagsReg cr) 8398 %{ 8399 match(Set rax (DivL rax div)); 8400 effect(KILL rdx, KILL cr); 8401 8402 ins_cost(30*100+10*100); // XXX 8403 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8404 "cmpq rax, rdx\n\t" 8405 "jne,s normal\n\t" 8406 "xorl rdx, rdx\n\t" 8407 "cmpq $div, -1\n\t" 8408 "je,s done\n" 8409 "normal: cdqq\n\t" 8410 "idivq $div\n" 8411 "done:" %} 8412 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8413 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8414 ins_pipe(ialu_reg_reg_alu0); 8415 %} 8416 8417 // Integer DIVMOD with Register, both quotient and mod results 8418 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8419 rFlagsReg cr) 8420 %{ 8421 match(DivModI rax div); 8422 effect(KILL cr); 8423 8424 ins_cost(30*100+10*100); // XXX 8425 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8426 "jne,s normal\n\t" 8427 "xorl rdx, rdx\n\t" 8428 "cmpl $div, -1\n\t" 8429 "je,s done\n" 8430 "normal: cdql\n\t" 8431 "idivl $div\n" 8432 "done:" %} 8433 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8434 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8435 ins_pipe(pipe_slow); 8436 %} 8437 8438 // Long DIVMOD with Register, both quotient and mod results 8439 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8440 rFlagsReg cr) 8441 %{ 8442 match(DivModL rax div); 8443 effect(KILL cr); 8444 8445 ins_cost(30*100+10*100); // XXX 8446 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8447 "cmpq rax, rdx\n\t" 8448 "jne,s normal\n\t" 8449 "xorl rdx, rdx\n\t" 8450 "cmpq $div, -1\n\t" 8451 "je,s done\n" 8452 "normal: cdqq\n\t" 8453 "idivq $div\n" 8454 "done:" %} 8455 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8456 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8457 ins_pipe(pipe_slow); 8458 %} 8459 8460 //----------- DivL-By-Constant-Expansions-------------------------------------- 8461 // DivI cases are handled by the compiler 8462 8463 // Magic constant, reciprocal of 10 8464 instruct loadConL_0x6666666666666667(rRegL dst) 8465 %{ 8466 effect(DEF dst); 8467 8468 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8469 ins_encode(load_immL(dst, 0x6666666666666667)); 8470 ins_pipe(ialu_reg); 8471 %} 8472 8473 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8474 %{ 8475 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8476 8477 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8478 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8479 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8480 ins_pipe(ialu_reg_reg_alu0); 8481 %} 8482 8483 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8484 %{ 8485 effect(USE_DEF dst, KILL cr); 8486 8487 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8488 opcode(0xC1, 0x7); /* C1 /7 ib */ 8489 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8490 ins_pipe(ialu_reg); 8491 %} 8492 8493 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8494 %{ 8495 effect(USE_DEF dst, KILL cr); 8496 8497 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8498 opcode(0xC1, 0x7); /* C1 /7 ib */ 8499 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8500 ins_pipe(ialu_reg); 8501 %} 8502 8503 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8504 %{ 8505 match(Set dst (DivL src div)); 8506 8507 ins_cost((5+8)*100); 8508 expand %{ 8509 rax_RegL rax; // Killed temp 8510 rFlagsReg cr; // Killed 8511 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8512 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8513 sarL_rReg_63(src, cr); // sarq src, 63 8514 sarL_rReg_2(dst, cr); // sarq rdx, 2 8515 subL_rReg(dst, src, cr); // subl rdx, src 8516 %} 8517 %} 8518 8519 //----------------------------------------------------------------------------- 8520 8521 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8522 rFlagsReg cr) 8523 %{ 8524 match(Set rdx (ModI rax div)); 8525 effect(KILL rax, KILL cr); 8526 8527 ins_cost(300); // XXX 8528 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8529 "jne,s normal\n\t" 8530 "xorl rdx, rdx\n\t" 8531 "cmpl $div, -1\n\t" 8532 "je,s done\n" 8533 "normal: cdql\n\t" 8534 "idivl $div\n" 8535 "done:" %} 8536 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8537 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8538 ins_pipe(ialu_reg_reg_alu0); 8539 %} 8540 8541 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8542 rFlagsReg cr) 8543 %{ 8544 match(Set rdx (ModL rax div)); 8545 effect(KILL rax, KILL cr); 8546 8547 ins_cost(300); // XXX 8548 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8549 "cmpq rax, rdx\n\t" 8550 "jne,s normal\n\t" 8551 "xorl rdx, rdx\n\t" 8552 "cmpq $div, -1\n\t" 8553 "je,s done\n" 8554 "normal: cdqq\n\t" 8555 "idivq $div\n" 8556 "done:" %} 8557 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8558 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8559 ins_pipe(ialu_reg_reg_alu0); 8560 %} 8561 8562 // Integer Shift Instructions 8563 // Shift Left by one 8564 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8565 %{ 8566 match(Set dst (LShiftI dst shift)); 8567 effect(KILL cr); 8568 8569 format %{ "sall $dst, $shift" %} 8570 opcode(0xD1, 0x4); /* D1 /4 */ 8571 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8572 ins_pipe(ialu_reg); 8573 %} 8574 8575 // Shift Left by one 8576 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8577 %{ 8578 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8579 effect(KILL cr); 8580 8581 format %{ "sall $dst, $shift\t" %} 8582 opcode(0xD1, 0x4); /* D1 /4 */ 8583 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8584 ins_pipe(ialu_mem_imm); 8585 %} 8586 8587 // Shift Left by 8-bit immediate 8588 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8589 %{ 8590 match(Set dst (LShiftI dst shift)); 8591 effect(KILL cr); 8592 8593 format %{ "sall $dst, $shift" %} 8594 opcode(0xC1, 0x4); /* C1 /4 ib */ 8595 ins_encode(reg_opc_imm(dst, shift)); 8596 ins_pipe(ialu_reg); 8597 %} 8598 8599 // Shift Left by 8-bit immediate 8600 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8601 %{ 8602 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8603 effect(KILL cr); 8604 8605 format %{ "sall $dst, $shift" %} 8606 opcode(0xC1, 0x4); /* C1 /4 ib */ 8607 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8608 ins_pipe(ialu_mem_imm); 8609 %} 8610 8611 // Shift Left by variable 8612 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8613 %{ 8614 match(Set dst (LShiftI dst shift)); 8615 effect(KILL cr); 8616 8617 format %{ "sall $dst, $shift" %} 8618 opcode(0xD3, 0x4); /* D3 /4 */ 8619 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8620 ins_pipe(ialu_reg_reg); 8621 %} 8622 8623 // Shift Left by variable 8624 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8625 %{ 8626 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8627 effect(KILL cr); 8628 8629 format %{ "sall $dst, $shift" %} 8630 opcode(0xD3, 0x4); /* D3 /4 */ 8631 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8632 ins_pipe(ialu_mem_reg); 8633 %} 8634 8635 // Arithmetic shift right by one 8636 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8637 %{ 8638 match(Set dst (RShiftI dst shift)); 8639 effect(KILL cr); 8640 8641 format %{ "sarl $dst, $shift" %} 8642 opcode(0xD1, 0x7); /* D1 /7 */ 8643 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8644 ins_pipe(ialu_reg); 8645 %} 8646 8647 // Arithmetic shift right by one 8648 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8649 %{ 8650 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8651 effect(KILL cr); 8652 8653 format %{ "sarl $dst, $shift" %} 8654 opcode(0xD1, 0x7); /* D1 /7 */ 8655 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8656 ins_pipe(ialu_mem_imm); 8657 %} 8658 8659 // Arithmetic Shift Right by 8-bit immediate 8660 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8661 %{ 8662 match(Set dst (RShiftI dst shift)); 8663 effect(KILL cr); 8664 8665 format %{ "sarl $dst, $shift" %} 8666 opcode(0xC1, 0x7); /* C1 /7 ib */ 8667 ins_encode(reg_opc_imm(dst, shift)); 8668 ins_pipe(ialu_mem_imm); 8669 %} 8670 8671 // Arithmetic Shift Right by 8-bit immediate 8672 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8673 %{ 8674 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8675 effect(KILL cr); 8676 8677 format %{ "sarl $dst, $shift" %} 8678 opcode(0xC1, 0x7); /* C1 /7 ib */ 8679 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8680 ins_pipe(ialu_mem_imm); 8681 %} 8682 8683 // Arithmetic Shift Right by variable 8684 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8685 %{ 8686 match(Set dst (RShiftI dst shift)); 8687 effect(KILL cr); 8688 8689 format %{ "sarl $dst, $shift" %} 8690 opcode(0xD3, 0x7); /* D3 /7 */ 8691 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8692 ins_pipe(ialu_reg_reg); 8693 %} 8694 8695 // Arithmetic Shift Right by variable 8696 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8697 %{ 8698 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8699 effect(KILL cr); 8700 8701 format %{ "sarl $dst, $shift" %} 8702 opcode(0xD3, 0x7); /* D3 /7 */ 8703 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8704 ins_pipe(ialu_mem_reg); 8705 %} 8706 8707 // Logical shift right by one 8708 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8709 %{ 8710 match(Set dst (URShiftI dst shift)); 8711 effect(KILL cr); 8712 8713 format %{ "shrl $dst, $shift" %} 8714 opcode(0xD1, 0x5); /* D1 /5 */ 8715 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8716 ins_pipe(ialu_reg); 8717 %} 8718 8719 // Logical shift right by one 8720 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8721 %{ 8722 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8723 effect(KILL cr); 8724 8725 format %{ "shrl $dst, $shift" %} 8726 opcode(0xD1, 0x5); /* D1 /5 */ 8727 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8728 ins_pipe(ialu_mem_imm); 8729 %} 8730 8731 // Logical Shift Right by 8-bit immediate 8732 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8733 %{ 8734 match(Set dst (URShiftI dst shift)); 8735 effect(KILL cr); 8736 8737 format %{ "shrl $dst, $shift" %} 8738 opcode(0xC1, 0x5); /* C1 /5 ib */ 8739 ins_encode(reg_opc_imm(dst, shift)); 8740 ins_pipe(ialu_reg); 8741 %} 8742 8743 // Logical Shift Right by 8-bit immediate 8744 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8745 %{ 8746 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8747 effect(KILL cr); 8748 8749 format %{ "shrl $dst, $shift" %} 8750 opcode(0xC1, 0x5); /* C1 /5 ib */ 8751 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8752 ins_pipe(ialu_mem_imm); 8753 %} 8754 8755 // Logical Shift Right by variable 8756 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8757 %{ 8758 match(Set dst (URShiftI dst shift)); 8759 effect(KILL cr); 8760 8761 format %{ "shrl $dst, $shift" %} 8762 opcode(0xD3, 0x5); /* D3 /5 */ 8763 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8764 ins_pipe(ialu_reg_reg); 8765 %} 8766 8767 // Logical Shift Right by variable 8768 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8769 %{ 8770 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8771 effect(KILL cr); 8772 8773 format %{ "shrl $dst, $shift" %} 8774 opcode(0xD3, 0x5); /* D3 /5 */ 8775 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8776 ins_pipe(ialu_mem_reg); 8777 %} 8778 8779 // Long Shift Instructions 8780 // Shift Left by one 8781 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8782 %{ 8783 match(Set dst (LShiftL dst shift)); 8784 effect(KILL cr); 8785 8786 format %{ "salq $dst, $shift" %} 8787 opcode(0xD1, 0x4); /* D1 /4 */ 8788 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8789 ins_pipe(ialu_reg); 8790 %} 8791 8792 // Shift Left by one 8793 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8794 %{ 8795 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8796 effect(KILL cr); 8797 8798 format %{ "salq $dst, $shift" %} 8799 opcode(0xD1, 0x4); /* D1 /4 */ 8800 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8801 ins_pipe(ialu_mem_imm); 8802 %} 8803 8804 // Shift Left by 8-bit immediate 8805 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8806 %{ 8807 match(Set dst (LShiftL dst shift)); 8808 effect(KILL cr); 8809 8810 format %{ "salq $dst, $shift" %} 8811 opcode(0xC1, 0x4); /* C1 /4 ib */ 8812 ins_encode(reg_opc_imm_wide(dst, shift)); 8813 ins_pipe(ialu_reg); 8814 %} 8815 8816 // Shift Left by 8-bit immediate 8817 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8818 %{ 8819 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8820 effect(KILL cr); 8821 8822 format %{ "salq $dst, $shift" %} 8823 opcode(0xC1, 0x4); /* C1 /4 ib */ 8824 ins_encode(REX_mem_wide(dst), OpcP, 8825 RM_opc_mem(secondary, dst), Con8or32(shift)); 8826 ins_pipe(ialu_mem_imm); 8827 %} 8828 8829 // Shift Left by variable 8830 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8831 %{ 8832 match(Set dst (LShiftL dst shift)); 8833 effect(KILL cr); 8834 8835 format %{ "salq $dst, $shift" %} 8836 opcode(0xD3, 0x4); /* D3 /4 */ 8837 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8838 ins_pipe(ialu_reg_reg); 8839 %} 8840 8841 // Shift Left by variable 8842 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8843 %{ 8844 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8845 effect(KILL cr); 8846 8847 format %{ "salq $dst, $shift" %} 8848 opcode(0xD3, 0x4); /* D3 /4 */ 8849 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8850 ins_pipe(ialu_mem_reg); 8851 %} 8852 8853 // Arithmetic shift right by one 8854 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8855 %{ 8856 match(Set dst (RShiftL dst shift)); 8857 effect(KILL cr); 8858 8859 format %{ "sarq $dst, $shift" %} 8860 opcode(0xD1, 0x7); /* D1 /7 */ 8861 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8862 ins_pipe(ialu_reg); 8863 %} 8864 8865 // Arithmetic shift right by one 8866 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8867 %{ 8868 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8869 effect(KILL cr); 8870 8871 format %{ "sarq $dst, $shift" %} 8872 opcode(0xD1, 0x7); /* D1 /7 */ 8873 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8874 ins_pipe(ialu_mem_imm); 8875 %} 8876 8877 // Arithmetic Shift Right by 8-bit immediate 8878 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8879 %{ 8880 match(Set dst (RShiftL dst shift)); 8881 effect(KILL cr); 8882 8883 format %{ "sarq $dst, $shift" %} 8884 opcode(0xC1, 0x7); /* C1 /7 ib */ 8885 ins_encode(reg_opc_imm_wide(dst, shift)); 8886 ins_pipe(ialu_mem_imm); 8887 %} 8888 8889 // Arithmetic Shift Right by 8-bit immediate 8890 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8891 %{ 8892 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8893 effect(KILL cr); 8894 8895 format %{ "sarq $dst, $shift" %} 8896 opcode(0xC1, 0x7); /* C1 /7 ib */ 8897 ins_encode(REX_mem_wide(dst), OpcP, 8898 RM_opc_mem(secondary, dst), Con8or32(shift)); 8899 ins_pipe(ialu_mem_imm); 8900 %} 8901 8902 // Arithmetic Shift Right by variable 8903 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8904 %{ 8905 match(Set dst (RShiftL dst shift)); 8906 effect(KILL cr); 8907 8908 format %{ "sarq $dst, $shift" %} 8909 opcode(0xD3, 0x7); /* D3 /7 */ 8910 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8911 ins_pipe(ialu_reg_reg); 8912 %} 8913 8914 // Arithmetic Shift Right by variable 8915 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8916 %{ 8917 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8918 effect(KILL cr); 8919 8920 format %{ "sarq $dst, $shift" %} 8921 opcode(0xD3, 0x7); /* D3 /7 */ 8922 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8923 ins_pipe(ialu_mem_reg); 8924 %} 8925 8926 // Logical shift right by one 8927 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8928 %{ 8929 match(Set dst (URShiftL dst shift)); 8930 effect(KILL cr); 8931 8932 format %{ "shrq $dst, $shift" %} 8933 opcode(0xD1, 0x5); /* D1 /5 */ 8934 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8935 ins_pipe(ialu_reg); 8936 %} 8937 8938 // Logical shift right by one 8939 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8940 %{ 8941 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8942 effect(KILL cr); 8943 8944 format %{ "shrq $dst, $shift" %} 8945 opcode(0xD1, 0x5); /* D1 /5 */ 8946 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8947 ins_pipe(ialu_mem_imm); 8948 %} 8949 8950 // Logical Shift Right by 8-bit immediate 8951 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8952 %{ 8953 match(Set dst (URShiftL dst shift)); 8954 effect(KILL cr); 8955 8956 format %{ "shrq $dst, $shift" %} 8957 opcode(0xC1, 0x5); /* C1 /5 ib */ 8958 ins_encode(reg_opc_imm_wide(dst, shift)); 8959 ins_pipe(ialu_reg); 8960 %} 8961 8962 8963 // Logical Shift Right by 8-bit immediate 8964 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8965 %{ 8966 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8967 effect(KILL cr); 8968 8969 format %{ "shrq $dst, $shift" %} 8970 opcode(0xC1, 0x5); /* C1 /5 ib */ 8971 ins_encode(REX_mem_wide(dst), OpcP, 8972 RM_opc_mem(secondary, dst), Con8or32(shift)); 8973 ins_pipe(ialu_mem_imm); 8974 %} 8975 8976 // Logical Shift Right by variable 8977 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8978 %{ 8979 match(Set dst (URShiftL dst shift)); 8980 effect(KILL cr); 8981 8982 format %{ "shrq $dst, $shift" %} 8983 opcode(0xD3, 0x5); /* D3 /5 */ 8984 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8985 ins_pipe(ialu_reg_reg); 8986 %} 8987 8988 // Logical Shift Right by variable 8989 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8990 %{ 8991 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8992 effect(KILL cr); 8993 8994 format %{ "shrq $dst, $shift" %} 8995 opcode(0xD3, 0x5); /* D3 /5 */ 8996 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8997 ins_pipe(ialu_mem_reg); 8998 %} 8999 9000 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9001 // This idiom is used by the compiler for the i2b bytecode. 9002 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9003 %{ 9004 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9005 9006 format %{ "movsbl $dst, $src\t# i2b" %} 9007 opcode(0x0F, 0xBE); 9008 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9009 ins_pipe(ialu_reg_reg); 9010 %} 9011 9012 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9013 // This idiom is used by the compiler the i2s bytecode. 9014 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9015 %{ 9016 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9017 9018 format %{ "movswl $dst, $src\t# i2s" %} 9019 opcode(0x0F, 0xBF); 9020 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9021 ins_pipe(ialu_reg_reg); 9022 %} 9023 9024 // ROL/ROR instructions 9025 9026 // ROL expand 9027 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9028 effect(KILL cr, USE_DEF dst); 9029 9030 format %{ "roll $dst" %} 9031 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9032 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9033 ins_pipe(ialu_reg); 9034 %} 9035 9036 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9037 effect(USE_DEF dst, USE shift, KILL cr); 9038 9039 format %{ "roll $dst, $shift" %} 9040 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9041 ins_encode( reg_opc_imm(dst, shift) ); 9042 ins_pipe(ialu_reg); 9043 %} 9044 9045 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9046 %{ 9047 effect(USE_DEF dst, USE shift, KILL cr); 9048 9049 format %{ "roll $dst, $shift" %} 9050 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9051 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9052 ins_pipe(ialu_reg_reg); 9053 %} 9054 // end of ROL expand 9055 9056 // Rotate Left by one 9057 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9058 %{ 9059 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9060 9061 expand %{ 9062 rolI_rReg_imm1(dst, cr); 9063 %} 9064 %} 9065 9066 // Rotate Left by 8-bit immediate 9067 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9068 %{ 9069 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9070 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9071 9072 expand %{ 9073 rolI_rReg_imm8(dst, lshift, cr); 9074 %} 9075 %} 9076 9077 // Rotate Left by variable 9078 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9079 %{ 9080 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9081 9082 expand %{ 9083 rolI_rReg_CL(dst, shift, cr); 9084 %} 9085 %} 9086 9087 // Rotate Left by variable 9088 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9089 %{ 9090 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9091 9092 expand %{ 9093 rolI_rReg_CL(dst, shift, cr); 9094 %} 9095 %} 9096 9097 // ROR expand 9098 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9099 %{ 9100 effect(USE_DEF dst, KILL cr); 9101 9102 format %{ "rorl $dst" %} 9103 opcode(0xD1, 0x1); /* D1 /1 */ 9104 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9105 ins_pipe(ialu_reg); 9106 %} 9107 9108 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9109 %{ 9110 effect(USE_DEF dst, USE shift, KILL cr); 9111 9112 format %{ "rorl $dst, $shift" %} 9113 opcode(0xC1, 0x1); /* C1 /1 ib */ 9114 ins_encode(reg_opc_imm(dst, shift)); 9115 ins_pipe(ialu_reg); 9116 %} 9117 9118 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9119 %{ 9120 effect(USE_DEF dst, USE shift, KILL cr); 9121 9122 format %{ "rorl $dst, $shift" %} 9123 opcode(0xD3, 0x1); /* D3 /1 */ 9124 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9125 ins_pipe(ialu_reg_reg); 9126 %} 9127 // end of ROR expand 9128 9129 // Rotate Right by one 9130 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9131 %{ 9132 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9133 9134 expand %{ 9135 rorI_rReg_imm1(dst, cr); 9136 %} 9137 %} 9138 9139 // Rotate Right by 8-bit immediate 9140 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9141 %{ 9142 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9143 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9144 9145 expand %{ 9146 rorI_rReg_imm8(dst, rshift, cr); 9147 %} 9148 %} 9149 9150 // Rotate Right by variable 9151 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9152 %{ 9153 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9154 9155 expand %{ 9156 rorI_rReg_CL(dst, shift, cr); 9157 %} 9158 %} 9159 9160 // Rotate Right by variable 9161 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9162 %{ 9163 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9164 9165 expand %{ 9166 rorI_rReg_CL(dst, shift, cr); 9167 %} 9168 %} 9169 9170 // for long rotate 9171 // ROL expand 9172 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9173 effect(USE_DEF dst, KILL cr); 9174 9175 format %{ "rolq $dst" %} 9176 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9177 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9178 ins_pipe(ialu_reg); 9179 %} 9180 9181 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9182 effect(USE_DEF dst, USE shift, KILL cr); 9183 9184 format %{ "rolq $dst, $shift" %} 9185 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9186 ins_encode( reg_opc_imm_wide(dst, shift) ); 9187 ins_pipe(ialu_reg); 9188 %} 9189 9190 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9191 %{ 9192 effect(USE_DEF dst, USE shift, KILL cr); 9193 9194 format %{ "rolq $dst, $shift" %} 9195 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9196 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9197 ins_pipe(ialu_reg_reg); 9198 %} 9199 // end of ROL expand 9200 9201 // Rotate Left by one 9202 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9203 %{ 9204 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9205 9206 expand %{ 9207 rolL_rReg_imm1(dst, cr); 9208 %} 9209 %} 9210 9211 // Rotate Left by 8-bit immediate 9212 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9213 %{ 9214 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9215 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9216 9217 expand %{ 9218 rolL_rReg_imm8(dst, lshift, cr); 9219 %} 9220 %} 9221 9222 // Rotate Left by variable 9223 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9224 %{ 9225 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9226 9227 expand %{ 9228 rolL_rReg_CL(dst, shift, cr); 9229 %} 9230 %} 9231 9232 // Rotate Left by variable 9233 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9234 %{ 9235 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9236 9237 expand %{ 9238 rolL_rReg_CL(dst, shift, cr); 9239 %} 9240 %} 9241 9242 // ROR expand 9243 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9244 %{ 9245 effect(USE_DEF dst, KILL cr); 9246 9247 format %{ "rorq $dst" %} 9248 opcode(0xD1, 0x1); /* D1 /1 */ 9249 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9250 ins_pipe(ialu_reg); 9251 %} 9252 9253 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9254 %{ 9255 effect(USE_DEF dst, USE shift, KILL cr); 9256 9257 format %{ "rorq $dst, $shift" %} 9258 opcode(0xC1, 0x1); /* C1 /1 ib */ 9259 ins_encode(reg_opc_imm_wide(dst, shift)); 9260 ins_pipe(ialu_reg); 9261 %} 9262 9263 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9264 %{ 9265 effect(USE_DEF dst, USE shift, KILL cr); 9266 9267 format %{ "rorq $dst, $shift" %} 9268 opcode(0xD3, 0x1); /* D3 /1 */ 9269 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9270 ins_pipe(ialu_reg_reg); 9271 %} 9272 // end of ROR expand 9273 9274 // Rotate Right by one 9275 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9276 %{ 9277 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9278 9279 expand %{ 9280 rorL_rReg_imm1(dst, cr); 9281 %} 9282 %} 9283 9284 // Rotate Right by 8-bit immediate 9285 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9286 %{ 9287 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9288 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9289 9290 expand %{ 9291 rorL_rReg_imm8(dst, rshift, cr); 9292 %} 9293 %} 9294 9295 // Rotate Right by variable 9296 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9297 %{ 9298 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9299 9300 expand %{ 9301 rorL_rReg_CL(dst, shift, cr); 9302 %} 9303 %} 9304 9305 // Rotate Right by variable 9306 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9307 %{ 9308 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9309 9310 expand %{ 9311 rorL_rReg_CL(dst, shift, cr); 9312 %} 9313 %} 9314 9315 // Logical Instructions 9316 9317 // Integer Logical Instructions 9318 9319 // And Instructions 9320 // And Register with Register 9321 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9322 %{ 9323 match(Set dst (AndI dst src)); 9324 effect(KILL cr); 9325 9326 format %{ "andl $dst, $src\t# int" %} 9327 opcode(0x23); 9328 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9329 ins_pipe(ialu_reg_reg); 9330 %} 9331 9332 // And Register with Immediate 255 9333 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9334 %{ 9335 match(Set dst (AndI dst src)); 9336 9337 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9338 opcode(0x0F, 0xB6); 9339 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9340 ins_pipe(ialu_reg); 9341 %} 9342 9343 // And Register with Immediate 255 and promote to long 9344 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9345 %{ 9346 match(Set dst (ConvI2L (AndI src mask))); 9347 9348 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9349 opcode(0x0F, 0xB6); 9350 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9351 ins_pipe(ialu_reg); 9352 %} 9353 9354 // And Register with Immediate 65535 9355 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9356 %{ 9357 match(Set dst (AndI dst src)); 9358 9359 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9360 opcode(0x0F, 0xB7); 9361 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9362 ins_pipe(ialu_reg); 9363 %} 9364 9365 // And Register with Immediate 65535 and promote to long 9366 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9367 %{ 9368 match(Set dst (ConvI2L (AndI src mask))); 9369 9370 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9371 opcode(0x0F, 0xB7); 9372 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9373 ins_pipe(ialu_reg); 9374 %} 9375 9376 // And Register with Immediate 9377 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9378 %{ 9379 match(Set dst (AndI dst src)); 9380 effect(KILL cr); 9381 9382 format %{ "andl $dst, $src\t# int" %} 9383 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9384 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9385 ins_pipe(ialu_reg); 9386 %} 9387 9388 // And Register with Memory 9389 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9390 %{ 9391 match(Set dst (AndI dst (LoadI src))); 9392 effect(KILL cr); 9393 9394 ins_cost(125); 9395 format %{ "andl $dst, $src\t# int" %} 9396 opcode(0x23); 9397 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9398 ins_pipe(ialu_reg_mem); 9399 %} 9400 9401 // And Memory with Register 9402 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9403 %{ 9404 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9405 effect(KILL cr); 9406 9407 ins_cost(150); 9408 format %{ "andb $dst, $src\t# byte" %} 9409 opcode(0x20); 9410 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9411 ins_pipe(ialu_mem_reg); 9412 %} 9413 9414 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9415 %{ 9416 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9417 effect(KILL cr); 9418 9419 ins_cost(150); 9420 format %{ "andl $dst, $src\t# int" %} 9421 opcode(0x21); /* Opcode 21 /r */ 9422 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9423 ins_pipe(ialu_mem_reg); 9424 %} 9425 9426 // And Memory with Immediate 9427 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9428 %{ 9429 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9430 effect(KILL cr); 9431 9432 ins_cost(125); 9433 format %{ "andl $dst, $src\t# int" %} 9434 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9435 ins_encode(REX_mem(dst), OpcSE(src), 9436 RM_opc_mem(secondary, dst), Con8or32(src)); 9437 ins_pipe(ialu_mem_imm); 9438 %} 9439 9440 // BMI1 instructions 9441 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9442 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9443 predicate(UseBMI1Instructions); 9444 effect(KILL cr); 9445 9446 ins_cost(125); 9447 format %{ "andnl $dst, $src1, $src2" %} 9448 9449 ins_encode %{ 9450 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9451 %} 9452 ins_pipe(ialu_reg_mem); 9453 %} 9454 9455 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9456 match(Set dst (AndI (XorI src1 minus_1) src2)); 9457 predicate(UseBMI1Instructions); 9458 effect(KILL cr); 9459 9460 format %{ "andnl $dst, $src1, $src2" %} 9461 9462 ins_encode %{ 9463 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9464 %} 9465 ins_pipe(ialu_reg); 9466 %} 9467 9468 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9469 match(Set dst (AndI (SubI imm_zero src) src)); 9470 predicate(UseBMI1Instructions); 9471 effect(KILL cr); 9472 9473 format %{ "blsil $dst, $src" %} 9474 9475 ins_encode %{ 9476 __ blsil($dst$$Register, $src$$Register); 9477 %} 9478 ins_pipe(ialu_reg); 9479 %} 9480 9481 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9482 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9483 predicate(UseBMI1Instructions); 9484 effect(KILL cr); 9485 9486 ins_cost(125); 9487 format %{ "blsil $dst, $src" %} 9488 9489 ins_encode %{ 9490 __ blsil($dst$$Register, $src$$Address); 9491 %} 9492 ins_pipe(ialu_reg_mem); 9493 %} 9494 9495 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9496 %{ 9497 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9498 predicate(UseBMI1Instructions); 9499 effect(KILL cr); 9500 9501 ins_cost(125); 9502 format %{ "blsmskl $dst, $src" %} 9503 9504 ins_encode %{ 9505 __ blsmskl($dst$$Register, $src$$Address); 9506 %} 9507 ins_pipe(ialu_reg_mem); 9508 %} 9509 9510 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9511 %{ 9512 match(Set dst (XorI (AddI src minus_1) src)); 9513 predicate(UseBMI1Instructions); 9514 effect(KILL cr); 9515 9516 format %{ "blsmskl $dst, $src" %} 9517 9518 ins_encode %{ 9519 __ blsmskl($dst$$Register, $src$$Register); 9520 %} 9521 9522 ins_pipe(ialu_reg); 9523 %} 9524 9525 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9526 %{ 9527 match(Set dst (AndI (AddI src minus_1) src) ); 9528 predicate(UseBMI1Instructions); 9529 effect(KILL cr); 9530 9531 format %{ "blsrl $dst, $src" %} 9532 9533 ins_encode %{ 9534 __ blsrl($dst$$Register, $src$$Register); 9535 %} 9536 9537 ins_pipe(ialu_reg_mem); 9538 %} 9539 9540 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9541 %{ 9542 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9543 predicate(UseBMI1Instructions); 9544 effect(KILL cr); 9545 9546 ins_cost(125); 9547 format %{ "blsrl $dst, $src" %} 9548 9549 ins_encode %{ 9550 __ blsrl($dst$$Register, $src$$Address); 9551 %} 9552 9553 ins_pipe(ialu_reg); 9554 %} 9555 9556 // Or Instructions 9557 // Or Register with Register 9558 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9559 %{ 9560 match(Set dst (OrI dst src)); 9561 effect(KILL cr); 9562 9563 format %{ "orl $dst, $src\t# int" %} 9564 opcode(0x0B); 9565 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9566 ins_pipe(ialu_reg_reg); 9567 %} 9568 9569 // Or Register with Immediate 9570 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9571 %{ 9572 match(Set dst (OrI dst src)); 9573 effect(KILL cr); 9574 9575 format %{ "orl $dst, $src\t# int" %} 9576 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9577 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9578 ins_pipe(ialu_reg); 9579 %} 9580 9581 // Or Register with Memory 9582 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9583 %{ 9584 match(Set dst (OrI dst (LoadI src))); 9585 effect(KILL cr); 9586 9587 ins_cost(125); 9588 format %{ "orl $dst, $src\t# int" %} 9589 opcode(0x0B); 9590 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9591 ins_pipe(ialu_reg_mem); 9592 %} 9593 9594 // Or Memory with Register 9595 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9596 %{ 9597 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9598 effect(KILL cr); 9599 9600 ins_cost(150); 9601 format %{ "orb $dst, $src\t# byte" %} 9602 opcode(0x08); 9603 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9604 ins_pipe(ialu_mem_reg); 9605 %} 9606 9607 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9608 %{ 9609 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9610 effect(KILL cr); 9611 9612 ins_cost(150); 9613 format %{ "orl $dst, $src\t# int" %} 9614 opcode(0x09); /* Opcode 09 /r */ 9615 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9616 ins_pipe(ialu_mem_reg); 9617 %} 9618 9619 // Or Memory with Immediate 9620 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9621 %{ 9622 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9623 effect(KILL cr); 9624 9625 ins_cost(125); 9626 format %{ "orl $dst, $src\t# int" %} 9627 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9628 ins_encode(REX_mem(dst), OpcSE(src), 9629 RM_opc_mem(secondary, dst), Con8or32(src)); 9630 ins_pipe(ialu_mem_imm); 9631 %} 9632 9633 // Xor Instructions 9634 // Xor Register with Register 9635 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9636 %{ 9637 match(Set dst (XorI dst src)); 9638 effect(KILL cr); 9639 9640 format %{ "xorl $dst, $src\t# int" %} 9641 opcode(0x33); 9642 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9643 ins_pipe(ialu_reg_reg); 9644 %} 9645 9646 // Xor Register with Immediate -1 9647 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9648 match(Set dst (XorI dst imm)); 9649 9650 format %{ "not $dst" %} 9651 ins_encode %{ 9652 __ notl($dst$$Register); 9653 %} 9654 ins_pipe(ialu_reg); 9655 %} 9656 9657 // Xor Register with Immediate 9658 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9659 %{ 9660 match(Set dst (XorI dst src)); 9661 effect(KILL cr); 9662 9663 format %{ "xorl $dst, $src\t# int" %} 9664 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9665 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9666 ins_pipe(ialu_reg); 9667 %} 9668 9669 // Xor Register with Memory 9670 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9671 %{ 9672 match(Set dst (XorI dst (LoadI src))); 9673 effect(KILL cr); 9674 9675 ins_cost(125); 9676 format %{ "xorl $dst, $src\t# int" %} 9677 opcode(0x33); 9678 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9679 ins_pipe(ialu_reg_mem); 9680 %} 9681 9682 // Xor Memory with Register 9683 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9684 %{ 9685 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9686 effect(KILL cr); 9687 9688 ins_cost(150); 9689 format %{ "xorb $dst, $src\t# byte" %} 9690 opcode(0x30); 9691 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9692 ins_pipe(ialu_mem_reg); 9693 %} 9694 9695 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9696 %{ 9697 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9698 effect(KILL cr); 9699 9700 ins_cost(150); 9701 format %{ "xorl $dst, $src\t# int" %} 9702 opcode(0x31); /* Opcode 31 /r */ 9703 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9704 ins_pipe(ialu_mem_reg); 9705 %} 9706 9707 // Xor Memory with Immediate 9708 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9709 %{ 9710 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9711 effect(KILL cr); 9712 9713 ins_cost(125); 9714 format %{ "xorl $dst, $src\t# int" %} 9715 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9716 ins_encode(REX_mem(dst), OpcSE(src), 9717 RM_opc_mem(secondary, dst), Con8or32(src)); 9718 ins_pipe(ialu_mem_imm); 9719 %} 9720 9721 9722 // Long Logical Instructions 9723 9724 // And Instructions 9725 // And Register with Register 9726 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9727 %{ 9728 match(Set dst (AndL dst src)); 9729 effect(KILL cr); 9730 9731 format %{ "andq $dst, $src\t# long" %} 9732 opcode(0x23); 9733 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9734 ins_pipe(ialu_reg_reg); 9735 %} 9736 9737 // And Register with Immediate 255 9738 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9739 %{ 9740 match(Set dst (AndL dst src)); 9741 9742 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9743 opcode(0x0F, 0xB6); 9744 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9745 ins_pipe(ialu_reg); 9746 %} 9747 9748 // And Register with Immediate 65535 9749 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9750 %{ 9751 match(Set dst (AndL dst src)); 9752 9753 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9754 opcode(0x0F, 0xB7); 9755 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9756 ins_pipe(ialu_reg); 9757 %} 9758 9759 // And Register with Immediate 9760 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9761 %{ 9762 match(Set dst (AndL dst src)); 9763 effect(KILL cr); 9764 9765 format %{ "andq $dst, $src\t# long" %} 9766 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9767 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9768 ins_pipe(ialu_reg); 9769 %} 9770 9771 // And Register with Memory 9772 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9773 %{ 9774 match(Set dst (AndL dst (LoadL src))); 9775 effect(KILL cr); 9776 9777 ins_cost(125); 9778 format %{ "andq $dst, $src\t# long" %} 9779 opcode(0x23); 9780 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9781 ins_pipe(ialu_reg_mem); 9782 %} 9783 9784 // And Memory with Register 9785 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9786 %{ 9787 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9788 effect(KILL cr); 9789 9790 ins_cost(150); 9791 format %{ "andq $dst, $src\t# long" %} 9792 opcode(0x21); /* Opcode 21 /r */ 9793 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9794 ins_pipe(ialu_mem_reg); 9795 %} 9796 9797 // And Memory with Immediate 9798 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9799 %{ 9800 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9801 effect(KILL cr); 9802 9803 ins_cost(125); 9804 format %{ "andq $dst, $src\t# long" %} 9805 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9806 ins_encode(REX_mem_wide(dst), OpcSE(src), 9807 RM_opc_mem(secondary, dst), Con8or32(src)); 9808 ins_pipe(ialu_mem_imm); 9809 %} 9810 9811 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9812 %{ 9813 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9814 // because AND/OR works well enough for 8/32-bit values. 9815 predicate(log2_long(~n->in(3)->in(2)->get_long()) > 30); 9816 9817 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9818 effect(KILL cr); 9819 9820 ins_cost(125); 9821 format %{ "btrq $dst, log2(not($con))\t# long" %} 9822 ins_encode %{ 9823 __ btrq($dst$$Address, log2_long(~$con$$constant)); 9824 %} 9825 ins_pipe(ialu_mem_imm); 9826 %} 9827 9828 // BMI1 instructions 9829 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9830 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9831 predicate(UseBMI1Instructions); 9832 effect(KILL cr); 9833 9834 ins_cost(125); 9835 format %{ "andnq $dst, $src1, $src2" %} 9836 9837 ins_encode %{ 9838 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9839 %} 9840 ins_pipe(ialu_reg_mem); 9841 %} 9842 9843 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9844 match(Set dst (AndL (XorL src1 minus_1) src2)); 9845 predicate(UseBMI1Instructions); 9846 effect(KILL cr); 9847 9848 format %{ "andnq $dst, $src1, $src2" %} 9849 9850 ins_encode %{ 9851 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9852 %} 9853 ins_pipe(ialu_reg_mem); 9854 %} 9855 9856 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9857 match(Set dst (AndL (SubL imm_zero src) src)); 9858 predicate(UseBMI1Instructions); 9859 effect(KILL cr); 9860 9861 format %{ "blsiq $dst, $src" %} 9862 9863 ins_encode %{ 9864 __ blsiq($dst$$Register, $src$$Register); 9865 %} 9866 ins_pipe(ialu_reg); 9867 %} 9868 9869 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9870 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9871 predicate(UseBMI1Instructions); 9872 effect(KILL cr); 9873 9874 ins_cost(125); 9875 format %{ "blsiq $dst, $src" %} 9876 9877 ins_encode %{ 9878 __ blsiq($dst$$Register, $src$$Address); 9879 %} 9880 ins_pipe(ialu_reg_mem); 9881 %} 9882 9883 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9884 %{ 9885 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9886 predicate(UseBMI1Instructions); 9887 effect(KILL cr); 9888 9889 ins_cost(125); 9890 format %{ "blsmskq $dst, $src" %} 9891 9892 ins_encode %{ 9893 __ blsmskq($dst$$Register, $src$$Address); 9894 %} 9895 ins_pipe(ialu_reg_mem); 9896 %} 9897 9898 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9899 %{ 9900 match(Set dst (XorL (AddL src minus_1) src)); 9901 predicate(UseBMI1Instructions); 9902 effect(KILL cr); 9903 9904 format %{ "blsmskq $dst, $src" %} 9905 9906 ins_encode %{ 9907 __ blsmskq($dst$$Register, $src$$Register); 9908 %} 9909 9910 ins_pipe(ialu_reg); 9911 %} 9912 9913 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9914 %{ 9915 match(Set dst (AndL (AddL src minus_1) src) ); 9916 predicate(UseBMI1Instructions); 9917 effect(KILL cr); 9918 9919 format %{ "blsrq $dst, $src" %} 9920 9921 ins_encode %{ 9922 __ blsrq($dst$$Register, $src$$Register); 9923 %} 9924 9925 ins_pipe(ialu_reg); 9926 %} 9927 9928 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9929 %{ 9930 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9931 predicate(UseBMI1Instructions); 9932 effect(KILL cr); 9933 9934 ins_cost(125); 9935 format %{ "blsrq $dst, $src" %} 9936 9937 ins_encode %{ 9938 __ blsrq($dst$$Register, $src$$Address); 9939 %} 9940 9941 ins_pipe(ialu_reg); 9942 %} 9943 9944 // Or Instructions 9945 // Or Register with Register 9946 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9947 %{ 9948 match(Set dst (OrL dst src)); 9949 effect(KILL cr); 9950 9951 format %{ "orq $dst, $src\t# long" %} 9952 opcode(0x0B); 9953 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9954 ins_pipe(ialu_reg_reg); 9955 %} 9956 9957 // Use any_RegP to match R15 (TLS register) without spilling. 9958 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9959 match(Set dst (OrL dst (CastP2X src))); 9960 effect(KILL cr); 9961 9962 format %{ "orq $dst, $src\t# long" %} 9963 opcode(0x0B); 9964 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9965 ins_pipe(ialu_reg_reg); 9966 %} 9967 9968 9969 // Or Register with Immediate 9970 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9971 %{ 9972 match(Set dst (OrL dst src)); 9973 effect(KILL cr); 9974 9975 format %{ "orq $dst, $src\t# long" %} 9976 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9977 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9978 ins_pipe(ialu_reg); 9979 %} 9980 9981 // Or Register with Memory 9982 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9983 %{ 9984 match(Set dst (OrL dst (LoadL src))); 9985 effect(KILL cr); 9986 9987 ins_cost(125); 9988 format %{ "orq $dst, $src\t# long" %} 9989 opcode(0x0B); 9990 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9991 ins_pipe(ialu_reg_mem); 9992 %} 9993 9994 // Or Memory with Register 9995 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9996 %{ 9997 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9998 effect(KILL cr); 9999 10000 ins_cost(150); 10001 format %{ "orq $dst, $src\t# long" %} 10002 opcode(0x09); /* Opcode 09 /r */ 10003 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10004 ins_pipe(ialu_mem_reg); 10005 %} 10006 10007 // Or Memory with Immediate 10008 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10009 %{ 10010 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10011 effect(KILL cr); 10012 10013 ins_cost(125); 10014 format %{ "orq $dst, $src\t# long" %} 10015 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 10016 ins_encode(REX_mem_wide(dst), OpcSE(src), 10017 RM_opc_mem(secondary, dst), Con8or32(src)); 10018 ins_pipe(ialu_mem_imm); 10019 %} 10020 10021 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 10022 %{ 10023 // con should be a pure 64-bit power of 2 immediate 10024 // because AND/OR works well enough for 8/32-bit values. 10025 predicate(log2_long(n->in(3)->in(2)->get_long()) > 31); 10026 10027 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 10028 effect(KILL cr); 10029 10030 ins_cost(125); 10031 format %{ "btsq $dst, log2($con)\t# long" %} 10032 ins_encode %{ 10033 __ btsq($dst$$Address, log2_long($con$$constant)); 10034 %} 10035 ins_pipe(ialu_mem_imm); 10036 %} 10037 10038 // Xor Instructions 10039 // Xor Register with Register 10040 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10041 %{ 10042 match(Set dst (XorL dst src)); 10043 effect(KILL cr); 10044 10045 format %{ "xorq $dst, $src\t# long" %} 10046 opcode(0x33); 10047 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10048 ins_pipe(ialu_reg_reg); 10049 %} 10050 10051 // Xor Register with Immediate -1 10052 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10053 match(Set dst (XorL dst imm)); 10054 10055 format %{ "notq $dst" %} 10056 ins_encode %{ 10057 __ notq($dst$$Register); 10058 %} 10059 ins_pipe(ialu_reg); 10060 %} 10061 10062 // Xor Register with Immediate 10063 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10064 %{ 10065 match(Set dst (XorL dst src)); 10066 effect(KILL cr); 10067 10068 format %{ "xorq $dst, $src\t# long" %} 10069 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10070 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10071 ins_pipe(ialu_reg); 10072 %} 10073 10074 // Xor Register with Memory 10075 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10076 %{ 10077 match(Set dst (XorL dst (LoadL src))); 10078 effect(KILL cr); 10079 10080 ins_cost(125); 10081 format %{ "xorq $dst, $src\t# long" %} 10082 opcode(0x33); 10083 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10084 ins_pipe(ialu_reg_mem); 10085 %} 10086 10087 // Xor Memory with Register 10088 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10089 %{ 10090 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10091 effect(KILL cr); 10092 10093 ins_cost(150); 10094 format %{ "xorq $dst, $src\t# long" %} 10095 opcode(0x31); /* Opcode 31 /r */ 10096 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10097 ins_pipe(ialu_mem_reg); 10098 %} 10099 10100 // Xor Memory with Immediate 10101 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10102 %{ 10103 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10104 effect(KILL cr); 10105 10106 ins_cost(125); 10107 format %{ "xorq $dst, $src\t# long" %} 10108 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10109 ins_encode(REX_mem_wide(dst), OpcSE(src), 10110 RM_opc_mem(secondary, dst), Con8or32(src)); 10111 ins_pipe(ialu_mem_imm); 10112 %} 10113 10114 // Convert Int to Boolean 10115 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10116 %{ 10117 match(Set dst (Conv2B src)); 10118 effect(KILL cr); 10119 10120 format %{ "testl $src, $src\t# ci2b\n\t" 10121 "setnz $dst\n\t" 10122 "movzbl $dst, $dst" %} 10123 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10124 setNZ_reg(dst), 10125 REX_reg_breg(dst, dst), // movzbl 10126 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10127 ins_pipe(pipe_slow); // XXX 10128 %} 10129 10130 // Convert Pointer to Boolean 10131 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10132 %{ 10133 match(Set dst (Conv2B src)); 10134 effect(KILL cr); 10135 10136 format %{ "testq $src, $src\t# cp2b\n\t" 10137 "setnz $dst\n\t" 10138 "movzbl $dst, $dst" %} 10139 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10140 setNZ_reg(dst), 10141 REX_reg_breg(dst, dst), // movzbl 10142 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10143 ins_pipe(pipe_slow); // XXX 10144 %} 10145 10146 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10147 %{ 10148 match(Set dst (CmpLTMask p q)); 10149 effect(KILL cr); 10150 10151 ins_cost(400); 10152 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10153 "setlt $dst\n\t" 10154 "movzbl $dst, $dst\n\t" 10155 "negl $dst" %} 10156 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10157 setLT_reg(dst), 10158 REX_reg_breg(dst, dst), // movzbl 10159 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10160 neg_reg(dst)); 10161 ins_pipe(pipe_slow); 10162 %} 10163 10164 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10165 %{ 10166 match(Set dst (CmpLTMask dst zero)); 10167 effect(KILL cr); 10168 10169 ins_cost(100); 10170 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10171 ins_encode %{ 10172 __ sarl($dst$$Register, 31); 10173 %} 10174 ins_pipe(ialu_reg); 10175 %} 10176 10177 /* Better to save a register than avoid a branch */ 10178 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10179 %{ 10180 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10181 effect(KILL cr); 10182 ins_cost(300); 10183 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10184 "jge done\n\t" 10185 "addl $p,$y\n" 10186 "done: " %} 10187 ins_encode %{ 10188 Register Rp = $p$$Register; 10189 Register Rq = $q$$Register; 10190 Register Ry = $y$$Register; 10191 Label done; 10192 __ subl(Rp, Rq); 10193 __ jccb(Assembler::greaterEqual, done); 10194 __ addl(Rp, Ry); 10195 __ bind(done); 10196 %} 10197 ins_pipe(pipe_cmplt); 10198 %} 10199 10200 /* Better to save a register than avoid a branch */ 10201 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10202 %{ 10203 match(Set y (AndI (CmpLTMask p q) y)); 10204 effect(KILL cr); 10205 10206 ins_cost(300); 10207 10208 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10209 "jlt done\n\t" 10210 "xorl $y, $y\n" 10211 "done: " %} 10212 ins_encode %{ 10213 Register Rp = $p$$Register; 10214 Register Rq = $q$$Register; 10215 Register Ry = $y$$Register; 10216 Label done; 10217 __ cmpl(Rp, Rq); 10218 __ jccb(Assembler::less, done); 10219 __ xorl(Ry, Ry); 10220 __ bind(done); 10221 %} 10222 ins_pipe(pipe_cmplt); 10223 %} 10224 10225 10226 //---------- FP Instructions------------------------------------------------ 10227 10228 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10229 %{ 10230 match(Set cr (CmpF src1 src2)); 10231 10232 ins_cost(145); 10233 format %{ "ucomiss $src1, $src2\n\t" 10234 "jnp,s exit\n\t" 10235 "pushfq\t# saw NaN, set CF\n\t" 10236 "andq [rsp], #0xffffff2b\n\t" 10237 "popfq\n" 10238 "exit:" %} 10239 ins_encode %{ 10240 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10241 emit_cmpfp_fixup(_masm); 10242 %} 10243 ins_pipe(pipe_slow); 10244 %} 10245 10246 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10247 match(Set cr (CmpF src1 src2)); 10248 10249 ins_cost(100); 10250 format %{ "ucomiss $src1, $src2" %} 10251 ins_encode %{ 10252 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10253 %} 10254 ins_pipe(pipe_slow); 10255 %} 10256 10257 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10258 %{ 10259 match(Set cr (CmpF src1 (LoadF src2))); 10260 10261 ins_cost(145); 10262 format %{ "ucomiss $src1, $src2\n\t" 10263 "jnp,s exit\n\t" 10264 "pushfq\t# saw NaN, set CF\n\t" 10265 "andq [rsp], #0xffffff2b\n\t" 10266 "popfq\n" 10267 "exit:" %} 10268 ins_encode %{ 10269 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10270 emit_cmpfp_fixup(_masm); 10271 %} 10272 ins_pipe(pipe_slow); 10273 %} 10274 10275 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10276 match(Set cr (CmpF src1 (LoadF src2))); 10277 10278 ins_cost(100); 10279 format %{ "ucomiss $src1, $src2" %} 10280 ins_encode %{ 10281 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10282 %} 10283 ins_pipe(pipe_slow); 10284 %} 10285 10286 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10287 match(Set cr (CmpF src con)); 10288 10289 ins_cost(145); 10290 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10291 "jnp,s exit\n\t" 10292 "pushfq\t# saw NaN, set CF\n\t" 10293 "andq [rsp], #0xffffff2b\n\t" 10294 "popfq\n" 10295 "exit:" %} 10296 ins_encode %{ 10297 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10298 emit_cmpfp_fixup(_masm); 10299 %} 10300 ins_pipe(pipe_slow); 10301 %} 10302 10303 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10304 match(Set cr (CmpF src con)); 10305 ins_cost(100); 10306 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10307 ins_encode %{ 10308 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10309 %} 10310 ins_pipe(pipe_slow); 10311 %} 10312 10313 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10314 %{ 10315 match(Set cr (CmpD src1 src2)); 10316 10317 ins_cost(145); 10318 format %{ "ucomisd $src1, $src2\n\t" 10319 "jnp,s exit\n\t" 10320 "pushfq\t# saw NaN, set CF\n\t" 10321 "andq [rsp], #0xffffff2b\n\t" 10322 "popfq\n" 10323 "exit:" %} 10324 ins_encode %{ 10325 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10326 emit_cmpfp_fixup(_masm); 10327 %} 10328 ins_pipe(pipe_slow); 10329 %} 10330 10331 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10332 match(Set cr (CmpD src1 src2)); 10333 10334 ins_cost(100); 10335 format %{ "ucomisd $src1, $src2 test" %} 10336 ins_encode %{ 10337 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10338 %} 10339 ins_pipe(pipe_slow); 10340 %} 10341 10342 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10343 %{ 10344 match(Set cr (CmpD src1 (LoadD src2))); 10345 10346 ins_cost(145); 10347 format %{ "ucomisd $src1, $src2\n\t" 10348 "jnp,s exit\n\t" 10349 "pushfq\t# saw NaN, set CF\n\t" 10350 "andq [rsp], #0xffffff2b\n\t" 10351 "popfq\n" 10352 "exit:" %} 10353 ins_encode %{ 10354 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10355 emit_cmpfp_fixup(_masm); 10356 %} 10357 ins_pipe(pipe_slow); 10358 %} 10359 10360 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10361 match(Set cr (CmpD src1 (LoadD src2))); 10362 10363 ins_cost(100); 10364 format %{ "ucomisd $src1, $src2" %} 10365 ins_encode %{ 10366 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10367 %} 10368 ins_pipe(pipe_slow); 10369 %} 10370 10371 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10372 match(Set cr (CmpD src con)); 10373 10374 ins_cost(145); 10375 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10376 "jnp,s exit\n\t" 10377 "pushfq\t# saw NaN, set CF\n\t" 10378 "andq [rsp], #0xffffff2b\n\t" 10379 "popfq\n" 10380 "exit:" %} 10381 ins_encode %{ 10382 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10383 emit_cmpfp_fixup(_masm); 10384 %} 10385 ins_pipe(pipe_slow); 10386 %} 10387 10388 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10389 match(Set cr (CmpD src con)); 10390 ins_cost(100); 10391 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10392 ins_encode %{ 10393 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10394 %} 10395 ins_pipe(pipe_slow); 10396 %} 10397 10398 // Compare into -1,0,1 10399 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10400 %{ 10401 match(Set dst (CmpF3 src1 src2)); 10402 effect(KILL cr); 10403 10404 ins_cost(275); 10405 format %{ "ucomiss $src1, $src2\n\t" 10406 "movl $dst, #-1\n\t" 10407 "jp,s done\n\t" 10408 "jb,s done\n\t" 10409 "setne $dst\n\t" 10410 "movzbl $dst, $dst\n" 10411 "done:" %} 10412 ins_encode %{ 10413 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10414 emit_cmpfp3(_masm, $dst$$Register); 10415 %} 10416 ins_pipe(pipe_slow); 10417 %} 10418 10419 // Compare into -1,0,1 10420 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10421 %{ 10422 match(Set dst (CmpF3 src1 (LoadF src2))); 10423 effect(KILL cr); 10424 10425 ins_cost(275); 10426 format %{ "ucomiss $src1, $src2\n\t" 10427 "movl $dst, #-1\n\t" 10428 "jp,s done\n\t" 10429 "jb,s done\n\t" 10430 "setne $dst\n\t" 10431 "movzbl $dst, $dst\n" 10432 "done:" %} 10433 ins_encode %{ 10434 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10435 emit_cmpfp3(_masm, $dst$$Register); 10436 %} 10437 ins_pipe(pipe_slow); 10438 %} 10439 10440 // Compare into -1,0,1 10441 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10442 match(Set dst (CmpF3 src con)); 10443 effect(KILL cr); 10444 10445 ins_cost(275); 10446 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10447 "movl $dst, #-1\n\t" 10448 "jp,s done\n\t" 10449 "jb,s done\n\t" 10450 "setne $dst\n\t" 10451 "movzbl $dst, $dst\n" 10452 "done:" %} 10453 ins_encode %{ 10454 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10455 emit_cmpfp3(_masm, $dst$$Register); 10456 %} 10457 ins_pipe(pipe_slow); 10458 %} 10459 10460 // Compare into -1,0,1 10461 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10462 %{ 10463 match(Set dst (CmpD3 src1 src2)); 10464 effect(KILL cr); 10465 10466 ins_cost(275); 10467 format %{ "ucomisd $src1, $src2\n\t" 10468 "movl $dst, #-1\n\t" 10469 "jp,s done\n\t" 10470 "jb,s done\n\t" 10471 "setne $dst\n\t" 10472 "movzbl $dst, $dst\n" 10473 "done:" %} 10474 ins_encode %{ 10475 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10476 emit_cmpfp3(_masm, $dst$$Register); 10477 %} 10478 ins_pipe(pipe_slow); 10479 %} 10480 10481 // Compare into -1,0,1 10482 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10483 %{ 10484 match(Set dst (CmpD3 src1 (LoadD src2))); 10485 effect(KILL cr); 10486 10487 ins_cost(275); 10488 format %{ "ucomisd $src1, $src2\n\t" 10489 "movl $dst, #-1\n\t" 10490 "jp,s done\n\t" 10491 "jb,s done\n\t" 10492 "setne $dst\n\t" 10493 "movzbl $dst, $dst\n" 10494 "done:" %} 10495 ins_encode %{ 10496 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10497 emit_cmpfp3(_masm, $dst$$Register); 10498 %} 10499 ins_pipe(pipe_slow); 10500 %} 10501 10502 // Compare into -1,0,1 10503 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10504 match(Set dst (CmpD3 src con)); 10505 effect(KILL cr); 10506 10507 ins_cost(275); 10508 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10509 "movl $dst, #-1\n\t" 10510 "jp,s done\n\t" 10511 "jb,s done\n\t" 10512 "setne $dst\n\t" 10513 "movzbl $dst, $dst\n" 10514 "done:" %} 10515 ins_encode %{ 10516 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10517 emit_cmpfp3(_masm, $dst$$Register); 10518 %} 10519 ins_pipe(pipe_slow); 10520 %} 10521 10522 //----------Arithmetic Conversion Instructions--------------------------------- 10523 10524 instruct roundFloat_nop(regF dst) 10525 %{ 10526 match(Set dst (RoundFloat dst)); 10527 10528 ins_cost(0); 10529 ins_encode(); 10530 ins_pipe(empty); 10531 %} 10532 10533 instruct roundDouble_nop(regD dst) 10534 %{ 10535 match(Set dst (RoundDouble dst)); 10536 10537 ins_cost(0); 10538 ins_encode(); 10539 ins_pipe(empty); 10540 %} 10541 10542 instruct convF2D_reg_reg(regD dst, regF src) 10543 %{ 10544 match(Set dst (ConvF2D src)); 10545 10546 format %{ "cvtss2sd $dst, $src" %} 10547 ins_encode %{ 10548 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10549 %} 10550 ins_pipe(pipe_slow); // XXX 10551 %} 10552 10553 instruct convF2D_reg_mem(regD dst, memory src) 10554 %{ 10555 match(Set dst (ConvF2D (LoadF src))); 10556 10557 format %{ "cvtss2sd $dst, $src" %} 10558 ins_encode %{ 10559 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10560 %} 10561 ins_pipe(pipe_slow); // XXX 10562 %} 10563 10564 instruct convD2F_reg_reg(regF dst, regD src) 10565 %{ 10566 match(Set dst (ConvD2F src)); 10567 10568 format %{ "cvtsd2ss $dst, $src" %} 10569 ins_encode %{ 10570 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10571 %} 10572 ins_pipe(pipe_slow); // XXX 10573 %} 10574 10575 instruct convD2F_reg_mem(regF dst, memory src) 10576 %{ 10577 match(Set dst (ConvD2F (LoadD src))); 10578 10579 format %{ "cvtsd2ss $dst, $src" %} 10580 ins_encode %{ 10581 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10582 %} 10583 ins_pipe(pipe_slow); // XXX 10584 %} 10585 10586 // XXX do mem variants 10587 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10588 %{ 10589 match(Set dst (ConvF2I src)); 10590 effect(KILL cr); 10591 format %{ "convert_f2i $dst,$src" %} 10592 ins_encode %{ 10593 __ convert_f2i($dst$$Register, $src$$XMMRegister); 10594 %} 10595 ins_pipe(pipe_slow); 10596 %} 10597 10598 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10599 %{ 10600 match(Set dst (ConvF2L src)); 10601 effect(KILL cr); 10602 format %{ "convert_f2l $dst,$src"%} 10603 ins_encode %{ 10604 __ convert_f2l($dst$$Register, $src$$XMMRegister); 10605 %} 10606 ins_pipe(pipe_slow); 10607 %} 10608 10609 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10610 %{ 10611 match(Set dst (ConvD2I src)); 10612 effect(KILL cr); 10613 format %{ "convert_d2i $dst,$src"%} 10614 ins_encode %{ 10615 __ convert_d2i($dst$$Register, $src$$XMMRegister); 10616 %} 10617 ins_pipe(pipe_slow); 10618 %} 10619 10620 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10621 %{ 10622 match(Set dst (ConvD2L src)); 10623 effect(KILL cr); 10624 format %{ "convert_d2l $dst,$src"%} 10625 ins_encode %{ 10626 __ convert_d2l($dst$$Register, $src$$XMMRegister); 10627 %} 10628 ins_pipe(pipe_slow); 10629 %} 10630 10631 instruct convI2F_reg_reg(regF dst, rRegI src) 10632 %{ 10633 predicate(!UseXmmI2F); 10634 match(Set dst (ConvI2F src)); 10635 10636 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10637 ins_encode %{ 10638 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10639 %} 10640 ins_pipe(pipe_slow); // XXX 10641 %} 10642 10643 instruct convI2F_reg_mem(regF dst, memory src) 10644 %{ 10645 match(Set dst (ConvI2F (LoadI src))); 10646 10647 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10648 ins_encode %{ 10649 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10650 %} 10651 ins_pipe(pipe_slow); // XXX 10652 %} 10653 10654 instruct convI2D_reg_reg(regD dst, rRegI src) 10655 %{ 10656 predicate(!UseXmmI2D); 10657 match(Set dst (ConvI2D src)); 10658 10659 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10660 ins_encode %{ 10661 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10662 %} 10663 ins_pipe(pipe_slow); // XXX 10664 %} 10665 10666 instruct convI2D_reg_mem(regD dst, memory src) 10667 %{ 10668 match(Set dst (ConvI2D (LoadI src))); 10669 10670 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10671 ins_encode %{ 10672 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10673 %} 10674 ins_pipe(pipe_slow); // XXX 10675 %} 10676 10677 instruct convXI2F_reg(regF dst, rRegI src) 10678 %{ 10679 predicate(UseXmmI2F); 10680 match(Set dst (ConvI2F src)); 10681 10682 format %{ "movdl $dst, $src\n\t" 10683 "cvtdq2psl $dst, $dst\t# i2f" %} 10684 ins_encode %{ 10685 __ movdl($dst$$XMMRegister, $src$$Register); 10686 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10687 %} 10688 ins_pipe(pipe_slow); // XXX 10689 %} 10690 10691 instruct convXI2D_reg(regD dst, rRegI src) 10692 %{ 10693 predicate(UseXmmI2D); 10694 match(Set dst (ConvI2D src)); 10695 10696 format %{ "movdl $dst, $src\n\t" 10697 "cvtdq2pdl $dst, $dst\t# i2d" %} 10698 ins_encode %{ 10699 __ movdl($dst$$XMMRegister, $src$$Register); 10700 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10701 %} 10702 ins_pipe(pipe_slow); // XXX 10703 %} 10704 10705 instruct convL2F_reg_reg(regF dst, rRegL src) 10706 %{ 10707 match(Set dst (ConvL2F src)); 10708 10709 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10710 ins_encode %{ 10711 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10712 %} 10713 ins_pipe(pipe_slow); // XXX 10714 %} 10715 10716 instruct convL2F_reg_mem(regF dst, memory src) 10717 %{ 10718 match(Set dst (ConvL2F (LoadL src))); 10719 10720 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10721 ins_encode %{ 10722 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10723 %} 10724 ins_pipe(pipe_slow); // XXX 10725 %} 10726 10727 instruct convL2D_reg_reg(regD dst, rRegL src) 10728 %{ 10729 match(Set dst (ConvL2D src)); 10730 10731 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10732 ins_encode %{ 10733 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10734 %} 10735 ins_pipe(pipe_slow); // XXX 10736 %} 10737 10738 instruct convL2D_reg_mem(regD dst, memory src) 10739 %{ 10740 match(Set dst (ConvL2D (LoadL src))); 10741 10742 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10743 ins_encode %{ 10744 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10745 %} 10746 ins_pipe(pipe_slow); // XXX 10747 %} 10748 10749 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10750 %{ 10751 match(Set dst (ConvI2L src)); 10752 10753 ins_cost(125); 10754 format %{ "movslq $dst, $src\t# i2l" %} 10755 ins_encode %{ 10756 __ movslq($dst$$Register, $src$$Register); 10757 %} 10758 ins_pipe(ialu_reg_reg); 10759 %} 10760 10761 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10762 // %{ 10763 // match(Set dst (ConvI2L src)); 10764 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10765 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10766 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10767 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10768 // ((const TypeNode*) n)->type()->is_long()->_lo == 10769 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10770 10771 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10772 // ins_encode(enc_copy(dst, src)); 10773 // // opcode(0x63); // needs REX.W 10774 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10775 // ins_pipe(ialu_reg_reg); 10776 // %} 10777 10778 // Zero-extend convert int to long 10779 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10780 %{ 10781 match(Set dst (AndL (ConvI2L src) mask)); 10782 10783 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10784 ins_encode %{ 10785 if ($dst$$reg != $src$$reg) { 10786 __ movl($dst$$Register, $src$$Register); 10787 } 10788 %} 10789 ins_pipe(ialu_reg_reg); 10790 %} 10791 10792 // Zero-extend convert int to long 10793 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10794 %{ 10795 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10796 10797 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10798 ins_encode %{ 10799 __ movl($dst$$Register, $src$$Address); 10800 %} 10801 ins_pipe(ialu_reg_mem); 10802 %} 10803 10804 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10805 %{ 10806 match(Set dst (AndL src mask)); 10807 10808 format %{ "movl $dst, $src\t# zero-extend long" %} 10809 ins_encode %{ 10810 __ movl($dst$$Register, $src$$Register); 10811 %} 10812 ins_pipe(ialu_reg_reg); 10813 %} 10814 10815 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10816 %{ 10817 match(Set dst (ConvL2I src)); 10818 10819 format %{ "movl $dst, $src\t# l2i" %} 10820 ins_encode %{ 10821 __ movl($dst$$Register, $src$$Register); 10822 %} 10823 ins_pipe(ialu_reg_reg); 10824 %} 10825 10826 10827 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10828 match(Set dst (MoveF2I src)); 10829 effect(DEF dst, USE src); 10830 10831 ins_cost(125); 10832 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10833 ins_encode %{ 10834 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10835 %} 10836 ins_pipe(ialu_reg_mem); 10837 %} 10838 10839 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10840 match(Set dst (MoveI2F src)); 10841 effect(DEF dst, USE src); 10842 10843 ins_cost(125); 10844 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10845 ins_encode %{ 10846 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10847 %} 10848 ins_pipe(pipe_slow); 10849 %} 10850 10851 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10852 match(Set dst (MoveD2L src)); 10853 effect(DEF dst, USE src); 10854 10855 ins_cost(125); 10856 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10857 ins_encode %{ 10858 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10859 %} 10860 ins_pipe(ialu_reg_mem); 10861 %} 10862 10863 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10864 predicate(!UseXmmLoadAndClearUpper); 10865 match(Set dst (MoveL2D src)); 10866 effect(DEF dst, USE src); 10867 10868 ins_cost(125); 10869 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10870 ins_encode %{ 10871 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10872 %} 10873 ins_pipe(pipe_slow); 10874 %} 10875 10876 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10877 predicate(UseXmmLoadAndClearUpper); 10878 match(Set dst (MoveL2D src)); 10879 effect(DEF dst, USE src); 10880 10881 ins_cost(125); 10882 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10883 ins_encode %{ 10884 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10885 %} 10886 ins_pipe(pipe_slow); 10887 %} 10888 10889 10890 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10891 match(Set dst (MoveF2I src)); 10892 effect(DEF dst, USE src); 10893 10894 ins_cost(95); // XXX 10895 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10896 ins_encode %{ 10897 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10898 %} 10899 ins_pipe(pipe_slow); 10900 %} 10901 10902 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10903 match(Set dst (MoveI2F src)); 10904 effect(DEF dst, USE src); 10905 10906 ins_cost(100); 10907 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10908 ins_encode %{ 10909 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10910 %} 10911 ins_pipe( ialu_mem_reg ); 10912 %} 10913 10914 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10915 match(Set dst (MoveD2L src)); 10916 effect(DEF dst, USE src); 10917 10918 ins_cost(95); // XXX 10919 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10920 ins_encode %{ 10921 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10922 %} 10923 ins_pipe(pipe_slow); 10924 %} 10925 10926 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10927 match(Set dst (MoveL2D src)); 10928 effect(DEF dst, USE src); 10929 10930 ins_cost(100); 10931 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10932 ins_encode %{ 10933 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10934 %} 10935 ins_pipe(ialu_mem_reg); 10936 %} 10937 10938 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10939 match(Set dst (MoveF2I src)); 10940 effect(DEF dst, USE src); 10941 ins_cost(85); 10942 format %{ "movd $dst,$src\t# MoveF2I" %} 10943 ins_encode %{ 10944 __ movdl($dst$$Register, $src$$XMMRegister); 10945 %} 10946 ins_pipe( pipe_slow ); 10947 %} 10948 10949 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10950 match(Set dst (MoveD2L src)); 10951 effect(DEF dst, USE src); 10952 ins_cost(85); 10953 format %{ "movd $dst,$src\t# MoveD2L" %} 10954 ins_encode %{ 10955 __ movdq($dst$$Register, $src$$XMMRegister); 10956 %} 10957 ins_pipe( pipe_slow ); 10958 %} 10959 10960 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10961 match(Set dst (MoveI2F src)); 10962 effect(DEF dst, USE src); 10963 ins_cost(100); 10964 format %{ "movd $dst,$src\t# MoveI2F" %} 10965 ins_encode %{ 10966 __ movdl($dst$$XMMRegister, $src$$Register); 10967 %} 10968 ins_pipe( pipe_slow ); 10969 %} 10970 10971 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10972 match(Set dst (MoveL2D src)); 10973 effect(DEF dst, USE src); 10974 ins_cost(100); 10975 format %{ "movd $dst,$src\t# MoveL2D" %} 10976 ins_encode %{ 10977 __ movdq($dst$$XMMRegister, $src$$Register); 10978 %} 10979 ins_pipe( pipe_slow ); 10980 %} 10981 10982 10983 // ======================================================================= 10984 // fast clearing of an array 10985 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10986 Universe dummy, rFlagsReg cr) 10987 %{ 10988 predicate(!((ClearArrayNode*)n)->is_large()); 10989 match(Set dummy (ClearArray cnt base)); 10990 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10991 10992 format %{ $$template 10993 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10994 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10995 $$emit$$"jg LARGE\n\t" 10996 $$emit$$"dec rcx\n\t" 10997 $$emit$$"js DONE\t# Zero length\n\t" 10998 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10999 $$emit$$"dec rcx\n\t" 11000 $$emit$$"jge LOOP\n\t" 11001 $$emit$$"jmp DONE\n\t" 11002 $$emit$$"# LARGE:\n\t" 11003 if (UseFastStosb) { 11004 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11005 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 11006 } else if (UseXMMForObjInit) { 11007 $$emit$$"mov rdi,rax\n\t" 11008 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11009 $$emit$$"jmpq L_zero_64_bytes\n\t" 11010 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11011 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11012 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11013 $$emit$$"add 0x40,rax\n\t" 11014 $$emit$$"# L_zero_64_bytes:\n\t" 11015 $$emit$$"sub 0x8,rcx\n\t" 11016 $$emit$$"jge L_loop\n\t" 11017 $$emit$$"add 0x4,rcx\n\t" 11018 $$emit$$"jl L_tail\n\t" 11019 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11020 $$emit$$"add 0x20,rax\n\t" 11021 $$emit$$"sub 0x4,rcx\n\t" 11022 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11023 $$emit$$"add 0x4,rcx\n\t" 11024 $$emit$$"jle L_end\n\t" 11025 $$emit$$"dec rcx\n\t" 11026 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11027 $$emit$$"vmovq xmm0,(rax)\n\t" 11028 $$emit$$"add 0x8,rax\n\t" 11029 $$emit$$"dec rcx\n\t" 11030 $$emit$$"jge L_sloop\n\t" 11031 $$emit$$"# L_end:\n\t" 11032 } else { 11033 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11034 } 11035 $$emit$$"# DONE" 11036 %} 11037 ins_encode %{ 11038 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11039 $tmp$$XMMRegister, false); 11040 %} 11041 ins_pipe(pipe_slow); 11042 %} 11043 11044 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 11045 Universe dummy, rFlagsReg cr) 11046 %{ 11047 predicate(((ClearArrayNode*)n)->is_large()); 11048 match(Set dummy (ClearArray cnt base)); 11049 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 11050 11051 format %{ $$template 11052 if (UseFastStosb) { 11053 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11054 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11055 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11056 } else if (UseXMMForObjInit) { 11057 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 11058 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11059 $$emit$$"jmpq L_zero_64_bytes\n\t" 11060 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11061 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11062 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11063 $$emit$$"add 0x40,rax\n\t" 11064 $$emit$$"# L_zero_64_bytes:\n\t" 11065 $$emit$$"sub 0x8,rcx\n\t" 11066 $$emit$$"jge L_loop\n\t" 11067 $$emit$$"add 0x4,rcx\n\t" 11068 $$emit$$"jl L_tail\n\t" 11069 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11070 $$emit$$"add 0x20,rax\n\t" 11071 $$emit$$"sub 0x4,rcx\n\t" 11072 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11073 $$emit$$"add 0x4,rcx\n\t" 11074 $$emit$$"jle L_end\n\t" 11075 $$emit$$"dec rcx\n\t" 11076 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11077 $$emit$$"vmovq xmm0,(rax)\n\t" 11078 $$emit$$"add 0x8,rax\n\t" 11079 $$emit$$"dec rcx\n\t" 11080 $$emit$$"jge L_sloop\n\t" 11081 $$emit$$"# L_end:\n\t" 11082 } else { 11083 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11084 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11085 } 11086 %} 11087 ins_encode %{ 11088 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11089 $tmp$$XMMRegister, true); 11090 %} 11091 ins_pipe(pipe_slow); 11092 %} 11093 11094 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11095 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11096 %{ 11097 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11098 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11099 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11100 11101 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11102 ins_encode %{ 11103 __ string_compare($str1$$Register, $str2$$Register, 11104 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11105 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11106 %} 11107 ins_pipe( pipe_slow ); 11108 %} 11109 11110 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11111 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11112 %{ 11113 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11114 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11115 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11116 11117 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11118 ins_encode %{ 11119 __ string_compare($str1$$Register, $str2$$Register, 11120 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11121 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11122 %} 11123 ins_pipe( pipe_slow ); 11124 %} 11125 11126 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11127 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11128 %{ 11129 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11130 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11131 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11132 11133 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11134 ins_encode %{ 11135 __ string_compare($str1$$Register, $str2$$Register, 11136 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11137 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11138 %} 11139 ins_pipe( pipe_slow ); 11140 %} 11141 11142 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11143 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11144 %{ 11145 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11146 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11147 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11148 11149 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11150 ins_encode %{ 11151 __ string_compare($str2$$Register, $str1$$Register, 11152 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11153 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11154 %} 11155 ins_pipe( pipe_slow ); 11156 %} 11157 11158 // fast search of substring with known size. 11159 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11160 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11161 %{ 11162 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11163 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11164 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11165 11166 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11167 ins_encode %{ 11168 int icnt2 = (int)$int_cnt2$$constant; 11169 if (icnt2 >= 16) { 11170 // IndexOf for constant substrings with size >= 16 elements 11171 // which don't need to be loaded through stack. 11172 __ string_indexofC8($str1$$Register, $str2$$Register, 11173 $cnt1$$Register, $cnt2$$Register, 11174 icnt2, $result$$Register, 11175 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11176 } else { 11177 // Small strings are loaded through stack if they cross page boundary. 11178 __ string_indexof($str1$$Register, $str2$$Register, 11179 $cnt1$$Register, $cnt2$$Register, 11180 icnt2, $result$$Register, 11181 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11182 } 11183 %} 11184 ins_pipe( pipe_slow ); 11185 %} 11186 11187 // fast search of substring with known size. 11188 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11189 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11190 %{ 11191 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11192 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11193 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11194 11195 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11196 ins_encode %{ 11197 int icnt2 = (int)$int_cnt2$$constant; 11198 if (icnt2 >= 8) { 11199 // IndexOf for constant substrings with size >= 8 elements 11200 // which don't need to be loaded through stack. 11201 __ string_indexofC8($str1$$Register, $str2$$Register, 11202 $cnt1$$Register, $cnt2$$Register, 11203 icnt2, $result$$Register, 11204 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11205 } else { 11206 // Small strings are loaded through stack if they cross page boundary. 11207 __ string_indexof($str1$$Register, $str2$$Register, 11208 $cnt1$$Register, $cnt2$$Register, 11209 icnt2, $result$$Register, 11210 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11211 } 11212 %} 11213 ins_pipe( pipe_slow ); 11214 %} 11215 11216 // fast search of substring with known size. 11217 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11218 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11219 %{ 11220 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11221 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11222 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11223 11224 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11225 ins_encode %{ 11226 int icnt2 = (int)$int_cnt2$$constant; 11227 if (icnt2 >= 8) { 11228 // IndexOf for constant substrings with size >= 8 elements 11229 // which don't need to be loaded through stack. 11230 __ string_indexofC8($str1$$Register, $str2$$Register, 11231 $cnt1$$Register, $cnt2$$Register, 11232 icnt2, $result$$Register, 11233 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11234 } else { 11235 // Small strings are loaded through stack if they cross page boundary. 11236 __ string_indexof($str1$$Register, $str2$$Register, 11237 $cnt1$$Register, $cnt2$$Register, 11238 icnt2, $result$$Register, 11239 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11240 } 11241 %} 11242 ins_pipe( pipe_slow ); 11243 %} 11244 11245 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11246 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11247 %{ 11248 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11249 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11250 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11251 11252 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11253 ins_encode %{ 11254 __ string_indexof($str1$$Register, $str2$$Register, 11255 $cnt1$$Register, $cnt2$$Register, 11256 (-1), $result$$Register, 11257 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11258 %} 11259 ins_pipe( pipe_slow ); 11260 %} 11261 11262 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11263 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11264 %{ 11265 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11266 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11267 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11268 11269 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11270 ins_encode %{ 11271 __ string_indexof($str1$$Register, $str2$$Register, 11272 $cnt1$$Register, $cnt2$$Register, 11273 (-1), $result$$Register, 11274 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11275 %} 11276 ins_pipe( pipe_slow ); 11277 %} 11278 11279 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11280 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11281 %{ 11282 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11283 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11284 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11285 11286 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11287 ins_encode %{ 11288 __ string_indexof($str1$$Register, $str2$$Register, 11289 $cnt1$$Register, $cnt2$$Register, 11290 (-1), $result$$Register, 11291 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11292 %} 11293 ins_pipe( pipe_slow ); 11294 %} 11295 11296 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11297 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11298 %{ 11299 predicate(UseSSE42Intrinsics); 11300 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11301 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11302 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11303 ins_encode %{ 11304 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11305 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11306 %} 11307 ins_pipe( pipe_slow ); 11308 %} 11309 11310 // fast string equals 11311 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11312 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11313 %{ 11314 match(Set result (StrEquals (Binary str1 str2) cnt)); 11315 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11316 11317 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11318 ins_encode %{ 11319 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11320 $cnt$$Register, $result$$Register, $tmp3$$Register, 11321 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11322 %} 11323 ins_pipe( pipe_slow ); 11324 %} 11325 11326 // fast array equals 11327 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11328 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11329 %{ 11330 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11331 match(Set result (AryEq ary1 ary2)); 11332 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11333 11334 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11335 ins_encode %{ 11336 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11337 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11338 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11339 %} 11340 ins_pipe( pipe_slow ); 11341 %} 11342 11343 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11344 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11345 %{ 11346 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11347 match(Set result (AryEq ary1 ary2)); 11348 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11349 11350 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11351 ins_encode %{ 11352 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11353 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11354 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11355 %} 11356 ins_pipe( pipe_slow ); 11357 %} 11358 11359 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11360 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11361 %{ 11362 match(Set result (HasNegatives ary1 len)); 11363 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11364 11365 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11366 ins_encode %{ 11367 __ has_negatives($ary1$$Register, $len$$Register, 11368 $result$$Register, $tmp3$$Register, 11369 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11370 %} 11371 ins_pipe( pipe_slow ); 11372 %} 11373 11374 // fast char[] to byte[] compression 11375 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11376 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11377 match(Set result (StrCompressedCopy src (Binary dst len))); 11378 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11379 11380 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11381 ins_encode %{ 11382 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11383 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11384 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11385 %} 11386 ins_pipe( pipe_slow ); 11387 %} 11388 11389 // fast byte[] to char[] inflation 11390 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11391 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11392 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11393 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11394 11395 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11396 ins_encode %{ 11397 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11398 $tmp1$$XMMRegister, $tmp2$$Register); 11399 %} 11400 ins_pipe( pipe_slow ); 11401 %} 11402 11403 // encode char[] to byte[] in ISO_8859_1 11404 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11405 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11406 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11407 match(Set result (EncodeISOArray src (Binary dst len))); 11408 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11409 11410 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11411 ins_encode %{ 11412 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11413 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11414 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11415 %} 11416 ins_pipe( pipe_slow ); 11417 %} 11418 11419 //----------Overflow Math Instructions----------------------------------------- 11420 11421 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11422 %{ 11423 match(Set cr (OverflowAddI op1 op2)); 11424 effect(DEF cr, USE_KILL op1, USE op2); 11425 11426 format %{ "addl $op1, $op2\t# overflow check int" %} 11427 11428 ins_encode %{ 11429 __ addl($op1$$Register, $op2$$Register); 11430 %} 11431 ins_pipe(ialu_reg_reg); 11432 %} 11433 11434 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11435 %{ 11436 match(Set cr (OverflowAddI op1 op2)); 11437 effect(DEF cr, USE_KILL op1, USE op2); 11438 11439 format %{ "addl $op1, $op2\t# overflow check int" %} 11440 11441 ins_encode %{ 11442 __ addl($op1$$Register, $op2$$constant); 11443 %} 11444 ins_pipe(ialu_reg_reg); 11445 %} 11446 11447 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11448 %{ 11449 match(Set cr (OverflowAddL op1 op2)); 11450 effect(DEF cr, USE_KILL op1, USE op2); 11451 11452 format %{ "addq $op1, $op2\t# overflow check long" %} 11453 ins_encode %{ 11454 __ addq($op1$$Register, $op2$$Register); 11455 %} 11456 ins_pipe(ialu_reg_reg); 11457 %} 11458 11459 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11460 %{ 11461 match(Set cr (OverflowAddL op1 op2)); 11462 effect(DEF cr, USE_KILL op1, USE op2); 11463 11464 format %{ "addq $op1, $op2\t# overflow check long" %} 11465 ins_encode %{ 11466 __ addq($op1$$Register, $op2$$constant); 11467 %} 11468 ins_pipe(ialu_reg_reg); 11469 %} 11470 11471 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11472 %{ 11473 match(Set cr (OverflowSubI op1 op2)); 11474 11475 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11476 ins_encode %{ 11477 __ cmpl($op1$$Register, $op2$$Register); 11478 %} 11479 ins_pipe(ialu_reg_reg); 11480 %} 11481 11482 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11483 %{ 11484 match(Set cr (OverflowSubI op1 op2)); 11485 11486 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11487 ins_encode %{ 11488 __ cmpl($op1$$Register, $op2$$constant); 11489 %} 11490 ins_pipe(ialu_reg_reg); 11491 %} 11492 11493 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11494 %{ 11495 match(Set cr (OverflowSubL op1 op2)); 11496 11497 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11498 ins_encode %{ 11499 __ cmpq($op1$$Register, $op2$$Register); 11500 %} 11501 ins_pipe(ialu_reg_reg); 11502 %} 11503 11504 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11505 %{ 11506 match(Set cr (OverflowSubL op1 op2)); 11507 11508 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11509 ins_encode %{ 11510 __ cmpq($op1$$Register, $op2$$constant); 11511 %} 11512 ins_pipe(ialu_reg_reg); 11513 %} 11514 11515 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11516 %{ 11517 match(Set cr (OverflowSubI zero op2)); 11518 effect(DEF cr, USE_KILL op2); 11519 11520 format %{ "negl $op2\t# overflow check int" %} 11521 ins_encode %{ 11522 __ negl($op2$$Register); 11523 %} 11524 ins_pipe(ialu_reg_reg); 11525 %} 11526 11527 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11528 %{ 11529 match(Set cr (OverflowSubL zero op2)); 11530 effect(DEF cr, USE_KILL op2); 11531 11532 format %{ "negq $op2\t# overflow check long" %} 11533 ins_encode %{ 11534 __ negq($op2$$Register); 11535 %} 11536 ins_pipe(ialu_reg_reg); 11537 %} 11538 11539 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11540 %{ 11541 match(Set cr (OverflowMulI op1 op2)); 11542 effect(DEF cr, USE_KILL op1, USE op2); 11543 11544 format %{ "imull $op1, $op2\t# overflow check int" %} 11545 ins_encode %{ 11546 __ imull($op1$$Register, $op2$$Register); 11547 %} 11548 ins_pipe(ialu_reg_reg_alu0); 11549 %} 11550 11551 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11552 %{ 11553 match(Set cr (OverflowMulI op1 op2)); 11554 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11555 11556 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11557 ins_encode %{ 11558 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11559 %} 11560 ins_pipe(ialu_reg_reg_alu0); 11561 %} 11562 11563 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11564 %{ 11565 match(Set cr (OverflowMulL op1 op2)); 11566 effect(DEF cr, USE_KILL op1, USE op2); 11567 11568 format %{ "imulq $op1, $op2\t# overflow check long" %} 11569 ins_encode %{ 11570 __ imulq($op1$$Register, $op2$$Register); 11571 %} 11572 ins_pipe(ialu_reg_reg_alu0); 11573 %} 11574 11575 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11576 %{ 11577 match(Set cr (OverflowMulL op1 op2)); 11578 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11579 11580 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11581 ins_encode %{ 11582 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11583 %} 11584 ins_pipe(ialu_reg_reg_alu0); 11585 %} 11586 11587 11588 //----------Control Flow Instructions------------------------------------------ 11589 // Signed compare Instructions 11590 11591 // XXX more variants!! 11592 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11593 %{ 11594 match(Set cr (CmpI op1 op2)); 11595 effect(DEF cr, USE op1, USE op2); 11596 11597 format %{ "cmpl $op1, $op2" %} 11598 opcode(0x3B); /* Opcode 3B /r */ 11599 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11600 ins_pipe(ialu_cr_reg_reg); 11601 %} 11602 11603 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11604 %{ 11605 match(Set cr (CmpI op1 op2)); 11606 11607 format %{ "cmpl $op1, $op2" %} 11608 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11609 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11610 ins_pipe(ialu_cr_reg_imm); 11611 %} 11612 11613 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11614 %{ 11615 match(Set cr (CmpI op1 (LoadI op2))); 11616 11617 ins_cost(500); // XXX 11618 format %{ "cmpl $op1, $op2" %} 11619 opcode(0x3B); /* Opcode 3B /r */ 11620 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11621 ins_pipe(ialu_cr_reg_mem); 11622 %} 11623 11624 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11625 %{ 11626 match(Set cr (CmpI src zero)); 11627 11628 format %{ "testl $src, $src" %} 11629 opcode(0x85); 11630 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11631 ins_pipe(ialu_cr_reg_imm); 11632 %} 11633 11634 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11635 %{ 11636 match(Set cr (CmpI (AndI src con) zero)); 11637 11638 format %{ "testl $src, $con" %} 11639 opcode(0xF7, 0x00); 11640 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11641 ins_pipe(ialu_cr_reg_imm); 11642 %} 11643 11644 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11645 %{ 11646 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11647 11648 format %{ "testl $src, $mem" %} 11649 opcode(0x85); 11650 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11651 ins_pipe(ialu_cr_reg_mem); 11652 %} 11653 11654 // Unsigned compare Instructions; really, same as signed except they 11655 // produce an rFlagsRegU instead of rFlagsReg. 11656 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11657 %{ 11658 match(Set cr (CmpU op1 op2)); 11659 11660 format %{ "cmpl $op1, $op2\t# unsigned" %} 11661 opcode(0x3B); /* Opcode 3B /r */ 11662 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11663 ins_pipe(ialu_cr_reg_reg); 11664 %} 11665 11666 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11667 %{ 11668 match(Set cr (CmpU op1 op2)); 11669 11670 format %{ "cmpl $op1, $op2\t# unsigned" %} 11671 opcode(0x81,0x07); /* Opcode 81 /7 */ 11672 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11673 ins_pipe(ialu_cr_reg_imm); 11674 %} 11675 11676 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11677 %{ 11678 match(Set cr (CmpU op1 (LoadI op2))); 11679 11680 ins_cost(500); // XXX 11681 format %{ "cmpl $op1, $op2\t# unsigned" %} 11682 opcode(0x3B); /* Opcode 3B /r */ 11683 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11684 ins_pipe(ialu_cr_reg_mem); 11685 %} 11686 11687 // // // Cisc-spilled version of cmpU_rReg 11688 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11689 // //%{ 11690 // // match(Set cr (CmpU (LoadI op1) op2)); 11691 // // 11692 // // format %{ "CMPu $op1,$op2" %} 11693 // // ins_cost(500); 11694 // // opcode(0x39); /* Opcode 39 /r */ 11695 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11696 // //%} 11697 11698 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11699 %{ 11700 match(Set cr (CmpU src zero)); 11701 11702 format %{ "testl $src, $src\t# unsigned" %} 11703 opcode(0x85); 11704 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11705 ins_pipe(ialu_cr_reg_imm); 11706 %} 11707 11708 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11709 %{ 11710 match(Set cr (CmpP op1 op2)); 11711 11712 format %{ "cmpq $op1, $op2\t# ptr" %} 11713 opcode(0x3B); /* Opcode 3B /r */ 11714 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11715 ins_pipe(ialu_cr_reg_reg); 11716 %} 11717 11718 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11719 %{ 11720 match(Set cr (CmpP op1 (LoadP op2))); 11721 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11722 11723 ins_cost(500); // XXX 11724 format %{ "cmpq $op1, $op2\t# ptr" %} 11725 opcode(0x3B); /* Opcode 3B /r */ 11726 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11727 ins_pipe(ialu_cr_reg_mem); 11728 %} 11729 11730 // // // Cisc-spilled version of cmpP_rReg 11731 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11732 // //%{ 11733 // // match(Set cr (CmpP (LoadP op1) op2)); 11734 // // 11735 // // format %{ "CMPu $op1,$op2" %} 11736 // // ins_cost(500); 11737 // // opcode(0x39); /* Opcode 39 /r */ 11738 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11739 // //%} 11740 11741 // XXX this is generalized by compP_rReg_mem??? 11742 // Compare raw pointer (used in out-of-heap check). 11743 // Only works because non-oop pointers must be raw pointers 11744 // and raw pointers have no anti-dependencies. 11745 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11746 %{ 11747 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11748 n->in(2)->as_Load()->barrier_data() == 0); 11749 match(Set cr (CmpP op1 (LoadP op2))); 11750 11751 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11752 opcode(0x3B); /* Opcode 3B /r */ 11753 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11754 ins_pipe(ialu_cr_reg_mem); 11755 %} 11756 11757 // This will generate a signed flags result. This should be OK since 11758 // any compare to a zero should be eq/neq. 11759 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11760 %{ 11761 match(Set cr (CmpP src zero)); 11762 11763 format %{ "testq $src, $src\t# ptr" %} 11764 opcode(0x85); 11765 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11766 ins_pipe(ialu_cr_reg_imm); 11767 %} 11768 11769 // This will generate a signed flags result. This should be OK since 11770 // any compare to a zero should be eq/neq. 11771 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11772 %{ 11773 predicate((!UseCompressedOops || (CompressedOops::base() != NULL)) && 11774 n->in(1)->as_Load()->barrier_data() == 0); 11775 match(Set cr (CmpP (LoadP op) zero)); 11776 11777 ins_cost(500); // XXX 11778 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11779 opcode(0xF7); /* Opcode F7 /0 */ 11780 ins_encode(REX_mem_wide(op), 11781 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11782 ins_pipe(ialu_cr_reg_imm); 11783 %} 11784 11785 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11786 %{ 11787 predicate(UseCompressedOops && (CompressedOops::base() == NULL) && 11788 (CompressedKlassPointers::base() == NULL) && 11789 n->in(1)->as_Load()->barrier_data() == 0); 11790 match(Set cr (CmpP (LoadP mem) zero)); 11791 11792 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11793 ins_encode %{ 11794 __ cmpq(r12, $mem$$Address); 11795 %} 11796 ins_pipe(ialu_cr_reg_mem); 11797 %} 11798 11799 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11800 %{ 11801 match(Set cr (CmpN op1 op2)); 11802 11803 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11804 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11805 ins_pipe(ialu_cr_reg_reg); 11806 %} 11807 11808 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11809 %{ 11810 match(Set cr (CmpN src (LoadN mem))); 11811 11812 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11813 ins_encode %{ 11814 __ cmpl($src$$Register, $mem$$Address); 11815 %} 11816 ins_pipe(ialu_cr_reg_mem); 11817 %} 11818 11819 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11820 match(Set cr (CmpN op1 op2)); 11821 11822 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11823 ins_encode %{ 11824 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11825 %} 11826 ins_pipe(ialu_cr_reg_imm); 11827 %} 11828 11829 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11830 %{ 11831 match(Set cr (CmpN src (LoadN mem))); 11832 11833 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11834 ins_encode %{ 11835 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11836 %} 11837 ins_pipe(ialu_cr_reg_mem); 11838 %} 11839 11840 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11841 match(Set cr (CmpN op1 op2)); 11842 11843 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11844 ins_encode %{ 11845 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11846 %} 11847 ins_pipe(ialu_cr_reg_imm); 11848 %} 11849 11850 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11851 %{ 11852 match(Set cr (CmpN src (LoadNKlass mem))); 11853 11854 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11855 ins_encode %{ 11856 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11857 %} 11858 ins_pipe(ialu_cr_reg_mem); 11859 %} 11860 11861 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11862 match(Set cr (CmpN src zero)); 11863 11864 format %{ "testl $src, $src\t# compressed ptr" %} 11865 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11866 ins_pipe(ialu_cr_reg_imm); 11867 %} 11868 11869 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11870 %{ 11871 predicate(CompressedOops::base() != NULL); 11872 match(Set cr (CmpN (LoadN mem) zero)); 11873 11874 ins_cost(500); // XXX 11875 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11876 ins_encode %{ 11877 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11878 %} 11879 ins_pipe(ialu_cr_reg_mem); 11880 %} 11881 11882 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11883 %{ 11884 predicate(CompressedOops::base() == NULL && (CompressedKlassPointers::base() == NULL)); 11885 match(Set cr (CmpN (LoadN mem) zero)); 11886 11887 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11888 ins_encode %{ 11889 __ cmpl(r12, $mem$$Address); 11890 %} 11891 ins_pipe(ialu_cr_reg_mem); 11892 %} 11893 11894 // Yanked all unsigned pointer compare operations. 11895 // Pointer compares are done with CmpP which is already unsigned. 11896 11897 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11898 %{ 11899 match(Set cr (CmpL op1 op2)); 11900 11901 format %{ "cmpq $op1, $op2" %} 11902 opcode(0x3B); /* Opcode 3B /r */ 11903 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11904 ins_pipe(ialu_cr_reg_reg); 11905 %} 11906 11907 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11908 %{ 11909 match(Set cr (CmpL op1 op2)); 11910 11911 format %{ "cmpq $op1, $op2" %} 11912 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11913 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11914 ins_pipe(ialu_cr_reg_imm); 11915 %} 11916 11917 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11918 %{ 11919 match(Set cr (CmpL op1 (LoadL op2))); 11920 11921 format %{ "cmpq $op1, $op2" %} 11922 opcode(0x3B); /* Opcode 3B /r */ 11923 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11924 ins_pipe(ialu_cr_reg_mem); 11925 %} 11926 11927 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11928 %{ 11929 match(Set cr (CmpL src zero)); 11930 11931 format %{ "testq $src, $src" %} 11932 opcode(0x85); 11933 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11934 ins_pipe(ialu_cr_reg_imm); 11935 %} 11936 11937 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11938 %{ 11939 match(Set cr (CmpL (AndL src con) zero)); 11940 11941 format %{ "testq $src, $con\t# long" %} 11942 opcode(0xF7, 0x00); 11943 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11944 ins_pipe(ialu_cr_reg_imm); 11945 %} 11946 11947 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11948 %{ 11949 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11950 11951 format %{ "testq $src, $mem" %} 11952 opcode(0x85); 11953 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11954 ins_pipe(ialu_cr_reg_mem); 11955 %} 11956 11957 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11958 %{ 11959 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11960 11961 format %{ "testq $src, $mem" %} 11962 opcode(0x85); 11963 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11964 ins_pipe(ialu_cr_reg_mem); 11965 %} 11966 11967 // Manifest a CmpL result in an integer register. Very painful. 11968 // This is the test to avoid. 11969 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11970 %{ 11971 match(Set dst (CmpL3 src1 src2)); 11972 effect(KILL flags); 11973 11974 ins_cost(275); // XXX 11975 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11976 "movl $dst, -1\n\t" 11977 "jl,s done\n\t" 11978 "setne $dst\n\t" 11979 "movzbl $dst, $dst\n\t" 11980 "done:" %} 11981 ins_encode(cmpl3_flag(src1, src2, dst)); 11982 ins_pipe(pipe_slow); 11983 %} 11984 11985 // Unsigned long compare Instructions; really, same as signed long except they 11986 // produce an rFlagsRegU instead of rFlagsReg. 11987 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11988 %{ 11989 match(Set cr (CmpUL op1 op2)); 11990 11991 format %{ "cmpq $op1, $op2\t# unsigned" %} 11992 opcode(0x3B); /* Opcode 3B /r */ 11993 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11994 ins_pipe(ialu_cr_reg_reg); 11995 %} 11996 11997 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11998 %{ 11999 match(Set cr (CmpUL op1 op2)); 12000 12001 format %{ "cmpq $op1, $op2\t# unsigned" %} 12002 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12003 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12004 ins_pipe(ialu_cr_reg_imm); 12005 %} 12006 12007 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12008 %{ 12009 match(Set cr (CmpUL op1 (LoadL op2))); 12010 12011 format %{ "cmpq $op1, $op2\t# unsigned" %} 12012 opcode(0x3B); /* Opcode 3B /r */ 12013 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12014 ins_pipe(ialu_cr_reg_mem); 12015 %} 12016 12017 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12018 %{ 12019 match(Set cr (CmpUL src zero)); 12020 12021 format %{ "testq $src, $src\t# unsigned" %} 12022 opcode(0x85); 12023 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12024 ins_pipe(ialu_cr_reg_imm); 12025 %} 12026 12027 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12028 %{ 12029 match(Set cr (CmpI (LoadB mem) imm)); 12030 12031 ins_cost(125); 12032 format %{ "cmpb $mem, $imm" %} 12033 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12034 ins_pipe(ialu_cr_reg_mem); 12035 %} 12036 12037 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 12038 %{ 12039 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12040 12041 ins_cost(125); 12042 format %{ "testb $mem, $imm\t# ubyte" %} 12043 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12044 ins_pipe(ialu_cr_reg_mem); 12045 %} 12046 12047 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 12048 %{ 12049 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12050 12051 ins_cost(125); 12052 format %{ "testb $mem, $imm\t# byte" %} 12053 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12054 ins_pipe(ialu_cr_reg_mem); 12055 %} 12056 12057 //----------Max and Min-------------------------------------------------------- 12058 // Min Instructions 12059 12060 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12061 %{ 12062 effect(USE_DEF dst, USE src, USE cr); 12063 12064 format %{ "cmovlgt $dst, $src\t# min" %} 12065 opcode(0x0F, 0x4F); 12066 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12067 ins_pipe(pipe_cmov_reg); 12068 %} 12069 12070 12071 instruct minI_rReg(rRegI dst, rRegI src) 12072 %{ 12073 match(Set dst (MinI dst src)); 12074 12075 ins_cost(200); 12076 expand %{ 12077 rFlagsReg cr; 12078 compI_rReg(cr, dst, src); 12079 cmovI_reg_g(dst, src, cr); 12080 %} 12081 %} 12082 12083 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12084 %{ 12085 effect(USE_DEF dst, USE src, USE cr); 12086 12087 format %{ "cmovllt $dst, $src\t# max" %} 12088 opcode(0x0F, 0x4C); 12089 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12090 ins_pipe(pipe_cmov_reg); 12091 %} 12092 12093 12094 instruct maxI_rReg(rRegI dst, rRegI src) 12095 %{ 12096 match(Set dst (MaxI dst src)); 12097 12098 ins_cost(200); 12099 expand %{ 12100 rFlagsReg cr; 12101 compI_rReg(cr, dst, src); 12102 cmovI_reg_l(dst, src, cr); 12103 %} 12104 %} 12105 12106 // ============================================================================ 12107 // Branch Instructions 12108 12109 // Jump Direct - Label defines a relative address from JMP+1 12110 instruct jmpDir(label labl) 12111 %{ 12112 match(Goto); 12113 effect(USE labl); 12114 12115 ins_cost(300); 12116 format %{ "jmp $labl" %} 12117 size(5); 12118 ins_encode %{ 12119 Label* L = $labl$$label; 12120 __ jmp(*L, false); // Always long jump 12121 %} 12122 ins_pipe(pipe_jmp); 12123 %} 12124 12125 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12126 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12127 %{ 12128 match(If cop cr); 12129 effect(USE labl); 12130 12131 ins_cost(300); 12132 format %{ "j$cop $labl" %} 12133 size(6); 12134 ins_encode %{ 12135 Label* L = $labl$$label; 12136 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12137 %} 12138 ins_pipe(pipe_jcc); 12139 %} 12140 12141 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12142 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12143 %{ 12144 predicate(!n->has_vector_mask_set()); 12145 match(CountedLoopEnd cop cr); 12146 effect(USE labl); 12147 12148 ins_cost(300); 12149 format %{ "j$cop $labl\t# loop end" %} 12150 size(6); 12151 ins_encode %{ 12152 Label* L = $labl$$label; 12153 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12154 %} 12155 ins_pipe(pipe_jcc); 12156 %} 12157 12158 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12159 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12160 predicate(!n->has_vector_mask_set()); 12161 match(CountedLoopEnd cop cmp); 12162 effect(USE labl); 12163 12164 ins_cost(300); 12165 format %{ "j$cop,u $labl\t# loop end" %} 12166 size(6); 12167 ins_encode %{ 12168 Label* L = $labl$$label; 12169 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12170 %} 12171 ins_pipe(pipe_jcc); 12172 %} 12173 12174 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12175 predicate(!n->has_vector_mask_set()); 12176 match(CountedLoopEnd cop cmp); 12177 effect(USE labl); 12178 12179 ins_cost(200); 12180 format %{ "j$cop,u $labl\t# loop end" %} 12181 size(6); 12182 ins_encode %{ 12183 Label* L = $labl$$label; 12184 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12185 %} 12186 ins_pipe(pipe_jcc); 12187 %} 12188 12189 // mask version 12190 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12191 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12192 %{ 12193 predicate(n->has_vector_mask_set()); 12194 match(CountedLoopEnd cop cr); 12195 effect(USE labl); 12196 12197 ins_cost(400); 12198 format %{ "j$cop $labl\t# loop end\n\t" 12199 "restorevectmask \t# vector mask restore for loops" %} 12200 size(10); 12201 ins_encode %{ 12202 Label* L = $labl$$label; 12203 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12204 __ restorevectmask(); 12205 %} 12206 ins_pipe(pipe_jcc); 12207 %} 12208 12209 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12210 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12211 predicate(n->has_vector_mask_set()); 12212 match(CountedLoopEnd cop cmp); 12213 effect(USE labl); 12214 12215 ins_cost(400); 12216 format %{ "j$cop,u $labl\t# loop end\n\t" 12217 "restorevectmask \t# vector mask restore for loops" %} 12218 size(10); 12219 ins_encode %{ 12220 Label* L = $labl$$label; 12221 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12222 __ restorevectmask(); 12223 %} 12224 ins_pipe(pipe_jcc); 12225 %} 12226 12227 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12228 predicate(n->has_vector_mask_set()); 12229 match(CountedLoopEnd cop cmp); 12230 effect(USE labl); 12231 12232 ins_cost(300); 12233 format %{ "j$cop,u $labl\t# loop end\n\t" 12234 "restorevectmask \t# vector mask restore for loops" %} 12235 size(10); 12236 ins_encode %{ 12237 Label* L = $labl$$label; 12238 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12239 __ restorevectmask(); 12240 %} 12241 ins_pipe(pipe_jcc); 12242 %} 12243 12244 // Jump Direct Conditional - using unsigned comparison 12245 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12246 match(If cop cmp); 12247 effect(USE labl); 12248 12249 ins_cost(300); 12250 format %{ "j$cop,u $labl" %} 12251 size(6); 12252 ins_encode %{ 12253 Label* L = $labl$$label; 12254 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12255 %} 12256 ins_pipe(pipe_jcc); 12257 %} 12258 12259 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12260 match(If cop cmp); 12261 effect(USE labl); 12262 12263 ins_cost(200); 12264 format %{ "j$cop,u $labl" %} 12265 size(6); 12266 ins_encode %{ 12267 Label* L = $labl$$label; 12268 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12269 %} 12270 ins_pipe(pipe_jcc); 12271 %} 12272 12273 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12274 match(If cop cmp); 12275 effect(USE labl); 12276 12277 ins_cost(200); 12278 format %{ $$template 12279 if ($cop$$cmpcode == Assembler::notEqual) { 12280 $$emit$$"jp,u $labl\n\t" 12281 $$emit$$"j$cop,u $labl" 12282 } else { 12283 $$emit$$"jp,u done\n\t" 12284 $$emit$$"j$cop,u $labl\n\t" 12285 $$emit$$"done:" 12286 } 12287 %} 12288 ins_encode %{ 12289 Label* l = $labl$$label; 12290 if ($cop$$cmpcode == Assembler::notEqual) { 12291 __ jcc(Assembler::parity, *l, false); 12292 __ jcc(Assembler::notEqual, *l, false); 12293 } else if ($cop$$cmpcode == Assembler::equal) { 12294 Label done; 12295 __ jccb(Assembler::parity, done); 12296 __ jcc(Assembler::equal, *l, false); 12297 __ bind(done); 12298 } else { 12299 ShouldNotReachHere(); 12300 } 12301 %} 12302 ins_pipe(pipe_jcc); 12303 %} 12304 12305 // ============================================================================ 12306 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12307 // superklass array for an instance of the superklass. Set a hidden 12308 // internal cache on a hit (cache is checked with exposed code in 12309 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12310 // encoding ALSO sets flags. 12311 12312 instruct partialSubtypeCheck(rdi_RegP result, 12313 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12314 rFlagsReg cr) 12315 %{ 12316 match(Set result (PartialSubtypeCheck sub super)); 12317 effect(KILL rcx, KILL cr); 12318 12319 ins_cost(1100); // slightly larger than the next version 12320 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12321 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12322 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12323 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12324 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12325 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12326 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12327 "miss:\t" %} 12328 12329 opcode(0x1); // Force a XOR of RDI 12330 ins_encode(enc_PartialSubtypeCheck()); 12331 ins_pipe(pipe_slow); 12332 %} 12333 12334 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12335 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12336 immP0 zero, 12337 rdi_RegP result) 12338 %{ 12339 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12340 effect(KILL rcx, KILL result); 12341 12342 ins_cost(1000); 12343 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12344 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12345 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12346 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12347 "jne,s miss\t\t# Missed: flags nz\n\t" 12348 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12349 "miss:\t" %} 12350 12351 opcode(0x0); // No need to XOR RDI 12352 ins_encode(enc_PartialSubtypeCheck()); 12353 ins_pipe(pipe_slow); 12354 %} 12355 12356 // ============================================================================ 12357 // Branch Instructions -- short offset versions 12358 // 12359 // These instructions are used to replace jumps of a long offset (the default 12360 // match) with jumps of a shorter offset. These instructions are all tagged 12361 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12362 // match rules in general matching. Instead, the ADLC generates a conversion 12363 // method in the MachNode which can be used to do in-place replacement of the 12364 // long variant with the shorter variant. The compiler will determine if a 12365 // branch can be taken by the is_short_branch_offset() predicate in the machine 12366 // specific code section of the file. 12367 12368 // Jump Direct - Label defines a relative address from JMP+1 12369 instruct jmpDir_short(label labl) %{ 12370 match(Goto); 12371 effect(USE labl); 12372 12373 ins_cost(300); 12374 format %{ "jmp,s $labl" %} 12375 size(2); 12376 ins_encode %{ 12377 Label* L = $labl$$label; 12378 __ jmpb(*L); 12379 %} 12380 ins_pipe(pipe_jmp); 12381 ins_short_branch(1); 12382 %} 12383 12384 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12385 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12386 match(If cop cr); 12387 effect(USE labl); 12388 12389 ins_cost(300); 12390 format %{ "j$cop,s $labl" %} 12391 size(2); 12392 ins_encode %{ 12393 Label* L = $labl$$label; 12394 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12395 %} 12396 ins_pipe(pipe_jcc); 12397 ins_short_branch(1); 12398 %} 12399 12400 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12401 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12402 match(CountedLoopEnd cop cr); 12403 effect(USE labl); 12404 12405 ins_cost(300); 12406 format %{ "j$cop,s $labl\t# loop end" %} 12407 size(2); 12408 ins_encode %{ 12409 Label* L = $labl$$label; 12410 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12411 %} 12412 ins_pipe(pipe_jcc); 12413 ins_short_branch(1); 12414 %} 12415 12416 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12417 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12418 match(CountedLoopEnd cop cmp); 12419 effect(USE labl); 12420 12421 ins_cost(300); 12422 format %{ "j$cop,us $labl\t# loop end" %} 12423 size(2); 12424 ins_encode %{ 12425 Label* L = $labl$$label; 12426 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12427 %} 12428 ins_pipe(pipe_jcc); 12429 ins_short_branch(1); 12430 %} 12431 12432 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12433 match(CountedLoopEnd cop cmp); 12434 effect(USE labl); 12435 12436 ins_cost(300); 12437 format %{ "j$cop,us $labl\t# loop end" %} 12438 size(2); 12439 ins_encode %{ 12440 Label* L = $labl$$label; 12441 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12442 %} 12443 ins_pipe(pipe_jcc); 12444 ins_short_branch(1); 12445 %} 12446 12447 // Jump Direct Conditional - using unsigned comparison 12448 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12449 match(If cop cmp); 12450 effect(USE labl); 12451 12452 ins_cost(300); 12453 format %{ "j$cop,us $labl" %} 12454 size(2); 12455 ins_encode %{ 12456 Label* L = $labl$$label; 12457 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12458 %} 12459 ins_pipe(pipe_jcc); 12460 ins_short_branch(1); 12461 %} 12462 12463 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12464 match(If cop cmp); 12465 effect(USE labl); 12466 12467 ins_cost(300); 12468 format %{ "j$cop,us $labl" %} 12469 size(2); 12470 ins_encode %{ 12471 Label* L = $labl$$label; 12472 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12473 %} 12474 ins_pipe(pipe_jcc); 12475 ins_short_branch(1); 12476 %} 12477 12478 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12479 match(If cop cmp); 12480 effect(USE labl); 12481 12482 ins_cost(300); 12483 format %{ $$template 12484 if ($cop$$cmpcode == Assembler::notEqual) { 12485 $$emit$$"jp,u,s $labl\n\t" 12486 $$emit$$"j$cop,u,s $labl" 12487 } else { 12488 $$emit$$"jp,u,s done\n\t" 12489 $$emit$$"j$cop,u,s $labl\n\t" 12490 $$emit$$"done:" 12491 } 12492 %} 12493 size(4); 12494 ins_encode %{ 12495 Label* l = $labl$$label; 12496 if ($cop$$cmpcode == Assembler::notEqual) { 12497 __ jccb(Assembler::parity, *l); 12498 __ jccb(Assembler::notEqual, *l); 12499 } else if ($cop$$cmpcode == Assembler::equal) { 12500 Label done; 12501 __ jccb(Assembler::parity, done); 12502 __ jccb(Assembler::equal, *l); 12503 __ bind(done); 12504 } else { 12505 ShouldNotReachHere(); 12506 } 12507 %} 12508 ins_pipe(pipe_jcc); 12509 ins_short_branch(1); 12510 %} 12511 12512 // ============================================================================ 12513 // inlined locking and unlocking 12514 12515 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12516 predicate(Compile::current()->use_rtm()); 12517 match(Set cr (FastLock object box)); 12518 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12519 ins_cost(300); 12520 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12521 ins_encode %{ 12522 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12523 $scr$$Register, $cx1$$Register, $cx2$$Register, 12524 _counters, _rtm_counters, _stack_rtm_counters, 12525 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12526 true, ra_->C->profile_rtm()); 12527 %} 12528 ins_pipe(pipe_slow); 12529 %} 12530 12531 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12532 predicate(!Compile::current()->use_rtm()); 12533 match(Set cr (FastLock object box)); 12534 effect(TEMP tmp, TEMP scr, USE_KILL box); 12535 ins_cost(300); 12536 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12537 ins_encode %{ 12538 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12539 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12540 %} 12541 ins_pipe(pipe_slow); 12542 %} 12543 12544 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12545 match(Set cr (FastUnlock object box)); 12546 effect(TEMP tmp, USE_KILL box); 12547 ins_cost(300); 12548 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12549 ins_encode %{ 12550 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12551 %} 12552 ins_pipe(pipe_slow); 12553 %} 12554 12555 12556 // ============================================================================ 12557 // Safepoint Instructions 12558 instruct safePoint_poll(rFlagsReg cr) 12559 %{ 12560 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12561 match(SafePoint); 12562 effect(KILL cr); 12563 12564 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12565 "# Safepoint: poll for GC" %} 12566 ins_cost(125); 12567 ins_encode %{ 12568 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12569 __ testl(rax, addr); 12570 %} 12571 ins_pipe(ialu_reg_mem); 12572 %} 12573 12574 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12575 %{ 12576 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12577 match(SafePoint poll); 12578 effect(KILL cr, USE poll); 12579 12580 format %{ "testl rax, [$poll]\t" 12581 "# Safepoint: poll for GC" %} 12582 ins_cost(125); 12583 ins_encode %{ 12584 __ relocate(relocInfo::poll_type); 12585 __ testl(rax, Address($poll$$Register, 0)); 12586 %} 12587 ins_pipe(ialu_reg_mem); 12588 %} 12589 12590 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12591 %{ 12592 predicate(SafepointMechanism::uses_thread_local_poll()); 12593 match(SafePoint poll); 12594 effect(KILL cr, USE poll); 12595 12596 format %{ "testl rax, [$poll]\t" 12597 "# Safepoint: poll for GC" %} 12598 ins_cost(125); 12599 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12600 ins_encode %{ 12601 __ relocate(relocInfo::poll_type); 12602 address pre_pc = __ pc(); 12603 __ testl(rax, Address($poll$$Register, 0)); 12604 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12605 %} 12606 ins_pipe(ialu_reg_mem); 12607 %} 12608 12609 // ============================================================================ 12610 // Procedure Call/Return Instructions 12611 // Call Java Static Instruction 12612 // Note: If this code changes, the corresponding ret_addr_offset() and 12613 // compute_padding() functions will have to be adjusted. 12614 instruct CallStaticJavaDirect(method meth) %{ 12615 match(CallStaticJava); 12616 effect(USE meth); 12617 12618 ins_cost(300); 12619 format %{ "call,static " %} 12620 opcode(0xE8); /* E8 cd */ 12621 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12622 ins_pipe(pipe_slow); 12623 ins_alignment(4); 12624 %} 12625 12626 // Call Java Dynamic Instruction 12627 // Note: If this code changes, the corresponding ret_addr_offset() and 12628 // compute_padding() functions will have to be adjusted. 12629 instruct CallDynamicJavaDirect(method meth) 12630 %{ 12631 match(CallDynamicJava); 12632 effect(USE meth); 12633 12634 ins_cost(300); 12635 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12636 "call,dynamic " %} 12637 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12638 ins_pipe(pipe_slow); 12639 ins_alignment(4); 12640 %} 12641 12642 // Call Runtime Instruction 12643 instruct CallRuntimeDirect(method meth) 12644 %{ 12645 match(CallRuntime); 12646 effect(USE meth); 12647 12648 ins_cost(300); 12649 format %{ "call,runtime " %} 12650 ins_encode(clear_avx, Java_To_Runtime(meth)); 12651 ins_pipe(pipe_slow); 12652 %} 12653 12654 // Call runtime without safepoint 12655 instruct CallLeafDirect(method meth) 12656 %{ 12657 match(CallLeaf); 12658 effect(USE meth); 12659 12660 ins_cost(300); 12661 format %{ "call_leaf,runtime " %} 12662 ins_encode(clear_avx, Java_To_Runtime(meth)); 12663 ins_pipe(pipe_slow); 12664 %} 12665 12666 // Call runtime without safepoint 12667 instruct CallLeafNoFPDirect(method meth) 12668 %{ 12669 match(CallLeafNoFP); 12670 effect(USE meth); 12671 12672 ins_cost(300); 12673 format %{ "call_leaf_nofp,runtime " %} 12674 ins_encode(clear_avx, Java_To_Runtime(meth)); 12675 ins_pipe(pipe_slow); 12676 %} 12677 12678 // Return Instruction 12679 // Remove the return address & jump to it. 12680 // Notice: We always emit a nop after a ret to make sure there is room 12681 // for safepoint patching 12682 instruct Ret() 12683 %{ 12684 match(Return); 12685 12686 format %{ "ret" %} 12687 opcode(0xC3); 12688 ins_encode(OpcP); 12689 ins_pipe(pipe_jmp); 12690 %} 12691 12692 // Tail Call; Jump from runtime stub to Java code. 12693 // Also known as an 'interprocedural jump'. 12694 // Target of jump will eventually return to caller. 12695 // TailJump below removes the return address. 12696 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12697 %{ 12698 match(TailCall jump_target method_oop); 12699 12700 ins_cost(300); 12701 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12702 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12703 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12704 ins_pipe(pipe_jmp); 12705 %} 12706 12707 // Tail Jump; remove the return address; jump to target. 12708 // TailCall above leaves the return address around. 12709 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12710 %{ 12711 match(TailJump jump_target ex_oop); 12712 12713 ins_cost(300); 12714 format %{ "popq rdx\t# pop return address\n\t" 12715 "jmp $jump_target" %} 12716 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12717 ins_encode(Opcode(0x5a), // popq rdx 12718 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12719 ins_pipe(pipe_jmp); 12720 %} 12721 12722 // Create exception oop: created by stack-crawling runtime code. 12723 // Created exception is now available to this handler, and is setup 12724 // just prior to jumping to this handler. No code emitted. 12725 instruct CreateException(rax_RegP ex_oop) 12726 %{ 12727 match(Set ex_oop (CreateEx)); 12728 12729 size(0); 12730 // use the following format syntax 12731 format %{ "# exception oop is in rax; no code emitted" %} 12732 ins_encode(); 12733 ins_pipe(empty); 12734 %} 12735 12736 // Rethrow exception: 12737 // The exception oop will come in the first argument position. 12738 // Then JUMP (not call) to the rethrow stub code. 12739 instruct RethrowException() 12740 %{ 12741 match(Rethrow); 12742 12743 // use the following format syntax 12744 format %{ "jmp rethrow_stub" %} 12745 ins_encode(enc_rethrow); 12746 ins_pipe(pipe_jmp); 12747 %} 12748 12749 // ============================================================================ 12750 // This name is KNOWN by the ADLC and cannot be changed. 12751 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12752 // for this guy. 12753 instruct tlsLoadP(r15_RegP dst) %{ 12754 match(Set dst (ThreadLocal)); 12755 effect(DEF dst); 12756 12757 size(0); 12758 format %{ "# TLS is in R15" %} 12759 ins_encode( /*empty encoding*/ ); 12760 ins_pipe(ialu_reg_reg); 12761 %} 12762 12763 12764 //----------PEEPHOLE RULES----------------------------------------------------- 12765 // These must follow all instruction definitions as they use the names 12766 // defined in the instructions definitions. 12767 // 12768 // peepmatch ( root_instr_name [preceding_instruction]* ); 12769 // 12770 // peepconstraint %{ 12771 // (instruction_number.operand_name relational_op instruction_number.operand_name 12772 // [, ...] ); 12773 // // instruction numbers are zero-based using left to right order in peepmatch 12774 // 12775 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12776 // // provide an instruction_number.operand_name for each operand that appears 12777 // // in the replacement instruction's match rule 12778 // 12779 // ---------VM FLAGS--------------------------------------------------------- 12780 // 12781 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12782 // 12783 // Each peephole rule is given an identifying number starting with zero and 12784 // increasing by one in the order seen by the parser. An individual peephole 12785 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12786 // on the command-line. 12787 // 12788 // ---------CURRENT LIMITATIONS---------------------------------------------- 12789 // 12790 // Only match adjacent instructions in same basic block 12791 // Only equality constraints 12792 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12793 // Only one replacement instruction 12794 // 12795 // ---------EXAMPLE---------------------------------------------------------- 12796 // 12797 // // pertinent parts of existing instructions in architecture description 12798 // instruct movI(rRegI dst, rRegI src) 12799 // %{ 12800 // match(Set dst (CopyI src)); 12801 // %} 12802 // 12803 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12804 // %{ 12805 // match(Set dst (AddI dst src)); 12806 // effect(KILL cr); 12807 // %} 12808 // 12809 // // Change (inc mov) to lea 12810 // peephole %{ 12811 // // increment preceeded by register-register move 12812 // peepmatch ( incI_rReg movI ); 12813 // // require that the destination register of the increment 12814 // // match the destination register of the move 12815 // peepconstraint ( 0.dst == 1.dst ); 12816 // // construct a replacement instruction that sets 12817 // // the destination to ( move's source register + one ) 12818 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12819 // %} 12820 // 12821 12822 // Implementation no longer uses movX instructions since 12823 // machine-independent system no longer uses CopyX nodes. 12824 // 12825 // peephole 12826 // %{ 12827 // peepmatch (incI_rReg movI); 12828 // peepconstraint (0.dst == 1.dst); 12829 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12830 // %} 12831 12832 // peephole 12833 // %{ 12834 // peepmatch (decI_rReg movI); 12835 // peepconstraint (0.dst == 1.dst); 12836 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12837 // %} 12838 12839 // peephole 12840 // %{ 12841 // peepmatch (addI_rReg_imm movI); 12842 // peepconstraint (0.dst == 1.dst); 12843 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12844 // %} 12845 12846 // peephole 12847 // %{ 12848 // peepmatch (incL_rReg movL); 12849 // peepconstraint (0.dst == 1.dst); 12850 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12851 // %} 12852 12853 // peephole 12854 // %{ 12855 // peepmatch (decL_rReg movL); 12856 // peepconstraint (0.dst == 1.dst); 12857 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12858 // %} 12859 12860 // peephole 12861 // %{ 12862 // peepmatch (addL_rReg_imm movL); 12863 // peepconstraint (0.dst == 1.dst); 12864 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12865 // %} 12866 12867 // peephole 12868 // %{ 12869 // peepmatch (addP_rReg_imm movP); 12870 // peepconstraint (0.dst == 1.dst); 12871 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12872 // %} 12873 12874 // // Change load of spilled value to only a spill 12875 // instruct storeI(memory mem, rRegI src) 12876 // %{ 12877 // match(Set mem (StoreI mem src)); 12878 // %} 12879 // 12880 // instruct loadI(rRegI dst, memory mem) 12881 // %{ 12882 // match(Set dst (LoadI mem)); 12883 // %} 12884 // 12885 12886 peephole 12887 %{ 12888 peepmatch (loadI storeI); 12889 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12890 peepreplace (storeI(1.mem 1.mem 1.src)); 12891 %} 12892 12893 peephole 12894 %{ 12895 peepmatch (loadL storeL); 12896 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12897 peepreplace (storeL(1.mem 1.mem 1.src)); 12898 %} 12899 12900 //----------SMARTSPILL RULES--------------------------------------------------- 12901 // These must follow all instruction definitions as they use the names 12902 // defined in the instructions definitions.