1 // 2 // Copyright (c) 2003, 2023, 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 // architecture. 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 stack_slots( /* one chunk of stack-based "registers" */ ) 165 // 166 167 // Empty register class. 168 reg_class no_reg(); 169 170 // Class for all pointer/long registers 171 reg_class all_reg(RAX, RAX_H, 172 RDX, RDX_H, 173 RBP, RBP_H, 174 RDI, RDI_H, 175 RSI, RSI_H, 176 RCX, RCX_H, 177 RBX, RBX_H, 178 RSP, RSP_H, 179 R8, R8_H, 180 R9, R9_H, 181 R10, R10_H, 182 R11, R11_H, 183 R12, R12_H, 184 R13, R13_H, 185 R14, R14_H, 186 R15, R15_H); 187 188 // Class for all int registers 189 reg_class all_int_reg(RAX 190 RDX, 191 RBP, 192 RDI, 193 RSI, 194 RCX, 195 RBX, 196 R8, 197 R9, 198 R10, 199 R11, 200 R12, 201 R13, 202 R14); 203 204 // Class for all pointer registers 205 reg_class any_reg %{ 206 return _ANY_REG_mask; 207 %} 208 209 // Class for all pointer registers (excluding RSP) 210 reg_class ptr_reg %{ 211 return _PTR_REG_mask; 212 %} 213 214 // Class for all pointer registers (excluding RSP and RBP) 215 reg_class ptr_reg_no_rbp %{ 216 return _PTR_REG_NO_RBP_mask; 217 %} 218 219 // Class for all pointer registers (excluding RAX and RSP) 220 reg_class ptr_no_rax_reg %{ 221 return _PTR_NO_RAX_REG_mask; 222 %} 223 224 // Class for all pointer registers (excluding RAX, RBX, and RSP) 225 reg_class ptr_no_rax_rbx_reg %{ 226 return _PTR_NO_RAX_RBX_REG_mask; 227 %} 228 229 // Class for all long registers (excluding RSP) 230 reg_class long_reg %{ 231 return _LONG_REG_mask; 232 %} 233 234 // Class for all long registers (excluding RAX, RDX and RSP) 235 reg_class long_no_rax_rdx_reg %{ 236 return _LONG_NO_RAX_RDX_REG_mask; 237 %} 238 239 // Class for all long registers (excluding RCX and RSP) 240 reg_class long_no_rcx_reg %{ 241 return _LONG_NO_RCX_REG_mask; 242 %} 243 244 // Class for all long registers (excluding RBP and R13) 245 reg_class long_no_rbp_r13_reg %{ 246 return _LONG_NO_RBP_R13_REG_mask; 247 %} 248 249 // Class for all int registers (excluding RSP) 250 reg_class int_reg %{ 251 return _INT_REG_mask; 252 %} 253 254 // Class for all int registers (excluding RAX, RDX, and RSP) 255 reg_class int_no_rax_rdx_reg %{ 256 return _INT_NO_RAX_RDX_REG_mask; 257 %} 258 259 // Class for all int registers (excluding RCX and RSP) 260 reg_class int_no_rcx_reg %{ 261 return _INT_NO_RCX_REG_mask; 262 %} 263 264 // Class for all int registers (excluding RBP and R13) 265 reg_class int_no_rbp_r13_reg %{ 266 return _INT_NO_RBP_R13_REG_mask; 267 %} 268 269 // Singleton class for RAX pointer register 270 reg_class ptr_rax_reg(RAX, RAX_H); 271 272 // Singleton class for RBX pointer register 273 reg_class ptr_rbx_reg(RBX, RBX_H); 274 275 // Singleton class for RSI pointer register 276 reg_class ptr_rsi_reg(RSI, RSI_H); 277 278 // Singleton class for RBP pointer register 279 reg_class ptr_rbp_reg(RBP, RBP_H); 280 281 // Singleton class for RDI pointer register 282 reg_class ptr_rdi_reg(RDI, RDI_H); 283 284 // Singleton class for stack pointer 285 reg_class ptr_rsp_reg(RSP, RSP_H); 286 287 // Singleton class for TLS pointer 288 reg_class ptr_r15_reg(R15, R15_H); 289 290 // Singleton class for RAX long register 291 reg_class long_rax_reg(RAX, RAX_H); 292 293 // Singleton class for RCX long register 294 reg_class long_rcx_reg(RCX, RCX_H); 295 296 // Singleton class for RDX long register 297 reg_class long_rdx_reg(RDX, RDX_H); 298 299 // Singleton class for RAX int register 300 reg_class int_rax_reg(RAX); 301 302 // Singleton class for RBX int register 303 reg_class int_rbx_reg(RBX); 304 305 // Singleton class for RCX int register 306 reg_class int_rcx_reg(RCX); 307 308 // Singleton class for RDX int register 309 reg_class int_rdx_reg(RDX); 310 311 // Singleton class for RDI int register 312 reg_class int_rdi_reg(RDI); 313 314 // Singleton class for instruction pointer 315 // reg_class ip_reg(RIP); 316 317 %} 318 319 //----------SOURCE BLOCK------------------------------------------------------- 320 // This is a block of C++ code which provides values, functions, and 321 // definitions necessary in the rest of the architecture description 322 323 source_hpp %{ 324 325 #include "peephole_x86_64.hpp" 326 327 %} 328 329 // Register masks 330 source_hpp %{ 331 332 extern RegMask _ANY_REG_mask; 333 extern RegMask _PTR_REG_mask; 334 extern RegMask _PTR_REG_NO_RBP_mask; 335 extern RegMask _PTR_NO_RAX_REG_mask; 336 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 337 extern RegMask _LONG_REG_mask; 338 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 339 extern RegMask _LONG_NO_RCX_REG_mask; 340 extern RegMask _LONG_NO_RBP_R13_REG_mask; 341 extern RegMask _INT_REG_mask; 342 extern RegMask _INT_NO_RAX_RDX_REG_mask; 343 extern RegMask _INT_NO_RCX_REG_mask; 344 extern RegMask _INT_NO_RBP_R13_REG_mask; 345 extern RegMask _FLOAT_REG_mask; 346 347 extern RegMask _STACK_OR_PTR_REG_mask; 348 extern RegMask _STACK_OR_LONG_REG_mask; 349 extern RegMask _STACK_OR_INT_REG_mask; 350 351 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 352 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 353 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 354 355 %} 356 357 source %{ 358 #define RELOC_IMM64 Assembler::imm_operand 359 #define RELOC_DISP32 Assembler::disp32_operand 360 361 #define __ _masm. 362 363 RegMask _ANY_REG_mask; 364 RegMask _PTR_REG_mask; 365 RegMask _PTR_REG_NO_RBP_mask; 366 RegMask _PTR_NO_RAX_REG_mask; 367 RegMask _PTR_NO_RAX_RBX_REG_mask; 368 RegMask _LONG_REG_mask; 369 RegMask _LONG_NO_RAX_RDX_REG_mask; 370 RegMask _LONG_NO_RCX_REG_mask; 371 RegMask _LONG_NO_RBP_R13_REG_mask; 372 RegMask _INT_REG_mask; 373 RegMask _INT_NO_RAX_RDX_REG_mask; 374 RegMask _INT_NO_RCX_REG_mask; 375 RegMask _INT_NO_RBP_R13_REG_mask; 376 RegMask _FLOAT_REG_mask; 377 RegMask _STACK_OR_PTR_REG_mask; 378 RegMask _STACK_OR_LONG_REG_mask; 379 RegMask _STACK_OR_INT_REG_mask; 380 381 static bool need_r12_heapbase() { 382 return UseCompressedOops; 383 } 384 385 void reg_mask_init() { 386 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 387 // We derive a number of subsets from it. 388 _ANY_REG_mask = _ALL_REG_mask; 389 390 if (PreserveFramePointer) { 391 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 392 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 393 } 394 if (need_r12_heapbase()) { 395 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 396 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 397 } 398 399 _PTR_REG_mask = _ANY_REG_mask; 400 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 401 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 402 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 403 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 404 405 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 406 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 407 408 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 409 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 410 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 411 412 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 413 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 414 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 415 416 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 417 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 418 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 419 420 _LONG_REG_mask = _PTR_REG_mask; 421 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 422 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 423 424 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 425 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 426 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 427 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 428 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 429 430 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 431 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 432 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 433 434 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 435 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 436 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 437 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 438 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 439 440 _INT_REG_mask = _ALL_INT_REG_mask; 441 if (PreserveFramePointer) { 442 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 443 } 444 if (need_r12_heapbase()) { 445 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 446 } 447 448 _STACK_OR_INT_REG_mask = _INT_REG_mask; 449 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 450 451 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 452 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 453 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 454 455 _INT_NO_RCX_REG_mask = _INT_REG_mask; 456 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 457 458 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 459 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 460 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 461 462 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 463 // from the float_reg_legacy/float_reg_evex register class. 464 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 465 } 466 467 static bool generate_vzeroupper(Compile* C) { 468 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 469 } 470 471 static int clear_avx_size() { 472 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 473 } 474 475 // !!!!! Special hack to get all types of calls to specify the byte offset 476 // from the start of the call to the point where the return address 477 // will point. 478 int MachCallStaticJavaNode::ret_addr_offset() 479 { 480 int offset = 5; // 5 bytes from start of call to where return address points 481 offset += clear_avx_size(); 482 return offset; 483 } 484 485 int MachCallDynamicJavaNode::ret_addr_offset() 486 { 487 int offset = 15; // 15 bytes from start of call to where return address points 488 offset += clear_avx_size(); 489 return offset; 490 } 491 492 int MachCallRuntimeNode::ret_addr_offset() { 493 if (_entry_point == nullptr) { 494 // CallLeafNoFPInDirect 495 return 3; // callq (register) 496 } 497 int offset = 13; // movq r10,#addr; callq (r10) 498 if (this->ideal_Opcode() != Op_CallLeafVector) { 499 offset += clear_avx_size(); 500 } 501 return offset; 502 } 503 504 // 505 // Compute padding required for nodes which need alignment 506 // 507 508 // The address of the call instruction needs to be 4-byte aligned to 509 // ensure that it does not span a cache line so that it can be patched. 510 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 511 { 512 current_offset += clear_avx_size(); // skip vzeroupper 513 current_offset += 1; // skip call opcode byte 514 return align_up(current_offset, alignment_required()) - current_offset; 515 } 516 517 // The address of the call instruction needs to be 4-byte aligned to 518 // ensure that it does not span a cache line so that it can be patched. 519 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 520 { 521 current_offset += clear_avx_size(); // skip vzeroupper 522 current_offset += 11; // skip movq instruction + call opcode byte 523 return align_up(current_offset, alignment_required()) - current_offset; 524 } 525 526 // This could be in MacroAssembler but it's fairly C2 specific 527 void emit_cmpfp_fixup(MacroAssembler& _masm) { 528 Label exit; 529 __ jccb(Assembler::noParity, exit); 530 __ pushf(); 531 // 532 // comiss/ucomiss instructions set ZF,PF,CF flags and 533 // zero OF,AF,SF for NaN values. 534 // Fixup flags by zeroing ZF,PF so that compare of NaN 535 // values returns 'less than' result (CF is set). 536 // Leave the rest of flags unchanged. 537 // 538 // 7 6 5 4 3 2 1 0 539 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 540 // 0 0 1 0 1 0 1 1 (0x2B) 541 // 542 __ andq(Address(rsp, 0), 0xffffff2b); 543 __ popf(); 544 __ bind(exit); 545 } 546 547 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 548 Label done; 549 __ movl(dst, -1); 550 __ jcc(Assembler::parity, done); 551 __ jcc(Assembler::below, done); 552 __ setb(Assembler::notEqual, dst); 553 __ movzbl(dst, dst); 554 __ bind(done); 555 } 556 557 // Math.min() # Math.max() 558 // -------------------------- 559 // ucomis[s/d] # 560 // ja -> b # a 561 // jp -> NaN # NaN 562 // jb -> a # b 563 // je # 564 // |-jz -> a | b # a & b 565 // | -> a # 566 void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst, 567 XMMRegister a, XMMRegister b, 568 XMMRegister xmmt, Register rt, 569 bool min, bool single) { 570 571 Label nan, zero, below, above, done; 572 573 if (single) 574 __ ucomiss(a, b); 575 else 576 __ ucomisd(a, b); 577 578 if (dst->encoding() != (min ? b : a)->encoding()) 579 __ jccb(Assembler::above, above); // CF=0 & ZF=0 580 else 581 __ jccb(Assembler::above, done); 582 583 __ jccb(Assembler::parity, nan); // PF=1 584 __ jccb(Assembler::below, below); // CF=1 585 586 // equal 587 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 588 if (single) { 589 __ ucomiss(a, xmmt); 590 __ jccb(Assembler::equal, zero); 591 592 __ movflt(dst, a); 593 __ jmp(done); 594 } 595 else { 596 __ ucomisd(a, xmmt); 597 __ jccb(Assembler::equal, zero); 598 599 __ movdbl(dst, a); 600 __ jmp(done); 601 } 602 603 __ bind(zero); 604 if (min) 605 __ vpor(dst, a, b, Assembler::AVX_128bit); 606 else 607 __ vpand(dst, a, b, Assembler::AVX_128bit); 608 609 __ jmp(done); 610 611 __ bind(above); 612 if (single) 613 __ movflt(dst, min ? b : a); 614 else 615 __ movdbl(dst, min ? b : a); 616 617 __ jmp(done); 618 619 __ bind(nan); 620 if (single) { 621 __ movl(rt, 0x7fc00000); // Float.NaN 622 __ movdl(dst, rt); 623 } 624 else { 625 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 626 __ movdq(dst, rt); 627 } 628 __ jmp(done); 629 630 __ bind(below); 631 if (single) 632 __ movflt(dst, min ? a : b); 633 else 634 __ movdbl(dst, min ? a : b); 635 636 __ bind(done); 637 } 638 639 //============================================================================= 640 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 641 642 int ConstantTable::calculate_table_base_offset() const { 643 return 0; // absolute addressing, no offset 644 } 645 646 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 647 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 648 ShouldNotReachHere(); 649 } 650 651 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 652 // Empty encoding 653 } 654 655 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 656 return 0; 657 } 658 659 #ifndef PRODUCT 660 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 661 st->print("# MachConstantBaseNode (empty encoding)"); 662 } 663 #endif 664 665 666 //============================================================================= 667 #ifndef PRODUCT 668 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 669 Compile* C = ra_->C; 670 671 int framesize = C->output()->frame_size_in_bytes(); 672 int bangsize = C->output()->bang_size_in_bytes(); 673 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 674 // Remove wordSize for return addr which is already pushed. 675 framesize -= wordSize; 676 677 if (C->output()->need_stack_bang(bangsize)) { 678 framesize -= wordSize; 679 st->print("# stack bang (%d bytes)", bangsize); 680 st->print("\n\t"); 681 st->print("pushq rbp\t# Save rbp"); 682 if (PreserveFramePointer) { 683 st->print("\n\t"); 684 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 685 } 686 if (framesize) { 687 st->print("\n\t"); 688 st->print("subq rsp, #%d\t# Create frame",framesize); 689 } 690 } else { 691 st->print("subq rsp, #%d\t# Create frame",framesize); 692 st->print("\n\t"); 693 framesize -= wordSize; 694 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 695 if (PreserveFramePointer) { 696 st->print("\n\t"); 697 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 698 if (framesize > 0) { 699 st->print("\n\t"); 700 st->print("addq rbp, #%d", framesize); 701 } 702 } 703 } 704 705 if (VerifyStackAtCalls) { 706 st->print("\n\t"); 707 framesize -= wordSize; 708 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 709 #ifdef ASSERT 710 st->print("\n\t"); 711 st->print("# stack alignment check"); 712 #endif 713 } 714 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 715 st->print("\n\t"); 716 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 717 st->print("\n\t"); 718 st->print("je fast_entry\t"); 719 st->print("\n\t"); 720 st->print("call #nmethod_entry_barrier_stub\t"); 721 st->print("\n\tfast_entry:"); 722 } 723 st->cr(); 724 } 725 #endif 726 727 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 728 Compile* C = ra_->C; 729 C2_MacroAssembler _masm(&cbuf); 730 731 __ verified_entry(C); 732 733 if (ra_->C->stub_function() == nullptr) { 734 __ entry_barrier(); 735 } 736 737 if (!Compile::current()->output()->in_scratch_emit_size()) { 738 __ bind(*_verified_entry); 739 } 740 741 C->output()->set_frame_complete(cbuf.insts_size()); 742 743 if (C->has_mach_constant_base_node()) { 744 // NOTE: We set the table base offset here because users might be 745 // emitted before MachConstantBaseNode. 746 ConstantTable& constant_table = C->output()->constant_table(); 747 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 748 } 749 } 750 751 int MachPrologNode::reloc() const 752 { 753 return 0; // a large enough number 754 } 755 756 //============================================================================= 757 #ifndef PRODUCT 758 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 759 { 760 Compile* C = ra_->C; 761 if (generate_vzeroupper(C)) { 762 st->print("vzeroupper"); 763 st->cr(); st->print("\t"); 764 } 765 766 int framesize = C->output()->frame_size_in_bytes(); 767 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 768 // Remove word for return adr already pushed 769 // and RBP 770 framesize -= 2*wordSize; 771 772 if (framesize) { 773 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 774 st->print("\t"); 775 } 776 777 st->print_cr("popq rbp"); 778 if (do_polling() && C->is_method_compilation()) { 779 st->print("\t"); 780 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 781 "ja #safepoint_stub\t" 782 "# Safepoint: poll for GC"); 783 } 784 } 785 #endif 786 787 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 788 { 789 Compile* C = ra_->C; 790 MacroAssembler _masm(&cbuf); 791 792 if (generate_vzeroupper(C)) { 793 // Clear upper bits of YMM registers when current compiled code uses 794 // wide vectors to avoid AVX <-> SSE transition penalty during call. 795 __ vzeroupper(); 796 } 797 798 // Subtract two words to account for return address and rbp 799 int initial_framesize = C->output()->frame_size_in_bytes() - 2*wordSize; 800 __ remove_frame(initial_framesize, C->needs_stack_repair()); 801 802 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 803 __ reserved_stack_check(); 804 } 805 806 if (do_polling() && C->is_method_compilation()) { 807 MacroAssembler _masm(&cbuf); 808 Label dummy_label; 809 Label* code_stub = &dummy_label; 810 if (!C->output()->in_scratch_emit_size()) { 811 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 812 C->output()->add_stub(stub); 813 code_stub = &stub->entry(); 814 } 815 __ relocate(relocInfo::poll_return_type); 816 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 817 } 818 } 819 820 int MachEpilogNode::reloc() const 821 { 822 return 2; // a large enough number 823 } 824 825 const Pipeline* MachEpilogNode::pipeline() const 826 { 827 return MachNode::pipeline_class(); 828 } 829 830 //============================================================================= 831 832 enum RC { 833 rc_bad, 834 rc_int, 835 rc_kreg, 836 rc_float, 837 rc_stack 838 }; 839 840 static enum RC rc_class(OptoReg::Name reg) 841 { 842 if( !OptoReg::is_valid(reg) ) return rc_bad; 843 844 if (OptoReg::is_stack(reg)) return rc_stack; 845 846 VMReg r = OptoReg::as_VMReg(reg); 847 848 if (r->is_Register()) return rc_int; 849 850 if (r->is_KRegister()) return rc_kreg; 851 852 assert(r->is_XMMRegister(), "must be"); 853 return rc_float; 854 } 855 856 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 857 static void vec_mov_helper(CodeBuffer *cbuf, int src_lo, int dst_lo, 858 int src_hi, int dst_hi, uint ireg, outputStream* st); 859 860 void vec_spill_helper(CodeBuffer *cbuf, bool is_load, 861 int stack_offset, int reg, uint ireg, outputStream* st); 862 863 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 864 int dst_offset, uint ireg, outputStream* st) { 865 if (cbuf) { 866 MacroAssembler _masm(cbuf); 867 switch (ireg) { 868 case Op_VecS: 869 __ movq(Address(rsp, -8), rax); 870 __ movl(rax, Address(rsp, src_offset)); 871 __ movl(Address(rsp, dst_offset), rax); 872 __ movq(rax, Address(rsp, -8)); 873 break; 874 case Op_VecD: 875 __ pushq(Address(rsp, src_offset)); 876 __ popq (Address(rsp, dst_offset)); 877 break; 878 case Op_VecX: 879 __ pushq(Address(rsp, src_offset)); 880 __ popq (Address(rsp, dst_offset)); 881 __ pushq(Address(rsp, src_offset+8)); 882 __ popq (Address(rsp, dst_offset+8)); 883 break; 884 case Op_VecY: 885 __ vmovdqu(Address(rsp, -32), xmm0); 886 __ vmovdqu(xmm0, Address(rsp, src_offset)); 887 __ vmovdqu(Address(rsp, dst_offset), xmm0); 888 __ vmovdqu(xmm0, Address(rsp, -32)); 889 break; 890 case Op_VecZ: 891 __ evmovdquq(Address(rsp, -64), xmm0, 2); 892 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 893 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 894 __ evmovdquq(xmm0, Address(rsp, -64), 2); 895 break; 896 default: 897 ShouldNotReachHere(); 898 } 899 #ifndef PRODUCT 900 } else { 901 switch (ireg) { 902 case Op_VecS: 903 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 904 "movl rax, [rsp + #%d]\n\t" 905 "movl [rsp + #%d], rax\n\t" 906 "movq rax, [rsp - #8]", 907 src_offset, dst_offset); 908 break; 909 case Op_VecD: 910 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 911 "popq [rsp + #%d]", 912 src_offset, dst_offset); 913 break; 914 case Op_VecX: 915 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 916 "popq [rsp + #%d]\n\t" 917 "pushq [rsp + #%d]\n\t" 918 "popq [rsp + #%d]", 919 src_offset, dst_offset, src_offset+8, dst_offset+8); 920 break; 921 case Op_VecY: 922 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 923 "vmovdqu xmm0, [rsp + #%d]\n\t" 924 "vmovdqu [rsp + #%d], xmm0\n\t" 925 "vmovdqu xmm0, [rsp - #32]", 926 src_offset, dst_offset); 927 break; 928 case Op_VecZ: 929 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 930 "vmovdqu xmm0, [rsp + #%d]\n\t" 931 "vmovdqu [rsp + #%d], xmm0\n\t" 932 "vmovdqu xmm0, [rsp - #64]", 933 src_offset, dst_offset); 934 break; 935 default: 936 ShouldNotReachHere(); 937 } 938 #endif 939 } 940 } 941 942 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 943 PhaseRegAlloc* ra_, 944 bool do_size, 945 outputStream* st) const { 946 assert(cbuf != nullptr || st != nullptr, "sanity"); 947 // Get registers to move 948 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 949 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 950 OptoReg::Name dst_second = ra_->get_reg_second(this); 951 OptoReg::Name dst_first = ra_->get_reg_first(this); 952 953 enum RC src_second_rc = rc_class(src_second); 954 enum RC src_first_rc = rc_class(src_first); 955 enum RC dst_second_rc = rc_class(dst_second); 956 enum RC dst_first_rc = rc_class(dst_first); 957 958 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 959 "must move at least 1 register" ); 960 961 if (src_first == dst_first && src_second == dst_second) { 962 // Self copy, no move 963 return 0; 964 } 965 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 966 uint ireg = ideal_reg(); 967 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 968 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 969 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 970 // mem -> mem 971 int src_offset = ra_->reg2offset(src_first); 972 int dst_offset = ra_->reg2offset(dst_first); 973 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 974 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 975 vec_mov_helper(cbuf, src_first, dst_first, src_second, dst_second, ireg, st); 976 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 977 int stack_offset = ra_->reg2offset(dst_first); 978 vec_spill_helper(cbuf, false, stack_offset, src_first, ireg, st); 979 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 980 int stack_offset = ra_->reg2offset(src_first); 981 vec_spill_helper(cbuf, true, stack_offset, dst_first, ireg, st); 982 } else { 983 ShouldNotReachHere(); 984 } 985 return 0; 986 } 987 if (src_first_rc == rc_stack) { 988 // mem -> 989 if (dst_first_rc == rc_stack) { 990 // mem -> mem 991 assert(src_second != dst_first, "overlap"); 992 if ((src_first & 1) == 0 && src_first + 1 == src_second && 993 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 994 // 64-bit 995 int src_offset = ra_->reg2offset(src_first); 996 int dst_offset = ra_->reg2offset(dst_first); 997 if (cbuf) { 998 MacroAssembler _masm(cbuf); 999 __ pushq(Address(rsp, src_offset)); 1000 __ popq (Address(rsp, dst_offset)); 1001 #ifndef PRODUCT 1002 } else { 1003 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1004 "popq [rsp + #%d]", 1005 src_offset, dst_offset); 1006 #endif 1007 } 1008 } else { 1009 // 32-bit 1010 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1011 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1012 // No pushl/popl, so: 1013 int src_offset = ra_->reg2offset(src_first); 1014 int dst_offset = ra_->reg2offset(dst_first); 1015 if (cbuf) { 1016 MacroAssembler _masm(cbuf); 1017 __ movq(Address(rsp, -8), rax); 1018 __ movl(rax, Address(rsp, src_offset)); 1019 __ movl(Address(rsp, dst_offset), rax); 1020 __ movq(rax, Address(rsp, -8)); 1021 #ifndef PRODUCT 1022 } else { 1023 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1024 "movl rax, [rsp + #%d]\n\t" 1025 "movl [rsp + #%d], rax\n\t" 1026 "movq rax, [rsp - #8]", 1027 src_offset, dst_offset); 1028 #endif 1029 } 1030 } 1031 return 0; 1032 } else if (dst_first_rc == rc_int) { 1033 // mem -> gpr 1034 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1035 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1036 // 64-bit 1037 int offset = ra_->reg2offset(src_first); 1038 if (cbuf) { 1039 MacroAssembler _masm(cbuf); 1040 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1041 #ifndef PRODUCT 1042 } else { 1043 st->print("movq %s, [rsp + #%d]\t# spill", 1044 Matcher::regName[dst_first], 1045 offset); 1046 #endif 1047 } 1048 } else { 1049 // 32-bit 1050 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1051 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1052 int offset = ra_->reg2offset(src_first); 1053 if (cbuf) { 1054 MacroAssembler _masm(cbuf); 1055 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1056 #ifndef PRODUCT 1057 } else { 1058 st->print("movl %s, [rsp + #%d]\t# spill", 1059 Matcher::regName[dst_first], 1060 offset); 1061 #endif 1062 } 1063 } 1064 return 0; 1065 } else if (dst_first_rc == rc_float) { 1066 // mem-> xmm 1067 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1068 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1069 // 64-bit 1070 int offset = ra_->reg2offset(src_first); 1071 if (cbuf) { 1072 MacroAssembler _masm(cbuf); 1073 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1074 #ifndef PRODUCT 1075 } else { 1076 st->print("%s %s, [rsp + #%d]\t# spill", 1077 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1078 Matcher::regName[dst_first], 1079 offset); 1080 #endif 1081 } 1082 } else { 1083 // 32-bit 1084 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1085 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1086 int offset = ra_->reg2offset(src_first); 1087 if (cbuf) { 1088 MacroAssembler _masm(cbuf); 1089 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1090 #ifndef PRODUCT 1091 } else { 1092 st->print("movss %s, [rsp + #%d]\t# spill", 1093 Matcher::regName[dst_first], 1094 offset); 1095 #endif 1096 } 1097 } 1098 return 0; 1099 } else if (dst_first_rc == rc_kreg) { 1100 // mem -> kreg 1101 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1102 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1103 // 64-bit 1104 int offset = ra_->reg2offset(src_first); 1105 if (cbuf) { 1106 MacroAssembler _masm(cbuf); 1107 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1108 #ifndef PRODUCT 1109 } else { 1110 st->print("kmovq %s, [rsp + #%d]\t# spill", 1111 Matcher::regName[dst_first], 1112 offset); 1113 #endif 1114 } 1115 } 1116 return 0; 1117 } 1118 } else if (src_first_rc == rc_int) { 1119 // gpr -> 1120 if (dst_first_rc == rc_stack) { 1121 // gpr -> mem 1122 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1123 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1124 // 64-bit 1125 int offset = ra_->reg2offset(dst_first); 1126 if (cbuf) { 1127 MacroAssembler _masm(cbuf); 1128 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1129 #ifndef PRODUCT 1130 } else { 1131 st->print("movq [rsp + #%d], %s\t# spill", 1132 offset, 1133 Matcher::regName[src_first]); 1134 #endif 1135 } 1136 } else { 1137 // 32-bit 1138 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1139 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1140 int offset = ra_->reg2offset(dst_first); 1141 if (cbuf) { 1142 MacroAssembler _masm(cbuf); 1143 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1144 #ifndef PRODUCT 1145 } else { 1146 st->print("movl [rsp + #%d], %s\t# spill", 1147 offset, 1148 Matcher::regName[src_first]); 1149 #endif 1150 } 1151 } 1152 return 0; 1153 } else if (dst_first_rc == rc_int) { 1154 // gpr -> gpr 1155 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1156 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1157 // 64-bit 1158 if (cbuf) { 1159 MacroAssembler _masm(cbuf); 1160 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1161 as_Register(Matcher::_regEncode[src_first])); 1162 #ifndef PRODUCT 1163 } else { 1164 st->print("movq %s, %s\t# spill", 1165 Matcher::regName[dst_first], 1166 Matcher::regName[src_first]); 1167 #endif 1168 } 1169 return 0; 1170 } else { 1171 // 32-bit 1172 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1173 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1174 if (cbuf) { 1175 MacroAssembler _masm(cbuf); 1176 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1177 as_Register(Matcher::_regEncode[src_first])); 1178 #ifndef PRODUCT 1179 } else { 1180 st->print("movl %s, %s\t# spill", 1181 Matcher::regName[dst_first], 1182 Matcher::regName[src_first]); 1183 #endif 1184 } 1185 return 0; 1186 } 1187 } else if (dst_first_rc == rc_float) { 1188 // gpr -> xmm 1189 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1190 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1191 // 64-bit 1192 if (cbuf) { 1193 MacroAssembler _masm(cbuf); 1194 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1195 #ifndef PRODUCT 1196 } else { 1197 st->print("movdq %s, %s\t# spill", 1198 Matcher::regName[dst_first], 1199 Matcher::regName[src_first]); 1200 #endif 1201 } 1202 } else { 1203 // 32-bit 1204 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1205 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1206 if (cbuf) { 1207 MacroAssembler _masm(cbuf); 1208 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1209 #ifndef PRODUCT 1210 } else { 1211 st->print("movdl %s, %s\t# spill", 1212 Matcher::regName[dst_first], 1213 Matcher::regName[src_first]); 1214 #endif 1215 } 1216 } 1217 return 0; 1218 } else if (dst_first_rc == rc_kreg) { 1219 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1220 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1221 // 64-bit 1222 if (cbuf) { 1223 MacroAssembler _masm(cbuf); 1224 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1225 #ifndef PRODUCT 1226 } else { 1227 st->print("kmovq %s, %s\t# spill", 1228 Matcher::regName[dst_first], 1229 Matcher::regName[src_first]); 1230 #endif 1231 } 1232 } 1233 Unimplemented(); 1234 return 0; 1235 } 1236 } else if (src_first_rc == rc_float) { 1237 // xmm -> 1238 if (dst_first_rc == rc_stack) { 1239 // xmm -> mem 1240 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1241 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1242 // 64-bit 1243 int offset = ra_->reg2offset(dst_first); 1244 if (cbuf) { 1245 MacroAssembler _masm(cbuf); 1246 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1247 #ifndef PRODUCT 1248 } else { 1249 st->print("movsd [rsp + #%d], %s\t# spill", 1250 offset, 1251 Matcher::regName[src_first]); 1252 #endif 1253 } 1254 } else { 1255 // 32-bit 1256 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1257 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1258 int offset = ra_->reg2offset(dst_first); 1259 if (cbuf) { 1260 MacroAssembler _masm(cbuf); 1261 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1262 #ifndef PRODUCT 1263 } else { 1264 st->print("movss [rsp + #%d], %s\t# spill", 1265 offset, 1266 Matcher::regName[src_first]); 1267 #endif 1268 } 1269 } 1270 return 0; 1271 } else if (dst_first_rc == rc_int) { 1272 // xmm -> gpr 1273 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1274 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1275 // 64-bit 1276 if (cbuf) { 1277 MacroAssembler _masm(cbuf); 1278 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1279 #ifndef PRODUCT 1280 } else { 1281 st->print("movdq %s, %s\t# spill", 1282 Matcher::regName[dst_first], 1283 Matcher::regName[src_first]); 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 if (cbuf) { 1291 MacroAssembler _masm(cbuf); 1292 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1293 #ifndef PRODUCT 1294 } else { 1295 st->print("movdl %s, %s\t# spill", 1296 Matcher::regName[dst_first], 1297 Matcher::regName[src_first]); 1298 #endif 1299 } 1300 } 1301 return 0; 1302 } else if (dst_first_rc == rc_float) { 1303 // xmm -> xmm 1304 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1305 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1306 // 64-bit 1307 if (cbuf) { 1308 MacroAssembler _masm(cbuf); 1309 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1310 #ifndef PRODUCT 1311 } else { 1312 st->print("%s %s, %s\t# spill", 1313 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1314 Matcher::regName[dst_first], 1315 Matcher::regName[src_first]); 1316 #endif 1317 } 1318 } else { 1319 // 32-bit 1320 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1321 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1322 if (cbuf) { 1323 MacroAssembler _masm(cbuf); 1324 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1325 #ifndef PRODUCT 1326 } else { 1327 st->print("%s %s, %s\t# spill", 1328 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1329 Matcher::regName[dst_first], 1330 Matcher::regName[src_first]); 1331 #endif 1332 } 1333 } 1334 return 0; 1335 } else if (dst_first_rc == rc_kreg) { 1336 assert(false, "Illegal spilling"); 1337 return 0; 1338 } 1339 } else if (src_first_rc == rc_kreg) { 1340 if (dst_first_rc == rc_stack) { 1341 // mem -> kreg 1342 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1343 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1344 // 64-bit 1345 int offset = ra_->reg2offset(dst_first); 1346 if (cbuf) { 1347 MacroAssembler _masm(cbuf); 1348 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1349 #ifndef PRODUCT 1350 } else { 1351 st->print("kmovq [rsp + #%d] , %s\t# spill", 1352 offset, 1353 Matcher::regName[src_first]); 1354 #endif 1355 } 1356 } 1357 return 0; 1358 } else if (dst_first_rc == rc_int) { 1359 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1360 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1361 // 64-bit 1362 if (cbuf) { 1363 MacroAssembler _masm(cbuf); 1364 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1365 #ifndef PRODUCT 1366 } else { 1367 st->print("kmovq %s, %s\t# spill", 1368 Matcher::regName[dst_first], 1369 Matcher::regName[src_first]); 1370 #endif 1371 } 1372 } 1373 Unimplemented(); 1374 return 0; 1375 } else if (dst_first_rc == rc_kreg) { 1376 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1377 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1378 // 64-bit 1379 if (cbuf) { 1380 MacroAssembler _masm(cbuf); 1381 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1382 #ifndef PRODUCT 1383 } else { 1384 st->print("kmovq %s, %s\t# spill", 1385 Matcher::regName[dst_first], 1386 Matcher::regName[src_first]); 1387 #endif 1388 } 1389 } 1390 return 0; 1391 } else if (dst_first_rc == rc_float) { 1392 assert(false, "Illegal spill"); 1393 return 0; 1394 } 1395 } 1396 1397 assert(0," foo "); 1398 Unimplemented(); 1399 return 0; 1400 } 1401 1402 #ifndef PRODUCT 1403 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1404 implementation(nullptr, ra_, false, st); 1405 } 1406 #endif 1407 1408 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1409 implementation(&cbuf, ra_, false, nullptr); 1410 } 1411 1412 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1413 return MachNode::size(ra_); 1414 } 1415 1416 //============================================================================= 1417 #ifndef PRODUCT 1418 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1419 { 1420 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1421 int reg = ra_->get_reg_first(this); 1422 st->print("leaq %s, [rsp + #%d]\t# box lock", 1423 Matcher::regName[reg], offset); 1424 } 1425 #endif 1426 1427 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1428 { 1429 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1430 int reg = ra_->get_encode(this); 1431 1432 MacroAssembler masm(&cbuf); 1433 masm.lea(as_Register(reg), Address(rsp, offset)); 1434 } 1435 1436 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1437 { 1438 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1439 return (offset < 0x80) ? 5 : 8; // REX 1440 } 1441 1442 //============================================================================= 1443 #ifndef PRODUCT 1444 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1445 { 1446 st->print_cr("MachVEPNode"); 1447 } 1448 #endif 1449 1450 void MachVEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1451 { 1452 C2_MacroAssembler _masm(&cbuf); 1453 uint insts_size = cbuf.insts_size(); 1454 if (!_verified) { 1455 if (UseCompressedClassPointers) { 1456 __ load_klass(rscratch1, j_rarg0, rscratch2); 1457 __ cmpptr(rax, rscratch1); 1458 } else { 1459 __ cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1460 } 1461 __ jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1462 } else { 1463 // TODO 8284443 Avoid creation of temporary frame 1464 if (ra_->C->stub_function() == nullptr) { 1465 __ verified_entry(ra_->C, 0); 1466 __ entry_barrier(); 1467 int initial_framesize = ra_->C->output()->frame_size_in_bytes() - 2*wordSize; 1468 __ remove_frame(initial_framesize, false); 1469 } 1470 // Unpack inline type args passed as oop and then jump to 1471 // the verified entry point (skipping the unverified entry). 1472 int sp_inc = __ unpack_inline_args(ra_->C, _receiver_only); 1473 // Emit code for verified entry and save increment for stack repair on return 1474 __ verified_entry(ra_->C, sp_inc); 1475 if (Compile::current()->output()->in_scratch_emit_size()) { 1476 Label dummy_verified_entry; 1477 __ jmp(dummy_verified_entry); 1478 } else { 1479 __ jmp(*_verified_entry); 1480 } 1481 } 1482 /* WARNING these NOPs are critical so that verified entry point is properly 1483 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1484 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1485 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1486 if (nops_cnt > 0) { 1487 __ nop(nops_cnt); 1488 } 1489 } 1490 1491 //============================================================================= 1492 #ifndef PRODUCT 1493 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1494 { 1495 if (UseCompressedClassPointers) { 1496 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1497 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1498 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1499 } else { 1500 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1501 "# Inline cache check"); 1502 } 1503 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1504 st->print_cr("\tnop\t# nops to align entry point"); 1505 } 1506 #endif 1507 1508 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1509 { 1510 MacroAssembler masm(&cbuf); 1511 uint insts_size = cbuf.insts_size(); 1512 if (UseCompressedClassPointers) { 1513 masm.load_klass(rscratch1, j_rarg0, rscratch2); 1514 masm.cmpptr(rax, rscratch1); 1515 } else { 1516 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1517 } 1518 1519 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1520 1521 /* WARNING these NOPs are critical so that verified entry point is properly 1522 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1523 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1524 if (OptoBreakpoint) { 1525 // Leave space for int3 1526 nops_cnt -= 1; 1527 } 1528 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1529 if (nops_cnt > 0) 1530 masm.nop(nops_cnt); 1531 } 1532 1533 //============================================================================= 1534 1535 bool Matcher::supports_vector_calling_convention(void) { 1536 if (EnableVectorSupport && UseVectorStubs) { 1537 return true; 1538 } 1539 return false; 1540 } 1541 1542 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1543 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1544 int lo = XMM0_num; 1545 int hi = XMM0b_num; 1546 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1547 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1548 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1549 return OptoRegPair(hi, lo); 1550 } 1551 1552 // Is this branch offset short enough that a short branch can be used? 1553 // 1554 // NOTE: If the platform does not provide any short branch variants, then 1555 // this method should return false for offset 0. 1556 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1557 // The passed offset is relative to address of the branch. 1558 // On 86 a branch displacement is calculated relative to address 1559 // of a next instruction. 1560 offset -= br_size; 1561 1562 // the short version of jmpConUCF2 contains multiple branches, 1563 // making the reach slightly less 1564 if (rule == jmpConUCF2_rule) 1565 return (-126 <= offset && offset <= 125); 1566 return (-128 <= offset && offset <= 127); 1567 } 1568 1569 // Return whether or not this register is ever used as an argument. 1570 // This function is used on startup to build the trampoline stubs in 1571 // generateOptoStub. Registers not mentioned will be killed by the VM 1572 // call in the trampoline, and arguments in those registers not be 1573 // available to the callee. 1574 bool Matcher::can_be_java_arg(int reg) 1575 { 1576 return 1577 reg == RDI_num || reg == RDI_H_num || 1578 reg == RSI_num || reg == RSI_H_num || 1579 reg == RDX_num || reg == RDX_H_num || 1580 reg == RCX_num || reg == RCX_H_num || 1581 reg == R8_num || reg == R8_H_num || 1582 reg == R9_num || reg == R9_H_num || 1583 reg == R12_num || reg == R12_H_num || 1584 reg == XMM0_num || reg == XMM0b_num || 1585 reg == XMM1_num || reg == XMM1b_num || 1586 reg == XMM2_num || reg == XMM2b_num || 1587 reg == XMM3_num || reg == XMM3b_num || 1588 reg == XMM4_num || reg == XMM4b_num || 1589 reg == XMM5_num || reg == XMM5b_num || 1590 reg == XMM6_num || reg == XMM6b_num || 1591 reg == XMM7_num || reg == XMM7b_num; 1592 } 1593 1594 bool Matcher::is_spillable_arg(int reg) 1595 { 1596 return can_be_java_arg(reg); 1597 } 1598 1599 uint Matcher::int_pressure_limit() 1600 { 1601 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1602 } 1603 1604 uint Matcher::float_pressure_limit() 1605 { 1606 // After experiment around with different values, the following default threshold 1607 // works best for LCM's register pressure scheduling on x64. 1608 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1609 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1610 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1611 } 1612 1613 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1614 // In 64 bit mode a code which use multiply when 1615 // devisor is constant is faster than hardware 1616 // DIV instruction (it uses MulHiL). 1617 return false; 1618 } 1619 1620 // Register for DIVI projection of divmodI 1621 RegMask Matcher::divI_proj_mask() { 1622 return INT_RAX_REG_mask(); 1623 } 1624 1625 // Register for MODI projection of divmodI 1626 RegMask Matcher::modI_proj_mask() { 1627 return INT_RDX_REG_mask(); 1628 } 1629 1630 // Register for DIVL projection of divmodL 1631 RegMask Matcher::divL_proj_mask() { 1632 return LONG_RAX_REG_mask(); 1633 } 1634 1635 // Register for MODL projection of divmodL 1636 RegMask Matcher::modL_proj_mask() { 1637 return LONG_RDX_REG_mask(); 1638 } 1639 1640 // Register for saving SP into on method handle invokes. Not used on x86_64. 1641 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1642 return NO_REG_mask(); 1643 } 1644 1645 %} 1646 1647 //----------ENCODING BLOCK----------------------------------------------------- 1648 // This block specifies the encoding classes used by the compiler to 1649 // output byte streams. Encoding classes are parameterized macros 1650 // used by Machine Instruction Nodes in order to generate the bit 1651 // encoding of the instruction. Operands specify their base encoding 1652 // interface with the interface keyword. There are currently 1653 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1654 // COND_INTER. REG_INTER causes an operand to generate a function 1655 // which returns its register number when queried. CONST_INTER causes 1656 // an operand to generate a function which returns the value of the 1657 // constant when queried. MEMORY_INTER causes an operand to generate 1658 // four functions which return the Base Register, the Index Register, 1659 // the Scale Value, and the Offset Value of the operand when queried. 1660 // COND_INTER causes an operand to generate six functions which return 1661 // the encoding code (ie - encoding bits for the instruction) 1662 // associated with each basic boolean condition for a conditional 1663 // instruction. 1664 // 1665 // Instructions specify two basic values for encoding. Again, a 1666 // function is available to check if the constant displacement is an 1667 // oop. They use the ins_encode keyword to specify their encoding 1668 // classes (which must be a sequence of enc_class names, and their 1669 // parameters, specified in the encoding block), and they use the 1670 // opcode keyword to specify, in order, their primary, secondary, and 1671 // tertiary opcode. Only the opcode sections which a particular 1672 // instruction needs for encoding need to be specified. 1673 encode %{ 1674 enc_class cdql_enc(no_rax_rdx_RegI div) 1675 %{ 1676 // Full implementation of Java idiv and irem; checks for 1677 // special case as described in JVM spec., p.243 & p.271. 1678 // 1679 // normal case special case 1680 // 1681 // input : rax: dividend min_int 1682 // reg: divisor -1 1683 // 1684 // output: rax: quotient (= rax idiv reg) min_int 1685 // rdx: remainder (= rax irem reg) 0 1686 // 1687 // Code sequnce: 1688 // 1689 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1690 // 5: 75 07/08 jne e <normal> 1691 // 7: 33 d2 xor %edx,%edx 1692 // [div >= 8 -> offset + 1] 1693 // [REX_B] 1694 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1695 // c: 74 03/04 je 11 <done> 1696 // 000000000000000e <normal>: 1697 // e: 99 cltd 1698 // [div >= 8 -> offset + 1] 1699 // [REX_B] 1700 // f: f7 f9 idiv $div 1701 // 0000000000000011 <done>: 1702 MacroAssembler _masm(&cbuf); 1703 Label normal; 1704 Label done; 1705 1706 // cmp $0x80000000,%eax 1707 __ cmpl(as_Register(RAX_enc), 0x80000000); 1708 1709 // jne e <normal> 1710 __ jccb(Assembler::notEqual, normal); 1711 1712 // xor %edx,%edx 1713 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1714 1715 // cmp $0xffffffffffffffff,%ecx 1716 __ cmpl($div$$Register, -1); 1717 1718 // je 11 <done> 1719 __ jccb(Assembler::equal, done); 1720 1721 // <normal> 1722 // cltd 1723 __ bind(normal); 1724 __ cdql(); 1725 1726 // idivl 1727 // <done> 1728 __ idivl($div$$Register); 1729 __ bind(done); 1730 %} 1731 1732 enc_class cdqq_enc(no_rax_rdx_RegL div) 1733 %{ 1734 // Full implementation of Java ldiv and lrem; checks for 1735 // special case as described in JVM spec., p.243 & p.271. 1736 // 1737 // normal case special case 1738 // 1739 // input : rax: dividend min_long 1740 // reg: divisor -1 1741 // 1742 // output: rax: quotient (= rax idiv reg) min_long 1743 // rdx: remainder (= rax irem reg) 0 1744 // 1745 // Code sequnce: 1746 // 1747 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1748 // 7: 00 00 80 1749 // a: 48 39 d0 cmp %rdx,%rax 1750 // d: 75 08 jne 17 <normal> 1751 // f: 33 d2 xor %edx,%edx 1752 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1753 // 15: 74 05 je 1c <done> 1754 // 0000000000000017 <normal>: 1755 // 17: 48 99 cqto 1756 // 19: 48 f7 f9 idiv $div 1757 // 000000000000001c <done>: 1758 MacroAssembler _masm(&cbuf); 1759 Label normal; 1760 Label done; 1761 1762 // mov $0x8000000000000000,%rdx 1763 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1764 1765 // cmp %rdx,%rax 1766 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1767 1768 // jne 17 <normal> 1769 __ jccb(Assembler::notEqual, normal); 1770 1771 // xor %edx,%edx 1772 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1773 1774 // cmp $0xffffffffffffffff,$div 1775 __ cmpq($div$$Register, -1); 1776 1777 // je 1e <done> 1778 __ jccb(Assembler::equal, done); 1779 1780 // <normal> 1781 // cqto 1782 __ bind(normal); 1783 __ cdqq(); 1784 1785 // idivq (note: must be emitted by the user of this rule) 1786 // <done> 1787 __ idivq($div$$Register); 1788 __ bind(done); 1789 %} 1790 1791 enc_class enc_PartialSubtypeCheck() 1792 %{ 1793 Register Rrdi = as_Register(RDI_enc); // result register 1794 Register Rrax = as_Register(RAX_enc); // super class 1795 Register Rrcx = as_Register(RCX_enc); // killed 1796 Register Rrsi = as_Register(RSI_enc); // sub class 1797 Label miss; 1798 const bool set_cond_codes = true; 1799 1800 MacroAssembler _masm(&cbuf); 1801 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1802 nullptr, &miss, 1803 /*set_cond_codes:*/ true); 1804 if ($primary) { 1805 __ xorptr(Rrdi, Rrdi); 1806 } 1807 __ bind(miss); 1808 %} 1809 1810 enc_class clear_avx %{ 1811 debug_only(int off0 = cbuf.insts_size()); 1812 if (generate_vzeroupper(Compile::current())) { 1813 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1814 // Clear upper bits of YMM registers when current compiled code uses 1815 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1816 MacroAssembler _masm(&cbuf); 1817 __ vzeroupper(); 1818 } 1819 debug_only(int off1 = cbuf.insts_size()); 1820 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1821 %} 1822 1823 enc_class Java_To_Runtime(method meth) %{ 1824 // No relocation needed 1825 MacroAssembler _masm(&cbuf); 1826 __ mov64(r10, (int64_t) $meth$$method); 1827 __ call(r10); 1828 __ post_call_nop(); 1829 %} 1830 1831 enc_class Java_Static_Call(method meth) 1832 %{ 1833 // JAVA STATIC CALL 1834 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1835 // determine who we intended to call. 1836 MacroAssembler _masm(&cbuf); 1837 1838 if (!_method) { 1839 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1840 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1841 // The NOP here is purely to ensure that eliding a call to 1842 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1843 __ addr_nop_5(); 1844 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1845 } else { 1846 int method_index = resolved_method_index(cbuf); 1847 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1848 : static_call_Relocation::spec(method_index); 1849 address mark = __ pc(); 1850 int call_offset = __ offset(); 1851 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1852 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1853 // Calls of the same statically bound method can share 1854 // a stub to the interpreter. 1855 cbuf.shared_stub_to_interp_for(_method, call_offset); 1856 } else { 1857 // Emit stubs for static call. 1858 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 1859 if (stub == nullptr) { 1860 ciEnv::current()->record_failure("CodeCache is full"); 1861 return; 1862 } 1863 } 1864 } 1865 __ post_call_nop(); 1866 %} 1867 1868 enc_class Java_Dynamic_Call(method meth) %{ 1869 MacroAssembler _masm(&cbuf); 1870 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 1871 __ post_call_nop(); 1872 %} 1873 1874 %} 1875 1876 1877 1878 //----------FRAME-------------------------------------------------------------- 1879 // Definition of frame structure and management information. 1880 // 1881 // S T A C K L A Y O U T Allocators stack-slot number 1882 // | (to get allocators register number 1883 // G Owned by | | v add OptoReg::stack0()) 1884 // r CALLER | | 1885 // o | +--------+ pad to even-align allocators stack-slot 1886 // w V | pad0 | numbers; owned by CALLER 1887 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1888 // h ^ | in | 5 1889 // | | args | 4 Holes in incoming args owned by SELF 1890 // | | | | 3 1891 // | | +--------+ 1892 // V | | old out| Empty on Intel, window on Sparc 1893 // | old |preserve| Must be even aligned. 1894 // | SP-+--------+----> Matcher::_old_SP, even aligned 1895 // | | in | 3 area for Intel ret address 1896 // Owned by |preserve| Empty on Sparc. 1897 // SELF +--------+ 1898 // | | pad2 | 2 pad to align old SP 1899 // | +--------+ 1 1900 // | | locks | 0 1901 // | +--------+----> OptoReg::stack0(), even aligned 1902 // | | pad1 | 11 pad to align new SP 1903 // | +--------+ 1904 // | | | 10 1905 // | | spills | 9 spills 1906 // V | | 8 (pad0 slot for callee) 1907 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1908 // ^ | out | 7 1909 // | | args | 6 Holes in outgoing args owned by CALLEE 1910 // Owned by +--------+ 1911 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1912 // | new |preserve| Must be even-aligned. 1913 // | SP-+--------+----> Matcher::_new_SP, even aligned 1914 // | | | 1915 // 1916 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1917 // known from SELF's arguments and the Java calling convention. 1918 // Region 6-7 is determined per call site. 1919 // Note 2: If the calling convention leaves holes in the incoming argument 1920 // area, those holes are owned by SELF. Holes in the outgoing area 1921 // are owned by the CALLEE. Holes should not be necessary in the 1922 // incoming area, as the Java calling convention is completely under 1923 // the control of the AD file. Doubles can be sorted and packed to 1924 // avoid holes. Holes in the outgoing arguments may be necessary for 1925 // varargs C calling conventions. 1926 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1927 // even aligned with pad0 as needed. 1928 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1929 // region 6-11 is even aligned; it may be padded out more so that 1930 // the region from SP to FP meets the minimum stack alignment. 1931 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1932 // alignment. Region 11, pad1, may be dynamically extended so that 1933 // SP meets the minimum alignment. 1934 1935 frame 1936 %{ 1937 // These three registers define part of the calling convention 1938 // between compiled code and the interpreter. 1939 inline_cache_reg(RAX); // Inline Cache Register 1940 1941 // Optional: name the operand used by cisc-spilling to access 1942 // [stack_pointer + offset] 1943 cisc_spilling_operand_name(indOffset32); 1944 1945 // Number of stack slots consumed by locking an object 1946 sync_stack_slots(2); 1947 1948 // Compiled code's Frame Pointer 1949 frame_pointer(RSP); 1950 1951 // Interpreter stores its frame pointer in a register which is 1952 // stored to the stack by I2CAdaptors. 1953 // I2CAdaptors convert from interpreted java to compiled java. 1954 interpreter_frame_pointer(RBP); 1955 1956 // Stack alignment requirement 1957 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1958 1959 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1960 // for calls to C. Supports the var-args backing area for register parms. 1961 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1962 1963 // The after-PROLOG location of the return address. Location of 1964 // return address specifies a type (REG or STACK) and a number 1965 // representing the register number (i.e. - use a register name) or 1966 // stack slot. 1967 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 1968 // Otherwise, it is above the locks and verification slot and alignment word 1969 return_addr(STACK - 2 + 1970 align_up((Compile::current()->in_preserve_stack_slots() + 1971 Compile::current()->fixed_slots()), 1972 stack_alignment_in_slots())); 1973 1974 // Location of compiled Java return values. Same as C for now. 1975 return_value 1976 %{ 1977 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 1978 "only return normal values"); 1979 1980 static const int lo[Op_RegL + 1] = { 1981 0, 1982 0, 1983 RAX_num, // Op_RegN 1984 RAX_num, // Op_RegI 1985 RAX_num, // Op_RegP 1986 XMM0_num, // Op_RegF 1987 XMM0_num, // Op_RegD 1988 RAX_num // Op_RegL 1989 }; 1990 static const int hi[Op_RegL + 1] = { 1991 0, 1992 0, 1993 OptoReg::Bad, // Op_RegN 1994 OptoReg::Bad, // Op_RegI 1995 RAX_H_num, // Op_RegP 1996 OptoReg::Bad, // Op_RegF 1997 XMM0b_num, // Op_RegD 1998 RAX_H_num // Op_RegL 1999 }; 2000 // Excluded flags and vector registers. 2001 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2002 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2003 %} 2004 %} 2005 2006 //----------ATTRIBUTES--------------------------------------------------------- 2007 //----------Operand Attributes------------------------------------------------- 2008 op_attrib op_cost(0); // Required cost attribute 2009 2010 //----------Instruction Attributes--------------------------------------------- 2011 ins_attrib ins_cost(100); // Required cost attribute 2012 ins_attrib ins_size(8); // Required size attribute (in bits) 2013 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2014 // a non-matching short branch variant 2015 // of some long branch? 2016 ins_attrib ins_alignment(1); // Required alignment attribute (must 2017 // be a power of 2) specifies the 2018 // alignment that some part of the 2019 // instruction (not necessarily the 2020 // start) requires. If > 1, a 2021 // compute_padding() function must be 2022 // provided for the instruction 2023 2024 //----------OPERANDS----------------------------------------------------------- 2025 // Operand definitions must precede instruction definitions for correct parsing 2026 // in the ADLC because operands constitute user defined types which are used in 2027 // instruction definitions. 2028 2029 //----------Simple Operands---------------------------------------------------- 2030 // Immediate Operands 2031 // Integer Immediate 2032 operand immI() 2033 %{ 2034 match(ConI); 2035 2036 op_cost(10); 2037 format %{ %} 2038 interface(CONST_INTER); 2039 %} 2040 2041 // Constant for test vs zero 2042 operand immI_0() 2043 %{ 2044 predicate(n->get_int() == 0); 2045 match(ConI); 2046 2047 op_cost(0); 2048 format %{ %} 2049 interface(CONST_INTER); 2050 %} 2051 2052 // Constant for increment 2053 operand immI_1() 2054 %{ 2055 predicate(n->get_int() == 1); 2056 match(ConI); 2057 2058 op_cost(0); 2059 format %{ %} 2060 interface(CONST_INTER); 2061 %} 2062 2063 // Constant for decrement 2064 operand immI_M1() 2065 %{ 2066 predicate(n->get_int() == -1); 2067 match(ConI); 2068 2069 op_cost(0); 2070 format %{ %} 2071 interface(CONST_INTER); 2072 %} 2073 2074 operand immI_2() 2075 %{ 2076 predicate(n->get_int() == 2); 2077 match(ConI); 2078 2079 op_cost(0); 2080 format %{ %} 2081 interface(CONST_INTER); 2082 %} 2083 2084 operand immI_4() 2085 %{ 2086 predicate(n->get_int() == 4); 2087 match(ConI); 2088 2089 op_cost(0); 2090 format %{ %} 2091 interface(CONST_INTER); 2092 %} 2093 2094 operand immI_8() 2095 %{ 2096 predicate(n->get_int() == 8); 2097 match(ConI); 2098 2099 op_cost(0); 2100 format %{ %} 2101 interface(CONST_INTER); 2102 %} 2103 2104 // Valid scale values for addressing modes 2105 operand immI2() 2106 %{ 2107 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2108 match(ConI); 2109 2110 format %{ %} 2111 interface(CONST_INTER); 2112 %} 2113 2114 operand immU7() 2115 %{ 2116 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2117 match(ConI); 2118 2119 op_cost(5); 2120 format %{ %} 2121 interface(CONST_INTER); 2122 %} 2123 2124 operand immI8() 2125 %{ 2126 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2127 match(ConI); 2128 2129 op_cost(5); 2130 format %{ %} 2131 interface(CONST_INTER); 2132 %} 2133 2134 operand immU8() 2135 %{ 2136 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2137 match(ConI); 2138 2139 op_cost(5); 2140 format %{ %} 2141 interface(CONST_INTER); 2142 %} 2143 2144 operand immI16() 2145 %{ 2146 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2147 match(ConI); 2148 2149 op_cost(10); 2150 format %{ %} 2151 interface(CONST_INTER); 2152 %} 2153 2154 // Int Immediate non-negative 2155 operand immU31() 2156 %{ 2157 predicate(n->get_int() >= 0); 2158 match(ConI); 2159 2160 op_cost(0); 2161 format %{ %} 2162 interface(CONST_INTER); 2163 %} 2164 2165 // Constant for long shifts 2166 operand immI_32() 2167 %{ 2168 predicate( n->get_int() == 32 ); 2169 match(ConI); 2170 2171 op_cost(0); 2172 format %{ %} 2173 interface(CONST_INTER); 2174 %} 2175 2176 // Constant for long shifts 2177 operand immI_64() 2178 %{ 2179 predicate( n->get_int() == 64 ); 2180 match(ConI); 2181 2182 op_cost(0); 2183 format %{ %} 2184 interface(CONST_INTER); 2185 %} 2186 2187 // Pointer Immediate 2188 operand immP() 2189 %{ 2190 match(ConP); 2191 2192 op_cost(10); 2193 format %{ %} 2194 interface(CONST_INTER); 2195 %} 2196 2197 // nullptr Pointer Immediate 2198 operand immP0() 2199 %{ 2200 predicate(n->get_ptr() == 0); 2201 match(ConP); 2202 2203 op_cost(5); 2204 format %{ %} 2205 interface(CONST_INTER); 2206 %} 2207 2208 // Pointer Immediate 2209 operand immN() %{ 2210 match(ConN); 2211 2212 op_cost(10); 2213 format %{ %} 2214 interface(CONST_INTER); 2215 %} 2216 2217 operand immNKlass() %{ 2218 match(ConNKlass); 2219 2220 op_cost(10); 2221 format %{ %} 2222 interface(CONST_INTER); 2223 %} 2224 2225 // nullptr Pointer Immediate 2226 operand immN0() %{ 2227 predicate(n->get_narrowcon() == 0); 2228 match(ConN); 2229 2230 op_cost(5); 2231 format %{ %} 2232 interface(CONST_INTER); 2233 %} 2234 2235 operand immP31() 2236 %{ 2237 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2238 && (n->get_ptr() >> 31) == 0); 2239 match(ConP); 2240 2241 op_cost(5); 2242 format %{ %} 2243 interface(CONST_INTER); 2244 %} 2245 2246 2247 // Long Immediate 2248 operand immL() 2249 %{ 2250 match(ConL); 2251 2252 op_cost(20); 2253 format %{ %} 2254 interface(CONST_INTER); 2255 %} 2256 2257 // Long Immediate 8-bit 2258 operand immL8() 2259 %{ 2260 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2261 match(ConL); 2262 2263 op_cost(5); 2264 format %{ %} 2265 interface(CONST_INTER); 2266 %} 2267 2268 // Long Immediate 32-bit unsigned 2269 operand immUL32() 2270 %{ 2271 predicate(n->get_long() == (unsigned int) (n->get_long())); 2272 match(ConL); 2273 2274 op_cost(10); 2275 format %{ %} 2276 interface(CONST_INTER); 2277 %} 2278 2279 // Long Immediate 32-bit signed 2280 operand immL32() 2281 %{ 2282 predicate(n->get_long() == (int) (n->get_long())); 2283 match(ConL); 2284 2285 op_cost(15); 2286 format %{ %} 2287 interface(CONST_INTER); 2288 %} 2289 2290 operand immL_Pow2() 2291 %{ 2292 predicate(is_power_of_2((julong)n->get_long())); 2293 match(ConL); 2294 2295 op_cost(15); 2296 format %{ %} 2297 interface(CONST_INTER); 2298 %} 2299 2300 operand immL_NotPow2() 2301 %{ 2302 predicate(is_power_of_2((julong)~n->get_long())); 2303 match(ConL); 2304 2305 op_cost(15); 2306 format %{ %} 2307 interface(CONST_INTER); 2308 %} 2309 2310 // Long Immediate zero 2311 operand immL0() 2312 %{ 2313 predicate(n->get_long() == 0L); 2314 match(ConL); 2315 2316 op_cost(10); 2317 format %{ %} 2318 interface(CONST_INTER); 2319 %} 2320 2321 // Constant for increment 2322 operand immL1() 2323 %{ 2324 predicate(n->get_long() == 1); 2325 match(ConL); 2326 2327 format %{ %} 2328 interface(CONST_INTER); 2329 %} 2330 2331 // Constant for decrement 2332 operand immL_M1() 2333 %{ 2334 predicate(n->get_long() == -1); 2335 match(ConL); 2336 2337 format %{ %} 2338 interface(CONST_INTER); 2339 %} 2340 2341 // Long Immediate: the value 10 2342 operand immL10() 2343 %{ 2344 predicate(n->get_long() == 10); 2345 match(ConL); 2346 2347 format %{ %} 2348 interface(CONST_INTER); 2349 %} 2350 2351 // Long immediate from 0 to 127. 2352 // Used for a shorter form of long mul by 10. 2353 operand immL_127() 2354 %{ 2355 predicate(0 <= n->get_long() && n->get_long() < 0x80); 2356 match(ConL); 2357 2358 op_cost(10); 2359 format %{ %} 2360 interface(CONST_INTER); 2361 %} 2362 2363 // Long Immediate: low 32-bit mask 2364 operand immL_32bits() 2365 %{ 2366 predicate(n->get_long() == 0xFFFFFFFFL); 2367 match(ConL); 2368 op_cost(20); 2369 2370 format %{ %} 2371 interface(CONST_INTER); 2372 %} 2373 2374 // Int Immediate: 2^n-1, positive 2375 operand immI_Pow2M1() 2376 %{ 2377 predicate((n->get_int() > 0) 2378 && is_power_of_2((juint)n->get_int() + 1)); 2379 match(ConI); 2380 2381 op_cost(20); 2382 format %{ %} 2383 interface(CONST_INTER); 2384 %} 2385 2386 // Float Immediate zero 2387 operand immF0() 2388 %{ 2389 predicate(jint_cast(n->getf()) == 0); 2390 match(ConF); 2391 2392 op_cost(5); 2393 format %{ %} 2394 interface(CONST_INTER); 2395 %} 2396 2397 // Float Immediate 2398 operand immF() 2399 %{ 2400 match(ConF); 2401 2402 op_cost(15); 2403 format %{ %} 2404 interface(CONST_INTER); 2405 %} 2406 2407 // Double Immediate zero 2408 operand immD0() 2409 %{ 2410 predicate(jlong_cast(n->getd()) == 0); 2411 match(ConD); 2412 2413 op_cost(5); 2414 format %{ %} 2415 interface(CONST_INTER); 2416 %} 2417 2418 // Double Immediate 2419 operand immD() 2420 %{ 2421 match(ConD); 2422 2423 op_cost(15); 2424 format %{ %} 2425 interface(CONST_INTER); 2426 %} 2427 2428 // Immediates for special shifts (sign extend) 2429 2430 // Constants for increment 2431 operand immI_16() 2432 %{ 2433 predicate(n->get_int() == 16); 2434 match(ConI); 2435 2436 format %{ %} 2437 interface(CONST_INTER); 2438 %} 2439 2440 operand immI_24() 2441 %{ 2442 predicate(n->get_int() == 24); 2443 match(ConI); 2444 2445 format %{ %} 2446 interface(CONST_INTER); 2447 %} 2448 2449 // Constant for byte-wide masking 2450 operand immI_255() 2451 %{ 2452 predicate(n->get_int() == 255); 2453 match(ConI); 2454 2455 format %{ %} 2456 interface(CONST_INTER); 2457 %} 2458 2459 // Constant for short-wide masking 2460 operand immI_65535() 2461 %{ 2462 predicate(n->get_int() == 65535); 2463 match(ConI); 2464 2465 format %{ %} 2466 interface(CONST_INTER); 2467 %} 2468 2469 // Constant for byte-wide masking 2470 operand immL_255() 2471 %{ 2472 predicate(n->get_long() == 255); 2473 match(ConL); 2474 2475 format %{ %} 2476 interface(CONST_INTER); 2477 %} 2478 2479 // Constant for short-wide masking 2480 operand immL_65535() 2481 %{ 2482 predicate(n->get_long() == 65535); 2483 match(ConL); 2484 2485 format %{ %} 2486 interface(CONST_INTER); 2487 %} 2488 2489 operand kReg() 2490 %{ 2491 constraint(ALLOC_IN_RC(vectmask_reg)); 2492 match(RegVectMask); 2493 format %{%} 2494 interface(REG_INTER); 2495 %} 2496 2497 operand kReg_K1() 2498 %{ 2499 constraint(ALLOC_IN_RC(vectmask_reg_K1)); 2500 match(RegVectMask); 2501 format %{%} 2502 interface(REG_INTER); 2503 %} 2504 2505 operand kReg_K2() 2506 %{ 2507 constraint(ALLOC_IN_RC(vectmask_reg_K2)); 2508 match(RegVectMask); 2509 format %{%} 2510 interface(REG_INTER); 2511 %} 2512 2513 // Special Registers 2514 operand kReg_K3() 2515 %{ 2516 constraint(ALLOC_IN_RC(vectmask_reg_K3)); 2517 match(RegVectMask); 2518 format %{%} 2519 interface(REG_INTER); 2520 %} 2521 2522 operand kReg_K4() 2523 %{ 2524 constraint(ALLOC_IN_RC(vectmask_reg_K4)); 2525 match(RegVectMask); 2526 format %{%} 2527 interface(REG_INTER); 2528 %} 2529 2530 operand kReg_K5() 2531 %{ 2532 constraint(ALLOC_IN_RC(vectmask_reg_K5)); 2533 match(RegVectMask); 2534 format %{%} 2535 interface(REG_INTER); 2536 %} 2537 2538 operand kReg_K6() 2539 %{ 2540 constraint(ALLOC_IN_RC(vectmask_reg_K6)); 2541 match(RegVectMask); 2542 format %{%} 2543 interface(REG_INTER); 2544 %} 2545 2546 // Special Registers 2547 operand kReg_K7() 2548 %{ 2549 constraint(ALLOC_IN_RC(vectmask_reg_K7)); 2550 match(RegVectMask); 2551 format %{%} 2552 interface(REG_INTER); 2553 %} 2554 2555 // Register Operands 2556 // Integer Register 2557 operand rRegI() 2558 %{ 2559 constraint(ALLOC_IN_RC(int_reg)); 2560 match(RegI); 2561 2562 match(rax_RegI); 2563 match(rbx_RegI); 2564 match(rcx_RegI); 2565 match(rdx_RegI); 2566 match(rdi_RegI); 2567 2568 format %{ %} 2569 interface(REG_INTER); 2570 %} 2571 2572 // Special Registers 2573 operand rax_RegI() 2574 %{ 2575 constraint(ALLOC_IN_RC(int_rax_reg)); 2576 match(RegI); 2577 match(rRegI); 2578 2579 format %{ "RAX" %} 2580 interface(REG_INTER); 2581 %} 2582 2583 // Special Registers 2584 operand rbx_RegI() 2585 %{ 2586 constraint(ALLOC_IN_RC(int_rbx_reg)); 2587 match(RegI); 2588 match(rRegI); 2589 2590 format %{ "RBX" %} 2591 interface(REG_INTER); 2592 %} 2593 2594 operand rcx_RegI() 2595 %{ 2596 constraint(ALLOC_IN_RC(int_rcx_reg)); 2597 match(RegI); 2598 match(rRegI); 2599 2600 format %{ "RCX" %} 2601 interface(REG_INTER); 2602 %} 2603 2604 operand rdx_RegI() 2605 %{ 2606 constraint(ALLOC_IN_RC(int_rdx_reg)); 2607 match(RegI); 2608 match(rRegI); 2609 2610 format %{ "RDX" %} 2611 interface(REG_INTER); 2612 %} 2613 2614 operand rdi_RegI() 2615 %{ 2616 constraint(ALLOC_IN_RC(int_rdi_reg)); 2617 match(RegI); 2618 match(rRegI); 2619 2620 format %{ "RDI" %} 2621 interface(REG_INTER); 2622 %} 2623 2624 operand no_rax_rdx_RegI() 2625 %{ 2626 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2627 match(RegI); 2628 match(rbx_RegI); 2629 match(rcx_RegI); 2630 match(rdi_RegI); 2631 2632 format %{ %} 2633 interface(REG_INTER); 2634 %} 2635 2636 operand no_rbp_r13_RegI() 2637 %{ 2638 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2639 match(RegI); 2640 match(rRegI); 2641 match(rax_RegI); 2642 match(rbx_RegI); 2643 match(rcx_RegI); 2644 match(rdx_RegI); 2645 match(rdi_RegI); 2646 2647 format %{ %} 2648 interface(REG_INTER); 2649 %} 2650 2651 // Pointer Register 2652 operand any_RegP() 2653 %{ 2654 constraint(ALLOC_IN_RC(any_reg)); 2655 match(RegP); 2656 match(rax_RegP); 2657 match(rbx_RegP); 2658 match(rdi_RegP); 2659 match(rsi_RegP); 2660 match(rbp_RegP); 2661 match(r15_RegP); 2662 match(rRegP); 2663 2664 format %{ %} 2665 interface(REG_INTER); 2666 %} 2667 2668 operand rRegP() 2669 %{ 2670 constraint(ALLOC_IN_RC(ptr_reg)); 2671 match(RegP); 2672 match(rax_RegP); 2673 match(rbx_RegP); 2674 match(rdi_RegP); 2675 match(rsi_RegP); 2676 match(rbp_RegP); // See Q&A below about 2677 match(r15_RegP); // r15_RegP and rbp_RegP. 2678 2679 format %{ %} 2680 interface(REG_INTER); 2681 %} 2682 2683 operand rRegN() %{ 2684 constraint(ALLOC_IN_RC(int_reg)); 2685 match(RegN); 2686 2687 format %{ %} 2688 interface(REG_INTER); 2689 %} 2690 2691 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2692 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2693 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2694 // The output of an instruction is controlled by the allocator, which respects 2695 // register class masks, not match rules. Unless an instruction mentions 2696 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2697 // by the allocator as an input. 2698 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2699 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2700 // result, RBP is not included in the output of the instruction either. 2701 2702 operand no_rax_RegP() 2703 %{ 2704 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 2705 match(RegP); 2706 match(rbx_RegP); 2707 match(rsi_RegP); 2708 match(rdi_RegP); 2709 2710 format %{ %} 2711 interface(REG_INTER); 2712 %} 2713 2714 // This operand is not allowed to use RBP even if 2715 // RBP is not used to hold the frame pointer. 2716 operand no_rbp_RegP() 2717 %{ 2718 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2719 match(RegP); 2720 match(rbx_RegP); 2721 match(rsi_RegP); 2722 match(rdi_RegP); 2723 2724 format %{ %} 2725 interface(REG_INTER); 2726 %} 2727 2728 operand no_rax_rbx_RegP() 2729 %{ 2730 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 2731 match(RegP); 2732 match(rsi_RegP); 2733 match(rdi_RegP); 2734 2735 format %{ %} 2736 interface(REG_INTER); 2737 %} 2738 2739 // Special Registers 2740 // Return a pointer value 2741 operand rax_RegP() 2742 %{ 2743 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2744 match(RegP); 2745 match(rRegP); 2746 2747 format %{ %} 2748 interface(REG_INTER); 2749 %} 2750 2751 // Special Registers 2752 // Return a compressed pointer value 2753 operand rax_RegN() 2754 %{ 2755 constraint(ALLOC_IN_RC(int_rax_reg)); 2756 match(RegN); 2757 match(rRegN); 2758 2759 format %{ %} 2760 interface(REG_INTER); 2761 %} 2762 2763 // Used in AtomicAdd 2764 operand rbx_RegP() 2765 %{ 2766 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2767 match(RegP); 2768 match(rRegP); 2769 2770 format %{ %} 2771 interface(REG_INTER); 2772 %} 2773 2774 operand rsi_RegP() 2775 %{ 2776 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2777 match(RegP); 2778 match(rRegP); 2779 2780 format %{ %} 2781 interface(REG_INTER); 2782 %} 2783 2784 operand rbp_RegP() 2785 %{ 2786 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2787 match(RegP); 2788 match(rRegP); 2789 2790 format %{ %} 2791 interface(REG_INTER); 2792 %} 2793 2794 // Used in rep stosq 2795 operand rdi_RegP() 2796 %{ 2797 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2798 match(RegP); 2799 match(rRegP); 2800 2801 format %{ %} 2802 interface(REG_INTER); 2803 %} 2804 2805 operand r15_RegP() 2806 %{ 2807 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2808 match(RegP); 2809 match(rRegP); 2810 2811 format %{ %} 2812 interface(REG_INTER); 2813 %} 2814 2815 operand rRegL() 2816 %{ 2817 constraint(ALLOC_IN_RC(long_reg)); 2818 match(RegL); 2819 match(rax_RegL); 2820 match(rdx_RegL); 2821 2822 format %{ %} 2823 interface(REG_INTER); 2824 %} 2825 2826 // Special Registers 2827 operand no_rax_rdx_RegL() 2828 %{ 2829 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2830 match(RegL); 2831 match(rRegL); 2832 2833 format %{ %} 2834 interface(REG_INTER); 2835 %} 2836 2837 operand rax_RegL() 2838 %{ 2839 constraint(ALLOC_IN_RC(long_rax_reg)); 2840 match(RegL); 2841 match(rRegL); 2842 2843 format %{ "RAX" %} 2844 interface(REG_INTER); 2845 %} 2846 2847 operand rcx_RegL() 2848 %{ 2849 constraint(ALLOC_IN_RC(long_rcx_reg)); 2850 match(RegL); 2851 match(rRegL); 2852 2853 format %{ %} 2854 interface(REG_INTER); 2855 %} 2856 2857 operand rdx_RegL() 2858 %{ 2859 constraint(ALLOC_IN_RC(long_rdx_reg)); 2860 match(RegL); 2861 match(rRegL); 2862 2863 format %{ %} 2864 interface(REG_INTER); 2865 %} 2866 2867 operand no_rbp_r13_RegL() 2868 %{ 2869 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2870 match(RegL); 2871 match(rRegL); 2872 match(rax_RegL); 2873 match(rcx_RegL); 2874 match(rdx_RegL); 2875 2876 format %{ %} 2877 interface(REG_INTER); 2878 %} 2879 2880 // Flags register, used as output of compare instructions 2881 operand rFlagsReg() 2882 %{ 2883 constraint(ALLOC_IN_RC(int_flags)); 2884 match(RegFlags); 2885 2886 format %{ "RFLAGS" %} 2887 interface(REG_INTER); 2888 %} 2889 2890 // Flags register, used as output of FLOATING POINT compare instructions 2891 operand rFlagsRegU() 2892 %{ 2893 constraint(ALLOC_IN_RC(int_flags)); 2894 match(RegFlags); 2895 2896 format %{ "RFLAGS_U" %} 2897 interface(REG_INTER); 2898 %} 2899 2900 operand rFlagsRegUCF() %{ 2901 constraint(ALLOC_IN_RC(int_flags)); 2902 match(RegFlags); 2903 predicate(false); 2904 2905 format %{ "RFLAGS_U_CF" %} 2906 interface(REG_INTER); 2907 %} 2908 2909 // Float register operands 2910 operand regF() %{ 2911 constraint(ALLOC_IN_RC(float_reg)); 2912 match(RegF); 2913 2914 format %{ %} 2915 interface(REG_INTER); 2916 %} 2917 2918 // Float register operands 2919 operand legRegF() %{ 2920 constraint(ALLOC_IN_RC(float_reg_legacy)); 2921 match(RegF); 2922 2923 format %{ %} 2924 interface(REG_INTER); 2925 %} 2926 2927 // Float register operands 2928 operand vlRegF() %{ 2929 constraint(ALLOC_IN_RC(float_reg_vl)); 2930 match(RegF); 2931 2932 format %{ %} 2933 interface(REG_INTER); 2934 %} 2935 2936 // Double register operands 2937 operand regD() %{ 2938 constraint(ALLOC_IN_RC(double_reg)); 2939 match(RegD); 2940 2941 format %{ %} 2942 interface(REG_INTER); 2943 %} 2944 2945 // Double register operands 2946 operand legRegD() %{ 2947 constraint(ALLOC_IN_RC(double_reg_legacy)); 2948 match(RegD); 2949 2950 format %{ %} 2951 interface(REG_INTER); 2952 %} 2953 2954 // Double register operands 2955 operand vlRegD() %{ 2956 constraint(ALLOC_IN_RC(double_reg_vl)); 2957 match(RegD); 2958 2959 format %{ %} 2960 interface(REG_INTER); 2961 %} 2962 2963 //----------Memory Operands---------------------------------------------------- 2964 // Direct Memory Operand 2965 // operand direct(immP addr) 2966 // %{ 2967 // match(addr); 2968 2969 // format %{ "[$addr]" %} 2970 // interface(MEMORY_INTER) %{ 2971 // base(0xFFFFFFFF); 2972 // index(0x4); 2973 // scale(0x0); 2974 // disp($addr); 2975 // %} 2976 // %} 2977 2978 // Indirect Memory Operand 2979 operand indirect(any_RegP reg) 2980 %{ 2981 constraint(ALLOC_IN_RC(ptr_reg)); 2982 match(reg); 2983 2984 format %{ "[$reg]" %} 2985 interface(MEMORY_INTER) %{ 2986 base($reg); 2987 index(0x4); 2988 scale(0x0); 2989 disp(0x0); 2990 %} 2991 %} 2992 2993 // Indirect Memory Plus Short Offset Operand 2994 operand indOffset8(any_RegP reg, immL8 off) 2995 %{ 2996 constraint(ALLOC_IN_RC(ptr_reg)); 2997 match(AddP reg off); 2998 2999 format %{ "[$reg + $off (8-bit)]" %} 3000 interface(MEMORY_INTER) %{ 3001 base($reg); 3002 index(0x4); 3003 scale(0x0); 3004 disp($off); 3005 %} 3006 %} 3007 3008 // Indirect Memory Plus Long Offset Operand 3009 operand indOffset32(any_RegP reg, immL32 off) 3010 %{ 3011 constraint(ALLOC_IN_RC(ptr_reg)); 3012 match(AddP reg off); 3013 3014 format %{ "[$reg + $off (32-bit)]" %} 3015 interface(MEMORY_INTER) %{ 3016 base($reg); 3017 index(0x4); 3018 scale(0x0); 3019 disp($off); 3020 %} 3021 %} 3022 3023 // Indirect Memory Plus Index Register Plus Offset Operand 3024 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3025 %{ 3026 constraint(ALLOC_IN_RC(ptr_reg)); 3027 match(AddP (AddP reg lreg) off); 3028 3029 op_cost(10); 3030 format %{"[$reg + $off + $lreg]" %} 3031 interface(MEMORY_INTER) %{ 3032 base($reg); 3033 index($lreg); 3034 scale(0x0); 3035 disp($off); 3036 %} 3037 %} 3038 3039 // Indirect Memory Plus Index Register Plus Offset Operand 3040 operand indIndex(any_RegP reg, rRegL lreg) 3041 %{ 3042 constraint(ALLOC_IN_RC(ptr_reg)); 3043 match(AddP reg lreg); 3044 3045 op_cost(10); 3046 format %{"[$reg + $lreg]" %} 3047 interface(MEMORY_INTER) %{ 3048 base($reg); 3049 index($lreg); 3050 scale(0x0); 3051 disp(0x0); 3052 %} 3053 %} 3054 3055 // Indirect Memory Times Scale Plus Index Register 3056 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3057 %{ 3058 constraint(ALLOC_IN_RC(ptr_reg)); 3059 match(AddP reg (LShiftL lreg scale)); 3060 3061 op_cost(10); 3062 format %{"[$reg + $lreg << $scale]" %} 3063 interface(MEMORY_INTER) %{ 3064 base($reg); 3065 index($lreg); 3066 scale($scale); 3067 disp(0x0); 3068 %} 3069 %} 3070 3071 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3072 %{ 3073 constraint(ALLOC_IN_RC(ptr_reg)); 3074 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3075 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3076 3077 op_cost(10); 3078 format %{"[$reg + pos $idx << $scale]" %} 3079 interface(MEMORY_INTER) %{ 3080 base($reg); 3081 index($idx); 3082 scale($scale); 3083 disp(0x0); 3084 %} 3085 %} 3086 3087 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3088 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3089 %{ 3090 constraint(ALLOC_IN_RC(ptr_reg)); 3091 match(AddP (AddP reg (LShiftL lreg scale)) off); 3092 3093 op_cost(10); 3094 format %{"[$reg + $off + $lreg << $scale]" %} 3095 interface(MEMORY_INTER) %{ 3096 base($reg); 3097 index($lreg); 3098 scale($scale); 3099 disp($off); 3100 %} 3101 %} 3102 3103 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3104 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3105 %{ 3106 constraint(ALLOC_IN_RC(ptr_reg)); 3107 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3108 match(AddP (AddP reg (ConvI2L idx)) off); 3109 3110 op_cost(10); 3111 format %{"[$reg + $off + $idx]" %} 3112 interface(MEMORY_INTER) %{ 3113 base($reg); 3114 index($idx); 3115 scale(0x0); 3116 disp($off); 3117 %} 3118 %} 3119 3120 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3121 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3122 %{ 3123 constraint(ALLOC_IN_RC(ptr_reg)); 3124 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3125 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3126 3127 op_cost(10); 3128 format %{"[$reg + $off + $idx << $scale]" %} 3129 interface(MEMORY_INTER) %{ 3130 base($reg); 3131 index($idx); 3132 scale($scale); 3133 disp($off); 3134 %} 3135 %} 3136 3137 // Indirect Narrow Oop Operand 3138 operand indCompressedOop(rRegN reg) %{ 3139 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3140 constraint(ALLOC_IN_RC(ptr_reg)); 3141 match(DecodeN reg); 3142 3143 op_cost(10); 3144 format %{"[R12 + $reg << 3] (compressed oop addressing)" %} 3145 interface(MEMORY_INTER) %{ 3146 base(0xc); // R12 3147 index($reg); 3148 scale(0x3); 3149 disp(0x0); 3150 %} 3151 %} 3152 3153 // Indirect Narrow Oop Plus Offset Operand 3154 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3155 // we can't free r12 even with CompressedOops::base() == nullptr. 3156 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3157 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3158 constraint(ALLOC_IN_RC(ptr_reg)); 3159 match(AddP (DecodeN reg) off); 3160 3161 op_cost(10); 3162 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3163 interface(MEMORY_INTER) %{ 3164 base(0xc); // R12 3165 index($reg); 3166 scale(0x3); 3167 disp($off); 3168 %} 3169 %} 3170 3171 // Indirect Memory Operand 3172 operand indirectNarrow(rRegN reg) 3173 %{ 3174 predicate(CompressedOops::shift() == 0); 3175 constraint(ALLOC_IN_RC(ptr_reg)); 3176 match(DecodeN reg); 3177 3178 format %{ "[$reg]" %} 3179 interface(MEMORY_INTER) %{ 3180 base($reg); 3181 index(0x4); 3182 scale(0x0); 3183 disp(0x0); 3184 %} 3185 %} 3186 3187 // Indirect Memory Plus Short Offset Operand 3188 operand indOffset8Narrow(rRegN reg, immL8 off) 3189 %{ 3190 predicate(CompressedOops::shift() == 0); 3191 constraint(ALLOC_IN_RC(ptr_reg)); 3192 match(AddP (DecodeN reg) off); 3193 3194 format %{ "[$reg + $off (8-bit)]" %} 3195 interface(MEMORY_INTER) %{ 3196 base($reg); 3197 index(0x4); 3198 scale(0x0); 3199 disp($off); 3200 %} 3201 %} 3202 3203 // Indirect Memory Plus Long Offset Operand 3204 operand indOffset32Narrow(rRegN reg, immL32 off) 3205 %{ 3206 predicate(CompressedOops::shift() == 0); 3207 constraint(ALLOC_IN_RC(ptr_reg)); 3208 match(AddP (DecodeN reg) off); 3209 3210 format %{ "[$reg + $off (32-bit)]" %} 3211 interface(MEMORY_INTER) %{ 3212 base($reg); 3213 index(0x4); 3214 scale(0x0); 3215 disp($off); 3216 %} 3217 %} 3218 3219 // Indirect Memory Plus Index Register Plus Offset Operand 3220 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3221 %{ 3222 predicate(CompressedOops::shift() == 0); 3223 constraint(ALLOC_IN_RC(ptr_reg)); 3224 match(AddP (AddP (DecodeN reg) lreg) off); 3225 3226 op_cost(10); 3227 format %{"[$reg + $off + $lreg]" %} 3228 interface(MEMORY_INTER) %{ 3229 base($reg); 3230 index($lreg); 3231 scale(0x0); 3232 disp($off); 3233 %} 3234 %} 3235 3236 // Indirect Memory Plus Index Register Plus Offset Operand 3237 operand indIndexNarrow(rRegN reg, rRegL lreg) 3238 %{ 3239 predicate(CompressedOops::shift() == 0); 3240 constraint(ALLOC_IN_RC(ptr_reg)); 3241 match(AddP (DecodeN reg) lreg); 3242 3243 op_cost(10); 3244 format %{"[$reg + $lreg]" %} 3245 interface(MEMORY_INTER) %{ 3246 base($reg); 3247 index($lreg); 3248 scale(0x0); 3249 disp(0x0); 3250 %} 3251 %} 3252 3253 // Indirect Memory Times Scale Plus Index Register 3254 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3255 %{ 3256 predicate(CompressedOops::shift() == 0); 3257 constraint(ALLOC_IN_RC(ptr_reg)); 3258 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3259 3260 op_cost(10); 3261 format %{"[$reg + $lreg << $scale]" %} 3262 interface(MEMORY_INTER) %{ 3263 base($reg); 3264 index($lreg); 3265 scale($scale); 3266 disp(0x0); 3267 %} 3268 %} 3269 3270 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3271 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3272 %{ 3273 predicate(CompressedOops::shift() == 0); 3274 constraint(ALLOC_IN_RC(ptr_reg)); 3275 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3276 3277 op_cost(10); 3278 format %{"[$reg + $off + $lreg << $scale]" %} 3279 interface(MEMORY_INTER) %{ 3280 base($reg); 3281 index($lreg); 3282 scale($scale); 3283 disp($off); 3284 %} 3285 %} 3286 3287 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3288 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3289 %{ 3290 constraint(ALLOC_IN_RC(ptr_reg)); 3291 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3292 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3293 3294 op_cost(10); 3295 format %{"[$reg + $off + $idx]" %} 3296 interface(MEMORY_INTER) %{ 3297 base($reg); 3298 index($idx); 3299 scale(0x0); 3300 disp($off); 3301 %} 3302 %} 3303 3304 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3305 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3306 %{ 3307 constraint(ALLOC_IN_RC(ptr_reg)); 3308 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3309 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3310 3311 op_cost(10); 3312 format %{"[$reg + $off + $idx << $scale]" %} 3313 interface(MEMORY_INTER) %{ 3314 base($reg); 3315 index($idx); 3316 scale($scale); 3317 disp($off); 3318 %} 3319 %} 3320 3321 //----------Special Memory Operands-------------------------------------------- 3322 // Stack Slot Operand - This operand is used for loading and storing temporary 3323 // values on the stack where a match requires a value to 3324 // flow through memory. 3325 operand stackSlotP(sRegP reg) 3326 %{ 3327 constraint(ALLOC_IN_RC(stack_slots)); 3328 // No match rule because this operand is only generated in matching 3329 3330 format %{ "[$reg]" %} 3331 interface(MEMORY_INTER) %{ 3332 base(0x4); // RSP 3333 index(0x4); // No Index 3334 scale(0x0); // No Scale 3335 disp($reg); // Stack Offset 3336 %} 3337 %} 3338 3339 operand stackSlotI(sRegI reg) 3340 %{ 3341 constraint(ALLOC_IN_RC(stack_slots)); 3342 // No match rule because this operand is only generated in matching 3343 3344 format %{ "[$reg]" %} 3345 interface(MEMORY_INTER) %{ 3346 base(0x4); // RSP 3347 index(0x4); // No Index 3348 scale(0x0); // No Scale 3349 disp($reg); // Stack Offset 3350 %} 3351 %} 3352 3353 operand stackSlotF(sRegF reg) 3354 %{ 3355 constraint(ALLOC_IN_RC(stack_slots)); 3356 // No match rule because this operand is only generated in matching 3357 3358 format %{ "[$reg]" %} 3359 interface(MEMORY_INTER) %{ 3360 base(0x4); // RSP 3361 index(0x4); // No Index 3362 scale(0x0); // No Scale 3363 disp($reg); // Stack Offset 3364 %} 3365 %} 3366 3367 operand stackSlotD(sRegD reg) 3368 %{ 3369 constraint(ALLOC_IN_RC(stack_slots)); 3370 // No match rule because this operand is only generated in matching 3371 3372 format %{ "[$reg]" %} 3373 interface(MEMORY_INTER) %{ 3374 base(0x4); // RSP 3375 index(0x4); // No Index 3376 scale(0x0); // No Scale 3377 disp($reg); // Stack Offset 3378 %} 3379 %} 3380 operand stackSlotL(sRegL reg) 3381 %{ 3382 constraint(ALLOC_IN_RC(stack_slots)); 3383 // No match rule because this operand is only generated in matching 3384 3385 format %{ "[$reg]" %} 3386 interface(MEMORY_INTER) %{ 3387 base(0x4); // RSP 3388 index(0x4); // No Index 3389 scale(0x0); // No Scale 3390 disp($reg); // Stack Offset 3391 %} 3392 %} 3393 3394 //----------Conditional Branch Operands---------------------------------------- 3395 // Comparison Op - This is the operation of the comparison, and is limited to 3396 // the following set of codes: 3397 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3398 // 3399 // Other attributes of the comparison, such as unsignedness, are specified 3400 // by the comparison instruction that sets a condition code flags register. 3401 // That result is represented by a flags operand whose subtype is appropriate 3402 // to the unsignedness (etc.) of the comparison. 3403 // 3404 // Later, the instruction which matches both the Comparison Op (a Bool) and 3405 // the flags (produced by the Cmp) specifies the coding of the comparison op 3406 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3407 3408 // Comparison Code 3409 operand cmpOp() 3410 %{ 3411 match(Bool); 3412 3413 format %{ "" %} 3414 interface(COND_INTER) %{ 3415 equal(0x4, "e"); 3416 not_equal(0x5, "ne"); 3417 less(0xC, "l"); 3418 greater_equal(0xD, "ge"); 3419 less_equal(0xE, "le"); 3420 greater(0xF, "g"); 3421 overflow(0x0, "o"); 3422 no_overflow(0x1, "no"); 3423 %} 3424 %} 3425 3426 // Comparison Code, unsigned compare. Used by FP also, with 3427 // C2 (unordered) turned into GT or LT already. The other bits 3428 // C0 and C3 are turned into Carry & Zero flags. 3429 operand cmpOpU() 3430 %{ 3431 match(Bool); 3432 3433 format %{ "" %} 3434 interface(COND_INTER) %{ 3435 equal(0x4, "e"); 3436 not_equal(0x5, "ne"); 3437 less(0x2, "b"); 3438 greater_equal(0x3, "ae"); 3439 less_equal(0x6, "be"); 3440 greater(0x7, "a"); 3441 overflow(0x0, "o"); 3442 no_overflow(0x1, "no"); 3443 %} 3444 %} 3445 3446 3447 // Floating comparisons that don't require any fixup for the unordered case, 3448 // If both inputs of the comparison are the same, ZF is always set so we 3449 // don't need to use cmpOpUCF2 for eq/ne 3450 operand cmpOpUCF() %{ 3451 match(Bool); 3452 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3453 n->as_Bool()->_test._test == BoolTest::ge || 3454 n->as_Bool()->_test._test == BoolTest::le || 3455 n->as_Bool()->_test._test == BoolTest::gt || 3456 n->in(1)->in(1) == n->in(1)->in(2)); 3457 format %{ "" %} 3458 interface(COND_INTER) %{ 3459 equal(0xb, "np"); 3460 not_equal(0xa, "p"); 3461 less(0x2, "b"); 3462 greater_equal(0x3, "ae"); 3463 less_equal(0x6, "be"); 3464 greater(0x7, "a"); 3465 overflow(0x0, "o"); 3466 no_overflow(0x1, "no"); 3467 %} 3468 %} 3469 3470 3471 // Floating comparisons that can be fixed up with extra conditional jumps 3472 operand cmpOpUCF2() %{ 3473 match(Bool); 3474 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3475 n->as_Bool()->_test._test == BoolTest::eq) && 3476 n->in(1)->in(1) != n->in(1)->in(2)); 3477 format %{ "" %} 3478 interface(COND_INTER) %{ 3479 equal(0x4, "e"); 3480 not_equal(0x5, "ne"); 3481 less(0x2, "b"); 3482 greater_equal(0x3, "ae"); 3483 less_equal(0x6, "be"); 3484 greater(0x7, "a"); 3485 overflow(0x0, "o"); 3486 no_overflow(0x1, "no"); 3487 %} 3488 %} 3489 3490 //----------OPERAND CLASSES---------------------------------------------------- 3491 // Operand Classes are groups of operands that are used as to simplify 3492 // instruction definitions by not requiring the AD writer to specify separate 3493 // instructions for every form of operand when the instruction accepts 3494 // multiple operand types with the same basic encoding and format. The classic 3495 // case of this is memory operands. 3496 3497 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3498 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3499 indCompressedOop, indCompressedOopOffset, 3500 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3501 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3502 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3503 3504 //----------PIPELINE----------------------------------------------------------- 3505 // Rules which define the behavior of the target architectures pipeline. 3506 pipeline %{ 3507 3508 //----------ATTRIBUTES--------------------------------------------------------- 3509 attributes %{ 3510 variable_size_instructions; // Fixed size instructions 3511 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3512 instruction_unit_size = 1; // An instruction is 1 bytes long 3513 instruction_fetch_unit_size = 16; // The processor fetches one line 3514 instruction_fetch_units = 1; // of 16 bytes 3515 3516 // List of nop instructions 3517 nops( MachNop ); 3518 %} 3519 3520 //----------RESOURCES---------------------------------------------------------- 3521 // Resources are the functional units available to the machine 3522 3523 // Generic P2/P3 pipeline 3524 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3525 // 3 instructions decoded per cycle. 3526 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3527 // 3 ALU op, only ALU0 handles mul instructions. 3528 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3529 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3530 BR, FPU, 3531 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3532 3533 //----------PIPELINE DESCRIPTION----------------------------------------------- 3534 // Pipeline Description specifies the stages in the machine's pipeline 3535 3536 // Generic P2/P3 pipeline 3537 pipe_desc(S0, S1, S2, S3, S4, S5); 3538 3539 //----------PIPELINE CLASSES--------------------------------------------------- 3540 // Pipeline Classes describe the stages in which input and output are 3541 // referenced by the hardware pipeline. 3542 3543 // Naming convention: ialu or fpu 3544 // Then: _reg 3545 // Then: _reg if there is a 2nd register 3546 // Then: _long if it's a pair of instructions implementing a long 3547 // Then: _fat if it requires the big decoder 3548 // Or: _mem if it requires the big decoder and a memory unit. 3549 3550 // Integer ALU reg operation 3551 pipe_class ialu_reg(rRegI dst) 3552 %{ 3553 single_instruction; 3554 dst : S4(write); 3555 dst : S3(read); 3556 DECODE : S0; // any decoder 3557 ALU : S3; // any alu 3558 %} 3559 3560 // Long ALU reg operation 3561 pipe_class ialu_reg_long(rRegL dst) 3562 %{ 3563 instruction_count(2); 3564 dst : S4(write); 3565 dst : S3(read); 3566 DECODE : S0(2); // any 2 decoders 3567 ALU : S3(2); // both alus 3568 %} 3569 3570 // Integer ALU reg operation using big decoder 3571 pipe_class ialu_reg_fat(rRegI dst) 3572 %{ 3573 single_instruction; 3574 dst : S4(write); 3575 dst : S3(read); 3576 D0 : S0; // big decoder only 3577 ALU : S3; // any alu 3578 %} 3579 3580 // Integer ALU reg-reg operation 3581 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3582 %{ 3583 single_instruction; 3584 dst : S4(write); 3585 src : S3(read); 3586 DECODE : S0; // any decoder 3587 ALU : S3; // any alu 3588 %} 3589 3590 // Integer ALU reg-reg operation 3591 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3592 %{ 3593 single_instruction; 3594 dst : S4(write); 3595 src : S3(read); 3596 D0 : S0; // big decoder only 3597 ALU : S3; // any alu 3598 %} 3599 3600 // Integer ALU reg-mem operation 3601 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3602 %{ 3603 single_instruction; 3604 dst : S5(write); 3605 mem : S3(read); 3606 D0 : S0; // big decoder only 3607 ALU : S4; // any alu 3608 MEM : S3; // any mem 3609 %} 3610 3611 // Integer mem operation (prefetch) 3612 pipe_class ialu_mem(memory mem) 3613 %{ 3614 single_instruction; 3615 mem : S3(read); 3616 D0 : S0; // big decoder only 3617 MEM : S3; // any mem 3618 %} 3619 3620 // Integer Store to Memory 3621 pipe_class ialu_mem_reg(memory mem, rRegI src) 3622 %{ 3623 single_instruction; 3624 mem : S3(read); 3625 src : S5(read); 3626 D0 : S0; // big decoder only 3627 ALU : S4; // any alu 3628 MEM : S3; 3629 %} 3630 3631 // // Long Store to Memory 3632 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3633 // %{ 3634 // instruction_count(2); 3635 // mem : S3(read); 3636 // src : S5(read); 3637 // D0 : S0(2); // big decoder only; twice 3638 // ALU : S4(2); // any 2 alus 3639 // MEM : S3(2); // Both mems 3640 // %} 3641 3642 // Integer Store to Memory 3643 pipe_class ialu_mem_imm(memory mem) 3644 %{ 3645 single_instruction; 3646 mem : S3(read); 3647 D0 : S0; // big decoder only 3648 ALU : S4; // any alu 3649 MEM : S3; 3650 %} 3651 3652 // Integer ALU0 reg-reg operation 3653 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3654 %{ 3655 single_instruction; 3656 dst : S4(write); 3657 src : S3(read); 3658 D0 : S0; // Big decoder only 3659 ALU0 : S3; // only alu0 3660 %} 3661 3662 // Integer ALU0 reg-mem operation 3663 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3664 %{ 3665 single_instruction; 3666 dst : S5(write); 3667 mem : S3(read); 3668 D0 : S0; // big decoder only 3669 ALU0 : S4; // ALU0 only 3670 MEM : S3; // any mem 3671 %} 3672 3673 // Integer ALU reg-reg operation 3674 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3675 %{ 3676 single_instruction; 3677 cr : S4(write); 3678 src1 : S3(read); 3679 src2 : S3(read); 3680 DECODE : S0; // any decoder 3681 ALU : S3; // any alu 3682 %} 3683 3684 // Integer ALU reg-imm operation 3685 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3686 %{ 3687 single_instruction; 3688 cr : S4(write); 3689 src1 : S3(read); 3690 DECODE : S0; // any decoder 3691 ALU : S3; // any alu 3692 %} 3693 3694 // Integer ALU reg-mem operation 3695 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3696 %{ 3697 single_instruction; 3698 cr : S4(write); 3699 src1 : S3(read); 3700 src2 : S3(read); 3701 D0 : S0; // big decoder only 3702 ALU : S4; // any alu 3703 MEM : S3; 3704 %} 3705 3706 // Conditional move reg-reg 3707 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3708 %{ 3709 instruction_count(4); 3710 y : S4(read); 3711 q : S3(read); 3712 p : S3(read); 3713 DECODE : S0(4); // any decoder 3714 %} 3715 3716 // Conditional move reg-reg 3717 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3718 %{ 3719 single_instruction; 3720 dst : S4(write); 3721 src : S3(read); 3722 cr : S3(read); 3723 DECODE : S0; // any decoder 3724 %} 3725 3726 // Conditional move reg-mem 3727 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3728 %{ 3729 single_instruction; 3730 dst : S4(write); 3731 src : S3(read); 3732 cr : S3(read); 3733 DECODE : S0; // any decoder 3734 MEM : S3; 3735 %} 3736 3737 // Conditional move reg-reg long 3738 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3739 %{ 3740 single_instruction; 3741 dst : S4(write); 3742 src : S3(read); 3743 cr : S3(read); 3744 DECODE : S0(2); // any 2 decoders 3745 %} 3746 3747 // Float reg-reg operation 3748 pipe_class fpu_reg(regD dst) 3749 %{ 3750 instruction_count(2); 3751 dst : S3(read); 3752 DECODE : S0(2); // any 2 decoders 3753 FPU : S3; 3754 %} 3755 3756 // Float reg-reg operation 3757 pipe_class fpu_reg_reg(regD dst, regD src) 3758 %{ 3759 instruction_count(2); 3760 dst : S4(write); 3761 src : S3(read); 3762 DECODE : S0(2); // any 2 decoders 3763 FPU : S3; 3764 %} 3765 3766 // Float reg-reg operation 3767 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3768 %{ 3769 instruction_count(3); 3770 dst : S4(write); 3771 src1 : S3(read); 3772 src2 : S3(read); 3773 DECODE : S0(3); // any 3 decoders 3774 FPU : S3(2); 3775 %} 3776 3777 // Float reg-reg operation 3778 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3779 %{ 3780 instruction_count(4); 3781 dst : S4(write); 3782 src1 : S3(read); 3783 src2 : S3(read); 3784 src3 : S3(read); 3785 DECODE : S0(4); // any 3 decoders 3786 FPU : S3(2); 3787 %} 3788 3789 // Float reg-reg operation 3790 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3791 %{ 3792 instruction_count(4); 3793 dst : S4(write); 3794 src1 : S3(read); 3795 src2 : S3(read); 3796 src3 : S3(read); 3797 DECODE : S1(3); // any 3 decoders 3798 D0 : S0; // Big decoder only 3799 FPU : S3(2); 3800 MEM : S3; 3801 %} 3802 3803 // Float reg-mem operation 3804 pipe_class fpu_reg_mem(regD dst, memory mem) 3805 %{ 3806 instruction_count(2); 3807 dst : S5(write); 3808 mem : S3(read); 3809 D0 : S0; // big decoder only 3810 DECODE : S1; // any decoder for FPU POP 3811 FPU : S4; 3812 MEM : S3; // any mem 3813 %} 3814 3815 // Float reg-mem operation 3816 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3817 %{ 3818 instruction_count(3); 3819 dst : S5(write); 3820 src1 : S3(read); 3821 mem : S3(read); 3822 D0 : S0; // big decoder only 3823 DECODE : S1(2); // any decoder for FPU POP 3824 FPU : S4; 3825 MEM : S3; // any mem 3826 %} 3827 3828 // Float mem-reg operation 3829 pipe_class fpu_mem_reg(memory mem, regD src) 3830 %{ 3831 instruction_count(2); 3832 src : S5(read); 3833 mem : S3(read); 3834 DECODE : S0; // any decoder for FPU PUSH 3835 D0 : S1; // big decoder only 3836 FPU : S4; 3837 MEM : S3; // any mem 3838 %} 3839 3840 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3841 %{ 3842 instruction_count(3); 3843 src1 : S3(read); 3844 src2 : S3(read); 3845 mem : S3(read); 3846 DECODE : S0(2); // any decoder for FPU PUSH 3847 D0 : S1; // big decoder only 3848 FPU : S4; 3849 MEM : S3; // any mem 3850 %} 3851 3852 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3853 %{ 3854 instruction_count(3); 3855 src1 : S3(read); 3856 src2 : S3(read); 3857 mem : S4(read); 3858 DECODE : S0; // any decoder for FPU PUSH 3859 D0 : S0(2); // big decoder only 3860 FPU : S4; 3861 MEM : S3(2); // any mem 3862 %} 3863 3864 pipe_class fpu_mem_mem(memory dst, memory src1) 3865 %{ 3866 instruction_count(2); 3867 src1 : S3(read); 3868 dst : S4(read); 3869 D0 : S0(2); // big decoder only 3870 MEM : S3(2); // any mem 3871 %} 3872 3873 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3874 %{ 3875 instruction_count(3); 3876 src1 : S3(read); 3877 src2 : S3(read); 3878 dst : S4(read); 3879 D0 : S0(3); // big decoder only 3880 FPU : S4; 3881 MEM : S3(3); // any mem 3882 %} 3883 3884 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3885 %{ 3886 instruction_count(3); 3887 src1 : S4(read); 3888 mem : S4(read); 3889 DECODE : S0; // any decoder for FPU PUSH 3890 D0 : S0(2); // big decoder only 3891 FPU : S4; 3892 MEM : S3(2); // any mem 3893 %} 3894 3895 // Float load constant 3896 pipe_class fpu_reg_con(regD dst) 3897 %{ 3898 instruction_count(2); 3899 dst : S5(write); 3900 D0 : S0; // big decoder only for the load 3901 DECODE : S1; // any decoder for FPU POP 3902 FPU : S4; 3903 MEM : S3; // any mem 3904 %} 3905 3906 // Float load constant 3907 pipe_class fpu_reg_reg_con(regD dst, regD src) 3908 %{ 3909 instruction_count(3); 3910 dst : S5(write); 3911 src : S3(read); 3912 D0 : S0; // big decoder only for the load 3913 DECODE : S1(2); // any decoder for FPU POP 3914 FPU : S4; 3915 MEM : S3; // any mem 3916 %} 3917 3918 // UnConditional branch 3919 pipe_class pipe_jmp(label labl) 3920 %{ 3921 single_instruction; 3922 BR : S3; 3923 %} 3924 3925 // Conditional branch 3926 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3927 %{ 3928 single_instruction; 3929 cr : S1(read); 3930 BR : S3; 3931 %} 3932 3933 // Allocation idiom 3934 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3935 %{ 3936 instruction_count(1); force_serialization; 3937 fixed_latency(6); 3938 heap_ptr : S3(read); 3939 DECODE : S0(3); 3940 D0 : S2; 3941 MEM : S3; 3942 ALU : S3(2); 3943 dst : S5(write); 3944 BR : S5; 3945 %} 3946 3947 // Generic big/slow expanded idiom 3948 pipe_class pipe_slow() 3949 %{ 3950 instruction_count(10); multiple_bundles; force_serialization; 3951 fixed_latency(100); 3952 D0 : S0(2); 3953 MEM : S3(2); 3954 %} 3955 3956 // The real do-nothing guy 3957 pipe_class empty() 3958 %{ 3959 instruction_count(0); 3960 %} 3961 3962 // Define the class for the Nop node 3963 define 3964 %{ 3965 MachNop = empty; 3966 %} 3967 3968 %} 3969 3970 //----------INSTRUCTIONS------------------------------------------------------- 3971 // 3972 // match -- States which machine-independent subtree may be replaced 3973 // by this instruction. 3974 // ins_cost -- The estimated cost of this instruction is used by instruction 3975 // selection to identify a minimum cost tree of machine 3976 // instructions that matches a tree of machine-independent 3977 // instructions. 3978 // format -- A string providing the disassembly for this instruction. 3979 // The value of an instruction's operand may be inserted 3980 // by referring to it with a '$' prefix. 3981 // opcode -- Three instruction opcodes may be provided. These are referred 3982 // to within an encode class as $primary, $secondary, and $tertiary 3983 // rrspectively. The primary opcode is commonly used to 3984 // indicate the type of machine instruction, while secondary 3985 // and tertiary are often used for prefix options or addressing 3986 // modes. 3987 // ins_encode -- A list of encode classes with parameters. The encode class 3988 // name must have been defined in an 'enc_class' specification 3989 // in the encode section of the architecture description. 3990 3991 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3992 // Load Float 3993 instruct MoveF2VL(vlRegF dst, regF src) %{ 3994 match(Set dst src); 3995 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3996 ins_encode %{ 3997 ShouldNotReachHere(); 3998 %} 3999 ins_pipe( fpu_reg_reg ); 4000 %} 4001 4002 // Load Float 4003 instruct MoveF2LEG(legRegF dst, regF src) %{ 4004 match(Set dst src); 4005 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 4006 ins_encode %{ 4007 ShouldNotReachHere(); 4008 %} 4009 ins_pipe( fpu_reg_reg ); 4010 %} 4011 4012 // Load Float 4013 instruct MoveVL2F(regF dst, vlRegF src) %{ 4014 match(Set dst src); 4015 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 4016 ins_encode %{ 4017 ShouldNotReachHere(); 4018 %} 4019 ins_pipe( fpu_reg_reg ); 4020 %} 4021 4022 // Load Float 4023 instruct MoveLEG2F(regF dst, legRegF src) %{ 4024 match(Set dst src); 4025 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 4026 ins_encode %{ 4027 ShouldNotReachHere(); 4028 %} 4029 ins_pipe( fpu_reg_reg ); 4030 %} 4031 4032 // Load Double 4033 instruct MoveD2VL(vlRegD dst, regD src) %{ 4034 match(Set dst src); 4035 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 4036 ins_encode %{ 4037 ShouldNotReachHere(); 4038 %} 4039 ins_pipe( fpu_reg_reg ); 4040 %} 4041 4042 // Load Double 4043 instruct MoveD2LEG(legRegD dst, regD src) %{ 4044 match(Set dst src); 4045 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 4046 ins_encode %{ 4047 ShouldNotReachHere(); 4048 %} 4049 ins_pipe( fpu_reg_reg ); 4050 %} 4051 4052 // Load Double 4053 instruct MoveVL2D(regD dst, vlRegD src) %{ 4054 match(Set dst src); 4055 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 4056 ins_encode %{ 4057 ShouldNotReachHere(); 4058 %} 4059 ins_pipe( fpu_reg_reg ); 4060 %} 4061 4062 // Load Double 4063 instruct MoveLEG2D(regD dst, legRegD src) %{ 4064 match(Set dst src); 4065 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 4066 ins_encode %{ 4067 ShouldNotReachHere(); 4068 %} 4069 ins_pipe( fpu_reg_reg ); 4070 %} 4071 4072 //----------Load/Store/Move Instructions--------------------------------------- 4073 //----------Load Instructions-------------------------------------------------- 4074 4075 // Load Byte (8 bit signed) 4076 instruct loadB(rRegI dst, memory mem) 4077 %{ 4078 match(Set dst (LoadB mem)); 4079 4080 ins_cost(125); 4081 format %{ "movsbl $dst, $mem\t# byte" %} 4082 4083 ins_encode %{ 4084 __ movsbl($dst$$Register, $mem$$Address); 4085 %} 4086 4087 ins_pipe(ialu_reg_mem); 4088 %} 4089 4090 // Load Byte (8 bit signed) into Long Register 4091 instruct loadB2L(rRegL dst, memory mem) 4092 %{ 4093 match(Set dst (ConvI2L (LoadB mem))); 4094 4095 ins_cost(125); 4096 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4097 4098 ins_encode %{ 4099 __ movsbq($dst$$Register, $mem$$Address); 4100 %} 4101 4102 ins_pipe(ialu_reg_mem); 4103 %} 4104 4105 // Load Unsigned Byte (8 bit UNsigned) 4106 instruct loadUB(rRegI dst, memory mem) 4107 %{ 4108 match(Set dst (LoadUB mem)); 4109 4110 ins_cost(125); 4111 format %{ "movzbl $dst, $mem\t# ubyte" %} 4112 4113 ins_encode %{ 4114 __ movzbl($dst$$Register, $mem$$Address); 4115 %} 4116 4117 ins_pipe(ialu_reg_mem); 4118 %} 4119 4120 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4121 instruct loadUB2L(rRegL dst, memory mem) 4122 %{ 4123 match(Set dst (ConvI2L (LoadUB mem))); 4124 4125 ins_cost(125); 4126 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4127 4128 ins_encode %{ 4129 __ movzbq($dst$$Register, $mem$$Address); 4130 %} 4131 4132 ins_pipe(ialu_reg_mem); 4133 %} 4134 4135 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4136 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4137 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4138 effect(KILL cr); 4139 4140 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4141 "andl $dst, right_n_bits($mask, 8)" %} 4142 ins_encode %{ 4143 Register Rdst = $dst$$Register; 4144 __ movzbq(Rdst, $mem$$Address); 4145 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4146 %} 4147 ins_pipe(ialu_reg_mem); 4148 %} 4149 4150 // Load Short (16 bit signed) 4151 instruct loadS(rRegI dst, memory mem) 4152 %{ 4153 match(Set dst (LoadS mem)); 4154 4155 ins_cost(125); 4156 format %{ "movswl $dst, $mem\t# short" %} 4157 4158 ins_encode %{ 4159 __ movswl($dst$$Register, $mem$$Address); 4160 %} 4161 4162 ins_pipe(ialu_reg_mem); 4163 %} 4164 4165 // Load Short (16 bit signed) to Byte (8 bit signed) 4166 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4167 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4168 4169 ins_cost(125); 4170 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4171 ins_encode %{ 4172 __ movsbl($dst$$Register, $mem$$Address); 4173 %} 4174 ins_pipe(ialu_reg_mem); 4175 %} 4176 4177 // Load Short (16 bit signed) into Long Register 4178 instruct loadS2L(rRegL dst, memory mem) 4179 %{ 4180 match(Set dst (ConvI2L (LoadS mem))); 4181 4182 ins_cost(125); 4183 format %{ "movswq $dst, $mem\t# short -> long" %} 4184 4185 ins_encode %{ 4186 __ movswq($dst$$Register, $mem$$Address); 4187 %} 4188 4189 ins_pipe(ialu_reg_mem); 4190 %} 4191 4192 // Load Unsigned Short/Char (16 bit UNsigned) 4193 instruct loadUS(rRegI dst, memory mem) 4194 %{ 4195 match(Set dst (LoadUS mem)); 4196 4197 ins_cost(125); 4198 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4199 4200 ins_encode %{ 4201 __ movzwl($dst$$Register, $mem$$Address); 4202 %} 4203 4204 ins_pipe(ialu_reg_mem); 4205 %} 4206 4207 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4208 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4209 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4210 4211 ins_cost(125); 4212 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4213 ins_encode %{ 4214 __ movsbl($dst$$Register, $mem$$Address); 4215 %} 4216 ins_pipe(ialu_reg_mem); 4217 %} 4218 4219 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4220 instruct loadUS2L(rRegL dst, memory mem) 4221 %{ 4222 match(Set dst (ConvI2L (LoadUS mem))); 4223 4224 ins_cost(125); 4225 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4226 4227 ins_encode %{ 4228 __ movzwq($dst$$Register, $mem$$Address); 4229 %} 4230 4231 ins_pipe(ialu_reg_mem); 4232 %} 4233 4234 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4235 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4236 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4237 4238 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4239 ins_encode %{ 4240 __ movzbq($dst$$Register, $mem$$Address); 4241 %} 4242 ins_pipe(ialu_reg_mem); 4243 %} 4244 4245 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4246 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4247 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4248 effect(KILL cr); 4249 4250 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4251 "andl $dst, right_n_bits($mask, 16)" %} 4252 ins_encode %{ 4253 Register Rdst = $dst$$Register; 4254 __ movzwq(Rdst, $mem$$Address); 4255 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4256 %} 4257 ins_pipe(ialu_reg_mem); 4258 %} 4259 4260 // Load Integer 4261 instruct loadI(rRegI dst, memory mem) 4262 %{ 4263 match(Set dst (LoadI mem)); 4264 4265 ins_cost(125); 4266 format %{ "movl $dst, $mem\t# int" %} 4267 4268 ins_encode %{ 4269 __ movl($dst$$Register, $mem$$Address); 4270 %} 4271 4272 ins_pipe(ialu_reg_mem); 4273 %} 4274 4275 // Load Integer (32 bit signed) to Byte (8 bit signed) 4276 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4277 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4278 4279 ins_cost(125); 4280 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4281 ins_encode %{ 4282 __ movsbl($dst$$Register, $mem$$Address); 4283 %} 4284 ins_pipe(ialu_reg_mem); 4285 %} 4286 4287 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4288 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4289 match(Set dst (AndI (LoadI mem) mask)); 4290 4291 ins_cost(125); 4292 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4293 ins_encode %{ 4294 __ movzbl($dst$$Register, $mem$$Address); 4295 %} 4296 ins_pipe(ialu_reg_mem); 4297 %} 4298 4299 // Load Integer (32 bit signed) to Short (16 bit signed) 4300 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4301 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4302 4303 ins_cost(125); 4304 format %{ "movswl $dst, $mem\t# int -> short" %} 4305 ins_encode %{ 4306 __ movswl($dst$$Register, $mem$$Address); 4307 %} 4308 ins_pipe(ialu_reg_mem); 4309 %} 4310 4311 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4312 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4313 match(Set dst (AndI (LoadI mem) mask)); 4314 4315 ins_cost(125); 4316 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4317 ins_encode %{ 4318 __ movzwl($dst$$Register, $mem$$Address); 4319 %} 4320 ins_pipe(ialu_reg_mem); 4321 %} 4322 4323 // Load Integer into Long Register 4324 instruct loadI2L(rRegL dst, memory mem) 4325 %{ 4326 match(Set dst (ConvI2L (LoadI mem))); 4327 4328 ins_cost(125); 4329 format %{ "movslq $dst, $mem\t# int -> long" %} 4330 4331 ins_encode %{ 4332 __ movslq($dst$$Register, $mem$$Address); 4333 %} 4334 4335 ins_pipe(ialu_reg_mem); 4336 %} 4337 4338 // Load Integer with mask 0xFF into Long Register 4339 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4340 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4341 4342 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4343 ins_encode %{ 4344 __ movzbq($dst$$Register, $mem$$Address); 4345 %} 4346 ins_pipe(ialu_reg_mem); 4347 %} 4348 4349 // Load Integer with mask 0xFFFF into Long Register 4350 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4351 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4352 4353 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4354 ins_encode %{ 4355 __ movzwq($dst$$Register, $mem$$Address); 4356 %} 4357 ins_pipe(ialu_reg_mem); 4358 %} 4359 4360 // Load Integer with a 31-bit mask into Long Register 4361 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4362 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4363 effect(KILL cr); 4364 4365 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4366 "andl $dst, $mask" %} 4367 ins_encode %{ 4368 Register Rdst = $dst$$Register; 4369 __ movl(Rdst, $mem$$Address); 4370 __ andl(Rdst, $mask$$constant); 4371 %} 4372 ins_pipe(ialu_reg_mem); 4373 %} 4374 4375 // Load Unsigned Integer into Long Register 4376 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4377 %{ 4378 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4379 4380 ins_cost(125); 4381 format %{ "movl $dst, $mem\t# uint -> long" %} 4382 4383 ins_encode %{ 4384 __ movl($dst$$Register, $mem$$Address); 4385 %} 4386 4387 ins_pipe(ialu_reg_mem); 4388 %} 4389 4390 // Load Long 4391 instruct loadL(rRegL dst, memory mem) 4392 %{ 4393 match(Set dst (LoadL mem)); 4394 4395 ins_cost(125); 4396 format %{ "movq $dst, $mem\t# long" %} 4397 4398 ins_encode %{ 4399 __ movq($dst$$Register, $mem$$Address); 4400 %} 4401 4402 ins_pipe(ialu_reg_mem); // XXX 4403 %} 4404 4405 // Load Range 4406 instruct loadRange(rRegI dst, memory mem) 4407 %{ 4408 match(Set dst (LoadRange mem)); 4409 4410 ins_cost(125); // XXX 4411 format %{ "movl $dst, $mem\t# range" %} 4412 ins_encode %{ 4413 __ movl($dst$$Register, $mem$$Address); 4414 %} 4415 ins_pipe(ialu_reg_mem); 4416 %} 4417 4418 // Load Pointer 4419 instruct loadP(rRegP dst, memory mem) 4420 %{ 4421 match(Set dst (LoadP mem)); 4422 predicate(n->as_Load()->barrier_data() == 0); 4423 4424 ins_cost(125); // XXX 4425 format %{ "movq $dst, $mem\t# ptr" %} 4426 ins_encode %{ 4427 __ movq($dst$$Register, $mem$$Address); 4428 %} 4429 ins_pipe(ialu_reg_mem); // XXX 4430 %} 4431 4432 // Load Compressed Pointer 4433 instruct loadN(rRegN dst, memory mem) 4434 %{ 4435 match(Set dst (LoadN mem)); 4436 4437 ins_cost(125); // XXX 4438 format %{ "movl $dst, $mem\t# compressed ptr" %} 4439 ins_encode %{ 4440 __ movl($dst$$Register, $mem$$Address); 4441 %} 4442 ins_pipe(ialu_reg_mem); // XXX 4443 %} 4444 4445 4446 // Load Klass Pointer 4447 instruct loadKlass(rRegP dst, memory mem) 4448 %{ 4449 match(Set dst (LoadKlass mem)); 4450 4451 ins_cost(125); // XXX 4452 format %{ "movq $dst, $mem\t# class" %} 4453 ins_encode %{ 4454 __ movq($dst$$Register, $mem$$Address); 4455 %} 4456 ins_pipe(ialu_reg_mem); // XXX 4457 %} 4458 4459 // Load narrow Klass Pointer 4460 instruct loadNKlass(rRegN dst, memory mem) 4461 %{ 4462 match(Set dst (LoadNKlass mem)); 4463 4464 ins_cost(125); // XXX 4465 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4466 ins_encode %{ 4467 __ movl($dst$$Register, $mem$$Address); 4468 %} 4469 ins_pipe(ialu_reg_mem); // XXX 4470 %} 4471 4472 // Load Float 4473 instruct loadF(regF dst, memory mem) 4474 %{ 4475 match(Set dst (LoadF mem)); 4476 4477 ins_cost(145); // XXX 4478 format %{ "movss $dst, $mem\t# float" %} 4479 ins_encode %{ 4480 __ movflt($dst$$XMMRegister, $mem$$Address); 4481 %} 4482 ins_pipe(pipe_slow); // XXX 4483 %} 4484 4485 // Load Double 4486 instruct loadD_partial(regD dst, memory mem) 4487 %{ 4488 predicate(!UseXmmLoadAndClearUpper); 4489 match(Set dst (LoadD mem)); 4490 4491 ins_cost(145); // XXX 4492 format %{ "movlpd $dst, $mem\t# double" %} 4493 ins_encode %{ 4494 __ movdbl($dst$$XMMRegister, $mem$$Address); 4495 %} 4496 ins_pipe(pipe_slow); // XXX 4497 %} 4498 4499 instruct loadD(regD dst, memory mem) 4500 %{ 4501 predicate(UseXmmLoadAndClearUpper); 4502 match(Set dst (LoadD mem)); 4503 4504 ins_cost(145); // XXX 4505 format %{ "movsd $dst, $mem\t# double" %} 4506 ins_encode %{ 4507 __ movdbl($dst$$XMMRegister, $mem$$Address); 4508 %} 4509 ins_pipe(pipe_slow); // XXX 4510 %} 4511 4512 4513 // Following pseudo code describes the algorithm for max[FD]: 4514 // Min algorithm is on similar lines 4515 // btmp = (b < +0.0) ? a : b 4516 // atmp = (b < +0.0) ? b : a 4517 // Tmp = Max_Float(atmp , btmp) 4518 // Res = (atmp == NaN) ? atmp : Tmp 4519 4520 // max = java.lang.Math.max(float a, float b) 4521 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4522 predicate(UseAVX > 0 && !SuperWord::is_reduction(n)); 4523 match(Set dst (MaxF a b)); 4524 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4525 format %{ 4526 "vblendvps $btmp,$b,$a,$b \n\t" 4527 "vblendvps $atmp,$a,$b,$b \n\t" 4528 "vmaxss $tmp,$atmp,$btmp \n\t" 4529 "vcmpps.unordered $btmp,$atmp,$atmp \n\t" 4530 "vblendvps $dst,$tmp,$atmp,$btmp \n\t" 4531 %} 4532 ins_encode %{ 4533 int vector_len = Assembler::AVX_128bit; 4534 __ vblendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 4535 __ vblendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 4536 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 4537 __ vcmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 4538 __ vblendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 4539 %} 4540 ins_pipe( pipe_slow ); 4541 %} 4542 4543 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4544 predicate(UseAVX > 0 && SuperWord::is_reduction(n)); 4545 match(Set dst (MaxF a b)); 4546 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4547 4548 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 4549 ins_encode %{ 4550 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4551 false /*min*/, true /*single*/); 4552 %} 4553 ins_pipe( pipe_slow ); 4554 %} 4555 4556 // max = java.lang.Math.max(double a, double b) 4557 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4558 predicate(UseAVX > 0 && !SuperWord::is_reduction(n)); 4559 match(Set dst (MaxD a b)); 4560 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4561 format %{ 4562 "vblendvpd $btmp,$b,$a,$b \n\t" 4563 "vblendvpd $atmp,$a,$b,$b \n\t" 4564 "vmaxsd $tmp,$atmp,$btmp \n\t" 4565 "vcmppd.unordered $btmp,$atmp,$atmp \n\t" 4566 "vblendvpd $dst,$tmp,$atmp,$btmp \n\t" 4567 %} 4568 ins_encode %{ 4569 int vector_len = Assembler::AVX_128bit; 4570 __ vblendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 4571 __ vblendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 4572 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 4573 __ vcmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 4574 __ vblendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 4575 %} 4576 ins_pipe( pipe_slow ); 4577 %} 4578 4579 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4580 predicate(UseAVX > 0 && SuperWord::is_reduction(n)); 4581 match(Set dst (MaxD a b)); 4582 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4583 4584 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 4585 ins_encode %{ 4586 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4587 false /*min*/, false /*single*/); 4588 %} 4589 ins_pipe( pipe_slow ); 4590 %} 4591 4592 // min = java.lang.Math.min(float a, float b) 4593 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4594 predicate(UseAVX > 0 && !SuperWord::is_reduction(n)); 4595 match(Set dst (MinF a b)); 4596 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4597 format %{ 4598 "vblendvps $atmp,$a,$b,$a \n\t" 4599 "vblendvps $btmp,$b,$a,$a \n\t" 4600 "vminss $tmp,$atmp,$btmp \n\t" 4601 "vcmpps.unordered $btmp,$atmp,$atmp \n\t" 4602 "vblendvps $dst,$tmp,$atmp,$btmp \n\t" 4603 %} 4604 ins_encode %{ 4605 int vector_len = Assembler::AVX_128bit; 4606 __ vblendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 4607 __ vblendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 4608 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 4609 __ vcmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 4610 __ vblendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 4611 %} 4612 ins_pipe( pipe_slow ); 4613 %} 4614 4615 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4616 predicate(UseAVX > 0 && SuperWord::is_reduction(n)); 4617 match(Set dst (MinF a b)); 4618 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4619 4620 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 4621 ins_encode %{ 4622 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4623 true /*min*/, true /*single*/); 4624 %} 4625 ins_pipe( pipe_slow ); 4626 %} 4627 4628 // min = java.lang.Math.min(double a, double b) 4629 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4630 predicate(UseAVX > 0 && !SuperWord::is_reduction(n)); 4631 match(Set dst (MinD a b)); 4632 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4633 format %{ 4634 "vblendvpd $atmp,$a,$b,$a \n\t" 4635 "vblendvpd $btmp,$b,$a,$a \n\t" 4636 "vminsd $tmp,$atmp,$btmp \n\t" 4637 "vcmppd.unordered $btmp,$atmp,$atmp \n\t" 4638 "vblendvpd $dst,$tmp,$atmp,$btmp \n\t" 4639 %} 4640 ins_encode %{ 4641 int vector_len = Assembler::AVX_128bit; 4642 __ vblendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 4643 __ vblendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 4644 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 4645 __ vcmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 4646 __ vblendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 4647 %} 4648 ins_pipe( pipe_slow ); 4649 %} 4650 4651 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4652 predicate(UseAVX > 0 && SuperWord::is_reduction(n)); 4653 match(Set dst (MinD a b)); 4654 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4655 4656 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 4657 ins_encode %{ 4658 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4659 true /*min*/, false /*single*/); 4660 %} 4661 ins_pipe( pipe_slow ); 4662 %} 4663 4664 // Load Effective Address 4665 instruct leaP8(rRegP dst, indOffset8 mem) 4666 %{ 4667 match(Set dst mem); 4668 4669 ins_cost(110); // XXX 4670 format %{ "leaq $dst, $mem\t# ptr 8" %} 4671 ins_encode %{ 4672 __ leaq($dst$$Register, $mem$$Address); 4673 %} 4674 ins_pipe(ialu_reg_reg_fat); 4675 %} 4676 4677 instruct leaP32(rRegP dst, indOffset32 mem) 4678 %{ 4679 match(Set dst mem); 4680 4681 ins_cost(110); 4682 format %{ "leaq $dst, $mem\t# ptr 32" %} 4683 ins_encode %{ 4684 __ leaq($dst$$Register, $mem$$Address); 4685 %} 4686 ins_pipe(ialu_reg_reg_fat); 4687 %} 4688 4689 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4690 %{ 4691 match(Set dst mem); 4692 4693 ins_cost(110); 4694 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4695 ins_encode %{ 4696 __ leaq($dst$$Register, $mem$$Address); 4697 %} 4698 ins_pipe(ialu_reg_reg_fat); 4699 %} 4700 4701 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4702 %{ 4703 match(Set dst mem); 4704 4705 ins_cost(110); 4706 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4707 ins_encode %{ 4708 __ leaq($dst$$Register, $mem$$Address); 4709 %} 4710 ins_pipe(ialu_reg_reg_fat); 4711 %} 4712 4713 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4714 %{ 4715 match(Set dst mem); 4716 4717 ins_cost(110); 4718 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4719 ins_encode %{ 4720 __ leaq($dst$$Register, $mem$$Address); 4721 %} 4722 ins_pipe(ialu_reg_reg_fat); 4723 %} 4724 4725 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4726 %{ 4727 match(Set dst mem); 4728 4729 ins_cost(110); 4730 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4731 ins_encode %{ 4732 __ leaq($dst$$Register, $mem$$Address); 4733 %} 4734 ins_pipe(ialu_reg_reg_fat); 4735 %} 4736 4737 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4738 %{ 4739 match(Set dst mem); 4740 4741 ins_cost(110); 4742 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4743 ins_encode %{ 4744 __ leaq($dst$$Register, $mem$$Address); 4745 %} 4746 ins_pipe(ialu_reg_reg_fat); 4747 %} 4748 4749 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4750 %{ 4751 match(Set dst mem); 4752 4753 ins_cost(110); 4754 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4755 ins_encode %{ 4756 __ leaq($dst$$Register, $mem$$Address); 4757 %} 4758 ins_pipe(ialu_reg_reg_fat); 4759 %} 4760 4761 // Load Effective Address which uses Narrow (32-bits) oop 4762 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4763 %{ 4764 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4765 match(Set dst mem); 4766 4767 ins_cost(110); 4768 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4769 ins_encode %{ 4770 __ leaq($dst$$Register, $mem$$Address); 4771 %} 4772 ins_pipe(ialu_reg_reg_fat); 4773 %} 4774 4775 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4776 %{ 4777 predicate(CompressedOops::shift() == 0); 4778 match(Set dst mem); 4779 4780 ins_cost(110); // XXX 4781 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4782 ins_encode %{ 4783 __ leaq($dst$$Register, $mem$$Address); 4784 %} 4785 ins_pipe(ialu_reg_reg_fat); 4786 %} 4787 4788 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4789 %{ 4790 predicate(CompressedOops::shift() == 0); 4791 match(Set dst mem); 4792 4793 ins_cost(110); 4794 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4795 ins_encode %{ 4796 __ leaq($dst$$Register, $mem$$Address); 4797 %} 4798 ins_pipe(ialu_reg_reg_fat); 4799 %} 4800 4801 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4802 %{ 4803 predicate(CompressedOops::shift() == 0); 4804 match(Set dst mem); 4805 4806 ins_cost(110); 4807 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4808 ins_encode %{ 4809 __ leaq($dst$$Register, $mem$$Address); 4810 %} 4811 ins_pipe(ialu_reg_reg_fat); 4812 %} 4813 4814 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4815 %{ 4816 predicate(CompressedOops::shift() == 0); 4817 match(Set dst mem); 4818 4819 ins_cost(110); 4820 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4821 ins_encode %{ 4822 __ leaq($dst$$Register, $mem$$Address); 4823 %} 4824 ins_pipe(ialu_reg_reg_fat); 4825 %} 4826 4827 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4828 %{ 4829 predicate(CompressedOops::shift() == 0); 4830 match(Set dst mem); 4831 4832 ins_cost(110); 4833 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4834 ins_encode %{ 4835 __ leaq($dst$$Register, $mem$$Address); 4836 %} 4837 ins_pipe(ialu_reg_reg_fat); 4838 %} 4839 4840 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4841 %{ 4842 predicate(CompressedOops::shift() == 0); 4843 match(Set dst mem); 4844 4845 ins_cost(110); 4846 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4847 ins_encode %{ 4848 __ leaq($dst$$Register, $mem$$Address); 4849 %} 4850 ins_pipe(ialu_reg_reg_fat); 4851 %} 4852 4853 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4854 %{ 4855 predicate(CompressedOops::shift() == 0); 4856 match(Set dst mem); 4857 4858 ins_cost(110); 4859 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4860 ins_encode %{ 4861 __ leaq($dst$$Register, $mem$$Address); 4862 %} 4863 ins_pipe(ialu_reg_reg_fat); 4864 %} 4865 4866 instruct loadConI(rRegI dst, immI src) 4867 %{ 4868 match(Set dst src); 4869 4870 format %{ "movl $dst, $src\t# int" %} 4871 ins_encode %{ 4872 __ movl($dst$$Register, $src$$constant); 4873 %} 4874 ins_pipe(ialu_reg_fat); // XXX 4875 %} 4876 4877 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4878 %{ 4879 match(Set dst src); 4880 effect(KILL cr); 4881 4882 ins_cost(50); 4883 format %{ "xorl $dst, $dst\t# int" %} 4884 ins_encode %{ 4885 __ xorl($dst$$Register, $dst$$Register); 4886 %} 4887 ins_pipe(ialu_reg); 4888 %} 4889 4890 instruct loadConL(rRegL dst, immL src) 4891 %{ 4892 match(Set dst src); 4893 4894 ins_cost(150); 4895 format %{ "movq $dst, $src\t# long" %} 4896 ins_encode %{ 4897 __ mov64($dst$$Register, $src$$constant); 4898 %} 4899 ins_pipe(ialu_reg); 4900 %} 4901 4902 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4903 %{ 4904 match(Set dst src); 4905 effect(KILL cr); 4906 4907 ins_cost(50); 4908 format %{ "xorl $dst, $dst\t# long" %} 4909 ins_encode %{ 4910 __ xorl($dst$$Register, $dst$$Register); 4911 %} 4912 ins_pipe(ialu_reg); // XXX 4913 %} 4914 4915 instruct loadConUL32(rRegL dst, immUL32 src) 4916 %{ 4917 match(Set dst src); 4918 4919 ins_cost(60); 4920 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4921 ins_encode %{ 4922 __ movl($dst$$Register, $src$$constant); 4923 %} 4924 ins_pipe(ialu_reg); 4925 %} 4926 4927 instruct loadConL32(rRegL dst, immL32 src) 4928 %{ 4929 match(Set dst src); 4930 4931 ins_cost(70); 4932 format %{ "movq $dst, $src\t# long (32-bit)" %} 4933 ins_encode %{ 4934 __ movq($dst$$Register, $src$$constant); 4935 %} 4936 ins_pipe(ialu_reg); 4937 %} 4938 4939 instruct loadConP(rRegP dst, immP con) %{ 4940 match(Set dst con); 4941 4942 format %{ "movq $dst, $con\t# ptr" %} 4943 ins_encode %{ 4944 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4945 %} 4946 ins_pipe(ialu_reg_fat); // XXX 4947 %} 4948 4949 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4950 %{ 4951 match(Set dst src); 4952 effect(KILL cr); 4953 4954 ins_cost(50); 4955 format %{ "xorl $dst, $dst\t# ptr" %} 4956 ins_encode %{ 4957 __ xorl($dst$$Register, $dst$$Register); 4958 %} 4959 ins_pipe(ialu_reg); 4960 %} 4961 4962 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4963 %{ 4964 match(Set dst src); 4965 effect(KILL cr); 4966 4967 ins_cost(60); 4968 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4969 ins_encode %{ 4970 __ movl($dst$$Register, $src$$constant); 4971 %} 4972 ins_pipe(ialu_reg); 4973 %} 4974 4975 instruct loadConF(regF dst, immF con) %{ 4976 match(Set dst con); 4977 ins_cost(125); 4978 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4979 ins_encode %{ 4980 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4981 %} 4982 ins_pipe(pipe_slow); 4983 %} 4984 4985 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4986 match(Set dst src); 4987 effect(KILL cr); 4988 format %{ "xorq $dst, $src\t# compressed nullptr ptr" %} 4989 ins_encode %{ 4990 __ xorq($dst$$Register, $dst$$Register); 4991 %} 4992 ins_pipe(ialu_reg); 4993 %} 4994 4995 instruct loadConN(rRegN dst, immN src) %{ 4996 match(Set dst src); 4997 4998 ins_cost(125); 4999 format %{ "movl $dst, $src\t# compressed ptr" %} 5000 ins_encode %{ 5001 address con = (address)$src$$constant; 5002 if (con == nullptr) { 5003 ShouldNotReachHere(); 5004 } else { 5005 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5006 } 5007 %} 5008 ins_pipe(ialu_reg_fat); // XXX 5009 %} 5010 5011 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5012 match(Set dst src); 5013 5014 ins_cost(125); 5015 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5016 ins_encode %{ 5017 address con = (address)$src$$constant; 5018 if (con == nullptr) { 5019 ShouldNotReachHere(); 5020 } else { 5021 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5022 } 5023 %} 5024 ins_pipe(ialu_reg_fat); // XXX 5025 %} 5026 5027 instruct loadConF0(regF dst, immF0 src) 5028 %{ 5029 match(Set dst src); 5030 ins_cost(100); 5031 5032 format %{ "xorps $dst, $dst\t# float 0.0" %} 5033 ins_encode %{ 5034 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5035 %} 5036 ins_pipe(pipe_slow); 5037 %} 5038 5039 // Use the same format since predicate() can not be used here. 5040 instruct loadConD(regD dst, immD con) %{ 5041 match(Set dst con); 5042 ins_cost(125); 5043 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5044 ins_encode %{ 5045 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5046 %} 5047 ins_pipe(pipe_slow); 5048 %} 5049 5050 instruct loadConD0(regD dst, immD0 src) 5051 %{ 5052 match(Set dst src); 5053 ins_cost(100); 5054 5055 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5056 ins_encode %{ 5057 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 5058 %} 5059 ins_pipe(pipe_slow); 5060 %} 5061 5062 instruct loadSSI(rRegI dst, stackSlotI src) 5063 %{ 5064 match(Set dst src); 5065 5066 ins_cost(125); 5067 format %{ "movl $dst, $src\t# int stk" %} 5068 ins_encode %{ 5069 __ movl($dst$$Register, $src$$Address); 5070 %} 5071 ins_pipe(ialu_reg_mem); 5072 %} 5073 5074 instruct loadSSL(rRegL dst, stackSlotL src) 5075 %{ 5076 match(Set dst src); 5077 5078 ins_cost(125); 5079 format %{ "movq $dst, $src\t# long stk" %} 5080 ins_encode %{ 5081 __ movq($dst$$Register, $src$$Address); 5082 %} 5083 ins_pipe(ialu_reg_mem); 5084 %} 5085 5086 instruct loadSSP(rRegP dst, stackSlotP src) 5087 %{ 5088 match(Set dst src); 5089 5090 ins_cost(125); 5091 format %{ "movq $dst, $src\t# ptr stk" %} 5092 ins_encode %{ 5093 __ movq($dst$$Register, $src$$Address); 5094 %} 5095 ins_pipe(ialu_reg_mem); 5096 %} 5097 5098 instruct loadSSF(regF dst, stackSlotF src) 5099 %{ 5100 match(Set dst src); 5101 5102 ins_cost(125); 5103 format %{ "movss $dst, $src\t# float stk" %} 5104 ins_encode %{ 5105 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5106 %} 5107 ins_pipe(pipe_slow); // XXX 5108 %} 5109 5110 // Use the same format since predicate() can not be used here. 5111 instruct loadSSD(regD dst, stackSlotD src) 5112 %{ 5113 match(Set dst src); 5114 5115 ins_cost(125); 5116 format %{ "movsd $dst, $src\t# double stk" %} 5117 ins_encode %{ 5118 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5119 %} 5120 ins_pipe(pipe_slow); // XXX 5121 %} 5122 5123 // Prefetch instructions for allocation. 5124 // Must be safe to execute with invalid address (cannot fault). 5125 5126 instruct prefetchAlloc( memory mem ) %{ 5127 predicate(AllocatePrefetchInstr==3); 5128 match(PrefetchAllocation mem); 5129 ins_cost(125); 5130 5131 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5132 ins_encode %{ 5133 __ prefetchw($mem$$Address); 5134 %} 5135 ins_pipe(ialu_mem); 5136 %} 5137 5138 instruct prefetchAllocNTA( memory mem ) %{ 5139 predicate(AllocatePrefetchInstr==0); 5140 match(PrefetchAllocation mem); 5141 ins_cost(125); 5142 5143 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5144 ins_encode %{ 5145 __ prefetchnta($mem$$Address); 5146 %} 5147 ins_pipe(ialu_mem); 5148 %} 5149 5150 instruct prefetchAllocT0( memory mem ) %{ 5151 predicate(AllocatePrefetchInstr==1); 5152 match(PrefetchAllocation mem); 5153 ins_cost(125); 5154 5155 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5156 ins_encode %{ 5157 __ prefetcht0($mem$$Address); 5158 %} 5159 ins_pipe(ialu_mem); 5160 %} 5161 5162 instruct prefetchAllocT2( memory mem ) %{ 5163 predicate(AllocatePrefetchInstr==2); 5164 match(PrefetchAllocation mem); 5165 ins_cost(125); 5166 5167 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5168 ins_encode %{ 5169 __ prefetcht2($mem$$Address); 5170 %} 5171 ins_pipe(ialu_mem); 5172 %} 5173 5174 //----------Store Instructions------------------------------------------------- 5175 5176 // Store Byte 5177 instruct storeB(memory mem, rRegI src) 5178 %{ 5179 match(Set mem (StoreB mem src)); 5180 5181 ins_cost(125); // XXX 5182 format %{ "movb $mem, $src\t# byte" %} 5183 ins_encode %{ 5184 __ movb($mem$$Address, $src$$Register); 5185 %} 5186 ins_pipe(ialu_mem_reg); 5187 %} 5188 5189 // Store Char/Short 5190 instruct storeC(memory mem, rRegI src) 5191 %{ 5192 match(Set mem (StoreC mem src)); 5193 5194 ins_cost(125); // XXX 5195 format %{ "movw $mem, $src\t# char/short" %} 5196 ins_encode %{ 5197 __ movw($mem$$Address, $src$$Register); 5198 %} 5199 ins_pipe(ialu_mem_reg); 5200 %} 5201 5202 // Store Integer 5203 instruct storeI(memory mem, rRegI src) 5204 %{ 5205 match(Set mem (StoreI mem src)); 5206 5207 ins_cost(125); // XXX 5208 format %{ "movl $mem, $src\t# int" %} 5209 ins_encode %{ 5210 __ movl($mem$$Address, $src$$Register); 5211 %} 5212 ins_pipe(ialu_mem_reg); 5213 %} 5214 5215 // Store Long 5216 instruct storeL(memory mem, rRegL src) 5217 %{ 5218 match(Set mem (StoreL mem src)); 5219 5220 ins_cost(125); // XXX 5221 format %{ "movq $mem, $src\t# long" %} 5222 ins_encode %{ 5223 __ movq($mem$$Address, $src$$Register); 5224 %} 5225 ins_pipe(ialu_mem_reg); // XXX 5226 %} 5227 5228 // Store Pointer 5229 instruct storeP(memory mem, any_RegP src) 5230 %{ 5231 predicate(n->as_Store()->barrier_data() == 0); 5232 match(Set mem (StoreP mem src)); 5233 5234 ins_cost(125); // XXX 5235 format %{ "movq $mem, $src\t# ptr" %} 5236 ins_encode %{ 5237 __ movq($mem$$Address, $src$$Register); 5238 %} 5239 ins_pipe(ialu_mem_reg); 5240 %} 5241 5242 instruct storeImmP0(memory mem, immP0 zero) 5243 %{ 5244 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5245 match(Set mem (StoreP mem zero)); 5246 5247 ins_cost(125); // XXX 5248 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5249 ins_encode %{ 5250 __ movq($mem$$Address, r12); 5251 %} 5252 ins_pipe(ialu_mem_reg); 5253 %} 5254 5255 // Store nullptr Pointer, mark word, or other simple pointer constant. 5256 instruct storeImmP(memory mem, immP31 src) 5257 %{ 5258 predicate(n->as_Store()->barrier_data() == 0); 5259 match(Set mem (StoreP mem src)); 5260 5261 ins_cost(150); // XXX 5262 format %{ "movq $mem, $src\t# ptr" %} 5263 ins_encode %{ 5264 __ movq($mem$$Address, $src$$constant); 5265 %} 5266 ins_pipe(ialu_mem_imm); 5267 %} 5268 5269 // Store Compressed Pointer 5270 instruct storeN(memory mem, rRegN src) 5271 %{ 5272 match(Set mem (StoreN mem src)); 5273 5274 ins_cost(125); // XXX 5275 format %{ "movl $mem, $src\t# compressed ptr" %} 5276 ins_encode %{ 5277 __ movl($mem$$Address, $src$$Register); 5278 %} 5279 ins_pipe(ialu_mem_reg); 5280 %} 5281 5282 instruct storeNKlass(memory mem, rRegN src) 5283 %{ 5284 match(Set mem (StoreNKlass mem src)); 5285 5286 ins_cost(125); // XXX 5287 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5288 ins_encode %{ 5289 __ movl($mem$$Address, $src$$Register); 5290 %} 5291 ins_pipe(ialu_mem_reg); 5292 %} 5293 5294 instruct storeImmN0(memory mem, immN0 zero) 5295 %{ 5296 predicate(CompressedOops::base() == nullptr); 5297 match(Set mem (StoreN mem zero)); 5298 5299 ins_cost(125); // XXX 5300 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5301 ins_encode %{ 5302 __ movl($mem$$Address, r12); 5303 %} 5304 ins_pipe(ialu_mem_reg); 5305 %} 5306 5307 instruct storeImmN(memory mem, immN src) 5308 %{ 5309 match(Set mem (StoreN mem src)); 5310 5311 ins_cost(150); // XXX 5312 format %{ "movl $mem, $src\t# compressed ptr" %} 5313 ins_encode %{ 5314 address con = (address)$src$$constant; 5315 if (con == nullptr) { 5316 __ movl($mem$$Address, 0); 5317 } else { 5318 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5319 } 5320 %} 5321 ins_pipe(ialu_mem_imm); 5322 %} 5323 5324 instruct storeImmNKlass(memory mem, immNKlass src) 5325 %{ 5326 match(Set mem (StoreNKlass mem src)); 5327 5328 ins_cost(150); // XXX 5329 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5330 ins_encode %{ 5331 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5332 %} 5333 ins_pipe(ialu_mem_imm); 5334 %} 5335 5336 // Store Integer Immediate 5337 instruct storeImmI0(memory mem, immI_0 zero) 5338 %{ 5339 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5340 match(Set mem (StoreI mem zero)); 5341 5342 ins_cost(125); // XXX 5343 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5344 ins_encode %{ 5345 __ movl($mem$$Address, r12); 5346 %} 5347 ins_pipe(ialu_mem_reg); 5348 %} 5349 5350 instruct storeImmI(memory mem, immI src) 5351 %{ 5352 match(Set mem (StoreI mem src)); 5353 5354 ins_cost(150); 5355 format %{ "movl $mem, $src\t# int" %} 5356 ins_encode %{ 5357 __ movl($mem$$Address, $src$$constant); 5358 %} 5359 ins_pipe(ialu_mem_imm); 5360 %} 5361 5362 // Store Long Immediate 5363 instruct storeImmL0(memory mem, immL0 zero) 5364 %{ 5365 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5366 match(Set mem (StoreL mem zero)); 5367 5368 ins_cost(125); // XXX 5369 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5370 ins_encode %{ 5371 __ movq($mem$$Address, r12); 5372 %} 5373 ins_pipe(ialu_mem_reg); 5374 %} 5375 5376 instruct storeImmL(memory mem, immL32 src) 5377 %{ 5378 match(Set mem (StoreL mem src)); 5379 5380 ins_cost(150); 5381 format %{ "movq $mem, $src\t# long" %} 5382 ins_encode %{ 5383 __ movq($mem$$Address, $src$$constant); 5384 %} 5385 ins_pipe(ialu_mem_imm); 5386 %} 5387 5388 // Store Short/Char Immediate 5389 instruct storeImmC0(memory mem, immI_0 zero) 5390 %{ 5391 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5392 match(Set mem (StoreC mem zero)); 5393 5394 ins_cost(125); // XXX 5395 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5396 ins_encode %{ 5397 __ movw($mem$$Address, r12); 5398 %} 5399 ins_pipe(ialu_mem_reg); 5400 %} 5401 5402 instruct storeImmI16(memory mem, immI16 src) 5403 %{ 5404 predicate(UseStoreImmI16); 5405 match(Set mem (StoreC mem src)); 5406 5407 ins_cost(150); 5408 format %{ "movw $mem, $src\t# short/char" %} 5409 ins_encode %{ 5410 __ movw($mem$$Address, $src$$constant); 5411 %} 5412 ins_pipe(ialu_mem_imm); 5413 %} 5414 5415 // Store Byte Immediate 5416 instruct storeImmB0(memory mem, immI_0 zero) 5417 %{ 5418 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5419 match(Set mem (StoreB mem zero)); 5420 5421 ins_cost(125); // XXX 5422 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5423 ins_encode %{ 5424 __ movb($mem$$Address, r12); 5425 %} 5426 ins_pipe(ialu_mem_reg); 5427 %} 5428 5429 instruct storeImmB(memory mem, immI8 src) 5430 %{ 5431 match(Set mem (StoreB mem src)); 5432 5433 ins_cost(150); // XXX 5434 format %{ "movb $mem, $src\t# byte" %} 5435 ins_encode %{ 5436 __ movb($mem$$Address, $src$$constant); 5437 %} 5438 ins_pipe(ialu_mem_imm); 5439 %} 5440 5441 // Store CMS card-mark Immediate 5442 instruct storeImmCM0_reg(memory mem, immI_0 zero) 5443 %{ 5444 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5445 match(Set mem (StoreCM mem zero)); 5446 5447 ins_cost(125); // XXX 5448 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5449 ins_encode %{ 5450 __ movb($mem$$Address, r12); 5451 %} 5452 ins_pipe(ialu_mem_reg); 5453 %} 5454 5455 instruct storeImmCM0(memory mem, immI_0 src) 5456 %{ 5457 match(Set mem (StoreCM mem src)); 5458 5459 ins_cost(150); // XXX 5460 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5461 ins_encode %{ 5462 __ movb($mem$$Address, $src$$constant); 5463 %} 5464 ins_pipe(ialu_mem_imm); 5465 %} 5466 5467 // Store Float 5468 instruct storeF(memory mem, regF src) 5469 %{ 5470 match(Set mem (StoreF mem src)); 5471 5472 ins_cost(95); // XXX 5473 format %{ "movss $mem, $src\t# float" %} 5474 ins_encode %{ 5475 __ movflt($mem$$Address, $src$$XMMRegister); 5476 %} 5477 ins_pipe(pipe_slow); // XXX 5478 %} 5479 5480 // Store immediate Float value (it is faster than store from XMM register) 5481 instruct storeF0(memory mem, immF0 zero) 5482 %{ 5483 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5484 match(Set mem (StoreF mem zero)); 5485 5486 ins_cost(25); // XXX 5487 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5488 ins_encode %{ 5489 __ movl($mem$$Address, r12); 5490 %} 5491 ins_pipe(ialu_mem_reg); 5492 %} 5493 5494 instruct storeF_imm(memory mem, immF src) 5495 %{ 5496 match(Set mem (StoreF mem src)); 5497 5498 ins_cost(50); 5499 format %{ "movl $mem, $src\t# float" %} 5500 ins_encode %{ 5501 __ movl($mem$$Address, jint_cast($src$$constant)); 5502 %} 5503 ins_pipe(ialu_mem_imm); 5504 %} 5505 5506 // Store Double 5507 instruct storeD(memory mem, regD src) 5508 %{ 5509 match(Set mem (StoreD mem src)); 5510 5511 ins_cost(95); // XXX 5512 format %{ "movsd $mem, $src\t# double" %} 5513 ins_encode %{ 5514 __ movdbl($mem$$Address, $src$$XMMRegister); 5515 %} 5516 ins_pipe(pipe_slow); // XXX 5517 %} 5518 5519 // Store immediate double 0.0 (it is faster than store from XMM register) 5520 instruct storeD0_imm(memory mem, immD0 src) 5521 %{ 5522 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5523 match(Set mem (StoreD mem src)); 5524 5525 ins_cost(50); 5526 format %{ "movq $mem, $src\t# double 0." %} 5527 ins_encode %{ 5528 __ movq($mem$$Address, $src$$constant); 5529 %} 5530 ins_pipe(ialu_mem_imm); 5531 %} 5532 5533 instruct storeD0(memory mem, immD0 zero) 5534 %{ 5535 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5536 match(Set mem (StoreD mem zero)); 5537 5538 ins_cost(25); // XXX 5539 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5540 ins_encode %{ 5541 __ movq($mem$$Address, r12); 5542 %} 5543 ins_pipe(ialu_mem_reg); 5544 %} 5545 5546 instruct storeSSI(stackSlotI dst, rRegI src) 5547 %{ 5548 match(Set dst src); 5549 5550 ins_cost(100); 5551 format %{ "movl $dst, $src\t# int stk" %} 5552 ins_encode %{ 5553 __ movl($dst$$Address, $src$$Register); 5554 %} 5555 ins_pipe( ialu_mem_reg ); 5556 %} 5557 5558 instruct storeSSL(stackSlotL dst, rRegL src) 5559 %{ 5560 match(Set dst src); 5561 5562 ins_cost(100); 5563 format %{ "movq $dst, $src\t# long stk" %} 5564 ins_encode %{ 5565 __ movq($dst$$Address, $src$$Register); 5566 %} 5567 ins_pipe(ialu_mem_reg); 5568 %} 5569 5570 instruct storeSSP(stackSlotP dst, rRegP src) 5571 %{ 5572 match(Set dst src); 5573 5574 ins_cost(100); 5575 format %{ "movq $dst, $src\t# ptr stk" %} 5576 ins_encode %{ 5577 __ movq($dst$$Address, $src$$Register); 5578 %} 5579 ins_pipe(ialu_mem_reg); 5580 %} 5581 5582 instruct storeSSF(stackSlotF dst, regF src) 5583 %{ 5584 match(Set dst src); 5585 5586 ins_cost(95); // XXX 5587 format %{ "movss $dst, $src\t# float stk" %} 5588 ins_encode %{ 5589 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5590 %} 5591 ins_pipe(pipe_slow); // XXX 5592 %} 5593 5594 instruct storeSSD(stackSlotD dst, regD src) 5595 %{ 5596 match(Set dst src); 5597 5598 ins_cost(95); // XXX 5599 format %{ "movsd $dst, $src\t# double stk" %} 5600 ins_encode %{ 5601 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5602 %} 5603 ins_pipe(pipe_slow); // XXX 5604 %} 5605 5606 instruct cacheWB(indirect addr) 5607 %{ 5608 predicate(VM_Version::supports_data_cache_line_flush()); 5609 match(CacheWB addr); 5610 5611 ins_cost(100); 5612 format %{"cache wb $addr" %} 5613 ins_encode %{ 5614 assert($addr->index_position() < 0, "should be"); 5615 assert($addr$$disp == 0, "should be"); 5616 __ cache_wb(Address($addr$$base$$Register, 0)); 5617 %} 5618 ins_pipe(pipe_slow); // XXX 5619 %} 5620 5621 instruct cacheWBPreSync() 5622 %{ 5623 predicate(VM_Version::supports_data_cache_line_flush()); 5624 match(CacheWBPreSync); 5625 5626 ins_cost(100); 5627 format %{"cache wb presync" %} 5628 ins_encode %{ 5629 __ cache_wbsync(true); 5630 %} 5631 ins_pipe(pipe_slow); // XXX 5632 %} 5633 5634 instruct cacheWBPostSync() 5635 %{ 5636 predicate(VM_Version::supports_data_cache_line_flush()); 5637 match(CacheWBPostSync); 5638 5639 ins_cost(100); 5640 format %{"cache wb postsync" %} 5641 ins_encode %{ 5642 __ cache_wbsync(false); 5643 %} 5644 ins_pipe(pipe_slow); // XXX 5645 %} 5646 5647 //----------BSWAP Instructions------------------------------------------------- 5648 instruct bytes_reverse_int(rRegI dst) %{ 5649 match(Set dst (ReverseBytesI dst)); 5650 5651 format %{ "bswapl $dst" %} 5652 ins_encode %{ 5653 __ bswapl($dst$$Register); 5654 %} 5655 ins_pipe( ialu_reg ); 5656 %} 5657 5658 instruct bytes_reverse_long(rRegL dst) %{ 5659 match(Set dst (ReverseBytesL dst)); 5660 5661 format %{ "bswapq $dst" %} 5662 ins_encode %{ 5663 __ bswapq($dst$$Register); 5664 %} 5665 ins_pipe( ialu_reg); 5666 %} 5667 5668 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5669 match(Set dst (ReverseBytesUS dst)); 5670 effect(KILL cr); 5671 5672 format %{ "bswapl $dst\n\t" 5673 "shrl $dst,16\n\t" %} 5674 ins_encode %{ 5675 __ bswapl($dst$$Register); 5676 __ shrl($dst$$Register, 16); 5677 %} 5678 ins_pipe( ialu_reg ); 5679 %} 5680 5681 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5682 match(Set dst (ReverseBytesS dst)); 5683 effect(KILL cr); 5684 5685 format %{ "bswapl $dst\n\t" 5686 "sar $dst,16\n\t" %} 5687 ins_encode %{ 5688 __ bswapl($dst$$Register); 5689 __ sarl($dst$$Register, 16); 5690 %} 5691 ins_pipe( ialu_reg ); 5692 %} 5693 5694 //---------- Zeros Count Instructions ------------------------------------------ 5695 5696 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5697 predicate(UseCountLeadingZerosInstruction); 5698 match(Set dst (CountLeadingZerosI src)); 5699 effect(KILL cr); 5700 5701 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5702 ins_encode %{ 5703 __ lzcntl($dst$$Register, $src$$Register); 5704 %} 5705 ins_pipe(ialu_reg); 5706 %} 5707 5708 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5709 predicate(UseCountLeadingZerosInstruction); 5710 match(Set dst (CountLeadingZerosI (LoadI src))); 5711 effect(KILL cr); 5712 ins_cost(175); 5713 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5714 ins_encode %{ 5715 __ lzcntl($dst$$Register, $src$$Address); 5716 %} 5717 ins_pipe(ialu_reg_mem); 5718 %} 5719 5720 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5721 predicate(!UseCountLeadingZerosInstruction); 5722 match(Set dst (CountLeadingZerosI src)); 5723 effect(KILL cr); 5724 5725 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5726 "jnz skip\n\t" 5727 "movl $dst, -1\n" 5728 "skip:\n\t" 5729 "negl $dst\n\t" 5730 "addl $dst, 31" %} 5731 ins_encode %{ 5732 Register Rdst = $dst$$Register; 5733 Register Rsrc = $src$$Register; 5734 Label skip; 5735 __ bsrl(Rdst, Rsrc); 5736 __ jccb(Assembler::notZero, skip); 5737 __ movl(Rdst, -1); 5738 __ bind(skip); 5739 __ negl(Rdst); 5740 __ addl(Rdst, BitsPerInt - 1); 5741 %} 5742 ins_pipe(ialu_reg); 5743 %} 5744 5745 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5746 predicate(UseCountLeadingZerosInstruction); 5747 match(Set dst (CountLeadingZerosL src)); 5748 effect(KILL cr); 5749 5750 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5751 ins_encode %{ 5752 __ lzcntq($dst$$Register, $src$$Register); 5753 %} 5754 ins_pipe(ialu_reg); 5755 %} 5756 5757 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5758 predicate(UseCountLeadingZerosInstruction); 5759 match(Set dst (CountLeadingZerosL (LoadL src))); 5760 effect(KILL cr); 5761 ins_cost(175); 5762 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5763 ins_encode %{ 5764 __ lzcntq($dst$$Register, $src$$Address); 5765 %} 5766 ins_pipe(ialu_reg_mem); 5767 %} 5768 5769 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5770 predicate(!UseCountLeadingZerosInstruction); 5771 match(Set dst (CountLeadingZerosL src)); 5772 effect(KILL cr); 5773 5774 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5775 "jnz skip\n\t" 5776 "movl $dst, -1\n" 5777 "skip:\n\t" 5778 "negl $dst\n\t" 5779 "addl $dst, 63" %} 5780 ins_encode %{ 5781 Register Rdst = $dst$$Register; 5782 Register Rsrc = $src$$Register; 5783 Label skip; 5784 __ bsrq(Rdst, Rsrc); 5785 __ jccb(Assembler::notZero, skip); 5786 __ movl(Rdst, -1); 5787 __ bind(skip); 5788 __ negl(Rdst); 5789 __ addl(Rdst, BitsPerLong - 1); 5790 %} 5791 ins_pipe(ialu_reg); 5792 %} 5793 5794 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5795 predicate(UseCountTrailingZerosInstruction); 5796 match(Set dst (CountTrailingZerosI src)); 5797 effect(KILL cr); 5798 5799 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5800 ins_encode %{ 5801 __ tzcntl($dst$$Register, $src$$Register); 5802 %} 5803 ins_pipe(ialu_reg); 5804 %} 5805 5806 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5807 predicate(UseCountTrailingZerosInstruction); 5808 match(Set dst (CountTrailingZerosI (LoadI src))); 5809 effect(KILL cr); 5810 ins_cost(175); 5811 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5812 ins_encode %{ 5813 __ tzcntl($dst$$Register, $src$$Address); 5814 %} 5815 ins_pipe(ialu_reg_mem); 5816 %} 5817 5818 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5819 predicate(!UseCountTrailingZerosInstruction); 5820 match(Set dst (CountTrailingZerosI src)); 5821 effect(KILL cr); 5822 5823 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5824 "jnz done\n\t" 5825 "movl $dst, 32\n" 5826 "done:" %} 5827 ins_encode %{ 5828 Register Rdst = $dst$$Register; 5829 Label done; 5830 __ bsfl(Rdst, $src$$Register); 5831 __ jccb(Assembler::notZero, done); 5832 __ movl(Rdst, BitsPerInt); 5833 __ bind(done); 5834 %} 5835 ins_pipe(ialu_reg); 5836 %} 5837 5838 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5839 predicate(UseCountTrailingZerosInstruction); 5840 match(Set dst (CountTrailingZerosL src)); 5841 effect(KILL cr); 5842 5843 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5844 ins_encode %{ 5845 __ tzcntq($dst$$Register, $src$$Register); 5846 %} 5847 ins_pipe(ialu_reg); 5848 %} 5849 5850 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5851 predicate(UseCountTrailingZerosInstruction); 5852 match(Set dst (CountTrailingZerosL (LoadL src))); 5853 effect(KILL cr); 5854 ins_cost(175); 5855 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5856 ins_encode %{ 5857 __ tzcntq($dst$$Register, $src$$Address); 5858 %} 5859 ins_pipe(ialu_reg_mem); 5860 %} 5861 5862 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5863 predicate(!UseCountTrailingZerosInstruction); 5864 match(Set dst (CountTrailingZerosL src)); 5865 effect(KILL cr); 5866 5867 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5868 "jnz done\n\t" 5869 "movl $dst, 64\n" 5870 "done:" %} 5871 ins_encode %{ 5872 Register Rdst = $dst$$Register; 5873 Label done; 5874 __ bsfq(Rdst, $src$$Register); 5875 __ jccb(Assembler::notZero, done); 5876 __ movl(Rdst, BitsPerLong); 5877 __ bind(done); 5878 %} 5879 ins_pipe(ialu_reg); 5880 %} 5881 5882 //--------------- Reverse Operation Instructions ---------------- 5883 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5884 predicate(!VM_Version::supports_gfni()); 5885 match(Set dst (ReverseI src)); 5886 effect(TEMP dst, TEMP rtmp, KILL cr); 5887 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5888 ins_encode %{ 5889 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5890 %} 5891 ins_pipe( ialu_reg ); 5892 %} 5893 5894 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, regF xtmp1, regF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5895 predicate(VM_Version::supports_gfni()); 5896 match(Set dst (ReverseI src)); 5897 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5898 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5899 ins_encode %{ 5900 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5901 %} 5902 ins_pipe( ialu_reg ); 5903 %} 5904 5905 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5906 predicate(!VM_Version::supports_gfni()); 5907 match(Set dst (ReverseL src)); 5908 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5909 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5910 ins_encode %{ 5911 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5912 %} 5913 ins_pipe( ialu_reg ); 5914 %} 5915 5916 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, regD xtmp1, regD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5917 predicate(VM_Version::supports_gfni()); 5918 match(Set dst (ReverseL src)); 5919 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5920 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5921 ins_encode %{ 5922 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5923 %} 5924 ins_pipe( ialu_reg ); 5925 %} 5926 5927 //---------- Population Count Instructions ------------------------------------- 5928 5929 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5930 predicate(UsePopCountInstruction); 5931 match(Set dst (PopCountI src)); 5932 effect(KILL cr); 5933 5934 format %{ "popcnt $dst, $src" %} 5935 ins_encode %{ 5936 __ popcntl($dst$$Register, $src$$Register); 5937 %} 5938 ins_pipe(ialu_reg); 5939 %} 5940 5941 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5942 predicate(UsePopCountInstruction); 5943 match(Set dst (PopCountI (LoadI mem))); 5944 effect(KILL cr); 5945 5946 format %{ "popcnt $dst, $mem" %} 5947 ins_encode %{ 5948 __ popcntl($dst$$Register, $mem$$Address); 5949 %} 5950 ins_pipe(ialu_reg); 5951 %} 5952 5953 // Note: Long.bitCount(long) returns an int. 5954 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5955 predicate(UsePopCountInstruction); 5956 match(Set dst (PopCountL src)); 5957 effect(KILL cr); 5958 5959 format %{ "popcnt $dst, $src" %} 5960 ins_encode %{ 5961 __ popcntq($dst$$Register, $src$$Register); 5962 %} 5963 ins_pipe(ialu_reg); 5964 %} 5965 5966 // Note: Long.bitCount(long) returns an int. 5967 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5968 predicate(UsePopCountInstruction); 5969 match(Set dst (PopCountL (LoadL mem))); 5970 effect(KILL cr); 5971 5972 format %{ "popcnt $dst, $mem" %} 5973 ins_encode %{ 5974 __ popcntq($dst$$Register, $mem$$Address); 5975 %} 5976 ins_pipe(ialu_reg); 5977 %} 5978 5979 5980 //----------MemBar Instructions----------------------------------------------- 5981 // Memory barrier flavors 5982 5983 instruct membar_acquire() 5984 %{ 5985 match(MemBarAcquire); 5986 match(LoadFence); 5987 ins_cost(0); 5988 5989 size(0); 5990 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5991 ins_encode(); 5992 ins_pipe(empty); 5993 %} 5994 5995 instruct membar_acquire_lock() 5996 %{ 5997 match(MemBarAcquireLock); 5998 ins_cost(0); 5999 6000 size(0); 6001 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6002 ins_encode(); 6003 ins_pipe(empty); 6004 %} 6005 6006 instruct membar_release() 6007 %{ 6008 match(MemBarRelease); 6009 match(StoreFence); 6010 ins_cost(0); 6011 6012 size(0); 6013 format %{ "MEMBAR-release ! (empty encoding)" %} 6014 ins_encode(); 6015 ins_pipe(empty); 6016 %} 6017 6018 instruct membar_release_lock() 6019 %{ 6020 match(MemBarReleaseLock); 6021 ins_cost(0); 6022 6023 size(0); 6024 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6025 ins_encode(); 6026 ins_pipe(empty); 6027 %} 6028 6029 instruct membar_volatile(rFlagsReg cr) %{ 6030 match(MemBarVolatile); 6031 effect(KILL cr); 6032 ins_cost(400); 6033 6034 format %{ 6035 $$template 6036 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6037 %} 6038 ins_encode %{ 6039 __ membar(Assembler::StoreLoad); 6040 %} 6041 ins_pipe(pipe_slow); 6042 %} 6043 6044 instruct unnecessary_membar_volatile() 6045 %{ 6046 match(MemBarVolatile); 6047 predicate(Matcher::post_store_load_barrier(n)); 6048 ins_cost(0); 6049 6050 size(0); 6051 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6052 ins_encode(); 6053 ins_pipe(empty); 6054 %} 6055 6056 instruct membar_storestore() %{ 6057 match(MemBarStoreStore); 6058 match(StoreStoreFence); 6059 ins_cost(0); 6060 6061 size(0); 6062 format %{ "MEMBAR-storestore (empty encoding)" %} 6063 ins_encode( ); 6064 ins_pipe(empty); 6065 %} 6066 6067 //----------Move Instructions-------------------------------------------------- 6068 6069 instruct castX2P(rRegP dst, rRegL src) 6070 %{ 6071 match(Set dst (CastX2P src)); 6072 6073 format %{ "movq $dst, $src\t# long->ptr" %} 6074 ins_encode %{ 6075 if ($dst$$reg != $src$$reg) { 6076 __ movptr($dst$$Register, $src$$Register); 6077 } 6078 %} 6079 ins_pipe(ialu_reg_reg); // XXX 6080 %} 6081 6082 instruct castN2X(rRegL dst, rRegN src) 6083 %{ 6084 match(Set dst (CastP2X src)); 6085 6086 format %{ "movq $dst, $src\t# ptr -> long" %} 6087 ins_encode %{ 6088 if ($dst$$reg != $src$$reg) { 6089 __ movptr($dst$$Register, $src$$Register); 6090 } 6091 %} 6092 ins_pipe(ialu_reg_reg); // XXX 6093 %} 6094 6095 instruct castP2X(rRegL dst, rRegP src) 6096 %{ 6097 match(Set dst (CastP2X src)); 6098 6099 format %{ "movq $dst, $src\t# ptr -> long" %} 6100 ins_encode %{ 6101 if ($dst$$reg != $src$$reg) { 6102 __ movptr($dst$$Register, $src$$Register); 6103 } 6104 %} 6105 ins_pipe(ialu_reg_reg); // XXX 6106 %} 6107 6108 // Convert oop into int for vectors alignment masking 6109 instruct convP2I(rRegI dst, rRegP src) 6110 %{ 6111 match(Set dst (ConvL2I (CastP2X src))); 6112 6113 format %{ "movl $dst, $src\t# ptr -> int" %} 6114 ins_encode %{ 6115 __ movl($dst$$Register, $src$$Register); 6116 %} 6117 ins_pipe(ialu_reg_reg); // XXX 6118 %} 6119 6120 // Convert compressed oop into int for vectors alignment masking 6121 // in case of 32bit oops (heap < 4Gb). 6122 instruct convN2I(rRegI dst, rRegN src) 6123 %{ 6124 predicate(CompressedOops::shift() == 0); 6125 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6126 6127 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6128 ins_encode %{ 6129 __ movl($dst$$Register, $src$$Register); 6130 %} 6131 ins_pipe(ialu_reg_reg); // XXX 6132 %} 6133 6134 // Convert oop pointer into compressed form 6135 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6136 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6137 match(Set dst (EncodeP src)); 6138 effect(KILL cr); 6139 format %{ "encode_heap_oop $dst,$src" %} 6140 ins_encode %{ 6141 Register s = $src$$Register; 6142 Register d = $dst$$Register; 6143 if (s != d) { 6144 __ movq(d, s); 6145 } 6146 __ encode_heap_oop(d); 6147 %} 6148 ins_pipe(ialu_reg_long); 6149 %} 6150 6151 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6152 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6153 match(Set dst (EncodeP src)); 6154 effect(KILL cr); 6155 format %{ "encode_heap_oop_not_null $dst,$src" %} 6156 ins_encode %{ 6157 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6158 %} 6159 ins_pipe(ialu_reg_long); 6160 %} 6161 6162 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6163 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6164 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6165 match(Set dst (DecodeN src)); 6166 effect(KILL cr); 6167 format %{ "decode_heap_oop $dst,$src" %} 6168 ins_encode %{ 6169 Register s = $src$$Register; 6170 Register d = $dst$$Register; 6171 if (s != d) { 6172 __ movq(d, s); 6173 } 6174 __ decode_heap_oop(d); 6175 %} 6176 ins_pipe(ialu_reg_long); 6177 %} 6178 6179 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6180 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6181 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6182 match(Set dst (DecodeN src)); 6183 effect(KILL cr); 6184 format %{ "decode_heap_oop_not_null $dst,$src" %} 6185 ins_encode %{ 6186 Register s = $src$$Register; 6187 Register d = $dst$$Register; 6188 if (s != d) { 6189 __ decode_heap_oop_not_null(d, s); 6190 } else { 6191 __ decode_heap_oop_not_null(d); 6192 } 6193 %} 6194 ins_pipe(ialu_reg_long); 6195 %} 6196 6197 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6198 match(Set dst (EncodePKlass src)); 6199 effect(TEMP dst, KILL cr); 6200 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6201 ins_encode %{ 6202 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6203 %} 6204 ins_pipe(ialu_reg_long); 6205 %} 6206 6207 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6208 match(Set dst (DecodeNKlass src)); 6209 effect(TEMP dst, KILL cr); 6210 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6211 ins_encode %{ 6212 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6213 %} 6214 ins_pipe(ialu_reg_long); 6215 %} 6216 6217 //----------Conditional Move--------------------------------------------------- 6218 // Jump 6219 // dummy instruction for generating temp registers 6220 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6221 match(Jump (LShiftL switch_val shift)); 6222 ins_cost(350); 6223 predicate(false); 6224 effect(TEMP dest); 6225 6226 format %{ "leaq $dest, [$constantaddress]\n\t" 6227 "jmp [$dest + $switch_val << $shift]\n\t" %} 6228 ins_encode %{ 6229 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6230 // to do that and the compiler is using that register as one it can allocate. 6231 // So we build it all by hand. 6232 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6233 // ArrayAddress dispatch(table, index); 6234 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6235 __ lea($dest$$Register, $constantaddress); 6236 __ jmp(dispatch); 6237 %} 6238 ins_pipe(pipe_jmp); 6239 %} 6240 6241 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6242 match(Jump (AddL (LShiftL switch_val shift) offset)); 6243 ins_cost(350); 6244 effect(TEMP dest); 6245 6246 format %{ "leaq $dest, [$constantaddress]\n\t" 6247 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6248 ins_encode %{ 6249 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6250 // to do that and the compiler is using that register as one it can allocate. 6251 // So we build it all by hand. 6252 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6253 // ArrayAddress dispatch(table, index); 6254 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6255 __ lea($dest$$Register, $constantaddress); 6256 __ jmp(dispatch); 6257 %} 6258 ins_pipe(pipe_jmp); 6259 %} 6260 6261 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6262 match(Jump switch_val); 6263 ins_cost(350); 6264 effect(TEMP dest); 6265 6266 format %{ "leaq $dest, [$constantaddress]\n\t" 6267 "jmp [$dest + $switch_val]\n\t" %} 6268 ins_encode %{ 6269 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6270 // to do that and the compiler is using that register as one it can allocate. 6271 // So we build it all by hand. 6272 // Address index(noreg, switch_reg, Address::times_1); 6273 // ArrayAddress dispatch(table, index); 6274 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6275 __ lea($dest$$Register, $constantaddress); 6276 __ jmp(dispatch); 6277 %} 6278 ins_pipe(pipe_jmp); 6279 %} 6280 6281 // Conditional move 6282 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6283 %{ 6284 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6285 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6286 6287 ins_cost(100); // XXX 6288 format %{ "setbn$cop $dst\t# signed, int" %} 6289 ins_encode %{ 6290 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6291 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6292 %} 6293 ins_pipe(ialu_reg); 6294 %} 6295 6296 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6297 %{ 6298 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6299 6300 ins_cost(200); // XXX 6301 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6302 ins_encode %{ 6303 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6304 %} 6305 ins_pipe(pipe_cmov_reg); 6306 %} 6307 6308 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6309 %{ 6310 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6311 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6312 6313 ins_cost(100); // XXX 6314 format %{ "setbn$cop $dst\t# unsigned, int" %} 6315 ins_encode %{ 6316 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6317 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6318 %} 6319 ins_pipe(ialu_reg); 6320 %} 6321 6322 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6323 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6324 6325 ins_cost(200); // XXX 6326 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6327 ins_encode %{ 6328 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6329 %} 6330 ins_pipe(pipe_cmov_reg); 6331 %} 6332 6333 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6334 %{ 6335 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6336 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6337 6338 ins_cost(100); // XXX 6339 format %{ "setbn$cop $dst\t# unsigned, int" %} 6340 ins_encode %{ 6341 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6342 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6343 %} 6344 ins_pipe(ialu_reg); 6345 %} 6346 6347 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6348 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6349 ins_cost(200); 6350 expand %{ 6351 cmovI_regU(cop, cr, dst, src); 6352 %} 6353 %} 6354 6355 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6356 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6357 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6358 6359 ins_cost(200); // XXX 6360 format %{ "cmovpl $dst, $src\n\t" 6361 "cmovnel $dst, $src" %} 6362 ins_encode %{ 6363 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6364 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6365 %} 6366 ins_pipe(pipe_cmov_reg); 6367 %} 6368 6369 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6370 // inputs of the CMove 6371 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6372 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6373 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6374 6375 ins_cost(200); // XXX 6376 format %{ "cmovpl $dst, $src\n\t" 6377 "cmovnel $dst, $src" %} 6378 ins_encode %{ 6379 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6380 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6381 %} 6382 ins_pipe(pipe_cmov_reg); 6383 %} 6384 6385 // Conditional move 6386 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6387 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6388 6389 ins_cost(250); // XXX 6390 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6391 ins_encode %{ 6392 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6393 %} 6394 ins_pipe(pipe_cmov_mem); 6395 %} 6396 6397 // Conditional move 6398 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6399 %{ 6400 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6401 6402 ins_cost(250); // XXX 6403 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6404 ins_encode %{ 6405 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6406 %} 6407 ins_pipe(pipe_cmov_mem); 6408 %} 6409 6410 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6411 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6412 ins_cost(250); 6413 expand %{ 6414 cmovI_memU(cop, cr, dst, src); 6415 %} 6416 %} 6417 6418 // Conditional move 6419 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6420 %{ 6421 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6422 6423 ins_cost(200); // XXX 6424 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6425 ins_encode %{ 6426 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6427 %} 6428 ins_pipe(pipe_cmov_reg); 6429 %} 6430 6431 // Conditional move 6432 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6433 %{ 6434 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6435 6436 ins_cost(200); // XXX 6437 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6438 ins_encode %{ 6439 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6440 %} 6441 ins_pipe(pipe_cmov_reg); 6442 %} 6443 6444 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6445 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6446 ins_cost(200); 6447 expand %{ 6448 cmovN_regU(cop, cr, dst, src); 6449 %} 6450 %} 6451 6452 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6453 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6454 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6455 6456 ins_cost(200); // XXX 6457 format %{ "cmovpl $dst, $src\n\t" 6458 "cmovnel $dst, $src" %} 6459 ins_encode %{ 6460 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6461 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6462 %} 6463 ins_pipe(pipe_cmov_reg); 6464 %} 6465 6466 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6467 // inputs of the CMove 6468 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6469 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6470 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6471 6472 ins_cost(200); // XXX 6473 format %{ "cmovpl $dst, $src\n\t" 6474 "cmovnel $dst, $src" %} 6475 ins_encode %{ 6476 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6477 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6478 %} 6479 ins_pipe(pipe_cmov_reg); 6480 %} 6481 6482 // Conditional move 6483 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6484 %{ 6485 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6486 6487 ins_cost(200); // XXX 6488 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6489 ins_encode %{ 6490 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6491 %} 6492 ins_pipe(pipe_cmov_reg); // XXX 6493 %} 6494 6495 // Conditional move 6496 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6497 %{ 6498 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6499 6500 ins_cost(200); // XXX 6501 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6502 ins_encode %{ 6503 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6504 %} 6505 ins_pipe(pipe_cmov_reg); // XXX 6506 %} 6507 6508 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6509 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6510 ins_cost(200); 6511 expand %{ 6512 cmovP_regU(cop, cr, dst, src); 6513 %} 6514 %} 6515 6516 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6517 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6518 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6519 6520 ins_cost(200); // XXX 6521 format %{ "cmovpq $dst, $src\n\t" 6522 "cmovneq $dst, $src" %} 6523 ins_encode %{ 6524 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6525 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6526 %} 6527 ins_pipe(pipe_cmov_reg); 6528 %} 6529 6530 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6531 // inputs of the CMove 6532 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6533 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6534 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6535 6536 ins_cost(200); // XXX 6537 format %{ "cmovpq $dst, $src\n\t" 6538 "cmovneq $dst, $src" %} 6539 ins_encode %{ 6540 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6541 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6542 %} 6543 ins_pipe(pipe_cmov_reg); 6544 %} 6545 6546 instruct cmovL_imm_01(rRegL dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6547 %{ 6548 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6549 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6550 6551 ins_cost(100); // XXX 6552 format %{ "setbn$cop $dst\t# signed, long" %} 6553 ins_encode %{ 6554 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6555 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6556 %} 6557 ins_pipe(ialu_reg); 6558 %} 6559 6560 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6561 %{ 6562 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6563 6564 ins_cost(200); // XXX 6565 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6566 ins_encode %{ 6567 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6568 %} 6569 ins_pipe(pipe_cmov_reg); // XXX 6570 %} 6571 6572 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6573 %{ 6574 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6575 6576 ins_cost(200); // XXX 6577 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6578 ins_encode %{ 6579 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6580 %} 6581 ins_pipe(pipe_cmov_mem); // XXX 6582 %} 6583 6584 instruct cmovL_imm_01U(rRegL dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6585 %{ 6586 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6587 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6588 6589 ins_cost(100); // XXX 6590 format %{ "setbn$cop $dst\t# unsigned, long" %} 6591 ins_encode %{ 6592 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6593 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6594 %} 6595 ins_pipe(ialu_reg); 6596 %} 6597 6598 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6599 %{ 6600 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6601 6602 ins_cost(200); // XXX 6603 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6604 ins_encode %{ 6605 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6606 %} 6607 ins_pipe(pipe_cmov_reg); // XXX 6608 %} 6609 6610 instruct cmovL_imm_01UCF(rRegL dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6611 %{ 6612 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6613 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6614 6615 ins_cost(100); // XXX 6616 format %{ "setbn$cop $dst\t# unsigned, long" %} 6617 ins_encode %{ 6618 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6619 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6620 %} 6621 ins_pipe(ialu_reg); 6622 %} 6623 6624 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6625 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6626 ins_cost(200); 6627 expand %{ 6628 cmovL_regU(cop, cr, dst, src); 6629 %} 6630 %} 6631 6632 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6633 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6634 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6635 6636 ins_cost(200); // XXX 6637 format %{ "cmovpq $dst, $src\n\t" 6638 "cmovneq $dst, $src" %} 6639 ins_encode %{ 6640 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6641 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6642 %} 6643 ins_pipe(pipe_cmov_reg); 6644 %} 6645 6646 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6647 // inputs of the CMove 6648 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6649 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6650 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6651 6652 ins_cost(200); // XXX 6653 format %{ "cmovpq $dst, $src\n\t" 6654 "cmovneq $dst, $src" %} 6655 ins_encode %{ 6656 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6657 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6658 %} 6659 ins_pipe(pipe_cmov_reg); 6660 %} 6661 6662 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6663 %{ 6664 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6665 6666 ins_cost(200); // XXX 6667 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6668 ins_encode %{ 6669 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6670 %} 6671 ins_pipe(pipe_cmov_mem); // XXX 6672 %} 6673 6674 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6675 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6676 ins_cost(200); 6677 expand %{ 6678 cmovL_memU(cop, cr, dst, src); 6679 %} 6680 %} 6681 6682 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6683 %{ 6684 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6685 6686 ins_cost(200); // XXX 6687 format %{ "jn$cop skip\t# signed cmove float\n\t" 6688 "movss $dst, $src\n" 6689 "skip:" %} 6690 ins_encode %{ 6691 Label Lskip; 6692 // Invert sense of branch from sense of CMOV 6693 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6694 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6695 __ bind(Lskip); 6696 %} 6697 ins_pipe(pipe_slow); 6698 %} 6699 6700 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6701 %{ 6702 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6703 6704 ins_cost(200); // XXX 6705 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6706 "movss $dst, $src\n" 6707 "skip:" %} 6708 ins_encode %{ 6709 Label Lskip; 6710 // Invert sense of branch from sense of CMOV 6711 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6712 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6713 __ bind(Lskip); 6714 %} 6715 ins_pipe(pipe_slow); 6716 %} 6717 6718 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6719 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6720 ins_cost(200); 6721 expand %{ 6722 cmovF_regU(cop, cr, dst, src); 6723 %} 6724 %} 6725 6726 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6727 %{ 6728 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6729 6730 ins_cost(200); // XXX 6731 format %{ "jn$cop skip\t# signed cmove double\n\t" 6732 "movsd $dst, $src\n" 6733 "skip:" %} 6734 ins_encode %{ 6735 Label Lskip; 6736 // Invert sense of branch from sense of CMOV 6737 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6738 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6739 __ bind(Lskip); 6740 %} 6741 ins_pipe(pipe_slow); 6742 %} 6743 6744 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6745 %{ 6746 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6747 6748 ins_cost(200); // XXX 6749 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6750 "movsd $dst, $src\n" 6751 "skip:" %} 6752 ins_encode %{ 6753 Label Lskip; 6754 // Invert sense of branch from sense of CMOV 6755 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6756 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6757 __ bind(Lskip); 6758 %} 6759 ins_pipe(pipe_slow); 6760 %} 6761 6762 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6763 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6764 ins_cost(200); 6765 expand %{ 6766 cmovD_regU(cop, cr, dst, src); 6767 %} 6768 %} 6769 6770 //----------Arithmetic Instructions-------------------------------------------- 6771 //----------Addition Instructions---------------------------------------------- 6772 6773 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6774 %{ 6775 match(Set dst (AddI dst src)); 6776 effect(KILL cr); 6777 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6778 format %{ "addl $dst, $src\t# int" %} 6779 ins_encode %{ 6780 __ addl($dst$$Register, $src$$Register); 6781 %} 6782 ins_pipe(ialu_reg_reg); 6783 %} 6784 6785 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6786 %{ 6787 match(Set dst (AddI dst src)); 6788 effect(KILL cr); 6789 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6790 6791 format %{ "addl $dst, $src\t# int" %} 6792 ins_encode %{ 6793 __ addl($dst$$Register, $src$$constant); 6794 %} 6795 ins_pipe( ialu_reg ); 6796 %} 6797 6798 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6799 %{ 6800 match(Set dst (AddI dst (LoadI src))); 6801 effect(KILL cr); 6802 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6803 6804 ins_cost(150); // XXX 6805 format %{ "addl $dst, $src\t# int" %} 6806 ins_encode %{ 6807 __ addl($dst$$Register, $src$$Address); 6808 %} 6809 ins_pipe(ialu_reg_mem); 6810 %} 6811 6812 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6813 %{ 6814 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6815 effect(KILL cr); 6816 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6817 6818 ins_cost(150); // XXX 6819 format %{ "addl $dst, $src\t# int" %} 6820 ins_encode %{ 6821 __ addl($dst$$Address, $src$$Register); 6822 %} 6823 ins_pipe(ialu_mem_reg); 6824 %} 6825 6826 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6827 %{ 6828 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6829 effect(KILL cr); 6830 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6831 6832 6833 ins_cost(125); // XXX 6834 format %{ "addl $dst, $src\t# int" %} 6835 ins_encode %{ 6836 __ addl($dst$$Address, $src$$constant); 6837 %} 6838 ins_pipe(ialu_mem_imm); 6839 %} 6840 6841 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6842 %{ 6843 predicate(UseIncDec); 6844 match(Set dst (AddI dst src)); 6845 effect(KILL cr); 6846 6847 format %{ "incl $dst\t# int" %} 6848 ins_encode %{ 6849 __ incrementl($dst$$Register); 6850 %} 6851 ins_pipe(ialu_reg); 6852 %} 6853 6854 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6855 %{ 6856 predicate(UseIncDec); 6857 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6858 effect(KILL cr); 6859 6860 ins_cost(125); // XXX 6861 format %{ "incl $dst\t# int" %} 6862 ins_encode %{ 6863 __ incrementl($dst$$Address); 6864 %} 6865 ins_pipe(ialu_mem_imm); 6866 %} 6867 6868 // XXX why does that use AddI 6869 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6870 %{ 6871 predicate(UseIncDec); 6872 match(Set dst (AddI dst src)); 6873 effect(KILL cr); 6874 6875 format %{ "decl $dst\t# int" %} 6876 ins_encode %{ 6877 __ decrementl($dst$$Register); 6878 %} 6879 ins_pipe(ialu_reg); 6880 %} 6881 6882 // XXX why does that use AddI 6883 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6884 %{ 6885 predicate(UseIncDec); 6886 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6887 effect(KILL cr); 6888 6889 ins_cost(125); // XXX 6890 format %{ "decl $dst\t# int" %} 6891 ins_encode %{ 6892 __ decrementl($dst$$Address); 6893 %} 6894 ins_pipe(ialu_mem_imm); 6895 %} 6896 6897 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6898 %{ 6899 predicate(VM_Version::supports_fast_2op_lea()); 6900 match(Set dst (AddI (LShiftI index scale) disp)); 6901 6902 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6903 ins_encode %{ 6904 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6905 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6906 %} 6907 ins_pipe(ialu_reg_reg); 6908 %} 6909 6910 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6911 %{ 6912 predicate(VM_Version::supports_fast_3op_lea()); 6913 match(Set dst (AddI (AddI base index) disp)); 6914 6915 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6916 ins_encode %{ 6917 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6918 %} 6919 ins_pipe(ialu_reg_reg); 6920 %} 6921 6922 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6923 %{ 6924 predicate(VM_Version::supports_fast_2op_lea()); 6925 match(Set dst (AddI base (LShiftI index scale))); 6926 6927 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6928 ins_encode %{ 6929 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6930 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6931 %} 6932 ins_pipe(ialu_reg_reg); 6933 %} 6934 6935 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6936 %{ 6937 predicate(VM_Version::supports_fast_3op_lea()); 6938 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6939 6940 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6941 ins_encode %{ 6942 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6943 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6944 %} 6945 ins_pipe(ialu_reg_reg); 6946 %} 6947 6948 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6949 %{ 6950 match(Set dst (AddL dst src)); 6951 effect(KILL cr); 6952 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6953 6954 format %{ "addq $dst, $src\t# long" %} 6955 ins_encode %{ 6956 __ addq($dst$$Register, $src$$Register); 6957 %} 6958 ins_pipe(ialu_reg_reg); 6959 %} 6960 6961 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6962 %{ 6963 match(Set dst (AddL dst src)); 6964 effect(KILL cr); 6965 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6966 6967 format %{ "addq $dst, $src\t# long" %} 6968 ins_encode %{ 6969 __ addq($dst$$Register, $src$$constant); 6970 %} 6971 ins_pipe( ialu_reg ); 6972 %} 6973 6974 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6975 %{ 6976 match(Set dst (AddL dst (LoadL src))); 6977 effect(KILL cr); 6978 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6979 6980 ins_cost(150); // XXX 6981 format %{ "addq $dst, $src\t# long" %} 6982 ins_encode %{ 6983 __ addq($dst$$Register, $src$$Address); 6984 %} 6985 ins_pipe(ialu_reg_mem); 6986 %} 6987 6988 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6989 %{ 6990 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6991 effect(KILL cr); 6992 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6993 6994 ins_cost(150); // XXX 6995 format %{ "addq $dst, $src\t# long" %} 6996 ins_encode %{ 6997 __ addq($dst$$Address, $src$$Register); 6998 %} 6999 ins_pipe(ialu_mem_reg); 7000 %} 7001 7002 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7003 %{ 7004 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7005 effect(KILL cr); 7006 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7007 7008 ins_cost(125); // XXX 7009 format %{ "addq $dst, $src\t# long" %} 7010 ins_encode %{ 7011 __ addq($dst$$Address, $src$$constant); 7012 %} 7013 ins_pipe(ialu_mem_imm); 7014 %} 7015 7016 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7017 %{ 7018 predicate(UseIncDec); 7019 match(Set dst (AddL dst src)); 7020 effect(KILL cr); 7021 7022 format %{ "incq $dst\t# long" %} 7023 ins_encode %{ 7024 __ incrementq($dst$$Register); 7025 %} 7026 ins_pipe(ialu_reg); 7027 %} 7028 7029 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7030 %{ 7031 predicate(UseIncDec); 7032 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7033 effect(KILL cr); 7034 7035 ins_cost(125); // XXX 7036 format %{ "incq $dst\t# long" %} 7037 ins_encode %{ 7038 __ incrementq($dst$$Address); 7039 %} 7040 ins_pipe(ialu_mem_imm); 7041 %} 7042 7043 // XXX why does that use AddL 7044 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7045 %{ 7046 predicate(UseIncDec); 7047 match(Set dst (AddL dst src)); 7048 effect(KILL cr); 7049 7050 format %{ "decq $dst\t# long" %} 7051 ins_encode %{ 7052 __ decrementq($dst$$Register); 7053 %} 7054 ins_pipe(ialu_reg); 7055 %} 7056 7057 // XXX why does that use AddL 7058 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7059 %{ 7060 predicate(UseIncDec); 7061 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7062 effect(KILL cr); 7063 7064 ins_cost(125); // XXX 7065 format %{ "decq $dst\t# long" %} 7066 ins_encode %{ 7067 __ decrementq($dst$$Address); 7068 %} 7069 ins_pipe(ialu_mem_imm); 7070 %} 7071 7072 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7073 %{ 7074 predicate(VM_Version::supports_fast_2op_lea()); 7075 match(Set dst (AddL (LShiftL index scale) disp)); 7076 7077 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7078 ins_encode %{ 7079 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7080 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7081 %} 7082 ins_pipe(ialu_reg_reg); 7083 %} 7084 7085 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7086 %{ 7087 predicate(VM_Version::supports_fast_3op_lea()); 7088 match(Set dst (AddL (AddL base index) disp)); 7089 7090 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7091 ins_encode %{ 7092 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7093 %} 7094 ins_pipe(ialu_reg_reg); 7095 %} 7096 7097 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7098 %{ 7099 predicate(VM_Version::supports_fast_2op_lea()); 7100 match(Set dst (AddL base (LShiftL index scale))); 7101 7102 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7103 ins_encode %{ 7104 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7105 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7106 %} 7107 ins_pipe(ialu_reg_reg); 7108 %} 7109 7110 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7111 %{ 7112 predicate(VM_Version::supports_fast_3op_lea()); 7113 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7114 7115 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7116 ins_encode %{ 7117 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7118 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7119 %} 7120 ins_pipe(ialu_reg_reg); 7121 %} 7122 7123 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7124 %{ 7125 match(Set dst (AddP dst src)); 7126 effect(KILL cr); 7127 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7128 7129 format %{ "addq $dst, $src\t# ptr" %} 7130 ins_encode %{ 7131 __ addq($dst$$Register, $src$$Register); 7132 %} 7133 ins_pipe(ialu_reg_reg); 7134 %} 7135 7136 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7137 %{ 7138 match(Set dst (AddP dst src)); 7139 effect(KILL cr); 7140 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7141 7142 format %{ "addq $dst, $src\t# ptr" %} 7143 ins_encode %{ 7144 __ addq($dst$$Register, $src$$constant); 7145 %} 7146 ins_pipe( ialu_reg ); 7147 %} 7148 7149 // XXX addP mem ops ???? 7150 7151 instruct checkCastPP(rRegP dst) 7152 %{ 7153 match(Set dst (CheckCastPP dst)); 7154 7155 size(0); 7156 format %{ "# checkcastPP of $dst" %} 7157 ins_encode(/* empty encoding */); 7158 ins_pipe(empty); 7159 %} 7160 7161 instruct castPP(rRegP dst) 7162 %{ 7163 match(Set dst (CastPP dst)); 7164 7165 size(0); 7166 format %{ "# castPP of $dst" %} 7167 ins_encode(/* empty encoding */); 7168 ins_pipe(empty); 7169 %} 7170 7171 instruct castII(rRegI dst) 7172 %{ 7173 match(Set dst (CastII dst)); 7174 7175 size(0); 7176 format %{ "# castII of $dst" %} 7177 ins_encode(/* empty encoding */); 7178 ins_cost(0); 7179 ins_pipe(empty); 7180 %} 7181 7182 instruct castLL(rRegL dst) 7183 %{ 7184 match(Set dst (CastLL dst)); 7185 7186 size(0); 7187 format %{ "# castLL of $dst" %} 7188 ins_encode(/* empty encoding */); 7189 ins_cost(0); 7190 ins_pipe(empty); 7191 %} 7192 7193 instruct castFF(regF dst) 7194 %{ 7195 match(Set dst (CastFF dst)); 7196 7197 size(0); 7198 format %{ "# castFF of $dst" %} 7199 ins_encode(/* empty encoding */); 7200 ins_cost(0); 7201 ins_pipe(empty); 7202 %} 7203 7204 instruct castDD(regD dst) 7205 %{ 7206 match(Set dst (CastDD dst)); 7207 7208 size(0); 7209 format %{ "# castDD of $dst" %} 7210 ins_encode(/* empty encoding */); 7211 ins_cost(0); 7212 ins_pipe(empty); 7213 %} 7214 7215 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7216 instruct compareAndSwapP(rRegI res, 7217 memory mem_ptr, 7218 rax_RegP oldval, rRegP newval, 7219 rFlagsReg cr) 7220 %{ 7221 predicate(n->as_LoadStore()->barrier_data() == 0); 7222 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7223 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7224 effect(KILL cr, KILL oldval); 7225 7226 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7227 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7228 "sete $res\n\t" 7229 "movzbl $res, $res" %} 7230 ins_encode %{ 7231 __ lock(); 7232 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7233 __ setb(Assembler::equal, $res$$Register); 7234 __ movzbl($res$$Register, $res$$Register); 7235 %} 7236 ins_pipe( pipe_cmpxchg ); 7237 %} 7238 7239 instruct compareAndSwapL(rRegI res, 7240 memory mem_ptr, 7241 rax_RegL oldval, rRegL newval, 7242 rFlagsReg cr) 7243 %{ 7244 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7245 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7246 effect(KILL cr, KILL oldval); 7247 7248 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7249 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7250 "sete $res\n\t" 7251 "movzbl $res, $res" %} 7252 ins_encode %{ 7253 __ lock(); 7254 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7255 __ setb(Assembler::equal, $res$$Register); 7256 __ movzbl($res$$Register, $res$$Register); 7257 %} 7258 ins_pipe( pipe_cmpxchg ); 7259 %} 7260 7261 instruct compareAndSwapI(rRegI res, 7262 memory mem_ptr, 7263 rax_RegI oldval, rRegI newval, 7264 rFlagsReg cr) 7265 %{ 7266 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7267 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7268 effect(KILL cr, KILL oldval); 7269 7270 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7271 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7272 "sete $res\n\t" 7273 "movzbl $res, $res" %} 7274 ins_encode %{ 7275 __ lock(); 7276 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7277 __ setb(Assembler::equal, $res$$Register); 7278 __ movzbl($res$$Register, $res$$Register); 7279 %} 7280 ins_pipe( pipe_cmpxchg ); 7281 %} 7282 7283 instruct compareAndSwapB(rRegI res, 7284 memory mem_ptr, 7285 rax_RegI oldval, rRegI newval, 7286 rFlagsReg cr) 7287 %{ 7288 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7289 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7290 effect(KILL cr, KILL oldval); 7291 7292 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7293 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7294 "sete $res\n\t" 7295 "movzbl $res, $res" %} 7296 ins_encode %{ 7297 __ lock(); 7298 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7299 __ setb(Assembler::equal, $res$$Register); 7300 __ movzbl($res$$Register, $res$$Register); 7301 %} 7302 ins_pipe( pipe_cmpxchg ); 7303 %} 7304 7305 instruct compareAndSwapS(rRegI res, 7306 memory mem_ptr, 7307 rax_RegI oldval, rRegI newval, 7308 rFlagsReg cr) 7309 %{ 7310 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7311 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7312 effect(KILL cr, KILL oldval); 7313 7314 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7315 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7316 "sete $res\n\t" 7317 "movzbl $res, $res" %} 7318 ins_encode %{ 7319 __ lock(); 7320 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7321 __ setb(Assembler::equal, $res$$Register); 7322 __ movzbl($res$$Register, $res$$Register); 7323 %} 7324 ins_pipe( pipe_cmpxchg ); 7325 %} 7326 7327 instruct compareAndSwapN(rRegI res, 7328 memory mem_ptr, 7329 rax_RegN oldval, rRegN newval, 7330 rFlagsReg cr) %{ 7331 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7332 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7333 effect(KILL cr, KILL oldval); 7334 7335 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7336 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7337 "sete $res\n\t" 7338 "movzbl $res, $res" %} 7339 ins_encode %{ 7340 __ lock(); 7341 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7342 __ setb(Assembler::equal, $res$$Register); 7343 __ movzbl($res$$Register, $res$$Register); 7344 %} 7345 ins_pipe( pipe_cmpxchg ); 7346 %} 7347 7348 instruct compareAndExchangeB( 7349 memory mem_ptr, 7350 rax_RegI oldval, rRegI newval, 7351 rFlagsReg cr) 7352 %{ 7353 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7354 effect(KILL cr); 7355 7356 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7357 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7358 ins_encode %{ 7359 __ lock(); 7360 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7361 %} 7362 ins_pipe( pipe_cmpxchg ); 7363 %} 7364 7365 instruct compareAndExchangeS( 7366 memory mem_ptr, 7367 rax_RegI oldval, rRegI newval, 7368 rFlagsReg cr) 7369 %{ 7370 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7371 effect(KILL cr); 7372 7373 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7374 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7375 ins_encode %{ 7376 __ lock(); 7377 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7378 %} 7379 ins_pipe( pipe_cmpxchg ); 7380 %} 7381 7382 instruct compareAndExchangeI( 7383 memory mem_ptr, 7384 rax_RegI oldval, rRegI newval, 7385 rFlagsReg cr) 7386 %{ 7387 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7388 effect(KILL cr); 7389 7390 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7391 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7392 ins_encode %{ 7393 __ lock(); 7394 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7395 %} 7396 ins_pipe( pipe_cmpxchg ); 7397 %} 7398 7399 instruct compareAndExchangeL( 7400 memory mem_ptr, 7401 rax_RegL oldval, rRegL newval, 7402 rFlagsReg cr) 7403 %{ 7404 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7405 effect(KILL cr); 7406 7407 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7408 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7409 ins_encode %{ 7410 __ lock(); 7411 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7412 %} 7413 ins_pipe( pipe_cmpxchg ); 7414 %} 7415 7416 instruct compareAndExchangeN( 7417 memory mem_ptr, 7418 rax_RegN oldval, rRegN newval, 7419 rFlagsReg cr) %{ 7420 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7421 effect(KILL cr); 7422 7423 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7424 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7425 ins_encode %{ 7426 __ lock(); 7427 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7428 %} 7429 ins_pipe( pipe_cmpxchg ); 7430 %} 7431 7432 instruct compareAndExchangeP( 7433 memory mem_ptr, 7434 rax_RegP oldval, rRegP newval, 7435 rFlagsReg cr) 7436 %{ 7437 predicate(n->as_LoadStore()->barrier_data() == 0); 7438 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7439 effect(KILL cr); 7440 7441 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7442 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7443 ins_encode %{ 7444 __ lock(); 7445 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7446 %} 7447 ins_pipe( pipe_cmpxchg ); 7448 %} 7449 7450 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7451 predicate(n->as_LoadStore()->result_not_used()); 7452 match(Set dummy (GetAndAddB mem add)); 7453 effect(KILL cr); 7454 format %{ "addb_lock $mem, $add" %} 7455 ins_encode %{ 7456 __ lock(); 7457 __ addb($mem$$Address, $add$$Register); 7458 %} 7459 ins_pipe(pipe_cmpxchg); 7460 %} 7461 7462 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7463 predicate(n->as_LoadStore()->result_not_used()); 7464 match(Set dummy (GetAndAddB mem add)); 7465 effect(KILL cr); 7466 format %{ "addb_lock $mem, $add" %} 7467 ins_encode %{ 7468 __ lock(); 7469 __ addb($mem$$Address, $add$$constant); 7470 %} 7471 ins_pipe(pipe_cmpxchg); 7472 %} 7473 7474 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7475 predicate(!n->as_LoadStore()->result_not_used()); 7476 match(Set newval (GetAndAddB mem newval)); 7477 effect(KILL cr); 7478 format %{ "xaddb_lock $mem, $newval" %} 7479 ins_encode %{ 7480 __ lock(); 7481 __ xaddb($mem$$Address, $newval$$Register); 7482 %} 7483 ins_pipe(pipe_cmpxchg); 7484 %} 7485 7486 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7487 predicate(n->as_LoadStore()->result_not_used()); 7488 match(Set dummy (GetAndAddS mem add)); 7489 effect(KILL cr); 7490 format %{ "addw_lock $mem, $add" %} 7491 ins_encode %{ 7492 __ lock(); 7493 __ addw($mem$$Address, $add$$Register); 7494 %} 7495 ins_pipe(pipe_cmpxchg); 7496 %} 7497 7498 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7499 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7500 match(Set dummy (GetAndAddS mem add)); 7501 effect(KILL cr); 7502 format %{ "addw_lock $mem, $add" %} 7503 ins_encode %{ 7504 __ lock(); 7505 __ addw($mem$$Address, $add$$constant); 7506 %} 7507 ins_pipe(pipe_cmpxchg); 7508 %} 7509 7510 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7511 predicate(!n->as_LoadStore()->result_not_used()); 7512 match(Set newval (GetAndAddS mem newval)); 7513 effect(KILL cr); 7514 format %{ "xaddw_lock $mem, $newval" %} 7515 ins_encode %{ 7516 __ lock(); 7517 __ xaddw($mem$$Address, $newval$$Register); 7518 %} 7519 ins_pipe(pipe_cmpxchg); 7520 %} 7521 7522 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7523 predicate(n->as_LoadStore()->result_not_used()); 7524 match(Set dummy (GetAndAddI mem add)); 7525 effect(KILL cr); 7526 format %{ "addl_lock $mem, $add" %} 7527 ins_encode %{ 7528 __ lock(); 7529 __ addl($mem$$Address, $add$$Register); 7530 %} 7531 ins_pipe(pipe_cmpxchg); 7532 %} 7533 7534 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7535 predicate(n->as_LoadStore()->result_not_used()); 7536 match(Set dummy (GetAndAddI mem add)); 7537 effect(KILL cr); 7538 format %{ "addl_lock $mem, $add" %} 7539 ins_encode %{ 7540 __ lock(); 7541 __ addl($mem$$Address, $add$$constant); 7542 %} 7543 ins_pipe(pipe_cmpxchg); 7544 %} 7545 7546 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7547 predicate(!n->as_LoadStore()->result_not_used()); 7548 match(Set newval (GetAndAddI mem newval)); 7549 effect(KILL cr); 7550 format %{ "xaddl_lock $mem, $newval" %} 7551 ins_encode %{ 7552 __ lock(); 7553 __ xaddl($mem$$Address, $newval$$Register); 7554 %} 7555 ins_pipe(pipe_cmpxchg); 7556 %} 7557 7558 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7559 predicate(n->as_LoadStore()->result_not_used()); 7560 match(Set dummy (GetAndAddL mem add)); 7561 effect(KILL cr); 7562 format %{ "addq_lock $mem, $add" %} 7563 ins_encode %{ 7564 __ lock(); 7565 __ addq($mem$$Address, $add$$Register); 7566 %} 7567 ins_pipe(pipe_cmpxchg); 7568 %} 7569 7570 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7571 predicate(n->as_LoadStore()->result_not_used()); 7572 match(Set dummy (GetAndAddL mem add)); 7573 effect(KILL cr); 7574 format %{ "addq_lock $mem, $add" %} 7575 ins_encode %{ 7576 __ lock(); 7577 __ addq($mem$$Address, $add$$constant); 7578 %} 7579 ins_pipe(pipe_cmpxchg); 7580 %} 7581 7582 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7583 predicate(!n->as_LoadStore()->result_not_used()); 7584 match(Set newval (GetAndAddL mem newval)); 7585 effect(KILL cr); 7586 format %{ "xaddq_lock $mem, $newval" %} 7587 ins_encode %{ 7588 __ lock(); 7589 __ xaddq($mem$$Address, $newval$$Register); 7590 %} 7591 ins_pipe(pipe_cmpxchg); 7592 %} 7593 7594 instruct xchgB( memory mem, rRegI newval) %{ 7595 match(Set newval (GetAndSetB mem newval)); 7596 format %{ "XCHGB $newval,[$mem]" %} 7597 ins_encode %{ 7598 __ xchgb($newval$$Register, $mem$$Address); 7599 %} 7600 ins_pipe( pipe_cmpxchg ); 7601 %} 7602 7603 instruct xchgS( memory mem, rRegI newval) %{ 7604 match(Set newval (GetAndSetS mem newval)); 7605 format %{ "XCHGW $newval,[$mem]" %} 7606 ins_encode %{ 7607 __ xchgw($newval$$Register, $mem$$Address); 7608 %} 7609 ins_pipe( pipe_cmpxchg ); 7610 %} 7611 7612 instruct xchgI( memory mem, rRegI newval) %{ 7613 match(Set newval (GetAndSetI mem newval)); 7614 format %{ "XCHGL $newval,[$mem]" %} 7615 ins_encode %{ 7616 __ xchgl($newval$$Register, $mem$$Address); 7617 %} 7618 ins_pipe( pipe_cmpxchg ); 7619 %} 7620 7621 instruct xchgL( memory mem, rRegL newval) %{ 7622 match(Set newval (GetAndSetL mem newval)); 7623 format %{ "XCHGL $newval,[$mem]" %} 7624 ins_encode %{ 7625 __ xchgq($newval$$Register, $mem$$Address); 7626 %} 7627 ins_pipe( pipe_cmpxchg ); 7628 %} 7629 7630 instruct xchgP( memory mem, rRegP newval) %{ 7631 match(Set newval (GetAndSetP mem newval)); 7632 predicate(n->as_LoadStore()->barrier_data() == 0); 7633 format %{ "XCHGQ $newval,[$mem]" %} 7634 ins_encode %{ 7635 __ xchgq($newval$$Register, $mem$$Address); 7636 %} 7637 ins_pipe( pipe_cmpxchg ); 7638 %} 7639 7640 instruct xchgN( memory mem, rRegN newval) %{ 7641 match(Set newval (GetAndSetN mem newval)); 7642 format %{ "XCHGL $newval,$mem]" %} 7643 ins_encode %{ 7644 __ xchgl($newval$$Register, $mem$$Address); 7645 %} 7646 ins_pipe( pipe_cmpxchg ); 7647 %} 7648 7649 //----------Abs Instructions------------------------------------------- 7650 7651 // Integer Absolute Instructions 7652 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7653 %{ 7654 match(Set dst (AbsI src)); 7655 effect(TEMP dst, KILL cr); 7656 format %{ "xorl $dst, $dst\t# abs int\n\t" 7657 "subl $dst, $src\n\t" 7658 "cmovll $dst, $src" %} 7659 ins_encode %{ 7660 __ xorl($dst$$Register, $dst$$Register); 7661 __ subl($dst$$Register, $src$$Register); 7662 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7663 %} 7664 7665 ins_pipe(ialu_reg_reg); 7666 %} 7667 7668 // Long Absolute Instructions 7669 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7670 %{ 7671 match(Set dst (AbsL src)); 7672 effect(TEMP dst, KILL cr); 7673 format %{ "xorl $dst, $dst\t# abs long\n\t" 7674 "subq $dst, $src\n\t" 7675 "cmovlq $dst, $src" %} 7676 ins_encode %{ 7677 __ xorl($dst$$Register, $dst$$Register); 7678 __ subq($dst$$Register, $src$$Register); 7679 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7680 %} 7681 7682 ins_pipe(ialu_reg_reg); 7683 %} 7684 7685 //----------Subtraction Instructions------------------------------------------- 7686 7687 // Integer Subtraction Instructions 7688 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7689 %{ 7690 match(Set dst (SubI dst src)); 7691 effect(KILL cr); 7692 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7693 7694 format %{ "subl $dst, $src\t# int" %} 7695 ins_encode %{ 7696 __ subl($dst$$Register, $src$$Register); 7697 %} 7698 ins_pipe(ialu_reg_reg); 7699 %} 7700 7701 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7702 %{ 7703 match(Set dst (SubI dst (LoadI src))); 7704 effect(KILL cr); 7705 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7706 7707 ins_cost(150); 7708 format %{ "subl $dst, $src\t# int" %} 7709 ins_encode %{ 7710 __ subl($dst$$Register, $src$$Address); 7711 %} 7712 ins_pipe(ialu_reg_mem); 7713 %} 7714 7715 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7716 %{ 7717 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7718 effect(KILL cr); 7719 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7720 7721 ins_cost(150); 7722 format %{ "subl $dst, $src\t# int" %} 7723 ins_encode %{ 7724 __ subl($dst$$Address, $src$$Register); 7725 %} 7726 ins_pipe(ialu_mem_reg); 7727 %} 7728 7729 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7730 %{ 7731 match(Set dst (SubL dst src)); 7732 effect(KILL cr); 7733 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7734 7735 format %{ "subq $dst, $src\t# long" %} 7736 ins_encode %{ 7737 __ subq($dst$$Register, $src$$Register); 7738 %} 7739 ins_pipe(ialu_reg_reg); 7740 %} 7741 7742 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7743 %{ 7744 match(Set dst (SubL dst (LoadL src))); 7745 effect(KILL cr); 7746 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7747 7748 ins_cost(150); 7749 format %{ "subq $dst, $src\t# long" %} 7750 ins_encode %{ 7751 __ subq($dst$$Register, $src$$Address); 7752 %} 7753 ins_pipe(ialu_reg_mem); 7754 %} 7755 7756 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7757 %{ 7758 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7759 effect(KILL cr); 7760 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7761 7762 ins_cost(150); 7763 format %{ "subq $dst, $src\t# long" %} 7764 ins_encode %{ 7765 __ subq($dst$$Address, $src$$Register); 7766 %} 7767 ins_pipe(ialu_mem_reg); 7768 %} 7769 7770 // Subtract from a pointer 7771 // XXX hmpf??? 7772 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7773 %{ 7774 match(Set dst (AddP dst (SubI zero src))); 7775 effect(KILL cr); 7776 7777 format %{ "subq $dst, $src\t# ptr - int" %} 7778 ins_encode %{ 7779 __ subq($dst$$Register, $src$$Register); 7780 %} 7781 ins_pipe(ialu_reg_reg); 7782 %} 7783 7784 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7785 %{ 7786 match(Set dst (SubI zero dst)); 7787 effect(KILL cr); 7788 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7789 7790 format %{ "negl $dst\t# int" %} 7791 ins_encode %{ 7792 __ negl($dst$$Register); 7793 %} 7794 ins_pipe(ialu_reg); 7795 %} 7796 7797 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7798 %{ 7799 match(Set dst (NegI dst)); 7800 effect(KILL cr); 7801 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7802 7803 format %{ "negl $dst\t# int" %} 7804 ins_encode %{ 7805 __ negl($dst$$Register); 7806 %} 7807 ins_pipe(ialu_reg); 7808 %} 7809 7810 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7811 %{ 7812 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7813 effect(KILL cr); 7814 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7815 7816 format %{ "negl $dst\t# int" %} 7817 ins_encode %{ 7818 __ negl($dst$$Address); 7819 %} 7820 ins_pipe(ialu_reg); 7821 %} 7822 7823 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7824 %{ 7825 match(Set dst (SubL zero dst)); 7826 effect(KILL cr); 7827 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7828 7829 format %{ "negq $dst\t# long" %} 7830 ins_encode %{ 7831 __ negq($dst$$Register); 7832 %} 7833 ins_pipe(ialu_reg); 7834 %} 7835 7836 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7837 %{ 7838 match(Set dst (NegL dst)); 7839 effect(KILL cr); 7840 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7841 7842 format %{ "negq $dst\t# int" %} 7843 ins_encode %{ 7844 __ negq($dst$$Register); 7845 %} 7846 ins_pipe(ialu_reg); 7847 %} 7848 7849 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7850 %{ 7851 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7852 effect(KILL cr); 7853 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7854 7855 format %{ "negq $dst\t# long" %} 7856 ins_encode %{ 7857 __ negq($dst$$Address); 7858 %} 7859 ins_pipe(ialu_reg); 7860 %} 7861 7862 //----------Multiplication/Division Instructions------------------------------- 7863 // Integer Multiplication Instructions 7864 // Multiply Register 7865 7866 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7867 %{ 7868 match(Set dst (MulI dst src)); 7869 effect(KILL cr); 7870 7871 ins_cost(300); 7872 format %{ "imull $dst, $src\t# int" %} 7873 ins_encode %{ 7874 __ imull($dst$$Register, $src$$Register); 7875 %} 7876 ins_pipe(ialu_reg_reg_alu0); 7877 %} 7878 7879 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7880 %{ 7881 match(Set dst (MulI src imm)); 7882 effect(KILL cr); 7883 7884 ins_cost(300); 7885 format %{ "imull $dst, $src, $imm\t# int" %} 7886 ins_encode %{ 7887 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7888 %} 7889 ins_pipe(ialu_reg_reg_alu0); 7890 %} 7891 7892 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7893 %{ 7894 match(Set dst (MulI dst (LoadI src))); 7895 effect(KILL cr); 7896 7897 ins_cost(350); 7898 format %{ "imull $dst, $src\t# int" %} 7899 ins_encode %{ 7900 __ imull($dst$$Register, $src$$Address); 7901 %} 7902 ins_pipe(ialu_reg_mem_alu0); 7903 %} 7904 7905 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7906 %{ 7907 match(Set dst (MulI (LoadI src) imm)); 7908 effect(KILL cr); 7909 7910 ins_cost(300); 7911 format %{ "imull $dst, $src, $imm\t# int" %} 7912 ins_encode %{ 7913 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7914 %} 7915 ins_pipe(ialu_reg_mem_alu0); 7916 %} 7917 7918 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7919 %{ 7920 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7921 effect(KILL cr, KILL src2); 7922 7923 expand %{ mulI_rReg(dst, src1, cr); 7924 mulI_rReg(src2, src3, cr); 7925 addI_rReg(dst, src2, cr); %} 7926 %} 7927 7928 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7929 %{ 7930 match(Set dst (MulL dst src)); 7931 effect(KILL cr); 7932 7933 ins_cost(300); 7934 format %{ "imulq $dst, $src\t# long" %} 7935 ins_encode %{ 7936 __ imulq($dst$$Register, $src$$Register); 7937 %} 7938 ins_pipe(ialu_reg_reg_alu0); 7939 %} 7940 7941 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7942 %{ 7943 match(Set dst (MulL src imm)); 7944 effect(KILL cr); 7945 7946 ins_cost(300); 7947 format %{ "imulq $dst, $src, $imm\t# long" %} 7948 ins_encode %{ 7949 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7950 %} 7951 ins_pipe(ialu_reg_reg_alu0); 7952 %} 7953 7954 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7955 %{ 7956 match(Set dst (MulL dst (LoadL src))); 7957 effect(KILL cr); 7958 7959 ins_cost(350); 7960 format %{ "imulq $dst, $src\t# long" %} 7961 ins_encode %{ 7962 __ imulq($dst$$Register, $src$$Address); 7963 %} 7964 ins_pipe(ialu_reg_mem_alu0); 7965 %} 7966 7967 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7968 %{ 7969 match(Set dst (MulL (LoadL src) imm)); 7970 effect(KILL cr); 7971 7972 ins_cost(300); 7973 format %{ "imulq $dst, $src, $imm\t# long" %} 7974 ins_encode %{ 7975 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7976 %} 7977 ins_pipe(ialu_reg_mem_alu0); 7978 %} 7979 7980 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7981 %{ 7982 match(Set dst (MulHiL src rax)); 7983 effect(USE_KILL rax, KILL cr); 7984 7985 ins_cost(300); 7986 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7987 ins_encode %{ 7988 __ imulq($src$$Register); 7989 %} 7990 ins_pipe(ialu_reg_reg_alu0); 7991 %} 7992 7993 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7994 %{ 7995 match(Set dst (UMulHiL src rax)); 7996 effect(USE_KILL rax, KILL cr); 7997 7998 ins_cost(300); 7999 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8000 ins_encode %{ 8001 __ mulq($src$$Register); 8002 %} 8003 ins_pipe(ialu_reg_reg_alu0); 8004 %} 8005 8006 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8007 rFlagsReg cr) 8008 %{ 8009 match(Set rax (DivI rax div)); 8010 effect(KILL rdx, KILL cr); 8011 8012 ins_cost(30*100+10*100); // XXX 8013 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8014 "jne,s normal\n\t" 8015 "xorl rdx, rdx\n\t" 8016 "cmpl $div, -1\n\t" 8017 "je,s done\n" 8018 "normal: cdql\n\t" 8019 "idivl $div\n" 8020 "done:" %} 8021 ins_encode(cdql_enc(div)); 8022 ins_pipe(ialu_reg_reg_alu0); 8023 %} 8024 8025 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8026 rFlagsReg cr) 8027 %{ 8028 match(Set rax (DivL rax div)); 8029 effect(KILL rdx, KILL cr); 8030 8031 ins_cost(30*100+10*100); // XXX 8032 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8033 "cmpq rax, rdx\n\t" 8034 "jne,s normal\n\t" 8035 "xorl rdx, rdx\n\t" 8036 "cmpq $div, -1\n\t" 8037 "je,s done\n" 8038 "normal: cdqq\n\t" 8039 "idivq $div\n" 8040 "done:" %} 8041 ins_encode(cdqq_enc(div)); 8042 ins_pipe(ialu_reg_reg_alu0); 8043 %} 8044 8045 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8046 %{ 8047 match(Set rax (UDivI rax div)); 8048 effect(KILL rdx, KILL cr); 8049 8050 ins_cost(300); 8051 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8052 ins_encode %{ 8053 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8054 %} 8055 ins_pipe(ialu_reg_reg_alu0); 8056 %} 8057 8058 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8059 %{ 8060 match(Set rax (UDivL rax div)); 8061 effect(KILL rdx, KILL cr); 8062 8063 ins_cost(300); 8064 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8065 ins_encode %{ 8066 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8067 %} 8068 ins_pipe(ialu_reg_reg_alu0); 8069 %} 8070 8071 // Integer DIVMOD with Register, both quotient and mod results 8072 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8073 rFlagsReg cr) 8074 %{ 8075 match(DivModI rax div); 8076 effect(KILL cr); 8077 8078 ins_cost(30*100+10*100); // XXX 8079 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8080 "jne,s normal\n\t" 8081 "xorl rdx, rdx\n\t" 8082 "cmpl $div, -1\n\t" 8083 "je,s done\n" 8084 "normal: cdql\n\t" 8085 "idivl $div\n" 8086 "done:" %} 8087 ins_encode(cdql_enc(div)); 8088 ins_pipe(pipe_slow); 8089 %} 8090 8091 // Long DIVMOD with Register, both quotient and mod results 8092 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8093 rFlagsReg cr) 8094 %{ 8095 match(DivModL rax div); 8096 effect(KILL cr); 8097 8098 ins_cost(30*100+10*100); // XXX 8099 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8100 "cmpq rax, rdx\n\t" 8101 "jne,s normal\n\t" 8102 "xorl rdx, rdx\n\t" 8103 "cmpq $div, -1\n\t" 8104 "je,s done\n" 8105 "normal: cdqq\n\t" 8106 "idivq $div\n" 8107 "done:" %} 8108 ins_encode(cdqq_enc(div)); 8109 ins_pipe(pipe_slow); 8110 %} 8111 8112 // Unsigned integer DIVMOD with Register, both quotient and mod results 8113 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8114 no_rax_rdx_RegI div, rFlagsReg cr) 8115 %{ 8116 match(UDivModI rax div); 8117 effect(TEMP tmp, KILL cr); 8118 8119 ins_cost(300); 8120 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8121 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8122 %} 8123 ins_encode %{ 8124 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8125 %} 8126 ins_pipe(pipe_slow); 8127 %} 8128 8129 // Unsigned long DIVMOD with Register, both quotient and mod results 8130 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8131 no_rax_rdx_RegL div, rFlagsReg cr) 8132 %{ 8133 match(UDivModL rax div); 8134 effect(TEMP tmp, KILL cr); 8135 8136 ins_cost(300); 8137 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8138 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8139 %} 8140 ins_encode %{ 8141 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8142 %} 8143 ins_pipe(pipe_slow); 8144 %} 8145 8146 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8147 rFlagsReg cr) 8148 %{ 8149 match(Set rdx (ModI rax div)); 8150 effect(KILL rax, KILL cr); 8151 8152 ins_cost(300); // XXX 8153 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8154 "jne,s normal\n\t" 8155 "xorl rdx, rdx\n\t" 8156 "cmpl $div, -1\n\t" 8157 "je,s done\n" 8158 "normal: cdql\n\t" 8159 "idivl $div\n" 8160 "done:" %} 8161 ins_encode(cdql_enc(div)); 8162 ins_pipe(ialu_reg_reg_alu0); 8163 %} 8164 8165 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8166 rFlagsReg cr) 8167 %{ 8168 match(Set rdx (ModL rax div)); 8169 effect(KILL rax, KILL cr); 8170 8171 ins_cost(300); // XXX 8172 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8173 "cmpq rax, rdx\n\t" 8174 "jne,s normal\n\t" 8175 "xorl rdx, rdx\n\t" 8176 "cmpq $div, -1\n\t" 8177 "je,s done\n" 8178 "normal: cdqq\n\t" 8179 "idivq $div\n" 8180 "done:" %} 8181 ins_encode(cdqq_enc(div)); 8182 ins_pipe(ialu_reg_reg_alu0); 8183 %} 8184 8185 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8186 %{ 8187 match(Set rdx (UModI rax div)); 8188 effect(KILL rax, KILL cr); 8189 8190 ins_cost(300); 8191 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8192 ins_encode %{ 8193 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8194 %} 8195 ins_pipe(ialu_reg_reg_alu0); 8196 %} 8197 8198 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8199 %{ 8200 match(Set rdx (UModL rax div)); 8201 effect(KILL rax, KILL cr); 8202 8203 ins_cost(300); 8204 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8205 ins_encode %{ 8206 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8207 %} 8208 ins_pipe(ialu_reg_reg_alu0); 8209 %} 8210 8211 // Integer Shift Instructions 8212 // Shift Left by one, two, three 8213 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8214 %{ 8215 match(Set dst (LShiftI dst shift)); 8216 effect(KILL cr); 8217 8218 format %{ "sall $dst, $shift" %} 8219 ins_encode %{ 8220 __ sall($dst$$Register, $shift$$constant); 8221 %} 8222 ins_pipe(ialu_reg); 8223 %} 8224 8225 // Shift Left by 8-bit immediate 8226 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8227 %{ 8228 match(Set dst (LShiftI dst shift)); 8229 effect(KILL cr); 8230 8231 format %{ "sall $dst, $shift" %} 8232 ins_encode %{ 8233 __ sall($dst$$Register, $shift$$constant); 8234 %} 8235 ins_pipe(ialu_reg); 8236 %} 8237 8238 // Shift Left by 8-bit immediate 8239 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8240 %{ 8241 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8242 effect(KILL cr); 8243 8244 format %{ "sall $dst, $shift" %} 8245 ins_encode %{ 8246 __ sall($dst$$Address, $shift$$constant); 8247 %} 8248 ins_pipe(ialu_mem_imm); 8249 %} 8250 8251 // Shift Left by variable 8252 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8253 %{ 8254 predicate(!VM_Version::supports_bmi2()); 8255 match(Set dst (LShiftI dst shift)); 8256 effect(KILL cr); 8257 8258 format %{ "sall $dst, $shift" %} 8259 ins_encode %{ 8260 __ sall($dst$$Register); 8261 %} 8262 ins_pipe(ialu_reg_reg); 8263 %} 8264 8265 // Shift Left by variable 8266 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8267 %{ 8268 predicate(!VM_Version::supports_bmi2()); 8269 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8270 effect(KILL cr); 8271 8272 format %{ "sall $dst, $shift" %} 8273 ins_encode %{ 8274 __ sall($dst$$Address); 8275 %} 8276 ins_pipe(ialu_mem_reg); 8277 %} 8278 8279 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8280 %{ 8281 predicate(VM_Version::supports_bmi2()); 8282 match(Set dst (LShiftI src shift)); 8283 8284 format %{ "shlxl $dst, $src, $shift" %} 8285 ins_encode %{ 8286 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8287 %} 8288 ins_pipe(ialu_reg_reg); 8289 %} 8290 8291 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8292 %{ 8293 predicate(VM_Version::supports_bmi2()); 8294 match(Set dst (LShiftI (LoadI src) shift)); 8295 ins_cost(175); 8296 format %{ "shlxl $dst, $src, $shift" %} 8297 ins_encode %{ 8298 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8299 %} 8300 ins_pipe(ialu_reg_mem); 8301 %} 8302 8303 // Arithmetic Shift Right by 8-bit immediate 8304 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8305 %{ 8306 match(Set dst (RShiftI dst shift)); 8307 effect(KILL cr); 8308 8309 format %{ "sarl $dst, $shift" %} 8310 ins_encode %{ 8311 __ sarl($dst$$Register, $shift$$constant); 8312 %} 8313 ins_pipe(ialu_mem_imm); 8314 %} 8315 8316 // Arithmetic Shift Right by 8-bit immediate 8317 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8318 %{ 8319 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8320 effect(KILL cr); 8321 8322 format %{ "sarl $dst, $shift" %} 8323 ins_encode %{ 8324 __ sarl($dst$$Address, $shift$$constant); 8325 %} 8326 ins_pipe(ialu_mem_imm); 8327 %} 8328 8329 // Arithmetic Shift Right by variable 8330 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8331 %{ 8332 predicate(!VM_Version::supports_bmi2()); 8333 match(Set dst (RShiftI dst shift)); 8334 effect(KILL cr); 8335 8336 format %{ "sarl $dst, $shift" %} 8337 ins_encode %{ 8338 __ sarl($dst$$Register); 8339 %} 8340 ins_pipe(ialu_reg_reg); 8341 %} 8342 8343 // Arithmetic Shift Right by variable 8344 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8345 %{ 8346 predicate(!VM_Version::supports_bmi2()); 8347 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8348 effect(KILL cr); 8349 8350 format %{ "sarl $dst, $shift" %} 8351 ins_encode %{ 8352 __ sarl($dst$$Address); 8353 %} 8354 ins_pipe(ialu_mem_reg); 8355 %} 8356 8357 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8358 %{ 8359 predicate(VM_Version::supports_bmi2()); 8360 match(Set dst (RShiftI src shift)); 8361 8362 format %{ "sarxl $dst, $src, $shift" %} 8363 ins_encode %{ 8364 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8365 %} 8366 ins_pipe(ialu_reg_reg); 8367 %} 8368 8369 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8370 %{ 8371 predicate(VM_Version::supports_bmi2()); 8372 match(Set dst (RShiftI (LoadI src) shift)); 8373 ins_cost(175); 8374 format %{ "sarxl $dst, $src, $shift" %} 8375 ins_encode %{ 8376 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8377 %} 8378 ins_pipe(ialu_reg_mem); 8379 %} 8380 8381 // Logical Shift Right by 8-bit immediate 8382 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8383 %{ 8384 match(Set dst (URShiftI dst shift)); 8385 effect(KILL cr); 8386 8387 format %{ "shrl $dst, $shift" %} 8388 ins_encode %{ 8389 __ shrl($dst$$Register, $shift$$constant); 8390 %} 8391 ins_pipe(ialu_reg); 8392 %} 8393 8394 // Logical Shift Right by 8-bit immediate 8395 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8396 %{ 8397 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8398 effect(KILL cr); 8399 8400 format %{ "shrl $dst, $shift" %} 8401 ins_encode %{ 8402 __ shrl($dst$$Address, $shift$$constant); 8403 %} 8404 ins_pipe(ialu_mem_imm); 8405 %} 8406 8407 // Logical Shift Right by variable 8408 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8409 %{ 8410 predicate(!VM_Version::supports_bmi2()); 8411 match(Set dst (URShiftI dst shift)); 8412 effect(KILL cr); 8413 8414 format %{ "shrl $dst, $shift" %} 8415 ins_encode %{ 8416 __ shrl($dst$$Register); 8417 %} 8418 ins_pipe(ialu_reg_reg); 8419 %} 8420 8421 // Logical Shift Right by variable 8422 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8423 %{ 8424 predicate(!VM_Version::supports_bmi2()); 8425 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8426 effect(KILL cr); 8427 8428 format %{ "shrl $dst, $shift" %} 8429 ins_encode %{ 8430 __ shrl($dst$$Address); 8431 %} 8432 ins_pipe(ialu_mem_reg); 8433 %} 8434 8435 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8436 %{ 8437 predicate(VM_Version::supports_bmi2()); 8438 match(Set dst (URShiftI src shift)); 8439 8440 format %{ "shrxl $dst, $src, $shift" %} 8441 ins_encode %{ 8442 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8443 %} 8444 ins_pipe(ialu_reg_reg); 8445 %} 8446 8447 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8448 %{ 8449 predicate(VM_Version::supports_bmi2()); 8450 match(Set dst (URShiftI (LoadI src) shift)); 8451 ins_cost(175); 8452 format %{ "shrxl $dst, $src, $shift" %} 8453 ins_encode %{ 8454 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8455 %} 8456 ins_pipe(ialu_reg_mem); 8457 %} 8458 8459 // Long Shift Instructions 8460 // Shift Left by one, two, three 8461 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8462 %{ 8463 match(Set dst (LShiftL dst shift)); 8464 effect(KILL cr); 8465 8466 format %{ "salq $dst, $shift" %} 8467 ins_encode %{ 8468 __ salq($dst$$Register, $shift$$constant); 8469 %} 8470 ins_pipe(ialu_reg); 8471 %} 8472 8473 // Shift Left by 8-bit immediate 8474 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8475 %{ 8476 match(Set dst (LShiftL dst shift)); 8477 effect(KILL cr); 8478 8479 format %{ "salq $dst, $shift" %} 8480 ins_encode %{ 8481 __ salq($dst$$Register, $shift$$constant); 8482 %} 8483 ins_pipe(ialu_reg); 8484 %} 8485 8486 // Shift Left by 8-bit immediate 8487 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8488 %{ 8489 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8490 effect(KILL cr); 8491 8492 format %{ "salq $dst, $shift" %} 8493 ins_encode %{ 8494 __ salq($dst$$Address, $shift$$constant); 8495 %} 8496 ins_pipe(ialu_mem_imm); 8497 %} 8498 8499 // Shift Left by variable 8500 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8501 %{ 8502 predicate(!VM_Version::supports_bmi2()); 8503 match(Set dst (LShiftL dst shift)); 8504 effect(KILL cr); 8505 8506 format %{ "salq $dst, $shift" %} 8507 ins_encode %{ 8508 __ salq($dst$$Register); 8509 %} 8510 ins_pipe(ialu_reg_reg); 8511 %} 8512 8513 // Shift Left by variable 8514 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8515 %{ 8516 predicate(!VM_Version::supports_bmi2()); 8517 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8518 effect(KILL cr); 8519 8520 format %{ "salq $dst, $shift" %} 8521 ins_encode %{ 8522 __ salq($dst$$Address); 8523 %} 8524 ins_pipe(ialu_mem_reg); 8525 %} 8526 8527 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8528 %{ 8529 predicate(VM_Version::supports_bmi2()); 8530 match(Set dst (LShiftL src shift)); 8531 8532 format %{ "shlxq $dst, $src, $shift" %} 8533 ins_encode %{ 8534 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8535 %} 8536 ins_pipe(ialu_reg_reg); 8537 %} 8538 8539 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8540 %{ 8541 predicate(VM_Version::supports_bmi2()); 8542 match(Set dst (LShiftL (LoadL src) shift)); 8543 ins_cost(175); 8544 format %{ "shlxq $dst, $src, $shift" %} 8545 ins_encode %{ 8546 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8547 %} 8548 ins_pipe(ialu_reg_mem); 8549 %} 8550 8551 // Arithmetic Shift Right by 8-bit immediate 8552 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8553 %{ 8554 match(Set dst (RShiftL dst shift)); 8555 effect(KILL cr); 8556 8557 format %{ "sarq $dst, $shift" %} 8558 ins_encode %{ 8559 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8560 %} 8561 ins_pipe(ialu_mem_imm); 8562 %} 8563 8564 // Arithmetic Shift Right by 8-bit immediate 8565 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8566 %{ 8567 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8568 effect(KILL cr); 8569 8570 format %{ "sarq $dst, $shift" %} 8571 ins_encode %{ 8572 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8573 %} 8574 ins_pipe(ialu_mem_imm); 8575 %} 8576 8577 // Arithmetic Shift Right by variable 8578 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8579 %{ 8580 predicate(!VM_Version::supports_bmi2()); 8581 match(Set dst (RShiftL dst shift)); 8582 effect(KILL cr); 8583 8584 format %{ "sarq $dst, $shift" %} 8585 ins_encode %{ 8586 __ sarq($dst$$Register); 8587 %} 8588 ins_pipe(ialu_reg_reg); 8589 %} 8590 8591 // Arithmetic Shift Right by variable 8592 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8593 %{ 8594 predicate(!VM_Version::supports_bmi2()); 8595 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8596 effect(KILL cr); 8597 8598 format %{ "sarq $dst, $shift" %} 8599 ins_encode %{ 8600 __ sarq($dst$$Address); 8601 %} 8602 ins_pipe(ialu_mem_reg); 8603 %} 8604 8605 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8606 %{ 8607 predicate(VM_Version::supports_bmi2()); 8608 match(Set dst (RShiftL src shift)); 8609 8610 format %{ "sarxq $dst, $src, $shift" %} 8611 ins_encode %{ 8612 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8613 %} 8614 ins_pipe(ialu_reg_reg); 8615 %} 8616 8617 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8618 %{ 8619 predicate(VM_Version::supports_bmi2()); 8620 match(Set dst (RShiftL (LoadL src) shift)); 8621 ins_cost(175); 8622 format %{ "sarxq $dst, $src, $shift" %} 8623 ins_encode %{ 8624 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8625 %} 8626 ins_pipe(ialu_reg_mem); 8627 %} 8628 8629 // Logical Shift Right by 8-bit immediate 8630 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8631 %{ 8632 match(Set dst (URShiftL dst shift)); 8633 effect(KILL cr); 8634 8635 format %{ "shrq $dst, $shift" %} 8636 ins_encode %{ 8637 __ shrq($dst$$Register, $shift$$constant); 8638 %} 8639 ins_pipe(ialu_reg); 8640 %} 8641 8642 // Logical Shift Right by 8-bit immediate 8643 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8644 %{ 8645 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8646 effect(KILL cr); 8647 8648 format %{ "shrq $dst, $shift" %} 8649 ins_encode %{ 8650 __ shrq($dst$$Address, $shift$$constant); 8651 %} 8652 ins_pipe(ialu_mem_imm); 8653 %} 8654 8655 // Logical Shift Right by variable 8656 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8657 %{ 8658 predicate(!VM_Version::supports_bmi2()); 8659 match(Set dst (URShiftL dst shift)); 8660 effect(KILL cr); 8661 8662 format %{ "shrq $dst, $shift" %} 8663 ins_encode %{ 8664 __ shrq($dst$$Register); 8665 %} 8666 ins_pipe(ialu_reg_reg); 8667 %} 8668 8669 // Logical Shift Right by variable 8670 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8671 %{ 8672 predicate(!VM_Version::supports_bmi2()); 8673 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8674 effect(KILL cr); 8675 8676 format %{ "shrq $dst, $shift" %} 8677 ins_encode %{ 8678 __ shrq($dst$$Address); 8679 %} 8680 ins_pipe(ialu_mem_reg); 8681 %} 8682 8683 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8684 %{ 8685 predicate(VM_Version::supports_bmi2()); 8686 match(Set dst (URShiftL src shift)); 8687 8688 format %{ "shrxq $dst, $src, $shift" %} 8689 ins_encode %{ 8690 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8691 %} 8692 ins_pipe(ialu_reg_reg); 8693 %} 8694 8695 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8696 %{ 8697 predicate(VM_Version::supports_bmi2()); 8698 match(Set dst (URShiftL (LoadL src) shift)); 8699 ins_cost(175); 8700 format %{ "shrxq $dst, $src, $shift" %} 8701 ins_encode %{ 8702 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8703 %} 8704 ins_pipe(ialu_reg_mem); 8705 %} 8706 8707 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8708 // This idiom is used by the compiler for the i2b bytecode. 8709 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8710 %{ 8711 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8712 8713 format %{ "movsbl $dst, $src\t# i2b" %} 8714 ins_encode %{ 8715 __ movsbl($dst$$Register, $src$$Register); 8716 %} 8717 ins_pipe(ialu_reg_reg); 8718 %} 8719 8720 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8721 // This idiom is used by the compiler the i2s bytecode. 8722 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8723 %{ 8724 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8725 8726 format %{ "movswl $dst, $src\t# i2s" %} 8727 ins_encode %{ 8728 __ movswl($dst$$Register, $src$$Register); 8729 %} 8730 ins_pipe(ialu_reg_reg); 8731 %} 8732 8733 // ROL/ROR instructions 8734 8735 // Rotate left by constant. 8736 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8737 %{ 8738 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8739 match(Set dst (RotateLeft dst shift)); 8740 effect(KILL cr); 8741 format %{ "roll $dst, $shift" %} 8742 ins_encode %{ 8743 __ roll($dst$$Register, $shift$$constant); 8744 %} 8745 ins_pipe(ialu_reg); 8746 %} 8747 8748 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8749 %{ 8750 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8751 match(Set dst (RotateLeft src shift)); 8752 format %{ "rolxl $dst, $src, $shift" %} 8753 ins_encode %{ 8754 int shift = 32 - ($shift$$constant & 31); 8755 __ rorxl($dst$$Register, $src$$Register, shift); 8756 %} 8757 ins_pipe(ialu_reg_reg); 8758 %} 8759 8760 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8761 %{ 8762 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8763 match(Set dst (RotateLeft (LoadI src) shift)); 8764 ins_cost(175); 8765 format %{ "rolxl $dst, $src, $shift" %} 8766 ins_encode %{ 8767 int shift = 32 - ($shift$$constant & 31); 8768 __ rorxl($dst$$Register, $src$$Address, shift); 8769 %} 8770 ins_pipe(ialu_reg_mem); 8771 %} 8772 8773 // Rotate Left by variable 8774 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8775 %{ 8776 predicate(n->bottom_type()->basic_type() == T_INT); 8777 match(Set dst (RotateLeft dst shift)); 8778 effect(KILL cr); 8779 format %{ "roll $dst, $shift" %} 8780 ins_encode %{ 8781 __ roll($dst$$Register); 8782 %} 8783 ins_pipe(ialu_reg_reg); 8784 %} 8785 8786 // Rotate Right by constant. 8787 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8788 %{ 8789 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8790 match(Set dst (RotateRight dst shift)); 8791 effect(KILL cr); 8792 format %{ "rorl $dst, $shift" %} 8793 ins_encode %{ 8794 __ rorl($dst$$Register, $shift$$constant); 8795 %} 8796 ins_pipe(ialu_reg); 8797 %} 8798 8799 // Rotate Right by constant. 8800 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8801 %{ 8802 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8803 match(Set dst (RotateRight src shift)); 8804 format %{ "rorxl $dst, $src, $shift" %} 8805 ins_encode %{ 8806 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8807 %} 8808 ins_pipe(ialu_reg_reg); 8809 %} 8810 8811 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8812 %{ 8813 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8814 match(Set dst (RotateRight (LoadI src) shift)); 8815 ins_cost(175); 8816 format %{ "rorxl $dst, $src, $shift" %} 8817 ins_encode %{ 8818 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8819 %} 8820 ins_pipe(ialu_reg_mem); 8821 %} 8822 8823 // Rotate Right by variable 8824 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8825 %{ 8826 predicate(n->bottom_type()->basic_type() == T_INT); 8827 match(Set dst (RotateRight dst shift)); 8828 effect(KILL cr); 8829 format %{ "rorl $dst, $shift" %} 8830 ins_encode %{ 8831 __ rorl($dst$$Register); 8832 %} 8833 ins_pipe(ialu_reg_reg); 8834 %} 8835 8836 // Rotate Left by constant. 8837 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8838 %{ 8839 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8840 match(Set dst (RotateLeft dst shift)); 8841 effect(KILL cr); 8842 format %{ "rolq $dst, $shift" %} 8843 ins_encode %{ 8844 __ rolq($dst$$Register, $shift$$constant); 8845 %} 8846 ins_pipe(ialu_reg); 8847 %} 8848 8849 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8850 %{ 8851 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8852 match(Set dst (RotateLeft src shift)); 8853 format %{ "rolxq $dst, $src, $shift" %} 8854 ins_encode %{ 8855 int shift = 64 - ($shift$$constant & 63); 8856 __ rorxq($dst$$Register, $src$$Register, shift); 8857 %} 8858 ins_pipe(ialu_reg_reg); 8859 %} 8860 8861 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8862 %{ 8863 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8864 match(Set dst (RotateLeft (LoadL src) shift)); 8865 ins_cost(175); 8866 format %{ "rolxq $dst, $src, $shift" %} 8867 ins_encode %{ 8868 int shift = 64 - ($shift$$constant & 63); 8869 __ rorxq($dst$$Register, $src$$Address, shift); 8870 %} 8871 ins_pipe(ialu_reg_mem); 8872 %} 8873 8874 // Rotate Left by variable 8875 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8876 %{ 8877 predicate(n->bottom_type()->basic_type() == T_LONG); 8878 match(Set dst (RotateLeft dst shift)); 8879 effect(KILL cr); 8880 format %{ "rolq $dst, $shift" %} 8881 ins_encode %{ 8882 __ rolq($dst$$Register); 8883 %} 8884 ins_pipe(ialu_reg_reg); 8885 %} 8886 8887 // Rotate Right by constant. 8888 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8889 %{ 8890 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8891 match(Set dst (RotateRight dst shift)); 8892 effect(KILL cr); 8893 format %{ "rorq $dst, $shift" %} 8894 ins_encode %{ 8895 __ rorq($dst$$Register, $shift$$constant); 8896 %} 8897 ins_pipe(ialu_reg); 8898 %} 8899 8900 // Rotate Right by constant 8901 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8902 %{ 8903 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8904 match(Set dst (RotateRight src shift)); 8905 format %{ "rorxq $dst, $src, $shift" %} 8906 ins_encode %{ 8907 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8908 %} 8909 ins_pipe(ialu_reg_reg); 8910 %} 8911 8912 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8913 %{ 8914 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8915 match(Set dst (RotateRight (LoadL src) shift)); 8916 ins_cost(175); 8917 format %{ "rorxq $dst, $src, $shift" %} 8918 ins_encode %{ 8919 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8920 %} 8921 ins_pipe(ialu_reg_mem); 8922 %} 8923 8924 // Rotate Right by variable 8925 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8926 %{ 8927 predicate(n->bottom_type()->basic_type() == T_LONG); 8928 match(Set dst (RotateRight dst shift)); 8929 effect(KILL cr); 8930 format %{ "rorq $dst, $shift" %} 8931 ins_encode %{ 8932 __ rorq($dst$$Register); 8933 %} 8934 ins_pipe(ialu_reg_reg); 8935 %} 8936 8937 //----------------------------- CompressBits/ExpandBits ------------------------ 8938 8939 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8940 predicate(n->bottom_type()->isa_long()); 8941 match(Set dst (CompressBits src mask)); 8942 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8943 ins_encode %{ 8944 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8945 %} 8946 ins_pipe( pipe_slow ); 8947 %} 8948 8949 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8950 predicate(n->bottom_type()->isa_long()); 8951 match(Set dst (ExpandBits src mask)); 8952 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8953 ins_encode %{ 8954 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8955 %} 8956 ins_pipe( pipe_slow ); 8957 %} 8958 8959 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8960 predicate(n->bottom_type()->isa_long()); 8961 match(Set dst (CompressBits src (LoadL mask))); 8962 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8963 ins_encode %{ 8964 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8965 %} 8966 ins_pipe( pipe_slow ); 8967 %} 8968 8969 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8970 predicate(n->bottom_type()->isa_long()); 8971 match(Set dst (ExpandBits src (LoadL mask))); 8972 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8973 ins_encode %{ 8974 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8975 %} 8976 ins_pipe( pipe_slow ); 8977 %} 8978 8979 8980 // Logical Instructions 8981 8982 // Integer Logical Instructions 8983 8984 // And Instructions 8985 // And Register with Register 8986 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8987 %{ 8988 match(Set dst (AndI dst src)); 8989 effect(KILL cr); 8990 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8991 8992 format %{ "andl $dst, $src\t# int" %} 8993 ins_encode %{ 8994 __ andl($dst$$Register, $src$$Register); 8995 %} 8996 ins_pipe(ialu_reg_reg); 8997 %} 8998 8999 // And Register with Immediate 255 9000 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 9001 %{ 9002 match(Set dst (AndI src mask)); 9003 9004 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 9005 ins_encode %{ 9006 __ movzbl($dst$$Register, $src$$Register); 9007 %} 9008 ins_pipe(ialu_reg); 9009 %} 9010 9011 // And Register with Immediate 255 and promote to long 9012 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9013 %{ 9014 match(Set dst (ConvI2L (AndI src mask))); 9015 9016 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9017 ins_encode %{ 9018 __ movzbl($dst$$Register, $src$$Register); 9019 %} 9020 ins_pipe(ialu_reg); 9021 %} 9022 9023 // And Register with Immediate 65535 9024 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 9025 %{ 9026 match(Set dst (AndI src mask)); 9027 9028 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 9029 ins_encode %{ 9030 __ movzwl($dst$$Register, $src$$Register); 9031 %} 9032 ins_pipe(ialu_reg); 9033 %} 9034 9035 // And Register with Immediate 65535 and promote to long 9036 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9037 %{ 9038 match(Set dst (ConvI2L (AndI src mask))); 9039 9040 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9041 ins_encode %{ 9042 __ movzwl($dst$$Register, $src$$Register); 9043 %} 9044 ins_pipe(ialu_reg); 9045 %} 9046 9047 // Can skip int2long conversions after AND with small bitmask 9048 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 9049 %{ 9050 predicate(VM_Version::supports_bmi2()); 9051 ins_cost(125); 9052 effect(TEMP tmp, KILL cr); 9053 match(Set dst (ConvI2L (AndI src mask))); 9054 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 9055 ins_encode %{ 9056 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 9057 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 9058 %} 9059 ins_pipe(ialu_reg_reg); 9060 %} 9061 9062 // And Register with Immediate 9063 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9064 %{ 9065 match(Set dst (AndI dst src)); 9066 effect(KILL cr); 9067 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9068 9069 format %{ "andl $dst, $src\t# int" %} 9070 ins_encode %{ 9071 __ andl($dst$$Register, $src$$constant); 9072 %} 9073 ins_pipe(ialu_reg); 9074 %} 9075 9076 // And Register with Memory 9077 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9078 %{ 9079 match(Set dst (AndI dst (LoadI src))); 9080 effect(KILL cr); 9081 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9082 9083 ins_cost(150); 9084 format %{ "andl $dst, $src\t# int" %} 9085 ins_encode %{ 9086 __ andl($dst$$Register, $src$$Address); 9087 %} 9088 ins_pipe(ialu_reg_mem); 9089 %} 9090 9091 // And Memory with Register 9092 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9093 %{ 9094 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9095 effect(KILL cr); 9096 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9097 9098 ins_cost(150); 9099 format %{ "andb $dst, $src\t# byte" %} 9100 ins_encode %{ 9101 __ andb($dst$$Address, $src$$Register); 9102 %} 9103 ins_pipe(ialu_mem_reg); 9104 %} 9105 9106 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9107 %{ 9108 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9109 effect(KILL cr); 9110 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9111 9112 ins_cost(150); 9113 format %{ "andl $dst, $src\t# int" %} 9114 ins_encode %{ 9115 __ andl($dst$$Address, $src$$Register); 9116 %} 9117 ins_pipe(ialu_mem_reg); 9118 %} 9119 9120 // And Memory with Immediate 9121 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9122 %{ 9123 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9124 effect(KILL cr); 9125 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9126 9127 ins_cost(125); 9128 format %{ "andl $dst, $src\t# int" %} 9129 ins_encode %{ 9130 __ andl($dst$$Address, $src$$constant); 9131 %} 9132 ins_pipe(ialu_mem_imm); 9133 %} 9134 9135 // BMI1 instructions 9136 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9137 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9138 predicate(UseBMI1Instructions); 9139 effect(KILL cr); 9140 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9141 9142 ins_cost(125); 9143 format %{ "andnl $dst, $src1, $src2" %} 9144 9145 ins_encode %{ 9146 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9147 %} 9148 ins_pipe(ialu_reg_mem); 9149 %} 9150 9151 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9152 match(Set dst (AndI (XorI src1 minus_1) src2)); 9153 predicate(UseBMI1Instructions); 9154 effect(KILL cr); 9155 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9156 9157 format %{ "andnl $dst, $src1, $src2" %} 9158 9159 ins_encode %{ 9160 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9161 %} 9162 ins_pipe(ialu_reg); 9163 %} 9164 9165 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 9166 match(Set dst (AndI (SubI imm_zero src) src)); 9167 predicate(UseBMI1Instructions); 9168 effect(KILL cr); 9169 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9170 9171 format %{ "blsil $dst, $src" %} 9172 9173 ins_encode %{ 9174 __ blsil($dst$$Register, $src$$Register); 9175 %} 9176 ins_pipe(ialu_reg); 9177 %} 9178 9179 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 9180 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9181 predicate(UseBMI1Instructions); 9182 effect(KILL cr); 9183 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9184 9185 ins_cost(125); 9186 format %{ "blsil $dst, $src" %} 9187 9188 ins_encode %{ 9189 __ blsil($dst$$Register, $src$$Address); 9190 %} 9191 ins_pipe(ialu_reg_mem); 9192 %} 9193 9194 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9195 %{ 9196 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9197 predicate(UseBMI1Instructions); 9198 effect(KILL cr); 9199 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9200 9201 ins_cost(125); 9202 format %{ "blsmskl $dst, $src" %} 9203 9204 ins_encode %{ 9205 __ blsmskl($dst$$Register, $src$$Address); 9206 %} 9207 ins_pipe(ialu_reg_mem); 9208 %} 9209 9210 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9211 %{ 9212 match(Set dst (XorI (AddI src minus_1) src)); 9213 predicate(UseBMI1Instructions); 9214 effect(KILL cr); 9215 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9216 9217 format %{ "blsmskl $dst, $src" %} 9218 9219 ins_encode %{ 9220 __ blsmskl($dst$$Register, $src$$Register); 9221 %} 9222 9223 ins_pipe(ialu_reg); 9224 %} 9225 9226 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9227 %{ 9228 match(Set dst (AndI (AddI src minus_1) src) ); 9229 predicate(UseBMI1Instructions); 9230 effect(KILL cr); 9231 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9232 9233 format %{ "blsrl $dst, $src" %} 9234 9235 ins_encode %{ 9236 __ blsrl($dst$$Register, $src$$Register); 9237 %} 9238 9239 ins_pipe(ialu_reg_mem); 9240 %} 9241 9242 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9243 %{ 9244 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9245 predicate(UseBMI1Instructions); 9246 effect(KILL cr); 9247 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9248 9249 ins_cost(125); 9250 format %{ "blsrl $dst, $src" %} 9251 9252 ins_encode %{ 9253 __ blsrl($dst$$Register, $src$$Address); 9254 %} 9255 9256 ins_pipe(ialu_reg); 9257 %} 9258 9259 // Or Instructions 9260 // Or Register with Register 9261 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9262 %{ 9263 match(Set dst (OrI dst src)); 9264 effect(KILL cr); 9265 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9266 9267 format %{ "orl $dst, $src\t# int" %} 9268 ins_encode %{ 9269 __ orl($dst$$Register, $src$$Register); 9270 %} 9271 ins_pipe(ialu_reg_reg); 9272 %} 9273 9274 // Or Register with Immediate 9275 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9276 %{ 9277 match(Set dst (OrI dst src)); 9278 effect(KILL cr); 9279 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9280 9281 format %{ "orl $dst, $src\t# int" %} 9282 ins_encode %{ 9283 __ orl($dst$$Register, $src$$constant); 9284 %} 9285 ins_pipe(ialu_reg); 9286 %} 9287 9288 // Or Register with Memory 9289 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9290 %{ 9291 match(Set dst (OrI dst (LoadI src))); 9292 effect(KILL cr); 9293 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9294 9295 ins_cost(150); 9296 format %{ "orl $dst, $src\t# int" %} 9297 ins_encode %{ 9298 __ orl($dst$$Register, $src$$Address); 9299 %} 9300 ins_pipe(ialu_reg_mem); 9301 %} 9302 9303 // Or Memory with Register 9304 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9305 %{ 9306 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9307 effect(KILL cr); 9308 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9309 9310 ins_cost(150); 9311 format %{ "orb $dst, $src\t# byte" %} 9312 ins_encode %{ 9313 __ orb($dst$$Address, $src$$Register); 9314 %} 9315 ins_pipe(ialu_mem_reg); 9316 %} 9317 9318 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9319 %{ 9320 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9321 effect(KILL cr); 9322 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9323 9324 ins_cost(150); 9325 format %{ "orl $dst, $src\t# int" %} 9326 ins_encode %{ 9327 __ orl($dst$$Address, $src$$Register); 9328 %} 9329 ins_pipe(ialu_mem_reg); 9330 %} 9331 9332 // Or Memory with Immediate 9333 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9334 %{ 9335 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9336 effect(KILL cr); 9337 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9338 9339 ins_cost(125); 9340 format %{ "orl $dst, $src\t# int" %} 9341 ins_encode %{ 9342 __ orl($dst$$Address, $src$$constant); 9343 %} 9344 ins_pipe(ialu_mem_imm); 9345 %} 9346 9347 // Xor Instructions 9348 // Xor Register with Register 9349 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9350 %{ 9351 match(Set dst (XorI dst src)); 9352 effect(KILL cr); 9353 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9354 9355 format %{ "xorl $dst, $src\t# int" %} 9356 ins_encode %{ 9357 __ xorl($dst$$Register, $src$$Register); 9358 %} 9359 ins_pipe(ialu_reg_reg); 9360 %} 9361 9362 // Xor Register with Immediate -1 9363 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9364 match(Set dst (XorI dst imm)); 9365 9366 format %{ "not $dst" %} 9367 ins_encode %{ 9368 __ notl($dst$$Register); 9369 %} 9370 ins_pipe(ialu_reg); 9371 %} 9372 9373 // Xor Register with Immediate 9374 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9375 %{ 9376 match(Set dst (XorI dst src)); 9377 effect(KILL cr); 9378 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9379 9380 format %{ "xorl $dst, $src\t# int" %} 9381 ins_encode %{ 9382 __ xorl($dst$$Register, $src$$constant); 9383 %} 9384 ins_pipe(ialu_reg); 9385 %} 9386 9387 // Xor Register with Memory 9388 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9389 %{ 9390 match(Set dst (XorI dst (LoadI src))); 9391 effect(KILL cr); 9392 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9393 9394 ins_cost(150); 9395 format %{ "xorl $dst, $src\t# int" %} 9396 ins_encode %{ 9397 __ xorl($dst$$Register, $src$$Address); 9398 %} 9399 ins_pipe(ialu_reg_mem); 9400 %} 9401 9402 // Xor Memory with Register 9403 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9404 %{ 9405 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9406 effect(KILL cr); 9407 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9408 9409 ins_cost(150); 9410 format %{ "xorb $dst, $src\t# byte" %} 9411 ins_encode %{ 9412 __ xorb($dst$$Address, $src$$Register); 9413 %} 9414 ins_pipe(ialu_mem_reg); 9415 %} 9416 9417 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9418 %{ 9419 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9420 effect(KILL cr); 9421 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9422 9423 ins_cost(150); 9424 format %{ "xorl $dst, $src\t# int" %} 9425 ins_encode %{ 9426 __ xorl($dst$$Address, $src$$Register); 9427 %} 9428 ins_pipe(ialu_mem_reg); 9429 %} 9430 9431 // Xor Memory with Immediate 9432 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9433 %{ 9434 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9435 effect(KILL cr); 9436 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9437 9438 ins_cost(125); 9439 format %{ "xorl $dst, $src\t# int" %} 9440 ins_encode %{ 9441 __ xorl($dst$$Address, $src$$constant); 9442 %} 9443 ins_pipe(ialu_mem_imm); 9444 %} 9445 9446 9447 // Long Logical Instructions 9448 9449 // And Instructions 9450 // And Register with Register 9451 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9452 %{ 9453 match(Set dst (AndL dst src)); 9454 effect(KILL cr); 9455 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9456 9457 format %{ "andq $dst, $src\t# long" %} 9458 ins_encode %{ 9459 __ andq($dst$$Register, $src$$Register); 9460 %} 9461 ins_pipe(ialu_reg_reg); 9462 %} 9463 9464 // And Register with Immediate 255 9465 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9466 %{ 9467 match(Set dst (AndL src mask)); 9468 9469 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9470 ins_encode %{ 9471 // movzbl zeroes out the upper 32-bit and does not need REX.W 9472 __ movzbl($dst$$Register, $src$$Register); 9473 %} 9474 ins_pipe(ialu_reg); 9475 %} 9476 9477 // And Register with Immediate 65535 9478 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9479 %{ 9480 match(Set dst (AndL src mask)); 9481 9482 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9483 ins_encode %{ 9484 // movzwl zeroes out the upper 32-bit and does not need REX.W 9485 __ movzwl($dst$$Register, $src$$Register); 9486 %} 9487 ins_pipe(ialu_reg); 9488 %} 9489 9490 // And Register with Immediate 9491 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9492 %{ 9493 match(Set dst (AndL dst src)); 9494 effect(KILL cr); 9495 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9496 9497 format %{ "andq $dst, $src\t# long" %} 9498 ins_encode %{ 9499 __ andq($dst$$Register, $src$$constant); 9500 %} 9501 ins_pipe(ialu_reg); 9502 %} 9503 9504 // And Register with Memory 9505 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9506 %{ 9507 match(Set dst (AndL dst (LoadL src))); 9508 effect(KILL cr); 9509 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9510 9511 ins_cost(150); 9512 format %{ "andq $dst, $src\t# long" %} 9513 ins_encode %{ 9514 __ andq($dst$$Register, $src$$Address); 9515 %} 9516 ins_pipe(ialu_reg_mem); 9517 %} 9518 9519 // And Memory with Register 9520 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9521 %{ 9522 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9523 effect(KILL cr); 9524 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9525 9526 ins_cost(150); 9527 format %{ "andq $dst, $src\t# long" %} 9528 ins_encode %{ 9529 __ andq($dst$$Address, $src$$Register); 9530 %} 9531 ins_pipe(ialu_mem_reg); 9532 %} 9533 9534 // And Memory with Immediate 9535 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9536 %{ 9537 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9538 effect(KILL cr); 9539 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9540 9541 ins_cost(125); 9542 format %{ "andq $dst, $src\t# long" %} 9543 ins_encode %{ 9544 __ andq($dst$$Address, $src$$constant); 9545 %} 9546 ins_pipe(ialu_mem_imm); 9547 %} 9548 9549 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9550 %{ 9551 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9552 // because AND/OR works well enough for 8/32-bit values. 9553 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9554 9555 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9556 effect(KILL cr); 9557 9558 ins_cost(125); 9559 format %{ "btrq $dst, log2(not($con))\t# long" %} 9560 ins_encode %{ 9561 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9562 %} 9563 ins_pipe(ialu_mem_imm); 9564 %} 9565 9566 // BMI1 instructions 9567 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9568 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9569 predicate(UseBMI1Instructions); 9570 effect(KILL cr); 9571 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9572 9573 ins_cost(125); 9574 format %{ "andnq $dst, $src1, $src2" %} 9575 9576 ins_encode %{ 9577 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9578 %} 9579 ins_pipe(ialu_reg_mem); 9580 %} 9581 9582 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9583 match(Set dst (AndL (XorL src1 minus_1) src2)); 9584 predicate(UseBMI1Instructions); 9585 effect(KILL cr); 9586 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9587 9588 format %{ "andnq $dst, $src1, $src2" %} 9589 9590 ins_encode %{ 9591 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9592 %} 9593 ins_pipe(ialu_reg_mem); 9594 %} 9595 9596 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9597 match(Set dst (AndL (SubL imm_zero src) src)); 9598 predicate(UseBMI1Instructions); 9599 effect(KILL cr); 9600 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9601 9602 format %{ "blsiq $dst, $src" %} 9603 9604 ins_encode %{ 9605 __ blsiq($dst$$Register, $src$$Register); 9606 %} 9607 ins_pipe(ialu_reg); 9608 %} 9609 9610 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9611 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9612 predicate(UseBMI1Instructions); 9613 effect(KILL cr); 9614 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9615 9616 ins_cost(125); 9617 format %{ "blsiq $dst, $src" %} 9618 9619 ins_encode %{ 9620 __ blsiq($dst$$Register, $src$$Address); 9621 %} 9622 ins_pipe(ialu_reg_mem); 9623 %} 9624 9625 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9626 %{ 9627 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9628 predicate(UseBMI1Instructions); 9629 effect(KILL cr); 9630 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9631 9632 ins_cost(125); 9633 format %{ "blsmskq $dst, $src" %} 9634 9635 ins_encode %{ 9636 __ blsmskq($dst$$Register, $src$$Address); 9637 %} 9638 ins_pipe(ialu_reg_mem); 9639 %} 9640 9641 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9642 %{ 9643 match(Set dst (XorL (AddL src minus_1) src)); 9644 predicate(UseBMI1Instructions); 9645 effect(KILL cr); 9646 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9647 9648 format %{ "blsmskq $dst, $src" %} 9649 9650 ins_encode %{ 9651 __ blsmskq($dst$$Register, $src$$Register); 9652 %} 9653 9654 ins_pipe(ialu_reg); 9655 %} 9656 9657 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9658 %{ 9659 match(Set dst (AndL (AddL src minus_1) src) ); 9660 predicate(UseBMI1Instructions); 9661 effect(KILL cr); 9662 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9663 9664 format %{ "blsrq $dst, $src" %} 9665 9666 ins_encode %{ 9667 __ blsrq($dst$$Register, $src$$Register); 9668 %} 9669 9670 ins_pipe(ialu_reg); 9671 %} 9672 9673 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9674 %{ 9675 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9676 predicate(UseBMI1Instructions); 9677 effect(KILL cr); 9678 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9679 9680 ins_cost(125); 9681 format %{ "blsrq $dst, $src" %} 9682 9683 ins_encode %{ 9684 __ blsrq($dst$$Register, $src$$Address); 9685 %} 9686 9687 ins_pipe(ialu_reg); 9688 %} 9689 9690 // Or Instructions 9691 // Or Register with Register 9692 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9693 %{ 9694 match(Set dst (OrL dst src)); 9695 effect(KILL cr); 9696 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9697 9698 format %{ "orq $dst, $src\t# long" %} 9699 ins_encode %{ 9700 __ orq($dst$$Register, $src$$Register); 9701 %} 9702 ins_pipe(ialu_reg_reg); 9703 %} 9704 9705 // Use any_RegP to match R15 (TLS register) without spilling. 9706 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9707 match(Set dst (OrL dst (CastP2X src))); 9708 effect(KILL cr); 9709 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9710 9711 format %{ "orq $dst, $src\t# long" %} 9712 ins_encode %{ 9713 __ orq($dst$$Register, $src$$Register); 9714 %} 9715 ins_pipe(ialu_reg_reg); 9716 %} 9717 9718 9719 // Or Register with Immediate 9720 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9721 %{ 9722 match(Set dst (OrL dst src)); 9723 effect(KILL cr); 9724 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9725 9726 format %{ "orq $dst, $src\t# long" %} 9727 ins_encode %{ 9728 __ orq($dst$$Register, $src$$constant); 9729 %} 9730 ins_pipe(ialu_reg); 9731 %} 9732 9733 // Or Register with Memory 9734 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9735 %{ 9736 match(Set dst (OrL dst (LoadL src))); 9737 effect(KILL cr); 9738 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9739 9740 ins_cost(150); 9741 format %{ "orq $dst, $src\t# long" %} 9742 ins_encode %{ 9743 __ orq($dst$$Register, $src$$Address); 9744 %} 9745 ins_pipe(ialu_reg_mem); 9746 %} 9747 9748 // Or Memory with Register 9749 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9750 %{ 9751 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9752 effect(KILL cr); 9753 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9754 9755 ins_cost(150); 9756 format %{ "orq $dst, $src\t# long" %} 9757 ins_encode %{ 9758 __ orq($dst$$Address, $src$$Register); 9759 %} 9760 ins_pipe(ialu_mem_reg); 9761 %} 9762 9763 // Or Memory with Immediate 9764 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9765 %{ 9766 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9767 effect(KILL cr); 9768 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9769 9770 ins_cost(125); 9771 format %{ "orq $dst, $src\t# long" %} 9772 ins_encode %{ 9773 __ orq($dst$$Address, $src$$constant); 9774 %} 9775 ins_pipe(ialu_mem_imm); 9776 %} 9777 9778 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9779 %{ 9780 // con should be a pure 64-bit power of 2 immediate 9781 // because AND/OR works well enough for 8/32-bit values. 9782 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9783 9784 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9785 effect(KILL cr); 9786 9787 ins_cost(125); 9788 format %{ "btsq $dst, log2($con)\t# long" %} 9789 ins_encode %{ 9790 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9791 %} 9792 ins_pipe(ialu_mem_imm); 9793 %} 9794 9795 // Xor Instructions 9796 // Xor Register with Register 9797 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9798 %{ 9799 match(Set dst (XorL dst src)); 9800 effect(KILL cr); 9801 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9802 9803 format %{ "xorq $dst, $src\t# long" %} 9804 ins_encode %{ 9805 __ xorq($dst$$Register, $src$$Register); 9806 %} 9807 ins_pipe(ialu_reg_reg); 9808 %} 9809 9810 // Xor Register with Immediate -1 9811 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9812 match(Set dst (XorL dst imm)); 9813 9814 format %{ "notq $dst" %} 9815 ins_encode %{ 9816 __ notq($dst$$Register); 9817 %} 9818 ins_pipe(ialu_reg); 9819 %} 9820 9821 // Xor Register with Immediate 9822 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9823 %{ 9824 match(Set dst (XorL dst src)); 9825 effect(KILL cr); 9826 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9827 9828 format %{ "xorq $dst, $src\t# long" %} 9829 ins_encode %{ 9830 __ xorq($dst$$Register, $src$$constant); 9831 %} 9832 ins_pipe(ialu_reg); 9833 %} 9834 9835 // Xor Register with Memory 9836 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9837 %{ 9838 match(Set dst (XorL dst (LoadL src))); 9839 effect(KILL cr); 9840 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9841 9842 ins_cost(150); 9843 format %{ "xorq $dst, $src\t# long" %} 9844 ins_encode %{ 9845 __ xorq($dst$$Register, $src$$Address); 9846 %} 9847 ins_pipe(ialu_reg_mem); 9848 %} 9849 9850 // Xor Memory with Register 9851 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9852 %{ 9853 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9854 effect(KILL cr); 9855 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9856 9857 ins_cost(150); 9858 format %{ "xorq $dst, $src\t# long" %} 9859 ins_encode %{ 9860 __ xorq($dst$$Address, $src$$Register); 9861 %} 9862 ins_pipe(ialu_mem_reg); 9863 %} 9864 9865 // Xor Memory with Immediate 9866 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9867 %{ 9868 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9869 effect(KILL cr); 9870 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9871 9872 ins_cost(125); 9873 format %{ "xorq $dst, $src\t# long" %} 9874 ins_encode %{ 9875 __ xorq($dst$$Address, $src$$constant); 9876 %} 9877 ins_pipe(ialu_mem_imm); 9878 %} 9879 9880 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9881 %{ 9882 match(Set dst (CmpLTMask p q)); 9883 effect(KILL cr); 9884 9885 ins_cost(400); 9886 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9887 "setlt $dst\n\t" 9888 "movzbl $dst, $dst\n\t" 9889 "negl $dst" %} 9890 ins_encode %{ 9891 __ cmpl($p$$Register, $q$$Register); 9892 __ setb(Assembler::less, $dst$$Register); 9893 __ movzbl($dst$$Register, $dst$$Register); 9894 __ negl($dst$$Register); 9895 %} 9896 ins_pipe(pipe_slow); 9897 %} 9898 9899 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9900 %{ 9901 match(Set dst (CmpLTMask dst zero)); 9902 effect(KILL cr); 9903 9904 ins_cost(100); 9905 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9906 ins_encode %{ 9907 __ sarl($dst$$Register, 31); 9908 %} 9909 ins_pipe(ialu_reg); 9910 %} 9911 9912 /* Better to save a register than avoid a branch */ 9913 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9914 %{ 9915 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9916 effect(KILL cr); 9917 ins_cost(300); 9918 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9919 "jge done\n\t" 9920 "addl $p,$y\n" 9921 "done: " %} 9922 ins_encode %{ 9923 Register Rp = $p$$Register; 9924 Register Rq = $q$$Register; 9925 Register Ry = $y$$Register; 9926 Label done; 9927 __ subl(Rp, Rq); 9928 __ jccb(Assembler::greaterEqual, done); 9929 __ addl(Rp, Ry); 9930 __ bind(done); 9931 %} 9932 ins_pipe(pipe_cmplt); 9933 %} 9934 9935 /* Better to save a register than avoid a branch */ 9936 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9937 %{ 9938 match(Set y (AndI (CmpLTMask p q) y)); 9939 effect(KILL cr); 9940 9941 ins_cost(300); 9942 9943 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9944 "jlt done\n\t" 9945 "xorl $y, $y\n" 9946 "done: " %} 9947 ins_encode %{ 9948 Register Rp = $p$$Register; 9949 Register Rq = $q$$Register; 9950 Register Ry = $y$$Register; 9951 Label done; 9952 __ cmpl(Rp, Rq); 9953 __ jccb(Assembler::less, done); 9954 __ xorl(Ry, Ry); 9955 __ bind(done); 9956 %} 9957 ins_pipe(pipe_cmplt); 9958 %} 9959 9960 9961 //---------- FP Instructions------------------------------------------------ 9962 9963 // Really expensive, avoid 9964 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9965 %{ 9966 match(Set cr (CmpF src1 src2)); 9967 9968 ins_cost(500); 9969 format %{ "ucomiss $src1, $src2\n\t" 9970 "jnp,s exit\n\t" 9971 "pushfq\t# saw NaN, set CF\n\t" 9972 "andq [rsp], #0xffffff2b\n\t" 9973 "popfq\n" 9974 "exit:" %} 9975 ins_encode %{ 9976 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9977 emit_cmpfp_fixup(_masm); 9978 %} 9979 ins_pipe(pipe_slow); 9980 %} 9981 9982 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9983 match(Set cr (CmpF src1 src2)); 9984 9985 ins_cost(100); 9986 format %{ "ucomiss $src1, $src2" %} 9987 ins_encode %{ 9988 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9989 %} 9990 ins_pipe(pipe_slow); 9991 %} 9992 9993 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9994 match(Set cr (CmpF src1 (LoadF src2))); 9995 9996 ins_cost(100); 9997 format %{ "ucomiss $src1, $src2" %} 9998 ins_encode %{ 9999 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10000 %} 10001 ins_pipe(pipe_slow); 10002 %} 10003 10004 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10005 match(Set cr (CmpF src con)); 10006 ins_cost(100); 10007 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10008 ins_encode %{ 10009 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10010 %} 10011 ins_pipe(pipe_slow); 10012 %} 10013 10014 // Really expensive, avoid 10015 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10016 %{ 10017 match(Set cr (CmpD src1 src2)); 10018 10019 ins_cost(500); 10020 format %{ "ucomisd $src1, $src2\n\t" 10021 "jnp,s exit\n\t" 10022 "pushfq\t# saw NaN, set CF\n\t" 10023 "andq [rsp], #0xffffff2b\n\t" 10024 "popfq\n" 10025 "exit:" %} 10026 ins_encode %{ 10027 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10028 emit_cmpfp_fixup(_masm); 10029 %} 10030 ins_pipe(pipe_slow); 10031 %} 10032 10033 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10034 match(Set cr (CmpD src1 src2)); 10035 10036 ins_cost(100); 10037 format %{ "ucomisd $src1, $src2 test" %} 10038 ins_encode %{ 10039 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10040 %} 10041 ins_pipe(pipe_slow); 10042 %} 10043 10044 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10045 match(Set cr (CmpD src1 (LoadD src2))); 10046 10047 ins_cost(100); 10048 format %{ "ucomisd $src1, $src2" %} 10049 ins_encode %{ 10050 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10051 %} 10052 ins_pipe(pipe_slow); 10053 %} 10054 10055 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10056 match(Set cr (CmpD src con)); 10057 ins_cost(100); 10058 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10059 ins_encode %{ 10060 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10061 %} 10062 ins_pipe(pipe_slow); 10063 %} 10064 10065 // Compare into -1,0,1 10066 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10067 %{ 10068 match(Set dst (CmpF3 src1 src2)); 10069 effect(KILL cr); 10070 10071 ins_cost(275); 10072 format %{ "ucomiss $src1, $src2\n\t" 10073 "movl $dst, #-1\n\t" 10074 "jp,s done\n\t" 10075 "jb,s done\n\t" 10076 "setne $dst\n\t" 10077 "movzbl $dst, $dst\n" 10078 "done:" %} 10079 ins_encode %{ 10080 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10081 emit_cmpfp3(_masm, $dst$$Register); 10082 %} 10083 ins_pipe(pipe_slow); 10084 %} 10085 10086 // Compare into -1,0,1 10087 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10088 %{ 10089 match(Set dst (CmpF3 src1 (LoadF src2))); 10090 effect(KILL cr); 10091 10092 ins_cost(275); 10093 format %{ "ucomiss $src1, $src2\n\t" 10094 "movl $dst, #-1\n\t" 10095 "jp,s done\n\t" 10096 "jb,s done\n\t" 10097 "setne $dst\n\t" 10098 "movzbl $dst, $dst\n" 10099 "done:" %} 10100 ins_encode %{ 10101 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10102 emit_cmpfp3(_masm, $dst$$Register); 10103 %} 10104 ins_pipe(pipe_slow); 10105 %} 10106 10107 // Compare into -1,0,1 10108 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10109 match(Set dst (CmpF3 src con)); 10110 effect(KILL cr); 10111 10112 ins_cost(275); 10113 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10114 "movl $dst, #-1\n\t" 10115 "jp,s done\n\t" 10116 "jb,s done\n\t" 10117 "setne $dst\n\t" 10118 "movzbl $dst, $dst\n" 10119 "done:" %} 10120 ins_encode %{ 10121 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10122 emit_cmpfp3(_masm, $dst$$Register); 10123 %} 10124 ins_pipe(pipe_slow); 10125 %} 10126 10127 // Compare into -1,0,1 10128 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10129 %{ 10130 match(Set dst (CmpD3 src1 src2)); 10131 effect(KILL cr); 10132 10133 ins_cost(275); 10134 format %{ "ucomisd $src1, $src2\n\t" 10135 "movl $dst, #-1\n\t" 10136 "jp,s done\n\t" 10137 "jb,s done\n\t" 10138 "setne $dst\n\t" 10139 "movzbl $dst, $dst\n" 10140 "done:" %} 10141 ins_encode %{ 10142 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10143 emit_cmpfp3(_masm, $dst$$Register); 10144 %} 10145 ins_pipe(pipe_slow); 10146 %} 10147 10148 // Compare into -1,0,1 10149 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10150 %{ 10151 match(Set dst (CmpD3 src1 (LoadD src2))); 10152 effect(KILL cr); 10153 10154 ins_cost(275); 10155 format %{ "ucomisd $src1, $src2\n\t" 10156 "movl $dst, #-1\n\t" 10157 "jp,s done\n\t" 10158 "jb,s done\n\t" 10159 "setne $dst\n\t" 10160 "movzbl $dst, $dst\n" 10161 "done:" %} 10162 ins_encode %{ 10163 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10164 emit_cmpfp3(_masm, $dst$$Register); 10165 %} 10166 ins_pipe(pipe_slow); 10167 %} 10168 10169 // Compare into -1,0,1 10170 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10171 match(Set dst (CmpD3 src con)); 10172 effect(KILL cr); 10173 10174 ins_cost(275); 10175 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10176 "movl $dst, #-1\n\t" 10177 "jp,s done\n\t" 10178 "jb,s done\n\t" 10179 "setne $dst\n\t" 10180 "movzbl $dst, $dst\n" 10181 "done:" %} 10182 ins_encode %{ 10183 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10184 emit_cmpfp3(_masm, $dst$$Register); 10185 %} 10186 ins_pipe(pipe_slow); 10187 %} 10188 10189 //----------Arithmetic Conversion Instructions--------------------------------- 10190 10191 instruct convF2D_reg_reg(regD dst, regF src) 10192 %{ 10193 match(Set dst (ConvF2D src)); 10194 effect(TEMP dst); 10195 format %{ "cvtss2sd $dst, $src" %} 10196 ins_encode %{ 10197 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10198 %} 10199 ins_pipe(pipe_slow); // XXX 10200 %} 10201 10202 instruct convF2D_reg_mem(regD dst, memory src) 10203 %{ 10204 match(Set dst (ConvF2D (LoadF src))); 10205 10206 format %{ "cvtss2sd $dst, $src" %} 10207 ins_encode %{ 10208 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10209 %} 10210 ins_pipe(pipe_slow); // XXX 10211 %} 10212 10213 instruct convD2F_reg_reg(regF dst, regD src) 10214 %{ 10215 match(Set dst (ConvD2F src)); 10216 effect(TEMP dst); 10217 format %{ "cvtsd2ss $dst, $src" %} 10218 ins_encode %{ 10219 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10220 %} 10221 ins_pipe(pipe_slow); // XXX 10222 %} 10223 10224 instruct convD2F_reg_mem(regF dst, memory src) 10225 %{ 10226 match(Set dst (ConvD2F (LoadD src))); 10227 10228 format %{ "cvtsd2ss $dst, $src" %} 10229 ins_encode %{ 10230 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10231 %} 10232 ins_pipe(pipe_slow); // XXX 10233 %} 10234 10235 // XXX do mem variants 10236 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10237 %{ 10238 match(Set dst (ConvF2I src)); 10239 effect(KILL cr); 10240 format %{ "convert_f2i $dst, $src" %} 10241 ins_encode %{ 10242 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10243 %} 10244 ins_pipe(pipe_slow); 10245 %} 10246 10247 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10248 %{ 10249 match(Set dst (ConvF2L src)); 10250 effect(KILL cr); 10251 format %{ "convert_f2l $dst, $src"%} 10252 ins_encode %{ 10253 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10254 %} 10255 ins_pipe(pipe_slow); 10256 %} 10257 10258 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10259 %{ 10260 match(Set dst (ConvD2I src)); 10261 effect(KILL cr); 10262 format %{ "convert_d2i $dst, $src"%} 10263 ins_encode %{ 10264 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10265 %} 10266 ins_pipe(pipe_slow); 10267 %} 10268 10269 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10270 %{ 10271 match(Set dst (ConvD2L src)); 10272 effect(KILL cr); 10273 format %{ "convert_d2l $dst, $src"%} 10274 ins_encode %{ 10275 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10276 %} 10277 ins_pipe(pipe_slow); 10278 %} 10279 10280 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10281 %{ 10282 match(Set dst (RoundD src)); 10283 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10284 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10285 ins_encode %{ 10286 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10287 %} 10288 ins_pipe(pipe_slow); 10289 %} 10290 10291 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10292 %{ 10293 match(Set dst (RoundF src)); 10294 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10295 format %{ "round_float $dst,$src" %} 10296 ins_encode %{ 10297 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10298 %} 10299 ins_pipe(pipe_slow); 10300 %} 10301 10302 instruct convI2F_reg_reg(regF dst, rRegI src) 10303 %{ 10304 predicate(!UseXmmI2F); 10305 match(Set dst (ConvI2F src)); 10306 10307 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10308 ins_encode %{ 10309 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10310 %} 10311 ins_pipe(pipe_slow); // XXX 10312 %} 10313 10314 instruct convI2F_reg_mem(regF dst, memory src) 10315 %{ 10316 match(Set dst (ConvI2F (LoadI src))); 10317 10318 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10319 ins_encode %{ 10320 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10321 %} 10322 ins_pipe(pipe_slow); // XXX 10323 %} 10324 10325 instruct convI2D_reg_reg(regD dst, rRegI src) 10326 %{ 10327 predicate(!UseXmmI2D); 10328 match(Set dst (ConvI2D src)); 10329 10330 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10331 ins_encode %{ 10332 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10333 %} 10334 ins_pipe(pipe_slow); // XXX 10335 %} 10336 10337 instruct convI2D_reg_mem(regD dst, memory src) 10338 %{ 10339 match(Set dst (ConvI2D (LoadI src))); 10340 10341 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10342 ins_encode %{ 10343 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10344 %} 10345 ins_pipe(pipe_slow); // XXX 10346 %} 10347 10348 instruct convXI2F_reg(regF dst, rRegI src) 10349 %{ 10350 predicate(UseXmmI2F); 10351 match(Set dst (ConvI2F src)); 10352 10353 format %{ "movdl $dst, $src\n\t" 10354 "cvtdq2psl $dst, $dst\t# i2f" %} 10355 ins_encode %{ 10356 __ movdl($dst$$XMMRegister, $src$$Register); 10357 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10358 %} 10359 ins_pipe(pipe_slow); // XXX 10360 %} 10361 10362 instruct convXI2D_reg(regD dst, rRegI src) 10363 %{ 10364 predicate(UseXmmI2D); 10365 match(Set dst (ConvI2D src)); 10366 10367 format %{ "movdl $dst, $src\n\t" 10368 "cvtdq2pdl $dst, $dst\t# i2d" %} 10369 ins_encode %{ 10370 __ movdl($dst$$XMMRegister, $src$$Register); 10371 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10372 %} 10373 ins_pipe(pipe_slow); // XXX 10374 %} 10375 10376 instruct convL2F_reg_reg(regF dst, rRegL src) 10377 %{ 10378 match(Set dst (ConvL2F src)); 10379 10380 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10381 ins_encode %{ 10382 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10383 %} 10384 ins_pipe(pipe_slow); // XXX 10385 %} 10386 10387 instruct convL2F_reg_mem(regF dst, memory src) 10388 %{ 10389 match(Set dst (ConvL2F (LoadL src))); 10390 10391 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10392 ins_encode %{ 10393 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10394 %} 10395 ins_pipe(pipe_slow); // XXX 10396 %} 10397 10398 instruct convL2D_reg_reg(regD dst, rRegL src) 10399 %{ 10400 match(Set dst (ConvL2D src)); 10401 10402 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10403 ins_encode %{ 10404 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10405 %} 10406 ins_pipe(pipe_slow); // XXX 10407 %} 10408 10409 instruct convL2D_reg_mem(regD dst, memory src) 10410 %{ 10411 match(Set dst (ConvL2D (LoadL src))); 10412 10413 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10414 ins_encode %{ 10415 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10416 %} 10417 ins_pipe(pipe_slow); // XXX 10418 %} 10419 10420 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10421 %{ 10422 match(Set dst (ConvI2L src)); 10423 10424 ins_cost(125); 10425 format %{ "movslq $dst, $src\t# i2l" %} 10426 ins_encode %{ 10427 __ movslq($dst$$Register, $src$$Register); 10428 %} 10429 ins_pipe(ialu_reg_reg); 10430 %} 10431 10432 // Zero-extend convert int to long 10433 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10434 %{ 10435 match(Set dst (AndL (ConvI2L src) mask)); 10436 10437 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10438 ins_encode %{ 10439 if ($dst$$reg != $src$$reg) { 10440 __ movl($dst$$Register, $src$$Register); 10441 } 10442 %} 10443 ins_pipe(ialu_reg_reg); 10444 %} 10445 10446 // Zero-extend convert int to long 10447 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10448 %{ 10449 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10450 10451 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10452 ins_encode %{ 10453 __ movl($dst$$Register, $src$$Address); 10454 %} 10455 ins_pipe(ialu_reg_mem); 10456 %} 10457 10458 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10459 %{ 10460 match(Set dst (AndL src mask)); 10461 10462 format %{ "movl $dst, $src\t# zero-extend long" %} 10463 ins_encode %{ 10464 __ movl($dst$$Register, $src$$Register); 10465 %} 10466 ins_pipe(ialu_reg_reg); 10467 %} 10468 10469 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10470 %{ 10471 match(Set dst (ConvL2I src)); 10472 10473 format %{ "movl $dst, $src\t# l2i" %} 10474 ins_encode %{ 10475 __ movl($dst$$Register, $src$$Register); 10476 %} 10477 ins_pipe(ialu_reg_reg); 10478 %} 10479 10480 10481 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10482 match(Set dst (MoveF2I src)); 10483 effect(DEF dst, USE src); 10484 10485 ins_cost(125); 10486 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10487 ins_encode %{ 10488 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10489 %} 10490 ins_pipe(ialu_reg_mem); 10491 %} 10492 10493 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10494 match(Set dst (MoveI2F src)); 10495 effect(DEF dst, USE src); 10496 10497 ins_cost(125); 10498 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10499 ins_encode %{ 10500 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10501 %} 10502 ins_pipe(pipe_slow); 10503 %} 10504 10505 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10506 match(Set dst (MoveD2L src)); 10507 effect(DEF dst, USE src); 10508 10509 ins_cost(125); 10510 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10511 ins_encode %{ 10512 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10513 %} 10514 ins_pipe(ialu_reg_mem); 10515 %} 10516 10517 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10518 predicate(!UseXmmLoadAndClearUpper); 10519 match(Set dst (MoveL2D src)); 10520 effect(DEF dst, USE src); 10521 10522 ins_cost(125); 10523 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10524 ins_encode %{ 10525 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10526 %} 10527 ins_pipe(pipe_slow); 10528 %} 10529 10530 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10531 predicate(UseXmmLoadAndClearUpper); 10532 match(Set dst (MoveL2D src)); 10533 effect(DEF dst, USE src); 10534 10535 ins_cost(125); 10536 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10537 ins_encode %{ 10538 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10539 %} 10540 ins_pipe(pipe_slow); 10541 %} 10542 10543 10544 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10545 match(Set dst (MoveF2I src)); 10546 effect(DEF dst, USE src); 10547 10548 ins_cost(95); // XXX 10549 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10550 ins_encode %{ 10551 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10552 %} 10553 ins_pipe(pipe_slow); 10554 %} 10555 10556 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10557 match(Set dst (MoveI2F src)); 10558 effect(DEF dst, USE src); 10559 10560 ins_cost(100); 10561 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10562 ins_encode %{ 10563 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10564 %} 10565 ins_pipe( ialu_mem_reg ); 10566 %} 10567 10568 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10569 match(Set dst (MoveD2L src)); 10570 effect(DEF dst, USE src); 10571 10572 ins_cost(95); // XXX 10573 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10574 ins_encode %{ 10575 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10576 %} 10577 ins_pipe(pipe_slow); 10578 %} 10579 10580 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10581 match(Set dst (MoveL2D src)); 10582 effect(DEF dst, USE src); 10583 10584 ins_cost(100); 10585 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10586 ins_encode %{ 10587 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10588 %} 10589 ins_pipe(ialu_mem_reg); 10590 %} 10591 10592 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10593 match(Set dst (MoveF2I src)); 10594 effect(DEF dst, USE src); 10595 ins_cost(85); 10596 format %{ "movd $dst,$src\t# MoveF2I" %} 10597 ins_encode %{ 10598 __ movdl($dst$$Register, $src$$XMMRegister); 10599 %} 10600 ins_pipe( pipe_slow ); 10601 %} 10602 10603 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10604 match(Set dst (MoveD2L src)); 10605 effect(DEF dst, USE src); 10606 ins_cost(85); 10607 format %{ "movd $dst,$src\t# MoveD2L" %} 10608 ins_encode %{ 10609 __ movdq($dst$$Register, $src$$XMMRegister); 10610 %} 10611 ins_pipe( pipe_slow ); 10612 %} 10613 10614 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10615 match(Set dst (MoveI2F src)); 10616 effect(DEF dst, USE src); 10617 ins_cost(100); 10618 format %{ "movd $dst,$src\t# MoveI2F" %} 10619 ins_encode %{ 10620 __ movdl($dst$$XMMRegister, $src$$Register); 10621 %} 10622 ins_pipe( pipe_slow ); 10623 %} 10624 10625 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10626 match(Set dst (MoveL2D src)); 10627 effect(DEF dst, USE src); 10628 ins_cost(100); 10629 format %{ "movd $dst,$src\t# MoveL2D" %} 10630 ins_encode %{ 10631 __ movdq($dst$$XMMRegister, $src$$Register); 10632 %} 10633 ins_pipe( pipe_slow ); 10634 %} 10635 10636 10637 // Fast clearing of an array 10638 // Small ClearArray non-AVX512. 10639 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10640 Universe dummy, rFlagsReg cr) 10641 %{ 10642 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10643 match(Set dummy (ClearArray (Binary cnt base) val)); 10644 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10645 10646 format %{ $$template 10647 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10648 $$emit$$"jg LARGE\n\t" 10649 $$emit$$"dec rcx\n\t" 10650 $$emit$$"js DONE\t# Zero length\n\t" 10651 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10652 $$emit$$"dec rcx\n\t" 10653 $$emit$$"jge LOOP\n\t" 10654 $$emit$$"jmp DONE\n\t" 10655 $$emit$$"# LARGE:\n\t" 10656 if (UseFastStosb) { 10657 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10658 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10659 } else if (UseXMMForObjInit) { 10660 $$emit$$"movdq $tmp, $val\n\t" 10661 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10662 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10663 $$emit$$"jmpq L_zero_64_bytes\n\t" 10664 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10665 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10666 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10667 $$emit$$"add 0x40,rax\n\t" 10668 $$emit$$"# L_zero_64_bytes:\n\t" 10669 $$emit$$"sub 0x8,rcx\n\t" 10670 $$emit$$"jge L_loop\n\t" 10671 $$emit$$"add 0x4,rcx\n\t" 10672 $$emit$$"jl L_tail\n\t" 10673 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10674 $$emit$$"add 0x20,rax\n\t" 10675 $$emit$$"sub 0x4,rcx\n\t" 10676 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10677 $$emit$$"add 0x4,rcx\n\t" 10678 $$emit$$"jle L_end\n\t" 10679 $$emit$$"dec rcx\n\t" 10680 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10681 $$emit$$"vmovq xmm0,(rax)\n\t" 10682 $$emit$$"add 0x8,rax\n\t" 10683 $$emit$$"dec rcx\n\t" 10684 $$emit$$"jge L_sloop\n\t" 10685 $$emit$$"# L_end:\n\t" 10686 } else { 10687 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10688 } 10689 $$emit$$"# DONE" 10690 %} 10691 ins_encode %{ 10692 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10693 $tmp$$XMMRegister, false, false); 10694 %} 10695 ins_pipe(pipe_slow); 10696 %} 10697 10698 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10699 Universe dummy, rFlagsReg cr) 10700 %{ 10701 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10702 match(Set dummy (ClearArray (Binary cnt base) val)); 10703 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10704 10705 format %{ $$template 10706 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10707 $$emit$$"jg LARGE\n\t" 10708 $$emit$$"dec rcx\n\t" 10709 $$emit$$"js DONE\t# Zero length\n\t" 10710 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10711 $$emit$$"dec rcx\n\t" 10712 $$emit$$"jge LOOP\n\t" 10713 $$emit$$"jmp DONE\n\t" 10714 $$emit$$"# LARGE:\n\t" 10715 if (UseXMMForObjInit) { 10716 $$emit$$"movdq $tmp, $val\n\t" 10717 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10718 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10719 $$emit$$"jmpq L_zero_64_bytes\n\t" 10720 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10721 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10722 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10723 $$emit$$"add 0x40,rax\n\t" 10724 $$emit$$"# L_zero_64_bytes:\n\t" 10725 $$emit$$"sub 0x8,rcx\n\t" 10726 $$emit$$"jge L_loop\n\t" 10727 $$emit$$"add 0x4,rcx\n\t" 10728 $$emit$$"jl L_tail\n\t" 10729 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10730 $$emit$$"add 0x20,rax\n\t" 10731 $$emit$$"sub 0x4,rcx\n\t" 10732 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10733 $$emit$$"add 0x4,rcx\n\t" 10734 $$emit$$"jle L_end\n\t" 10735 $$emit$$"dec rcx\n\t" 10736 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10737 $$emit$$"vmovq xmm0,(rax)\n\t" 10738 $$emit$$"add 0x8,rax\n\t" 10739 $$emit$$"dec rcx\n\t" 10740 $$emit$$"jge L_sloop\n\t" 10741 $$emit$$"# L_end:\n\t" 10742 } else { 10743 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10744 } 10745 $$emit$$"# DONE" 10746 %} 10747 ins_encode %{ 10748 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10749 $tmp$$XMMRegister, false, true); 10750 %} 10751 ins_pipe(pipe_slow); 10752 %} 10753 10754 // Small ClearArray AVX512 non-constant length. 10755 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10756 Universe dummy, rFlagsReg cr) 10757 %{ 10758 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10759 match(Set dummy (ClearArray (Binary cnt base) val)); 10760 ins_cost(125); 10761 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10762 10763 format %{ $$template 10764 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10765 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10766 $$emit$$"jg LARGE\n\t" 10767 $$emit$$"dec rcx\n\t" 10768 $$emit$$"js DONE\t# Zero length\n\t" 10769 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10770 $$emit$$"dec rcx\n\t" 10771 $$emit$$"jge LOOP\n\t" 10772 $$emit$$"jmp DONE\n\t" 10773 $$emit$$"# LARGE:\n\t" 10774 if (UseFastStosb) { 10775 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10776 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10777 } else if (UseXMMForObjInit) { 10778 $$emit$$"mov rdi,rax\n\t" 10779 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10780 $$emit$$"jmpq L_zero_64_bytes\n\t" 10781 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10782 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10783 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10784 $$emit$$"add 0x40,rax\n\t" 10785 $$emit$$"# L_zero_64_bytes:\n\t" 10786 $$emit$$"sub 0x8,rcx\n\t" 10787 $$emit$$"jge L_loop\n\t" 10788 $$emit$$"add 0x4,rcx\n\t" 10789 $$emit$$"jl L_tail\n\t" 10790 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10791 $$emit$$"add 0x20,rax\n\t" 10792 $$emit$$"sub 0x4,rcx\n\t" 10793 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10794 $$emit$$"add 0x4,rcx\n\t" 10795 $$emit$$"jle L_end\n\t" 10796 $$emit$$"dec rcx\n\t" 10797 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10798 $$emit$$"vmovq xmm0,(rax)\n\t" 10799 $$emit$$"add 0x8,rax\n\t" 10800 $$emit$$"dec rcx\n\t" 10801 $$emit$$"jge L_sloop\n\t" 10802 $$emit$$"# L_end:\n\t" 10803 } else { 10804 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10805 } 10806 $$emit$$"# DONE" 10807 %} 10808 ins_encode %{ 10809 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10810 $tmp$$XMMRegister, false, false, $ktmp$$KRegister); 10811 %} 10812 ins_pipe(pipe_slow); 10813 %} 10814 10815 instruct rep_stos_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10816 Universe dummy, rFlagsReg cr) 10817 %{ 10818 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10819 match(Set dummy (ClearArray (Binary cnt base) val)); 10820 ins_cost(125); 10821 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10822 10823 format %{ $$template 10824 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10825 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10826 $$emit$$"jg LARGE\n\t" 10827 $$emit$$"dec rcx\n\t" 10828 $$emit$$"js DONE\t# Zero length\n\t" 10829 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10830 $$emit$$"dec rcx\n\t" 10831 $$emit$$"jge LOOP\n\t" 10832 $$emit$$"jmp DONE\n\t" 10833 $$emit$$"# LARGE:\n\t" 10834 if (UseFastStosb) { 10835 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10836 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10837 } else if (UseXMMForObjInit) { 10838 $$emit$$"mov rdi,rax\n\t" 10839 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10840 $$emit$$"jmpq L_zero_64_bytes\n\t" 10841 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10842 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10843 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10844 $$emit$$"add 0x40,rax\n\t" 10845 $$emit$$"# L_zero_64_bytes:\n\t" 10846 $$emit$$"sub 0x8,rcx\n\t" 10847 $$emit$$"jge L_loop\n\t" 10848 $$emit$$"add 0x4,rcx\n\t" 10849 $$emit$$"jl L_tail\n\t" 10850 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10851 $$emit$$"add 0x20,rax\n\t" 10852 $$emit$$"sub 0x4,rcx\n\t" 10853 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10854 $$emit$$"add 0x4,rcx\n\t" 10855 $$emit$$"jle L_end\n\t" 10856 $$emit$$"dec rcx\n\t" 10857 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10858 $$emit$$"vmovq xmm0,(rax)\n\t" 10859 $$emit$$"add 0x8,rax\n\t" 10860 $$emit$$"dec rcx\n\t" 10861 $$emit$$"jge L_sloop\n\t" 10862 $$emit$$"# L_end:\n\t" 10863 } else { 10864 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10865 } 10866 $$emit$$"# DONE" 10867 %} 10868 ins_encode %{ 10869 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10870 $tmp$$XMMRegister, false, true, $ktmp$$KRegister); 10871 %} 10872 ins_pipe(pipe_slow); 10873 %} 10874 10875 // Large ClearArray non-AVX512. 10876 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10877 Universe dummy, rFlagsReg cr) 10878 %{ 10879 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10880 match(Set dummy (ClearArray (Binary cnt base) val)); 10881 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10882 10883 format %{ $$template 10884 if (UseFastStosb) { 10885 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10886 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10887 } else if (UseXMMForObjInit) { 10888 $$emit$$"movdq $tmp, $val\n\t" 10889 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10890 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10891 $$emit$$"jmpq L_zero_64_bytes\n\t" 10892 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10893 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10894 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10895 $$emit$$"add 0x40,rax\n\t" 10896 $$emit$$"# L_zero_64_bytes:\n\t" 10897 $$emit$$"sub 0x8,rcx\n\t" 10898 $$emit$$"jge L_loop\n\t" 10899 $$emit$$"add 0x4,rcx\n\t" 10900 $$emit$$"jl L_tail\n\t" 10901 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10902 $$emit$$"add 0x20,rax\n\t" 10903 $$emit$$"sub 0x4,rcx\n\t" 10904 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10905 $$emit$$"add 0x4,rcx\n\t" 10906 $$emit$$"jle L_end\n\t" 10907 $$emit$$"dec rcx\n\t" 10908 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10909 $$emit$$"vmovq xmm0,(rax)\n\t" 10910 $$emit$$"add 0x8,rax\n\t" 10911 $$emit$$"dec rcx\n\t" 10912 $$emit$$"jge L_sloop\n\t" 10913 $$emit$$"# L_end:\n\t" 10914 } else { 10915 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10916 } 10917 %} 10918 ins_encode %{ 10919 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10920 $tmp$$XMMRegister, true, false); 10921 %} 10922 ins_pipe(pipe_slow); 10923 %} 10924 10925 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10926 Universe dummy, rFlagsReg cr) 10927 %{ 10928 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10929 match(Set dummy (ClearArray (Binary cnt base) val)); 10930 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10931 10932 format %{ $$template 10933 if (UseXMMForObjInit) { 10934 $$emit$$"movdq $tmp, $val\n\t" 10935 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10936 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10937 $$emit$$"jmpq L_zero_64_bytes\n\t" 10938 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10939 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10940 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10941 $$emit$$"add 0x40,rax\n\t" 10942 $$emit$$"# L_zero_64_bytes:\n\t" 10943 $$emit$$"sub 0x8,rcx\n\t" 10944 $$emit$$"jge L_loop\n\t" 10945 $$emit$$"add 0x4,rcx\n\t" 10946 $$emit$$"jl L_tail\n\t" 10947 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10948 $$emit$$"add 0x20,rax\n\t" 10949 $$emit$$"sub 0x4,rcx\n\t" 10950 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10951 $$emit$$"add 0x4,rcx\n\t" 10952 $$emit$$"jle L_end\n\t" 10953 $$emit$$"dec rcx\n\t" 10954 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10955 $$emit$$"vmovq xmm0,(rax)\n\t" 10956 $$emit$$"add 0x8,rax\n\t" 10957 $$emit$$"dec rcx\n\t" 10958 $$emit$$"jge L_sloop\n\t" 10959 $$emit$$"# L_end:\n\t" 10960 } else { 10961 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10962 } 10963 %} 10964 ins_encode %{ 10965 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10966 $tmp$$XMMRegister, true, true); 10967 %} 10968 ins_pipe(pipe_slow); 10969 %} 10970 10971 // Large ClearArray AVX512. 10972 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10973 Universe dummy, rFlagsReg cr) 10974 %{ 10975 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10976 match(Set dummy (ClearArray (Binary cnt base) val)); 10977 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10978 10979 format %{ $$template 10980 if (UseFastStosb) { 10981 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10982 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10983 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10984 } else if (UseXMMForObjInit) { 10985 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10986 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10987 $$emit$$"jmpq L_zero_64_bytes\n\t" 10988 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10989 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10990 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10991 $$emit$$"add 0x40,rax\n\t" 10992 $$emit$$"# L_zero_64_bytes:\n\t" 10993 $$emit$$"sub 0x8,rcx\n\t" 10994 $$emit$$"jge L_loop\n\t" 10995 $$emit$$"add 0x4,rcx\n\t" 10996 $$emit$$"jl L_tail\n\t" 10997 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10998 $$emit$$"add 0x20,rax\n\t" 10999 $$emit$$"sub 0x4,rcx\n\t" 11000 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11001 $$emit$$"add 0x4,rcx\n\t" 11002 $$emit$$"jle L_end\n\t" 11003 $$emit$$"dec rcx\n\t" 11004 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11005 $$emit$$"vmovq xmm0,(rax)\n\t" 11006 $$emit$$"add 0x8,rax\n\t" 11007 $$emit$$"dec rcx\n\t" 11008 $$emit$$"jge L_sloop\n\t" 11009 $$emit$$"# L_end:\n\t" 11010 } else { 11011 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11012 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11013 } 11014 %} 11015 ins_encode %{ 11016 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11017 $tmp$$XMMRegister, true, false, $ktmp$$KRegister); 11018 %} 11019 ins_pipe(pipe_slow); 11020 %} 11021 11022 instruct rep_stos_large_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 11023 Universe dummy, rFlagsReg cr) 11024 %{ 11025 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 11026 match(Set dummy (ClearArray (Binary cnt base) val)); 11027 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 11028 11029 format %{ $$template 11030 if (UseFastStosb) { 11031 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11032 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11033 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11034 } else if (UseXMMForObjInit) { 11035 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 11036 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11037 $$emit$$"jmpq L_zero_64_bytes\n\t" 11038 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11039 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11040 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11041 $$emit$$"add 0x40,rax\n\t" 11042 $$emit$$"# L_zero_64_bytes:\n\t" 11043 $$emit$$"sub 0x8,rcx\n\t" 11044 $$emit$$"jge L_loop\n\t" 11045 $$emit$$"add 0x4,rcx\n\t" 11046 $$emit$$"jl L_tail\n\t" 11047 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11048 $$emit$$"add 0x20,rax\n\t" 11049 $$emit$$"sub 0x4,rcx\n\t" 11050 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11051 $$emit$$"add 0x4,rcx\n\t" 11052 $$emit$$"jle L_end\n\t" 11053 $$emit$$"dec rcx\n\t" 11054 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11055 $$emit$$"vmovq xmm0,(rax)\n\t" 11056 $$emit$$"add 0x8,rax\n\t" 11057 $$emit$$"dec rcx\n\t" 11058 $$emit$$"jge L_sloop\n\t" 11059 $$emit$$"# L_end:\n\t" 11060 } else { 11061 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11062 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11063 } 11064 %} 11065 ins_encode %{ 11066 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 11067 $tmp$$XMMRegister, true, true, $ktmp$$KRegister); 11068 %} 11069 ins_pipe(pipe_slow); 11070 %} 11071 11072 // Small ClearArray AVX512 constant length. 11073 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rax_RegL val, kReg ktmp, Universe dummy, rFlagsReg cr) 11074 %{ 11075 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && 11076 ((UseAVX > 2) && VM_Version::supports_avx512vlbw())); 11077 match(Set dummy (ClearArray (Binary cnt base) val)); 11078 ins_cost(100); 11079 effect(TEMP tmp, USE_KILL val, TEMP ktmp, KILL cr); 11080 format %{ "clear_mem_imm $base , $cnt \n\t" %} 11081 ins_encode %{ 11082 __ clear_mem($base$$Register, $cnt$$constant, $val$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 11083 %} 11084 ins_pipe(pipe_slow); 11085 %} 11086 11087 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11088 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11089 %{ 11090 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11091 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11092 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11093 11094 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11095 ins_encode %{ 11096 __ string_compare($str1$$Register, $str2$$Register, 11097 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11098 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 11099 %} 11100 ins_pipe( pipe_slow ); 11101 %} 11102 11103 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11104 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11105 %{ 11106 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11107 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11108 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11109 11110 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11111 ins_encode %{ 11112 __ string_compare($str1$$Register, $str2$$Register, 11113 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11114 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 11115 %} 11116 ins_pipe( pipe_slow ); 11117 %} 11118 11119 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11120 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11121 %{ 11122 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11123 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11124 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11125 11126 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11127 ins_encode %{ 11128 __ string_compare($str1$$Register, $str2$$Register, 11129 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11130 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 11131 %} 11132 ins_pipe( pipe_slow ); 11133 %} 11134 11135 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11136 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11137 %{ 11138 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11139 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11140 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11141 11142 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11143 ins_encode %{ 11144 __ string_compare($str1$$Register, $str2$$Register, 11145 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11146 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 11147 %} 11148 ins_pipe( pipe_slow ); 11149 %} 11150 11151 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11152 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11153 %{ 11154 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11155 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11156 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11157 11158 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11159 ins_encode %{ 11160 __ string_compare($str1$$Register, $str2$$Register, 11161 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11162 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 11163 %} 11164 ins_pipe( pipe_slow ); 11165 %} 11166 11167 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11168 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11169 %{ 11170 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11171 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11172 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11173 11174 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11175 ins_encode %{ 11176 __ string_compare($str1$$Register, $str2$$Register, 11177 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11178 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 11179 %} 11180 ins_pipe( pipe_slow ); 11181 %} 11182 11183 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11184 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11185 %{ 11186 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11187 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11188 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11189 11190 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11191 ins_encode %{ 11192 __ string_compare($str2$$Register, $str1$$Register, 11193 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11194 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 11195 %} 11196 ins_pipe( pipe_slow ); 11197 %} 11198 11199 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11200 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11201 %{ 11202 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11203 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11204 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11205 11206 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11207 ins_encode %{ 11208 __ string_compare($str2$$Register, $str1$$Register, 11209 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11210 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 11211 %} 11212 ins_pipe( pipe_slow ); 11213 %} 11214 11215 // fast search of substring with known size. 11216 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11217 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11218 %{ 11219 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11220 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11221 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11222 11223 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11224 ins_encode %{ 11225 int icnt2 = (int)$int_cnt2$$constant; 11226 if (icnt2 >= 16) { 11227 // IndexOf for constant substrings with size >= 16 elements 11228 // which don't need to be loaded through stack. 11229 __ string_indexofC8($str1$$Register, $str2$$Register, 11230 $cnt1$$Register, $cnt2$$Register, 11231 icnt2, $result$$Register, 11232 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11233 } else { 11234 // Small strings are loaded through stack if they cross page boundary. 11235 __ string_indexof($str1$$Register, $str2$$Register, 11236 $cnt1$$Register, $cnt2$$Register, 11237 icnt2, $result$$Register, 11238 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11239 } 11240 %} 11241 ins_pipe( pipe_slow ); 11242 %} 11243 11244 // fast search of substring with known size. 11245 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11246 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11247 %{ 11248 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11249 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11250 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11251 11252 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11253 ins_encode %{ 11254 int icnt2 = (int)$int_cnt2$$constant; 11255 if (icnt2 >= 8) { 11256 // IndexOf for constant substrings with size >= 8 elements 11257 // which don't need to be loaded through stack. 11258 __ string_indexofC8($str1$$Register, $str2$$Register, 11259 $cnt1$$Register, $cnt2$$Register, 11260 icnt2, $result$$Register, 11261 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11262 } else { 11263 // Small strings are loaded through stack if they cross page boundary. 11264 __ string_indexof($str1$$Register, $str2$$Register, 11265 $cnt1$$Register, $cnt2$$Register, 11266 icnt2, $result$$Register, 11267 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11268 } 11269 %} 11270 ins_pipe( pipe_slow ); 11271 %} 11272 11273 // fast search of substring with known size. 11274 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11275 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11276 %{ 11277 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11278 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11279 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11280 11281 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11282 ins_encode %{ 11283 int icnt2 = (int)$int_cnt2$$constant; 11284 if (icnt2 >= 8) { 11285 // IndexOf for constant substrings with size >= 8 elements 11286 // which don't need to be loaded through stack. 11287 __ string_indexofC8($str1$$Register, $str2$$Register, 11288 $cnt1$$Register, $cnt2$$Register, 11289 icnt2, $result$$Register, 11290 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11291 } else { 11292 // Small strings are loaded through stack if they cross page boundary. 11293 __ string_indexof($str1$$Register, $str2$$Register, 11294 $cnt1$$Register, $cnt2$$Register, 11295 icnt2, $result$$Register, 11296 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11297 } 11298 %} 11299 ins_pipe( pipe_slow ); 11300 %} 11301 11302 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11303 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11304 %{ 11305 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11306 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11307 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11308 11309 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11310 ins_encode %{ 11311 __ string_indexof($str1$$Register, $str2$$Register, 11312 $cnt1$$Register, $cnt2$$Register, 11313 (-1), $result$$Register, 11314 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11315 %} 11316 ins_pipe( pipe_slow ); 11317 %} 11318 11319 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11320 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11321 %{ 11322 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11323 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11324 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11325 11326 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11327 ins_encode %{ 11328 __ string_indexof($str1$$Register, $str2$$Register, 11329 $cnt1$$Register, $cnt2$$Register, 11330 (-1), $result$$Register, 11331 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11332 %} 11333 ins_pipe( pipe_slow ); 11334 %} 11335 11336 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11337 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11338 %{ 11339 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11340 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11341 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11342 11343 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11344 ins_encode %{ 11345 __ string_indexof($str1$$Register, $str2$$Register, 11346 $cnt1$$Register, $cnt2$$Register, 11347 (-1), $result$$Register, 11348 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11349 %} 11350 ins_pipe( pipe_slow ); 11351 %} 11352 11353 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11354 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11355 %{ 11356 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 11357 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11358 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11359 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11360 ins_encode %{ 11361 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11362 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11363 %} 11364 ins_pipe( pipe_slow ); 11365 %} 11366 11367 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11368 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11369 %{ 11370 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 11371 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11372 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11373 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11374 ins_encode %{ 11375 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11376 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11377 %} 11378 ins_pipe( pipe_slow ); 11379 %} 11380 11381 // fast string equals 11382 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11383 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11384 %{ 11385 predicate(!VM_Version::supports_avx512vlbw()); 11386 match(Set result (StrEquals (Binary str1 str2) cnt)); 11387 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11388 11389 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11390 ins_encode %{ 11391 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11392 $cnt$$Register, $result$$Register, $tmp3$$Register, 11393 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11394 %} 11395 ins_pipe( pipe_slow ); 11396 %} 11397 11398 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11399 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11400 %{ 11401 predicate(VM_Version::supports_avx512vlbw()); 11402 match(Set result (StrEquals (Binary str1 str2) cnt)); 11403 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11404 11405 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11406 ins_encode %{ 11407 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11408 $cnt$$Register, $result$$Register, $tmp3$$Register, 11409 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11410 %} 11411 ins_pipe( pipe_slow ); 11412 %} 11413 11414 // fast array equals 11415 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11416 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11417 %{ 11418 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11419 match(Set result (AryEq ary1 ary2)); 11420 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11421 11422 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11423 ins_encode %{ 11424 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11425 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11426 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11427 %} 11428 ins_pipe( pipe_slow ); 11429 %} 11430 11431 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11432 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11433 %{ 11434 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11435 match(Set result (AryEq ary1 ary2)); 11436 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11437 11438 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11439 ins_encode %{ 11440 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11441 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11442 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11443 %} 11444 ins_pipe( pipe_slow ); 11445 %} 11446 11447 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11448 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11449 %{ 11450 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11451 match(Set result (AryEq ary1 ary2)); 11452 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11453 11454 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11455 ins_encode %{ 11456 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11457 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11458 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11459 %} 11460 ins_pipe( pipe_slow ); 11461 %} 11462 11463 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11464 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11465 %{ 11466 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11467 match(Set result (AryEq ary1 ary2)); 11468 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11469 11470 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11471 ins_encode %{ 11472 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11473 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11474 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11475 %} 11476 ins_pipe( pipe_slow ); 11477 %} 11478 11479 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11480 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11481 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11482 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11483 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11484 %{ 11485 predicate(UseAVX >= 2); 11486 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11487 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11488 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11489 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11490 USE basic_type, KILL cr); 11491 11492 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11493 ins_encode %{ 11494 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11495 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11496 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11497 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11498 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11499 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11500 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11501 %} 11502 ins_pipe( pipe_slow ); 11503 %} 11504 11505 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11506 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11507 %{ 11508 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11509 match(Set result (CountPositives ary1 len)); 11510 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11511 11512 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11513 ins_encode %{ 11514 __ count_positives($ary1$$Register, $len$$Register, 11515 $result$$Register, $tmp3$$Register, 11516 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11517 %} 11518 ins_pipe( pipe_slow ); 11519 %} 11520 11521 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11522 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11523 %{ 11524 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11525 match(Set result (CountPositives ary1 len)); 11526 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11527 11528 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11529 ins_encode %{ 11530 __ count_positives($ary1$$Register, $len$$Register, 11531 $result$$Register, $tmp3$$Register, 11532 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11533 %} 11534 ins_pipe( pipe_slow ); 11535 %} 11536 11537 // fast char[] to byte[] compression 11538 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11539 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11540 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11541 match(Set result (StrCompressedCopy src (Binary dst len))); 11542 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11543 USE_KILL len, KILL tmp5, KILL cr); 11544 11545 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11546 ins_encode %{ 11547 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11548 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11549 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11550 knoreg, knoreg); 11551 %} 11552 ins_pipe( pipe_slow ); 11553 %} 11554 11555 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11556 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11557 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11558 match(Set result (StrCompressedCopy src (Binary dst len))); 11559 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11560 USE_KILL len, KILL tmp5, KILL cr); 11561 11562 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11563 ins_encode %{ 11564 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11565 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11566 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11567 $ktmp1$$KRegister, $ktmp2$$KRegister); 11568 %} 11569 ins_pipe( pipe_slow ); 11570 %} 11571 // fast byte[] to char[] inflation 11572 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11573 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11574 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11575 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11576 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11577 11578 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11579 ins_encode %{ 11580 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11581 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11582 %} 11583 ins_pipe( pipe_slow ); 11584 %} 11585 11586 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11587 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11588 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11589 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11590 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11591 11592 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11593 ins_encode %{ 11594 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11595 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11596 %} 11597 ins_pipe( pipe_slow ); 11598 %} 11599 11600 // encode char[] to byte[] in ISO_8859_1 11601 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11602 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11603 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11604 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11605 match(Set result (EncodeISOArray src (Binary dst len))); 11606 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11607 11608 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11609 ins_encode %{ 11610 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11611 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11612 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11613 %} 11614 ins_pipe( pipe_slow ); 11615 %} 11616 11617 // encode char[] to byte[] in ASCII 11618 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11619 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11620 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11621 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11622 match(Set result (EncodeISOArray src (Binary dst len))); 11623 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11624 11625 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11626 ins_encode %{ 11627 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11628 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11629 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11630 %} 11631 ins_pipe( pipe_slow ); 11632 %} 11633 11634 //----------Overflow Math Instructions----------------------------------------- 11635 11636 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11637 %{ 11638 match(Set cr (OverflowAddI op1 op2)); 11639 effect(DEF cr, USE_KILL op1, USE op2); 11640 11641 format %{ "addl $op1, $op2\t# overflow check int" %} 11642 11643 ins_encode %{ 11644 __ addl($op1$$Register, $op2$$Register); 11645 %} 11646 ins_pipe(ialu_reg_reg); 11647 %} 11648 11649 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11650 %{ 11651 match(Set cr (OverflowAddI op1 op2)); 11652 effect(DEF cr, USE_KILL op1, USE op2); 11653 11654 format %{ "addl $op1, $op2\t# overflow check int" %} 11655 11656 ins_encode %{ 11657 __ addl($op1$$Register, $op2$$constant); 11658 %} 11659 ins_pipe(ialu_reg_reg); 11660 %} 11661 11662 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11663 %{ 11664 match(Set cr (OverflowAddL op1 op2)); 11665 effect(DEF cr, USE_KILL op1, USE op2); 11666 11667 format %{ "addq $op1, $op2\t# overflow check long" %} 11668 ins_encode %{ 11669 __ addq($op1$$Register, $op2$$Register); 11670 %} 11671 ins_pipe(ialu_reg_reg); 11672 %} 11673 11674 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11675 %{ 11676 match(Set cr (OverflowAddL op1 op2)); 11677 effect(DEF cr, USE_KILL op1, USE op2); 11678 11679 format %{ "addq $op1, $op2\t# overflow check long" %} 11680 ins_encode %{ 11681 __ addq($op1$$Register, $op2$$constant); 11682 %} 11683 ins_pipe(ialu_reg_reg); 11684 %} 11685 11686 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11687 %{ 11688 match(Set cr (OverflowSubI op1 op2)); 11689 11690 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11691 ins_encode %{ 11692 __ cmpl($op1$$Register, $op2$$Register); 11693 %} 11694 ins_pipe(ialu_reg_reg); 11695 %} 11696 11697 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11698 %{ 11699 match(Set cr (OverflowSubI op1 op2)); 11700 11701 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11702 ins_encode %{ 11703 __ cmpl($op1$$Register, $op2$$constant); 11704 %} 11705 ins_pipe(ialu_reg_reg); 11706 %} 11707 11708 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11709 %{ 11710 match(Set cr (OverflowSubL op1 op2)); 11711 11712 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11713 ins_encode %{ 11714 __ cmpq($op1$$Register, $op2$$Register); 11715 %} 11716 ins_pipe(ialu_reg_reg); 11717 %} 11718 11719 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11720 %{ 11721 match(Set cr (OverflowSubL op1 op2)); 11722 11723 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11724 ins_encode %{ 11725 __ cmpq($op1$$Register, $op2$$constant); 11726 %} 11727 ins_pipe(ialu_reg_reg); 11728 %} 11729 11730 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11731 %{ 11732 match(Set cr (OverflowSubI zero op2)); 11733 effect(DEF cr, USE_KILL op2); 11734 11735 format %{ "negl $op2\t# overflow check int" %} 11736 ins_encode %{ 11737 __ negl($op2$$Register); 11738 %} 11739 ins_pipe(ialu_reg_reg); 11740 %} 11741 11742 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11743 %{ 11744 match(Set cr (OverflowSubL zero op2)); 11745 effect(DEF cr, USE_KILL op2); 11746 11747 format %{ "negq $op2\t# overflow check long" %} 11748 ins_encode %{ 11749 __ negq($op2$$Register); 11750 %} 11751 ins_pipe(ialu_reg_reg); 11752 %} 11753 11754 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11755 %{ 11756 match(Set cr (OverflowMulI op1 op2)); 11757 effect(DEF cr, USE_KILL op1, USE op2); 11758 11759 format %{ "imull $op1, $op2\t# overflow check int" %} 11760 ins_encode %{ 11761 __ imull($op1$$Register, $op2$$Register); 11762 %} 11763 ins_pipe(ialu_reg_reg_alu0); 11764 %} 11765 11766 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11767 %{ 11768 match(Set cr (OverflowMulI op1 op2)); 11769 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11770 11771 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11772 ins_encode %{ 11773 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11774 %} 11775 ins_pipe(ialu_reg_reg_alu0); 11776 %} 11777 11778 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11779 %{ 11780 match(Set cr (OverflowMulL op1 op2)); 11781 effect(DEF cr, USE_KILL op1, USE op2); 11782 11783 format %{ "imulq $op1, $op2\t# overflow check long" %} 11784 ins_encode %{ 11785 __ imulq($op1$$Register, $op2$$Register); 11786 %} 11787 ins_pipe(ialu_reg_reg_alu0); 11788 %} 11789 11790 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11791 %{ 11792 match(Set cr (OverflowMulL op1 op2)); 11793 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11794 11795 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11796 ins_encode %{ 11797 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11798 %} 11799 ins_pipe(ialu_reg_reg_alu0); 11800 %} 11801 11802 11803 //----------Control Flow Instructions------------------------------------------ 11804 // Signed compare Instructions 11805 11806 // XXX more variants!! 11807 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11808 %{ 11809 match(Set cr (CmpI op1 op2)); 11810 effect(DEF cr, USE op1, USE op2); 11811 11812 format %{ "cmpl $op1, $op2" %} 11813 ins_encode %{ 11814 __ cmpl($op1$$Register, $op2$$Register); 11815 %} 11816 ins_pipe(ialu_cr_reg_reg); 11817 %} 11818 11819 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11820 %{ 11821 match(Set cr (CmpI op1 op2)); 11822 11823 format %{ "cmpl $op1, $op2" %} 11824 ins_encode %{ 11825 __ cmpl($op1$$Register, $op2$$constant); 11826 %} 11827 ins_pipe(ialu_cr_reg_imm); 11828 %} 11829 11830 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11831 %{ 11832 match(Set cr (CmpI op1 (LoadI op2))); 11833 11834 ins_cost(500); // XXX 11835 format %{ "cmpl $op1, $op2" %} 11836 ins_encode %{ 11837 __ cmpl($op1$$Register, $op2$$Address); 11838 %} 11839 ins_pipe(ialu_cr_reg_mem); 11840 %} 11841 11842 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11843 %{ 11844 match(Set cr (CmpI src zero)); 11845 11846 format %{ "testl $src, $src" %} 11847 ins_encode %{ 11848 __ testl($src$$Register, $src$$Register); 11849 %} 11850 ins_pipe(ialu_cr_reg_imm); 11851 %} 11852 11853 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11854 %{ 11855 match(Set cr (CmpI (AndI src con) zero)); 11856 11857 format %{ "testl $src, $con" %} 11858 ins_encode %{ 11859 __ testl($src$$Register, $con$$constant); 11860 %} 11861 ins_pipe(ialu_cr_reg_imm); 11862 %} 11863 11864 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11865 %{ 11866 match(Set cr (CmpI (AndI src1 src2) zero)); 11867 11868 format %{ "testl $src1, $src2" %} 11869 ins_encode %{ 11870 __ testl($src1$$Register, $src2$$Register); 11871 %} 11872 ins_pipe(ialu_cr_reg_imm); 11873 %} 11874 11875 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11876 %{ 11877 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11878 11879 format %{ "testl $src, $mem" %} 11880 ins_encode %{ 11881 __ testl($src$$Register, $mem$$Address); 11882 %} 11883 ins_pipe(ialu_cr_reg_mem); 11884 %} 11885 11886 // Unsigned compare Instructions; really, same as signed except they 11887 // produce an rFlagsRegU instead of rFlagsReg. 11888 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11889 %{ 11890 match(Set cr (CmpU op1 op2)); 11891 11892 format %{ "cmpl $op1, $op2\t# unsigned" %} 11893 ins_encode %{ 11894 __ cmpl($op1$$Register, $op2$$Register); 11895 %} 11896 ins_pipe(ialu_cr_reg_reg); 11897 %} 11898 11899 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11900 %{ 11901 match(Set cr (CmpU op1 op2)); 11902 11903 format %{ "cmpl $op1, $op2\t# unsigned" %} 11904 ins_encode %{ 11905 __ cmpl($op1$$Register, $op2$$constant); 11906 %} 11907 ins_pipe(ialu_cr_reg_imm); 11908 %} 11909 11910 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11911 %{ 11912 match(Set cr (CmpU op1 (LoadI op2))); 11913 11914 ins_cost(500); // XXX 11915 format %{ "cmpl $op1, $op2\t# unsigned" %} 11916 ins_encode %{ 11917 __ cmpl($op1$$Register, $op2$$Address); 11918 %} 11919 ins_pipe(ialu_cr_reg_mem); 11920 %} 11921 11922 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11923 %{ 11924 match(Set cr (CmpU src zero)); 11925 11926 format %{ "testl $src, $src\t# unsigned" %} 11927 ins_encode %{ 11928 __ testl($src$$Register, $src$$Register); 11929 %} 11930 ins_pipe(ialu_cr_reg_imm); 11931 %} 11932 11933 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11934 %{ 11935 match(Set cr (CmpP op1 op2)); 11936 11937 format %{ "cmpq $op1, $op2\t# ptr" %} 11938 ins_encode %{ 11939 __ cmpq($op1$$Register, $op2$$Register); 11940 %} 11941 ins_pipe(ialu_cr_reg_reg); 11942 %} 11943 11944 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11945 %{ 11946 match(Set cr (CmpP op1 (LoadP op2))); 11947 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11948 11949 ins_cost(500); // XXX 11950 format %{ "cmpq $op1, $op2\t# ptr" %} 11951 ins_encode %{ 11952 __ cmpq($op1$$Register, $op2$$Address); 11953 %} 11954 ins_pipe(ialu_cr_reg_mem); 11955 %} 11956 11957 // XXX this is generalized by compP_rReg_mem??? 11958 // Compare raw pointer (used in out-of-heap check). 11959 // Only works because non-oop pointers must be raw pointers 11960 // and raw pointers have no anti-dependencies. 11961 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11962 %{ 11963 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11964 n->in(2)->as_Load()->barrier_data() == 0); 11965 match(Set cr (CmpP op1 (LoadP op2))); 11966 11967 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11968 ins_encode %{ 11969 __ cmpq($op1$$Register, $op2$$Address); 11970 %} 11971 ins_pipe(ialu_cr_reg_mem); 11972 %} 11973 11974 // This will generate a signed flags result. This should be OK since 11975 // any compare to a zero should be eq/neq. 11976 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11977 %{ 11978 match(Set cr (CmpP src zero)); 11979 11980 format %{ "testq $src, $src\t# ptr" %} 11981 ins_encode %{ 11982 __ testq($src$$Register, $src$$Register); 11983 %} 11984 ins_pipe(ialu_cr_reg_imm); 11985 %} 11986 11987 // This will generate a signed flags result. This should be OK since 11988 // any compare to a zero should be eq/neq. 11989 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11990 %{ 11991 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11992 n->in(1)->as_Load()->barrier_data() == 0); 11993 match(Set cr (CmpP (LoadP op) zero)); 11994 11995 ins_cost(500); // XXX 11996 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11997 ins_encode %{ 11998 __ testq($op$$Address, 0xFFFFFFFF); 11999 %} 12000 ins_pipe(ialu_cr_reg_imm); 12001 %} 12002 12003 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 12004 %{ 12005 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 12006 n->in(1)->as_Load()->barrier_data() == 0); 12007 match(Set cr (CmpP (LoadP mem) zero)); 12008 12009 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 12010 ins_encode %{ 12011 __ cmpq(r12, $mem$$Address); 12012 %} 12013 ins_pipe(ialu_cr_reg_mem); 12014 %} 12015 12016 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 12017 %{ 12018 match(Set cr (CmpN op1 op2)); 12019 12020 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12021 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 12022 ins_pipe(ialu_cr_reg_reg); 12023 %} 12024 12025 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 12026 %{ 12027 match(Set cr (CmpN src (LoadN mem))); 12028 12029 format %{ "cmpl $src, $mem\t# compressed ptr" %} 12030 ins_encode %{ 12031 __ cmpl($src$$Register, $mem$$Address); 12032 %} 12033 ins_pipe(ialu_cr_reg_mem); 12034 %} 12035 12036 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 12037 match(Set cr (CmpN op1 op2)); 12038 12039 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12040 ins_encode %{ 12041 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 12042 %} 12043 ins_pipe(ialu_cr_reg_imm); 12044 %} 12045 12046 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 12047 %{ 12048 match(Set cr (CmpN src (LoadN mem))); 12049 12050 format %{ "cmpl $mem, $src\t# compressed ptr" %} 12051 ins_encode %{ 12052 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 12053 %} 12054 ins_pipe(ialu_cr_reg_mem); 12055 %} 12056 12057 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 12058 match(Set cr (CmpN op1 op2)); 12059 12060 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 12061 ins_encode %{ 12062 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 12063 %} 12064 ins_pipe(ialu_cr_reg_imm); 12065 %} 12066 12067 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 12068 %{ 12069 match(Set cr (CmpN src (LoadNKlass mem))); 12070 12071 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 12072 ins_encode %{ 12073 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 12074 %} 12075 ins_pipe(ialu_cr_reg_mem); 12076 %} 12077 12078 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 12079 match(Set cr (CmpN src zero)); 12080 12081 format %{ "testl $src, $src\t# compressed ptr" %} 12082 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 12083 ins_pipe(ialu_cr_reg_imm); 12084 %} 12085 12086 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 12087 %{ 12088 predicate(CompressedOops::base() != nullptr); 12089 match(Set cr (CmpN (LoadN mem) zero)); 12090 12091 ins_cost(500); // XXX 12092 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 12093 ins_encode %{ 12094 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 12095 %} 12096 ins_pipe(ialu_cr_reg_mem); 12097 %} 12098 12099 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 12100 %{ 12101 predicate(CompressedOops::base() == nullptr); 12102 match(Set cr (CmpN (LoadN mem) zero)); 12103 12104 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 12105 ins_encode %{ 12106 __ cmpl(r12, $mem$$Address); 12107 %} 12108 ins_pipe(ialu_cr_reg_mem); 12109 %} 12110 12111 // Yanked all unsigned pointer compare operations. 12112 // Pointer compares are done with CmpP which is already unsigned. 12113 12114 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 12115 %{ 12116 match(Set cr (CmpL op1 op2)); 12117 12118 format %{ "cmpq $op1, $op2" %} 12119 ins_encode %{ 12120 __ cmpq($op1$$Register, $op2$$Register); 12121 %} 12122 ins_pipe(ialu_cr_reg_reg); 12123 %} 12124 12125 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 12126 %{ 12127 match(Set cr (CmpL op1 op2)); 12128 12129 format %{ "cmpq $op1, $op2" %} 12130 ins_encode %{ 12131 __ cmpq($op1$$Register, $op2$$constant); 12132 %} 12133 ins_pipe(ialu_cr_reg_imm); 12134 %} 12135 12136 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 12137 %{ 12138 match(Set cr (CmpL op1 (LoadL op2))); 12139 12140 format %{ "cmpq $op1, $op2" %} 12141 ins_encode %{ 12142 __ cmpq($op1$$Register, $op2$$Address); 12143 %} 12144 ins_pipe(ialu_cr_reg_mem); 12145 %} 12146 12147 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12148 %{ 12149 match(Set cr (CmpL src zero)); 12150 12151 format %{ "testq $src, $src" %} 12152 ins_encode %{ 12153 __ testq($src$$Register, $src$$Register); 12154 %} 12155 ins_pipe(ialu_cr_reg_imm); 12156 %} 12157 12158 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12159 %{ 12160 match(Set cr (CmpL (AndL src con) zero)); 12161 12162 format %{ "testq $src, $con\t# long" %} 12163 ins_encode %{ 12164 __ testq($src$$Register, $con$$constant); 12165 %} 12166 ins_pipe(ialu_cr_reg_imm); 12167 %} 12168 12169 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 12170 %{ 12171 match(Set cr (CmpL (AndL src1 src2) zero)); 12172 12173 format %{ "testq $src1, $src2\t# long" %} 12174 ins_encode %{ 12175 __ testq($src1$$Register, $src2$$Register); 12176 %} 12177 ins_pipe(ialu_cr_reg_imm); 12178 %} 12179 12180 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12181 %{ 12182 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12183 12184 format %{ "testq $src, $mem" %} 12185 ins_encode %{ 12186 __ testq($src$$Register, $mem$$Address); 12187 %} 12188 ins_pipe(ialu_cr_reg_mem); 12189 %} 12190 12191 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12192 %{ 12193 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12194 12195 format %{ "testq $src, $mem" %} 12196 ins_encode %{ 12197 __ testq($src$$Register, $mem$$Address); 12198 %} 12199 ins_pipe(ialu_cr_reg_mem); 12200 %} 12201 12202 // Manifest a CmpU result in an integer register. Very painful. 12203 // This is the test to avoid. 12204 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 12205 %{ 12206 match(Set dst (CmpU3 src1 src2)); 12207 effect(KILL flags); 12208 12209 ins_cost(275); // XXX 12210 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 12211 "movl $dst, -1\n\t" 12212 "jb,u done\n\t" 12213 "setne $dst\n\t" 12214 "movzbl $dst, $dst\n\t" 12215 "done:" %} 12216 ins_encode %{ 12217 Label done; 12218 __ cmpl($src1$$Register, $src2$$Register); 12219 __ movl($dst$$Register, -1); 12220 __ jccb(Assembler::below, done); 12221 __ setb(Assembler::notZero, $dst$$Register); 12222 __ movzbl($dst$$Register, $dst$$Register); 12223 __ bind(done); 12224 %} 12225 ins_pipe(pipe_slow); 12226 %} 12227 12228 // Manifest a CmpL result in an integer register. Very painful. 12229 // This is the test to avoid. 12230 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12231 %{ 12232 match(Set dst (CmpL3 src1 src2)); 12233 effect(KILL flags); 12234 12235 ins_cost(275); // XXX 12236 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12237 "movl $dst, -1\n\t" 12238 "jl,s done\n\t" 12239 "setne $dst\n\t" 12240 "movzbl $dst, $dst\n\t" 12241 "done:" %} 12242 ins_encode %{ 12243 Label done; 12244 __ cmpq($src1$$Register, $src2$$Register); 12245 __ movl($dst$$Register, -1); 12246 __ jccb(Assembler::less, done); 12247 __ setb(Assembler::notZero, $dst$$Register); 12248 __ movzbl($dst$$Register, $dst$$Register); 12249 __ bind(done); 12250 %} 12251 ins_pipe(pipe_slow); 12252 %} 12253 12254 // Manifest a CmpUL result in an integer register. Very painful. 12255 // This is the test to avoid. 12256 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12257 %{ 12258 match(Set dst (CmpUL3 src1 src2)); 12259 effect(KILL flags); 12260 12261 ins_cost(275); // XXX 12262 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12263 "movl $dst, -1\n\t" 12264 "jb,u done\n\t" 12265 "setne $dst\n\t" 12266 "movzbl $dst, $dst\n\t" 12267 "done:" %} 12268 ins_encode %{ 12269 Label done; 12270 __ cmpq($src1$$Register, $src2$$Register); 12271 __ movl($dst$$Register, -1); 12272 __ jccb(Assembler::below, done); 12273 __ setb(Assembler::notZero, $dst$$Register); 12274 __ movzbl($dst$$Register, $dst$$Register); 12275 __ bind(done); 12276 %} 12277 ins_pipe(pipe_slow); 12278 %} 12279 12280 // Unsigned long compare Instructions; really, same as signed long except they 12281 // produce an rFlagsRegU instead of rFlagsReg. 12282 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12283 %{ 12284 match(Set cr (CmpUL op1 op2)); 12285 12286 format %{ "cmpq $op1, $op2\t# unsigned" %} 12287 ins_encode %{ 12288 __ cmpq($op1$$Register, $op2$$Register); 12289 %} 12290 ins_pipe(ialu_cr_reg_reg); 12291 %} 12292 12293 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12294 %{ 12295 match(Set cr (CmpUL op1 op2)); 12296 12297 format %{ "cmpq $op1, $op2\t# unsigned" %} 12298 ins_encode %{ 12299 __ cmpq($op1$$Register, $op2$$constant); 12300 %} 12301 ins_pipe(ialu_cr_reg_imm); 12302 %} 12303 12304 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12305 %{ 12306 match(Set cr (CmpUL op1 (LoadL op2))); 12307 12308 format %{ "cmpq $op1, $op2\t# unsigned" %} 12309 ins_encode %{ 12310 __ cmpq($op1$$Register, $op2$$Address); 12311 %} 12312 ins_pipe(ialu_cr_reg_mem); 12313 %} 12314 12315 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12316 %{ 12317 match(Set cr (CmpUL src zero)); 12318 12319 format %{ "testq $src, $src\t# unsigned" %} 12320 ins_encode %{ 12321 __ testq($src$$Register, $src$$Register); 12322 %} 12323 ins_pipe(ialu_cr_reg_imm); 12324 %} 12325 12326 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12327 %{ 12328 match(Set cr (CmpI (LoadB mem) imm)); 12329 12330 ins_cost(125); 12331 format %{ "cmpb $mem, $imm" %} 12332 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12333 ins_pipe(ialu_cr_reg_mem); 12334 %} 12335 12336 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 12337 %{ 12338 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12339 12340 ins_cost(125); 12341 format %{ "testb $mem, $imm\t# ubyte" %} 12342 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12343 ins_pipe(ialu_cr_reg_mem); 12344 %} 12345 12346 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 12347 %{ 12348 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12349 12350 ins_cost(125); 12351 format %{ "testb $mem, $imm\t# byte" %} 12352 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12353 ins_pipe(ialu_cr_reg_mem); 12354 %} 12355 12356 //----------Max and Min-------------------------------------------------------- 12357 // Min Instructions 12358 12359 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12360 %{ 12361 effect(USE_DEF dst, USE src, USE cr); 12362 12363 format %{ "cmovlgt $dst, $src\t# min" %} 12364 ins_encode %{ 12365 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 12366 %} 12367 ins_pipe(pipe_cmov_reg); 12368 %} 12369 12370 12371 instruct minI_rReg(rRegI dst, rRegI src) 12372 %{ 12373 match(Set dst (MinI dst src)); 12374 12375 ins_cost(200); 12376 expand %{ 12377 rFlagsReg cr; 12378 compI_rReg(cr, dst, src); 12379 cmovI_reg_g(dst, src, cr); 12380 %} 12381 %} 12382 12383 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12384 %{ 12385 effect(USE_DEF dst, USE src, USE cr); 12386 12387 format %{ "cmovllt $dst, $src\t# max" %} 12388 ins_encode %{ 12389 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12390 %} 12391 ins_pipe(pipe_cmov_reg); 12392 %} 12393 12394 12395 instruct maxI_rReg(rRegI dst, rRegI src) 12396 %{ 12397 match(Set dst (MaxI dst src)); 12398 12399 ins_cost(200); 12400 expand %{ 12401 rFlagsReg cr; 12402 compI_rReg(cr, dst, src); 12403 cmovI_reg_l(dst, src, cr); 12404 %} 12405 %} 12406 12407 // ============================================================================ 12408 // Branch Instructions 12409 12410 // Jump Direct - Label defines a relative address from JMP+1 12411 instruct jmpDir(label labl) 12412 %{ 12413 match(Goto); 12414 effect(USE labl); 12415 12416 ins_cost(300); 12417 format %{ "jmp $labl" %} 12418 size(5); 12419 ins_encode %{ 12420 Label* L = $labl$$label; 12421 __ jmp(*L, false); // Always long jump 12422 %} 12423 ins_pipe(pipe_jmp); 12424 %} 12425 12426 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12427 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12428 %{ 12429 match(If cop cr); 12430 effect(USE labl); 12431 12432 ins_cost(300); 12433 format %{ "j$cop $labl" %} 12434 size(6); 12435 ins_encode %{ 12436 Label* L = $labl$$label; 12437 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12438 %} 12439 ins_pipe(pipe_jcc); 12440 %} 12441 12442 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12443 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12444 %{ 12445 match(CountedLoopEnd cop cr); 12446 effect(USE labl); 12447 12448 ins_cost(300); 12449 format %{ "j$cop $labl\t# loop end" %} 12450 size(6); 12451 ins_encode %{ 12452 Label* L = $labl$$label; 12453 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12454 %} 12455 ins_pipe(pipe_jcc); 12456 %} 12457 12458 // Jump Direct Conditional - using unsigned comparison 12459 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12460 match(If cop cmp); 12461 effect(USE labl); 12462 12463 ins_cost(300); 12464 format %{ "j$cop,u $labl" %} 12465 size(6); 12466 ins_encode %{ 12467 Label* L = $labl$$label; 12468 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12469 %} 12470 ins_pipe(pipe_jcc); 12471 %} 12472 12473 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12474 match(If cop cmp); 12475 effect(USE labl); 12476 12477 ins_cost(200); 12478 format %{ "j$cop,u $labl" %} 12479 size(6); 12480 ins_encode %{ 12481 Label* L = $labl$$label; 12482 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12483 %} 12484 ins_pipe(pipe_jcc); 12485 %} 12486 12487 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12488 match(If cop cmp); 12489 effect(USE labl); 12490 12491 ins_cost(200); 12492 format %{ $$template 12493 if ($cop$$cmpcode == Assembler::notEqual) { 12494 $$emit$$"jp,u $labl\n\t" 12495 $$emit$$"j$cop,u $labl" 12496 } else { 12497 $$emit$$"jp,u done\n\t" 12498 $$emit$$"j$cop,u $labl\n\t" 12499 $$emit$$"done:" 12500 } 12501 %} 12502 ins_encode %{ 12503 Label* l = $labl$$label; 12504 if ($cop$$cmpcode == Assembler::notEqual) { 12505 __ jcc(Assembler::parity, *l, false); 12506 __ jcc(Assembler::notEqual, *l, false); 12507 } else if ($cop$$cmpcode == Assembler::equal) { 12508 Label done; 12509 __ jccb(Assembler::parity, done); 12510 __ jcc(Assembler::equal, *l, false); 12511 __ bind(done); 12512 } else { 12513 ShouldNotReachHere(); 12514 } 12515 %} 12516 ins_pipe(pipe_jcc); 12517 %} 12518 12519 // ============================================================================ 12520 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12521 // superklass array for an instance of the superklass. Set a hidden 12522 // internal cache on a hit (cache is checked with exposed code in 12523 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12524 // encoding ALSO sets flags. 12525 12526 instruct partialSubtypeCheck(rdi_RegP result, 12527 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12528 rFlagsReg cr) 12529 %{ 12530 match(Set result (PartialSubtypeCheck sub super)); 12531 effect(KILL rcx, KILL cr); 12532 12533 ins_cost(1100); // slightly larger than the next version 12534 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12535 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12536 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12537 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12538 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12539 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12540 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12541 "miss:\t" %} 12542 12543 opcode(0x1); // Force a XOR of RDI 12544 ins_encode(enc_PartialSubtypeCheck()); 12545 ins_pipe(pipe_slow); 12546 %} 12547 12548 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12549 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12550 immP0 zero, 12551 rdi_RegP result) 12552 %{ 12553 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12554 effect(KILL rcx, KILL result); 12555 12556 ins_cost(1000); 12557 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12558 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12559 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12560 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12561 "jne,s miss\t\t# Missed: flags nz\n\t" 12562 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12563 "miss:\t" %} 12564 12565 opcode(0x0); // No need to XOR RDI 12566 ins_encode(enc_PartialSubtypeCheck()); 12567 ins_pipe(pipe_slow); 12568 %} 12569 12570 // ============================================================================ 12571 // Branch Instructions -- short offset versions 12572 // 12573 // These instructions are used to replace jumps of a long offset (the default 12574 // match) with jumps of a shorter offset. These instructions are all tagged 12575 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12576 // match rules in general matching. Instead, the ADLC generates a conversion 12577 // method in the MachNode which can be used to do in-place replacement of the 12578 // long variant with the shorter variant. The compiler will determine if a 12579 // branch can be taken by the is_short_branch_offset() predicate in the machine 12580 // specific code section of the file. 12581 12582 // Jump Direct - Label defines a relative address from JMP+1 12583 instruct jmpDir_short(label labl) %{ 12584 match(Goto); 12585 effect(USE labl); 12586 12587 ins_cost(300); 12588 format %{ "jmp,s $labl" %} 12589 size(2); 12590 ins_encode %{ 12591 Label* L = $labl$$label; 12592 __ jmpb(*L); 12593 %} 12594 ins_pipe(pipe_jmp); 12595 ins_short_branch(1); 12596 %} 12597 12598 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12599 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12600 match(If cop cr); 12601 effect(USE labl); 12602 12603 ins_cost(300); 12604 format %{ "j$cop,s $labl" %} 12605 size(2); 12606 ins_encode %{ 12607 Label* L = $labl$$label; 12608 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12609 %} 12610 ins_pipe(pipe_jcc); 12611 ins_short_branch(1); 12612 %} 12613 12614 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12615 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12616 match(CountedLoopEnd cop cr); 12617 effect(USE labl); 12618 12619 ins_cost(300); 12620 format %{ "j$cop,s $labl\t# loop end" %} 12621 size(2); 12622 ins_encode %{ 12623 Label* L = $labl$$label; 12624 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12625 %} 12626 ins_pipe(pipe_jcc); 12627 ins_short_branch(1); 12628 %} 12629 12630 // Jump Direct Conditional - using unsigned comparison 12631 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12632 match(If cop cmp); 12633 effect(USE labl); 12634 12635 ins_cost(300); 12636 format %{ "j$cop,us $labl" %} 12637 size(2); 12638 ins_encode %{ 12639 Label* L = $labl$$label; 12640 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12641 %} 12642 ins_pipe(pipe_jcc); 12643 ins_short_branch(1); 12644 %} 12645 12646 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12647 match(If cop cmp); 12648 effect(USE labl); 12649 12650 ins_cost(300); 12651 format %{ "j$cop,us $labl" %} 12652 size(2); 12653 ins_encode %{ 12654 Label* L = $labl$$label; 12655 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12656 %} 12657 ins_pipe(pipe_jcc); 12658 ins_short_branch(1); 12659 %} 12660 12661 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12662 match(If cop cmp); 12663 effect(USE labl); 12664 12665 ins_cost(300); 12666 format %{ $$template 12667 if ($cop$$cmpcode == Assembler::notEqual) { 12668 $$emit$$"jp,u,s $labl\n\t" 12669 $$emit$$"j$cop,u,s $labl" 12670 } else { 12671 $$emit$$"jp,u,s done\n\t" 12672 $$emit$$"j$cop,u,s $labl\n\t" 12673 $$emit$$"done:" 12674 } 12675 %} 12676 size(4); 12677 ins_encode %{ 12678 Label* l = $labl$$label; 12679 if ($cop$$cmpcode == Assembler::notEqual) { 12680 __ jccb(Assembler::parity, *l); 12681 __ jccb(Assembler::notEqual, *l); 12682 } else if ($cop$$cmpcode == Assembler::equal) { 12683 Label done; 12684 __ jccb(Assembler::parity, done); 12685 __ jccb(Assembler::equal, *l); 12686 __ bind(done); 12687 } else { 12688 ShouldNotReachHere(); 12689 } 12690 %} 12691 ins_pipe(pipe_jcc); 12692 ins_short_branch(1); 12693 %} 12694 12695 // ============================================================================ 12696 // inlined locking and unlocking 12697 12698 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12699 predicate(Compile::current()->use_rtm()); 12700 match(Set cr (FastLock object box)); 12701 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12702 ins_cost(300); 12703 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12704 ins_encode %{ 12705 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12706 $scr$$Register, $cx1$$Register, $cx2$$Register, r15_thread, 12707 _rtm_counters, _stack_rtm_counters, 12708 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12709 true, ra_->C->profile_rtm()); 12710 %} 12711 ins_pipe(pipe_slow); 12712 %} 12713 12714 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12715 predicate(!Compile::current()->use_rtm()); 12716 match(Set cr (FastLock object box)); 12717 effect(TEMP tmp, TEMP scr, USE_KILL box); 12718 ins_cost(300); 12719 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12720 ins_encode %{ 12721 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12722 $scr$$Register, noreg, noreg, r15_thread, nullptr, nullptr, nullptr, false, false); 12723 %} 12724 ins_pipe(pipe_slow); 12725 %} 12726 12727 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12728 match(Set cr (FastUnlock object box)); 12729 effect(TEMP tmp, USE_KILL box); 12730 ins_cost(300); 12731 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12732 ins_encode %{ 12733 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12734 %} 12735 ins_pipe(pipe_slow); 12736 %} 12737 12738 12739 // ============================================================================ 12740 // Safepoint Instructions 12741 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12742 %{ 12743 match(SafePoint poll); 12744 effect(KILL cr, USE poll); 12745 12746 format %{ "testl rax, [$poll]\t" 12747 "# Safepoint: poll for GC" %} 12748 ins_cost(125); 12749 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12750 ins_encode %{ 12751 __ relocate(relocInfo::poll_type); 12752 address pre_pc = __ pc(); 12753 __ testl(rax, Address($poll$$Register, 0)); 12754 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12755 %} 12756 ins_pipe(ialu_reg_mem); 12757 %} 12758 12759 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12760 match(Set dst (MaskAll src)); 12761 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12762 ins_encode %{ 12763 int mask_len = Matcher::vector_length(this); 12764 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12765 %} 12766 ins_pipe( pipe_slow ); 12767 %} 12768 12769 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12770 predicate(Matcher::vector_length(n) > 32); 12771 match(Set dst (MaskAll src)); 12772 effect(TEMP tmp); 12773 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12774 ins_encode %{ 12775 int mask_len = Matcher::vector_length(this); 12776 __ movslq($tmp$$Register, $src$$Register); 12777 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12778 %} 12779 ins_pipe( pipe_slow ); 12780 %} 12781 12782 // ============================================================================ 12783 // Procedure Call/Return Instructions 12784 // Call Java Static Instruction 12785 // Note: If this code changes, the corresponding ret_addr_offset() and 12786 // compute_padding() functions will have to be adjusted. 12787 instruct CallStaticJavaDirect(method meth) %{ 12788 match(CallStaticJava); 12789 effect(USE meth); 12790 12791 ins_cost(300); 12792 format %{ "call,static " %} 12793 opcode(0xE8); /* E8 cd */ 12794 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12795 ins_pipe(pipe_slow); 12796 ins_alignment(4); 12797 %} 12798 12799 // Call Java Dynamic Instruction 12800 // Note: If this code changes, the corresponding ret_addr_offset() and 12801 // compute_padding() functions will have to be adjusted. 12802 instruct CallDynamicJavaDirect(method meth) 12803 %{ 12804 match(CallDynamicJava); 12805 effect(USE meth); 12806 12807 ins_cost(300); 12808 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12809 "call,dynamic " %} 12810 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12811 ins_pipe(pipe_slow); 12812 ins_alignment(4); 12813 %} 12814 12815 // Call Runtime Instruction 12816 instruct CallRuntimeDirect(method meth) 12817 %{ 12818 match(CallRuntime); 12819 effect(USE meth); 12820 12821 ins_cost(300); 12822 format %{ "call,runtime " %} 12823 ins_encode(clear_avx, Java_To_Runtime(meth)); 12824 ins_pipe(pipe_slow); 12825 %} 12826 12827 // Call runtime without safepoint 12828 instruct CallLeafDirect(method meth) 12829 %{ 12830 match(CallLeaf); 12831 effect(USE meth); 12832 12833 ins_cost(300); 12834 format %{ "call_leaf,runtime " %} 12835 ins_encode(clear_avx, Java_To_Runtime(meth)); 12836 ins_pipe(pipe_slow); 12837 %} 12838 12839 // Call runtime without safepoint and with vector arguments 12840 instruct CallLeafDirectVector(method meth) 12841 %{ 12842 match(CallLeafVector); 12843 effect(USE meth); 12844 12845 ins_cost(300); 12846 format %{ "call_leaf,vector " %} 12847 ins_encode(Java_To_Runtime(meth)); 12848 ins_pipe(pipe_slow); 12849 %} 12850 12851 // Call runtime without safepoint 12852 // entry point is null, target holds the address to call 12853 instruct CallLeafNoFPInDirect(rRegP target) 12854 %{ 12855 predicate(n->as_Call()->entry_point() == nullptr); 12856 match(CallLeafNoFP target); 12857 12858 ins_cost(300); 12859 format %{ "call_leaf_nofp,runtime indirect " %} 12860 ins_encode %{ 12861 __ call($target$$Register); 12862 %} 12863 12864 ins_pipe(pipe_slow); 12865 %} 12866 12867 instruct CallLeafNoFPDirect(method meth) 12868 %{ 12869 predicate(n->as_Call()->entry_point() != nullptr); 12870 match(CallLeafNoFP); 12871 effect(USE meth); 12872 12873 ins_cost(300); 12874 format %{ "call_leaf_nofp,runtime " %} 12875 ins_encode(clear_avx, Java_To_Runtime(meth)); 12876 ins_pipe(pipe_slow); 12877 %} 12878 12879 // Return Instruction 12880 // Remove the return address & jump to it. 12881 // Notice: We always emit a nop after a ret to make sure there is room 12882 // for safepoint patching 12883 instruct Ret() 12884 %{ 12885 match(Return); 12886 12887 format %{ "ret" %} 12888 ins_encode %{ 12889 __ ret(0); 12890 %} 12891 ins_pipe(pipe_jmp); 12892 %} 12893 12894 // Tail Call; Jump from runtime stub to Java code. 12895 // Also known as an 'interprocedural jump'. 12896 // Target of jump will eventually return to caller. 12897 // TailJump below removes the return address. 12898 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12899 %{ 12900 match(TailCall jump_target method_ptr); 12901 12902 ins_cost(300); 12903 format %{ "jmp $jump_target\t# rbx holds method" %} 12904 ins_encode %{ 12905 __ jmp($jump_target$$Register); 12906 %} 12907 ins_pipe(pipe_jmp); 12908 %} 12909 12910 // Tail Jump; remove the return address; jump to target. 12911 // TailCall above leaves the return address around. 12912 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12913 %{ 12914 match(TailJump jump_target ex_oop); 12915 12916 ins_cost(300); 12917 format %{ "popq rdx\t# pop return address\n\t" 12918 "jmp $jump_target" %} 12919 ins_encode %{ 12920 __ popq(as_Register(RDX_enc)); 12921 __ jmp($jump_target$$Register); 12922 %} 12923 ins_pipe(pipe_jmp); 12924 %} 12925 12926 // Create exception oop: created by stack-crawling runtime code. 12927 // Created exception is now available to this handler, and is setup 12928 // just prior to jumping to this handler. No code emitted. 12929 instruct CreateException(rax_RegP ex_oop) 12930 %{ 12931 match(Set ex_oop (CreateEx)); 12932 12933 size(0); 12934 // use the following format syntax 12935 format %{ "# exception oop is in rax; no code emitted" %} 12936 ins_encode(); 12937 ins_pipe(empty); 12938 %} 12939 12940 // Rethrow exception: 12941 // The exception oop will come in the first argument position. 12942 // Then JUMP (not call) to the rethrow stub code. 12943 instruct RethrowException() 12944 %{ 12945 match(Rethrow); 12946 12947 // use the following format syntax 12948 format %{ "jmp rethrow_stub" %} 12949 ins_encode %{ 12950 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12951 %} 12952 ins_pipe(pipe_jmp); 12953 %} 12954 12955 // ============================================================================ 12956 // This name is KNOWN by the ADLC and cannot be changed. 12957 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12958 // for this guy. 12959 instruct tlsLoadP(r15_RegP dst) %{ 12960 match(Set dst (ThreadLocal)); 12961 effect(DEF dst); 12962 12963 size(0); 12964 format %{ "# TLS is in R15" %} 12965 ins_encode( /*empty encoding*/ ); 12966 ins_pipe(ialu_reg_reg); 12967 %} 12968 12969 12970 //----------PEEPHOLE RULES----------------------------------------------------- 12971 // These must follow all instruction definitions as they use the names 12972 // defined in the instructions definitions. 12973 // 12974 // peeppredicate ( rule_predicate ); 12975 // // the predicate unless which the peephole rule will be ignored 12976 // 12977 // peepmatch ( root_instr_name [preceding_instruction]* ); 12978 // 12979 // peepprocedure ( procedure_name ); 12980 // // provide a procedure name to perform the optimization, the procedure should 12981 // // reside in the architecture dependent peephole file, the method has the 12982 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12983 // // with the arguments being the basic block, the current node index inside the 12984 // // block, the register allocator, the functions upon invoked return a new node 12985 // // defined in peepreplace, and the rules of the nodes appearing in the 12986 // // corresponding peepmatch, the function return true if successful, else 12987 // // return false 12988 // 12989 // peepconstraint %{ 12990 // (instruction_number.operand_name relational_op instruction_number.operand_name 12991 // [, ...] ); 12992 // // instruction numbers are zero-based using left to right order in peepmatch 12993 // 12994 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12995 // // provide an instruction_number.operand_name for each operand that appears 12996 // // in the replacement instruction's match rule 12997 // 12998 // ---------VM FLAGS--------------------------------------------------------- 12999 // 13000 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13001 // 13002 // Each peephole rule is given an identifying number starting with zero and 13003 // increasing by one in the order seen by the parser. An individual peephole 13004 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13005 // on the command-line. 13006 // 13007 // ---------CURRENT LIMITATIONS---------------------------------------------- 13008 // 13009 // Only transformations inside a basic block (do we need more for peephole) 13010 // 13011 // ---------EXAMPLE---------------------------------------------------------- 13012 // 13013 // // pertinent parts of existing instructions in architecture description 13014 // instruct movI(rRegI dst, rRegI src) 13015 // %{ 13016 // match(Set dst (CopyI src)); 13017 // %} 13018 // 13019 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 13020 // %{ 13021 // match(Set dst (AddI dst src)); 13022 // effect(KILL cr); 13023 // %} 13024 // 13025 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 13026 // %{ 13027 // match(Set dst (AddI dst src)); 13028 // %} 13029 // 13030 // 1. Simple replacement 13031 // - Only match adjacent instructions in same basic block 13032 // - Only equality constraints 13033 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 13034 // - Only one replacement instruction 13035 // 13036 // // Change (inc mov) to lea 13037 // peephole %{ 13038 // // lea should only be emitted when beneficial 13039 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 13040 // // increment preceded by register-register move 13041 // peepmatch ( incI_rReg movI ); 13042 // // require that the destination register of the increment 13043 // // match the destination register of the move 13044 // peepconstraint ( 0.dst == 1.dst ); 13045 // // construct a replacement instruction that sets 13046 // // the destination to ( move's source register + one ) 13047 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 13048 // %} 13049 // 13050 // 2. Procedural replacement 13051 // - More flexible finding relevent nodes 13052 // - More flexible constraints 13053 // - More flexible transformations 13054 // - May utilise architecture-dependent API more effectively 13055 // - Currently only one replacement instruction due to adlc parsing capabilities 13056 // 13057 // // Change (inc mov) to lea 13058 // peephole %{ 13059 // // lea should only be emitted when beneficial 13060 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 13061 // // the rule numbers of these nodes inside are passed into the function below 13062 // peepmatch ( incI_rReg movI ); 13063 // // the method that takes the responsibility of transformation 13064 // peepprocedure ( inc_mov_to_lea ); 13065 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 13066 // // node is passed into the function above 13067 // peepreplace ( leaI_rReg_immI() ); 13068 // %} 13069 13070 // These instructions is not matched by the matcher but used by the peephole 13071 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 13072 %{ 13073 predicate(false); 13074 match(Set dst (AddI src1 src2)); 13075 format %{ "leal $dst, [$src1 + $src2]" %} 13076 ins_encode %{ 13077 Register dst = $dst$$Register; 13078 Register src1 = $src1$$Register; 13079 Register src2 = $src2$$Register; 13080 if (src1 != rbp && src1 != r13) { 13081 __ leal(dst, Address(src1, src2, Address::times_1)); 13082 } else { 13083 assert(src2 != rbp && src2 != r13, ""); 13084 __ leal(dst, Address(src2, src1, Address::times_1)); 13085 } 13086 %} 13087 ins_pipe(ialu_reg_reg); 13088 %} 13089 13090 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 13091 %{ 13092 predicate(false); 13093 match(Set dst (AddI src1 src2)); 13094 format %{ "leal $dst, [$src1 + $src2]" %} 13095 ins_encode %{ 13096 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 13097 %} 13098 ins_pipe(ialu_reg_reg); 13099 %} 13100 13101 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 13102 %{ 13103 predicate(false); 13104 match(Set dst (LShiftI src shift)); 13105 format %{ "leal $dst, [$src << $shift]" %} 13106 ins_encode %{ 13107 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 13108 Register src = $src$$Register; 13109 if (scale == Address::times_2 && src != rbp && src != r13) { 13110 __ leal($dst$$Register, Address(src, src, Address::times_1)); 13111 } else { 13112 __ leal($dst$$Register, Address(noreg, src, scale)); 13113 } 13114 %} 13115 ins_pipe(ialu_reg_reg); 13116 %} 13117 13118 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 13119 %{ 13120 predicate(false); 13121 match(Set dst (AddL src1 src2)); 13122 format %{ "leaq $dst, [$src1 + $src2]" %} 13123 ins_encode %{ 13124 Register dst = $dst$$Register; 13125 Register src1 = $src1$$Register; 13126 Register src2 = $src2$$Register; 13127 if (src1 != rbp && src1 != r13) { 13128 __ leaq(dst, Address(src1, src2, Address::times_1)); 13129 } else { 13130 assert(src2 != rbp && src2 != r13, ""); 13131 __ leaq(dst, Address(src2, src1, Address::times_1)); 13132 } 13133 %} 13134 ins_pipe(ialu_reg_reg); 13135 %} 13136 13137 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 13138 %{ 13139 predicate(false); 13140 match(Set dst (AddL src1 src2)); 13141 format %{ "leaq $dst, [$src1 + $src2]" %} 13142 ins_encode %{ 13143 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 13144 %} 13145 ins_pipe(ialu_reg_reg); 13146 %} 13147 13148 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 13149 %{ 13150 predicate(false); 13151 match(Set dst (LShiftL src shift)); 13152 format %{ "leaq $dst, [$src << $shift]" %} 13153 ins_encode %{ 13154 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 13155 Register src = $src$$Register; 13156 if (scale == Address::times_2 && src != rbp && src != r13) { 13157 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 13158 } else { 13159 __ leaq($dst$$Register, Address(noreg, src, scale)); 13160 } 13161 %} 13162 ins_pipe(ialu_reg_reg); 13163 %} 13164 13165 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 13166 // sal}) with lea instructions. The {add, sal} rules are beneficial in 13167 // processors with at least partial ALU support for lea 13168 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 13169 // beneficial for processors with full ALU support 13170 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 13171 13172 peephole 13173 %{ 13174 peeppredicate(VM_Version::supports_fast_2op_lea()); 13175 peepmatch (addI_rReg); 13176 peepprocedure (lea_coalesce_reg); 13177 peepreplace (leaI_rReg_rReg_peep()); 13178 %} 13179 13180 peephole 13181 %{ 13182 peeppredicate(VM_Version::supports_fast_2op_lea()); 13183 peepmatch (addI_rReg_imm); 13184 peepprocedure (lea_coalesce_imm); 13185 peepreplace (leaI_rReg_immI_peep()); 13186 %} 13187 13188 peephole 13189 %{ 13190 peeppredicate(VM_Version::supports_fast_3op_lea() || 13191 VM_Version::is_intel_cascade_lake()); 13192 peepmatch (incI_rReg); 13193 peepprocedure (lea_coalesce_imm); 13194 peepreplace (leaI_rReg_immI_peep()); 13195 %} 13196 13197 peephole 13198 %{ 13199 peeppredicate(VM_Version::supports_fast_3op_lea() || 13200 VM_Version::is_intel_cascade_lake()); 13201 peepmatch (decI_rReg); 13202 peepprocedure (lea_coalesce_imm); 13203 peepreplace (leaI_rReg_immI_peep()); 13204 %} 13205 13206 peephole 13207 %{ 13208 peeppredicate(VM_Version::supports_fast_2op_lea()); 13209 peepmatch (salI_rReg_immI2); 13210 peepprocedure (lea_coalesce_imm); 13211 peepreplace (leaI_rReg_immI2_peep()); 13212 %} 13213 13214 peephole 13215 %{ 13216 peeppredicate(VM_Version::supports_fast_2op_lea()); 13217 peepmatch (addL_rReg); 13218 peepprocedure (lea_coalesce_reg); 13219 peepreplace (leaL_rReg_rReg_peep()); 13220 %} 13221 13222 peephole 13223 %{ 13224 peeppredicate(VM_Version::supports_fast_2op_lea()); 13225 peepmatch (addL_rReg_imm); 13226 peepprocedure (lea_coalesce_imm); 13227 peepreplace (leaL_rReg_immL32_peep()); 13228 %} 13229 13230 peephole 13231 %{ 13232 peeppredicate(VM_Version::supports_fast_3op_lea() || 13233 VM_Version::is_intel_cascade_lake()); 13234 peepmatch (incL_rReg); 13235 peepprocedure (lea_coalesce_imm); 13236 peepreplace (leaL_rReg_immL32_peep()); 13237 %} 13238 13239 peephole 13240 %{ 13241 peeppredicate(VM_Version::supports_fast_3op_lea() || 13242 VM_Version::is_intel_cascade_lake()); 13243 peepmatch (decL_rReg); 13244 peepprocedure (lea_coalesce_imm); 13245 peepreplace (leaL_rReg_immL32_peep()); 13246 %} 13247 13248 peephole 13249 %{ 13250 peeppredicate(VM_Version::supports_fast_2op_lea()); 13251 peepmatch (salL_rReg_immI2); 13252 peepprocedure (lea_coalesce_imm); 13253 peepreplace (leaL_rReg_immI2_peep()); 13254 %} 13255 13256 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 13257 // The test instruction is redudanent in case the downstream instuctions (like JCC or CMOV) only use flags that are already set by the previous instruction 13258 13259 //int variant 13260 peephole 13261 %{ 13262 peepmatch (testI_reg); 13263 peepprocedure (test_may_remove); 13264 %} 13265 13266 //long variant 13267 peephole 13268 %{ 13269 peepmatch (testL_reg); 13270 peepprocedure (test_may_remove); 13271 %} 13272 13273 13274 //----------SMARTSPILL RULES--------------------------------------------------- 13275 // These must follow all instruction definitions as they use the names 13276 // defined in the instructions definitions.