1 // 2 // Copyright (c) 2003, 2024, 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 R11 long register 300 reg_class long_r11_reg(R11, R11_H); 301 302 // Singleton class for RAX int register 303 reg_class int_rax_reg(RAX); 304 305 // Singleton class for RBX int register 306 reg_class int_rbx_reg(RBX); 307 308 // Singleton class for RCX int register 309 reg_class int_rcx_reg(RCX); 310 311 // Singleton class for RDX int register 312 reg_class int_rdx_reg(RDX); 313 314 // Singleton class for RDI int register 315 reg_class int_rdi_reg(RDI); 316 317 // Singleton class for instruction pointer 318 // reg_class ip_reg(RIP); 319 320 %} 321 322 //----------SOURCE BLOCK------------------------------------------------------- 323 // This is a block of C++ code which provides values, functions, and 324 // definitions necessary in the rest of the architecture description 325 326 source_hpp %{ 327 328 #include "peephole_x86_64.hpp" 329 330 %} 331 332 // Register masks 333 source_hpp %{ 334 335 extern RegMask _ANY_REG_mask; 336 extern RegMask _PTR_REG_mask; 337 extern RegMask _PTR_REG_NO_RBP_mask; 338 extern RegMask _PTR_NO_RAX_REG_mask; 339 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 340 extern RegMask _LONG_REG_mask; 341 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 342 extern RegMask _LONG_NO_RCX_REG_mask; 343 extern RegMask _LONG_NO_RBP_R13_REG_mask; 344 extern RegMask _INT_REG_mask; 345 extern RegMask _INT_NO_RAX_RDX_REG_mask; 346 extern RegMask _INT_NO_RCX_REG_mask; 347 extern RegMask _INT_NO_RBP_R13_REG_mask; 348 extern RegMask _FLOAT_REG_mask; 349 350 extern RegMask _STACK_OR_PTR_REG_mask; 351 extern RegMask _STACK_OR_LONG_REG_mask; 352 extern RegMask _STACK_OR_INT_REG_mask; 353 354 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 355 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 356 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 357 358 %} 359 360 source %{ 361 #define RELOC_IMM64 Assembler::imm_operand 362 #define RELOC_DISP32 Assembler::disp32_operand 363 364 #define __ masm-> 365 366 RegMask _ANY_REG_mask; 367 RegMask _PTR_REG_mask; 368 RegMask _PTR_REG_NO_RBP_mask; 369 RegMask _PTR_NO_RAX_REG_mask; 370 RegMask _PTR_NO_RAX_RBX_REG_mask; 371 RegMask _LONG_REG_mask; 372 RegMask _LONG_NO_RAX_RDX_REG_mask; 373 RegMask _LONG_NO_RCX_REG_mask; 374 RegMask _LONG_NO_RBP_R13_REG_mask; 375 RegMask _INT_REG_mask; 376 RegMask _INT_NO_RAX_RDX_REG_mask; 377 RegMask _INT_NO_RCX_REG_mask; 378 RegMask _INT_NO_RBP_R13_REG_mask; 379 RegMask _FLOAT_REG_mask; 380 RegMask _STACK_OR_PTR_REG_mask; 381 RegMask _STACK_OR_LONG_REG_mask; 382 RegMask _STACK_OR_INT_REG_mask; 383 384 static bool need_r12_heapbase() { 385 return UseCompressedOops; 386 } 387 388 void reg_mask_init() { 389 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 390 // We derive a number of subsets from it. 391 _ANY_REG_mask = _ALL_REG_mask; 392 393 if (PreserveFramePointer) { 394 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 395 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 396 } 397 if (need_r12_heapbase()) { 398 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 399 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 400 } 401 402 _PTR_REG_mask = _ANY_REG_mask; 403 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 404 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 405 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 406 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 407 408 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 409 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 410 411 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 412 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 413 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 414 415 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 416 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 417 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 418 419 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 420 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 421 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 422 423 _LONG_REG_mask = _PTR_REG_mask; 424 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 425 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 426 427 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 428 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 429 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 430 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 431 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 432 433 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 434 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 435 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 436 437 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 438 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 439 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 440 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 441 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 442 443 _INT_REG_mask = _ALL_INT_REG_mask; 444 if (PreserveFramePointer) { 445 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 446 } 447 if (need_r12_heapbase()) { 448 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 449 } 450 451 _STACK_OR_INT_REG_mask = _INT_REG_mask; 452 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 453 454 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 455 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 456 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 457 458 _INT_NO_RCX_REG_mask = _INT_REG_mask; 459 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 460 461 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 462 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 463 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 464 465 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 466 // from the float_reg_legacy/float_reg_evex register class. 467 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 468 } 469 470 static bool generate_vzeroupper(Compile* C) { 471 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 472 } 473 474 static int clear_avx_size() { 475 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 476 } 477 478 // !!!!! Special hack to get all types of calls to specify the byte offset 479 // from the start of the call to the point where the return address 480 // will point. 481 int MachCallStaticJavaNode::ret_addr_offset() 482 { 483 int offset = 5; // 5 bytes from start of call to where return address points 484 offset += clear_avx_size(); 485 return offset; 486 } 487 488 int MachCallDynamicJavaNode::ret_addr_offset() 489 { 490 int offset = 15; // 15 bytes from start of call to where return address points 491 offset += clear_avx_size(); 492 return offset; 493 } 494 495 int MachCallRuntimeNode::ret_addr_offset() { 496 int offset = 13; // movq r10,#addr; callq (r10) 497 if (this->ideal_Opcode() != Op_CallLeafVector) { 498 offset += clear_avx_size(); 499 } 500 return offset; 501 } 502 // 503 // Compute padding required for nodes which need alignment 504 // 505 506 // The address of the call instruction needs to be 4-byte aligned to 507 // ensure that it does not span a cache line so that it can be patched. 508 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 509 { 510 current_offset += clear_avx_size(); // skip vzeroupper 511 current_offset += 1; // skip call opcode byte 512 return align_up(current_offset, alignment_required()) - current_offset; 513 } 514 515 // The address of the call instruction needs to be 4-byte aligned to 516 // ensure that it does not span a cache line so that it can be patched. 517 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 518 { 519 current_offset += clear_avx_size(); // skip vzeroupper 520 current_offset += 11; // skip movq instruction + call opcode byte 521 return align_up(current_offset, alignment_required()) - current_offset; 522 } 523 524 // This could be in MacroAssembler but it's fairly C2 specific 525 static void emit_cmpfp_fixup(MacroAssembler* masm) { 526 Label exit; 527 __ jccb(Assembler::noParity, exit); 528 __ pushf(); 529 // 530 // comiss/ucomiss instructions set ZF,PF,CF flags and 531 // zero OF,AF,SF for NaN values. 532 // Fixup flags by zeroing ZF,PF so that compare of NaN 533 // values returns 'less than' result (CF is set). 534 // Leave the rest of flags unchanged. 535 // 536 // 7 6 5 4 3 2 1 0 537 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 538 // 0 0 1 0 1 0 1 1 (0x2B) 539 // 540 __ andq(Address(rsp, 0), 0xffffff2b); 541 __ popf(); 542 __ bind(exit); 543 } 544 545 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 546 Label done; 547 __ movl(dst, -1); 548 __ jcc(Assembler::parity, done); 549 __ jcc(Assembler::below, done); 550 __ setb(Assembler::notEqual, dst); 551 __ movzbl(dst, dst); 552 __ bind(done); 553 } 554 555 // Math.min() # Math.max() 556 // -------------------------- 557 // ucomis[s/d] # 558 // ja -> b # a 559 // jp -> NaN # NaN 560 // jb -> a # b 561 // je # 562 // |-jz -> a | b # a & b 563 // | -> a # 564 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 565 XMMRegister a, XMMRegister b, 566 XMMRegister xmmt, Register rt, 567 bool min, bool single) { 568 569 Label nan, zero, below, above, done; 570 571 if (single) 572 __ ucomiss(a, b); 573 else 574 __ ucomisd(a, b); 575 576 if (dst->encoding() != (min ? b : a)->encoding()) 577 __ jccb(Assembler::above, above); // CF=0 & ZF=0 578 else 579 __ jccb(Assembler::above, done); 580 581 __ jccb(Assembler::parity, nan); // PF=1 582 __ jccb(Assembler::below, below); // CF=1 583 584 // equal 585 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 586 if (single) { 587 __ ucomiss(a, xmmt); 588 __ jccb(Assembler::equal, zero); 589 590 __ movflt(dst, a); 591 __ jmp(done); 592 } 593 else { 594 __ ucomisd(a, xmmt); 595 __ jccb(Assembler::equal, zero); 596 597 __ movdbl(dst, a); 598 __ jmp(done); 599 } 600 601 __ bind(zero); 602 if (min) 603 __ vpor(dst, a, b, Assembler::AVX_128bit); 604 else 605 __ vpand(dst, a, b, Assembler::AVX_128bit); 606 607 __ jmp(done); 608 609 __ bind(above); 610 if (single) 611 __ movflt(dst, min ? b : a); 612 else 613 __ movdbl(dst, min ? b : a); 614 615 __ jmp(done); 616 617 __ bind(nan); 618 if (single) { 619 __ movl(rt, 0x7fc00000); // Float.NaN 620 __ movdl(dst, rt); 621 } 622 else { 623 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 624 __ movdq(dst, rt); 625 } 626 __ jmp(done); 627 628 __ bind(below); 629 if (single) 630 __ movflt(dst, min ? a : b); 631 else 632 __ movdbl(dst, min ? a : b); 633 634 __ bind(done); 635 } 636 637 //============================================================================= 638 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 639 640 int ConstantTable::calculate_table_base_offset() const { 641 return 0; // absolute addressing, no offset 642 } 643 644 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 645 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 646 ShouldNotReachHere(); 647 } 648 649 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 650 // Empty encoding 651 } 652 653 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 654 return 0; 655 } 656 657 #ifndef PRODUCT 658 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 659 st->print("# MachConstantBaseNode (empty encoding)"); 660 } 661 #endif 662 663 664 //============================================================================= 665 #ifndef PRODUCT 666 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 667 Compile* C = ra_->C; 668 669 int framesize = C->output()->frame_size_in_bytes(); 670 int bangsize = C->output()->bang_size_in_bytes(); 671 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 672 // Remove wordSize for return addr which is already pushed. 673 framesize -= wordSize; 674 675 if (C->output()->need_stack_bang(bangsize)) { 676 framesize -= wordSize; 677 st->print("# stack bang (%d bytes)", bangsize); 678 st->print("\n\t"); 679 st->print("pushq rbp\t# Save rbp"); 680 if (PreserveFramePointer) { 681 st->print("\n\t"); 682 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 683 } 684 if (framesize) { 685 st->print("\n\t"); 686 st->print("subq rsp, #%d\t# Create frame",framesize); 687 } 688 } else { 689 st->print("subq rsp, #%d\t# Create frame",framesize); 690 st->print("\n\t"); 691 framesize -= wordSize; 692 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 693 if (PreserveFramePointer) { 694 st->print("\n\t"); 695 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 696 if (framesize > 0) { 697 st->print("\n\t"); 698 st->print("addq rbp, #%d", framesize); 699 } 700 } 701 } 702 703 if (VerifyStackAtCalls) { 704 st->print("\n\t"); 705 framesize -= wordSize; 706 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 707 #ifdef ASSERT 708 st->print("\n\t"); 709 st->print("# stack alignment check"); 710 #endif 711 } 712 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 713 st->print("\n\t"); 714 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 715 st->print("\n\t"); 716 st->print("je fast_entry\t"); 717 st->print("\n\t"); 718 st->print("call #nmethod_entry_barrier_stub\t"); 719 st->print("\n\tfast_entry:"); 720 } 721 st->cr(); 722 } 723 #endif 724 725 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 726 Compile* C = ra_->C; 727 728 int framesize = C->output()->frame_size_in_bytes(); 729 int bangsize = C->output()->bang_size_in_bytes(); 730 731 if (C->clinit_barrier_on_entry()) { 732 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 733 assert(!C->method()->holder()->is_not_initialized() || C->do_clinit_barriers(), "initialization should have been started"); 734 735 Label L_skip_barrier; 736 Register klass = rscratch1; 737 738 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 739 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 740 741 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 742 743 __ bind(L_skip_barrier); 744 } 745 746 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 747 748 C->output()->set_frame_complete(__ offset()); 749 750 if (C->has_mach_constant_base_node()) { 751 // NOTE: We set the table base offset here because users might be 752 // emitted before MachConstantBaseNode. 753 ConstantTable& constant_table = C->output()->constant_table(); 754 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 755 } 756 } 757 758 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 759 { 760 return MachNode::size(ra_); // too many variables; just compute it 761 // the hard way 762 } 763 764 int MachPrologNode::reloc() const 765 { 766 return 0; // a large enough number 767 } 768 769 //============================================================================= 770 #ifndef PRODUCT 771 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 772 { 773 Compile* C = ra_->C; 774 if (generate_vzeroupper(C)) { 775 st->print("vzeroupper"); 776 st->cr(); st->print("\t"); 777 } 778 779 int framesize = C->output()->frame_size_in_bytes(); 780 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 781 // Remove word for return adr already pushed 782 // and RBP 783 framesize -= 2*wordSize; 784 785 if (framesize) { 786 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 787 st->print("\t"); 788 } 789 790 st->print_cr("popq rbp"); 791 if (do_polling() && C->is_method_compilation()) { 792 st->print("\t"); 793 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 794 "ja #safepoint_stub\t" 795 "# Safepoint: poll for GC"); 796 } 797 } 798 #endif 799 800 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 801 { 802 Compile* C = ra_->C; 803 804 if (generate_vzeroupper(C)) { 805 // Clear upper bits of YMM registers when current compiled code uses 806 // wide vectors to avoid AVX <-> SSE transition penalty during call. 807 __ vzeroupper(); 808 } 809 810 int framesize = C->output()->frame_size_in_bytes(); 811 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 812 // Remove word for return adr already pushed 813 // and RBP 814 framesize -= 2*wordSize; 815 816 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 817 818 if (framesize) { 819 __ addq(rsp, framesize); 820 } 821 822 __ popq(rbp); 823 824 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 825 __ reserved_stack_check(); 826 } 827 828 if (do_polling() && C->is_method_compilation()) { 829 Label dummy_label; 830 Label* code_stub = &dummy_label; 831 if (!C->output()->in_scratch_emit_size()) { 832 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 833 C->output()->add_stub(stub); 834 code_stub = &stub->entry(); 835 } 836 __ relocate(relocInfo::poll_return_type); 837 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 838 } 839 } 840 841 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 842 { 843 return MachNode::size(ra_); // too many variables; just compute it 844 // the hard way 845 } 846 847 int MachEpilogNode::reloc() const 848 { 849 return 2; // a large enough number 850 } 851 852 const Pipeline* MachEpilogNode::pipeline() const 853 { 854 return MachNode::pipeline_class(); 855 } 856 857 //============================================================================= 858 859 enum RC { 860 rc_bad, 861 rc_int, 862 rc_kreg, 863 rc_float, 864 rc_stack 865 }; 866 867 static enum RC rc_class(OptoReg::Name reg) 868 { 869 if( !OptoReg::is_valid(reg) ) return rc_bad; 870 871 if (OptoReg::is_stack(reg)) return rc_stack; 872 873 VMReg r = OptoReg::as_VMReg(reg); 874 875 if (r->is_Register()) return rc_int; 876 877 if (r->is_KRegister()) return rc_kreg; 878 879 assert(r->is_XMMRegister(), "must be"); 880 return rc_float; 881 } 882 883 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 884 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 885 int src_hi, int dst_hi, uint ireg, outputStream* st); 886 887 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 888 int stack_offset, int reg, uint ireg, outputStream* st); 889 890 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 891 int dst_offset, uint ireg, outputStream* st) { 892 if (masm) { 893 switch (ireg) { 894 case Op_VecS: 895 __ movq(Address(rsp, -8), rax); 896 __ movl(rax, Address(rsp, src_offset)); 897 __ movl(Address(rsp, dst_offset), rax); 898 __ movq(rax, Address(rsp, -8)); 899 break; 900 case Op_VecD: 901 __ pushq(Address(rsp, src_offset)); 902 __ popq (Address(rsp, dst_offset)); 903 break; 904 case Op_VecX: 905 __ pushq(Address(rsp, src_offset)); 906 __ popq (Address(rsp, dst_offset)); 907 __ pushq(Address(rsp, src_offset+8)); 908 __ popq (Address(rsp, dst_offset+8)); 909 break; 910 case Op_VecY: 911 __ vmovdqu(Address(rsp, -32), xmm0); 912 __ vmovdqu(xmm0, Address(rsp, src_offset)); 913 __ vmovdqu(Address(rsp, dst_offset), xmm0); 914 __ vmovdqu(xmm0, Address(rsp, -32)); 915 break; 916 case Op_VecZ: 917 __ evmovdquq(Address(rsp, -64), xmm0, 2); 918 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 919 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 920 __ evmovdquq(xmm0, Address(rsp, -64), 2); 921 break; 922 default: 923 ShouldNotReachHere(); 924 } 925 #ifndef PRODUCT 926 } else { 927 switch (ireg) { 928 case Op_VecS: 929 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 930 "movl rax, [rsp + #%d]\n\t" 931 "movl [rsp + #%d], rax\n\t" 932 "movq rax, [rsp - #8]", 933 src_offset, dst_offset); 934 break; 935 case Op_VecD: 936 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 937 "popq [rsp + #%d]", 938 src_offset, dst_offset); 939 break; 940 case Op_VecX: 941 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 942 "popq [rsp + #%d]\n\t" 943 "pushq [rsp + #%d]\n\t" 944 "popq [rsp + #%d]", 945 src_offset, dst_offset, src_offset+8, dst_offset+8); 946 break; 947 case Op_VecY: 948 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 949 "vmovdqu xmm0, [rsp + #%d]\n\t" 950 "vmovdqu [rsp + #%d], xmm0\n\t" 951 "vmovdqu xmm0, [rsp - #32]", 952 src_offset, dst_offset); 953 break; 954 case Op_VecZ: 955 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 956 "vmovdqu xmm0, [rsp + #%d]\n\t" 957 "vmovdqu [rsp + #%d], xmm0\n\t" 958 "vmovdqu xmm0, [rsp - #64]", 959 src_offset, dst_offset); 960 break; 961 default: 962 ShouldNotReachHere(); 963 } 964 #endif 965 } 966 } 967 968 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 969 PhaseRegAlloc* ra_, 970 bool do_size, 971 outputStream* st) const { 972 assert(masm != nullptr || st != nullptr, "sanity"); 973 // Get registers to move 974 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 975 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 976 OptoReg::Name dst_second = ra_->get_reg_second(this); 977 OptoReg::Name dst_first = ra_->get_reg_first(this); 978 979 enum RC src_second_rc = rc_class(src_second); 980 enum RC src_first_rc = rc_class(src_first); 981 enum RC dst_second_rc = rc_class(dst_second); 982 enum RC dst_first_rc = rc_class(dst_first); 983 984 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 985 "must move at least 1 register" ); 986 987 if (src_first == dst_first && src_second == dst_second) { 988 // Self copy, no move 989 return 0; 990 } 991 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 992 uint ireg = ideal_reg(); 993 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 994 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 995 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 996 // mem -> mem 997 int src_offset = ra_->reg2offset(src_first); 998 int dst_offset = ra_->reg2offset(dst_first); 999 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1000 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1001 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1002 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1003 int stack_offset = ra_->reg2offset(dst_first); 1004 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1005 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1006 int stack_offset = ra_->reg2offset(src_first); 1007 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1008 } else { 1009 ShouldNotReachHere(); 1010 } 1011 return 0; 1012 } 1013 if (src_first_rc == rc_stack) { 1014 // mem -> 1015 if (dst_first_rc == rc_stack) { 1016 // mem -> mem 1017 assert(src_second != dst_first, "overlap"); 1018 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1019 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1020 // 64-bit 1021 int src_offset = ra_->reg2offset(src_first); 1022 int dst_offset = ra_->reg2offset(dst_first); 1023 if (masm) { 1024 __ pushq(Address(rsp, src_offset)); 1025 __ popq (Address(rsp, dst_offset)); 1026 #ifndef PRODUCT 1027 } else { 1028 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1029 "popq [rsp + #%d]", 1030 src_offset, dst_offset); 1031 #endif 1032 } 1033 } else { 1034 // 32-bit 1035 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1036 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1037 // No pushl/popl, so: 1038 int src_offset = ra_->reg2offset(src_first); 1039 int dst_offset = ra_->reg2offset(dst_first); 1040 if (masm) { 1041 __ movq(Address(rsp, -8), rax); 1042 __ movl(rax, Address(rsp, src_offset)); 1043 __ movl(Address(rsp, dst_offset), rax); 1044 __ movq(rax, Address(rsp, -8)); 1045 #ifndef PRODUCT 1046 } else { 1047 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1048 "movl rax, [rsp + #%d]\n\t" 1049 "movl [rsp + #%d], rax\n\t" 1050 "movq rax, [rsp - #8]", 1051 src_offset, dst_offset); 1052 #endif 1053 } 1054 } 1055 return 0; 1056 } else if (dst_first_rc == rc_int) { 1057 // mem -> gpr 1058 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1059 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1060 // 64-bit 1061 int offset = ra_->reg2offset(src_first); 1062 if (masm) { 1063 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1064 #ifndef PRODUCT 1065 } else { 1066 st->print("movq %s, [rsp + #%d]\t# spill", 1067 Matcher::regName[dst_first], 1068 offset); 1069 #endif 1070 } 1071 } else { 1072 // 32-bit 1073 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1074 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1075 int offset = ra_->reg2offset(src_first); 1076 if (masm) { 1077 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1078 #ifndef PRODUCT 1079 } else { 1080 st->print("movl %s, [rsp + #%d]\t# spill", 1081 Matcher::regName[dst_first], 1082 offset); 1083 #endif 1084 } 1085 } 1086 return 0; 1087 } else if (dst_first_rc == rc_float) { 1088 // mem-> xmm 1089 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1090 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1091 // 64-bit 1092 int offset = ra_->reg2offset(src_first); 1093 if (masm) { 1094 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1095 #ifndef PRODUCT 1096 } else { 1097 st->print("%s %s, [rsp + #%d]\t# spill", 1098 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1099 Matcher::regName[dst_first], 1100 offset); 1101 #endif 1102 } 1103 } else { 1104 // 32-bit 1105 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1106 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1107 int offset = ra_->reg2offset(src_first); 1108 if (masm) { 1109 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1110 #ifndef PRODUCT 1111 } else { 1112 st->print("movss %s, [rsp + #%d]\t# spill", 1113 Matcher::regName[dst_first], 1114 offset); 1115 #endif 1116 } 1117 } 1118 return 0; 1119 } else if (dst_first_rc == rc_kreg) { 1120 // mem -> kreg 1121 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1122 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1123 // 64-bit 1124 int offset = ra_->reg2offset(src_first); 1125 if (masm) { 1126 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1127 #ifndef PRODUCT 1128 } else { 1129 st->print("kmovq %s, [rsp + #%d]\t# spill", 1130 Matcher::regName[dst_first], 1131 offset); 1132 #endif 1133 } 1134 } 1135 return 0; 1136 } 1137 } else if (src_first_rc == rc_int) { 1138 // gpr -> 1139 if (dst_first_rc == rc_stack) { 1140 // gpr -> mem 1141 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1142 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1143 // 64-bit 1144 int offset = ra_->reg2offset(dst_first); 1145 if (masm) { 1146 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1147 #ifndef PRODUCT 1148 } else { 1149 st->print("movq [rsp + #%d], %s\t# spill", 1150 offset, 1151 Matcher::regName[src_first]); 1152 #endif 1153 } 1154 } else { 1155 // 32-bit 1156 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1157 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1158 int offset = ra_->reg2offset(dst_first); 1159 if (masm) { 1160 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1161 #ifndef PRODUCT 1162 } else { 1163 st->print("movl [rsp + #%d], %s\t# spill", 1164 offset, 1165 Matcher::regName[src_first]); 1166 #endif 1167 } 1168 } 1169 return 0; 1170 } else if (dst_first_rc == rc_int) { 1171 // gpr -> gpr 1172 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1173 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1174 // 64-bit 1175 if (masm) { 1176 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1177 as_Register(Matcher::_regEncode[src_first])); 1178 #ifndef PRODUCT 1179 } else { 1180 st->print("movq %s, %s\t# spill", 1181 Matcher::regName[dst_first], 1182 Matcher::regName[src_first]); 1183 #endif 1184 } 1185 return 0; 1186 } else { 1187 // 32-bit 1188 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1189 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1190 if (masm) { 1191 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1192 as_Register(Matcher::_regEncode[src_first])); 1193 #ifndef PRODUCT 1194 } else { 1195 st->print("movl %s, %s\t# spill", 1196 Matcher::regName[dst_first], 1197 Matcher::regName[src_first]); 1198 #endif 1199 } 1200 return 0; 1201 } 1202 } else if (dst_first_rc == rc_float) { 1203 // gpr -> xmm 1204 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1205 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1206 // 64-bit 1207 if (masm) { 1208 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1209 #ifndef PRODUCT 1210 } else { 1211 st->print("movdq %s, %s\t# spill", 1212 Matcher::regName[dst_first], 1213 Matcher::regName[src_first]); 1214 #endif 1215 } 1216 } else { 1217 // 32-bit 1218 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1219 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1220 if (masm) { 1221 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1222 #ifndef PRODUCT 1223 } else { 1224 st->print("movdl %s, %s\t# spill", 1225 Matcher::regName[dst_first], 1226 Matcher::regName[src_first]); 1227 #endif 1228 } 1229 } 1230 return 0; 1231 } else if (dst_first_rc == rc_kreg) { 1232 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1233 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1234 // 64-bit 1235 if (masm) { 1236 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1237 #ifndef PRODUCT 1238 } else { 1239 st->print("kmovq %s, %s\t# spill", 1240 Matcher::regName[dst_first], 1241 Matcher::regName[src_first]); 1242 #endif 1243 } 1244 } 1245 Unimplemented(); 1246 return 0; 1247 } 1248 } else if (src_first_rc == rc_float) { 1249 // xmm -> 1250 if (dst_first_rc == rc_stack) { 1251 // xmm -> mem 1252 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1253 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1254 // 64-bit 1255 int offset = ra_->reg2offset(dst_first); 1256 if (masm) { 1257 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1258 #ifndef PRODUCT 1259 } else { 1260 st->print("movsd [rsp + #%d], %s\t# spill", 1261 offset, 1262 Matcher::regName[src_first]); 1263 #endif 1264 } 1265 } else { 1266 // 32-bit 1267 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1268 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1269 int offset = ra_->reg2offset(dst_first); 1270 if (masm) { 1271 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1272 #ifndef PRODUCT 1273 } else { 1274 st->print("movss [rsp + #%d], %s\t# spill", 1275 offset, 1276 Matcher::regName[src_first]); 1277 #endif 1278 } 1279 } 1280 return 0; 1281 } else if (dst_first_rc == rc_int) { 1282 // xmm -> gpr 1283 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1284 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1285 // 64-bit 1286 if (masm) { 1287 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1288 #ifndef PRODUCT 1289 } else { 1290 st->print("movdq %s, %s\t# spill", 1291 Matcher::regName[dst_first], 1292 Matcher::regName[src_first]); 1293 #endif 1294 } 1295 } else { 1296 // 32-bit 1297 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1298 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1299 if (masm) { 1300 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1301 #ifndef PRODUCT 1302 } else { 1303 st->print("movdl %s, %s\t# spill", 1304 Matcher::regName[dst_first], 1305 Matcher::regName[src_first]); 1306 #endif 1307 } 1308 } 1309 return 0; 1310 } else if (dst_first_rc == rc_float) { 1311 // xmm -> xmm 1312 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1313 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1314 // 64-bit 1315 if (masm) { 1316 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1317 #ifndef PRODUCT 1318 } else { 1319 st->print("%s %s, %s\t# spill", 1320 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1321 Matcher::regName[dst_first], 1322 Matcher::regName[src_first]); 1323 #endif 1324 } 1325 } else { 1326 // 32-bit 1327 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1328 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1329 if (masm) { 1330 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1331 #ifndef PRODUCT 1332 } else { 1333 st->print("%s %s, %s\t# spill", 1334 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1335 Matcher::regName[dst_first], 1336 Matcher::regName[src_first]); 1337 #endif 1338 } 1339 } 1340 return 0; 1341 } else if (dst_first_rc == rc_kreg) { 1342 assert(false, "Illegal spilling"); 1343 return 0; 1344 } 1345 } else if (src_first_rc == rc_kreg) { 1346 if (dst_first_rc == rc_stack) { 1347 // mem -> kreg 1348 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1349 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1350 // 64-bit 1351 int offset = ra_->reg2offset(dst_first); 1352 if (masm) { 1353 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1354 #ifndef PRODUCT 1355 } else { 1356 st->print("kmovq [rsp + #%d] , %s\t# spill", 1357 offset, 1358 Matcher::regName[src_first]); 1359 #endif 1360 } 1361 } 1362 return 0; 1363 } else if (dst_first_rc == rc_int) { 1364 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1365 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1366 // 64-bit 1367 if (masm) { 1368 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1369 #ifndef PRODUCT 1370 } else { 1371 st->print("kmovq %s, %s\t# spill", 1372 Matcher::regName[dst_first], 1373 Matcher::regName[src_first]); 1374 #endif 1375 } 1376 } 1377 Unimplemented(); 1378 return 0; 1379 } else if (dst_first_rc == rc_kreg) { 1380 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1381 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1382 // 64-bit 1383 if (masm) { 1384 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1385 #ifndef PRODUCT 1386 } else { 1387 st->print("kmovq %s, %s\t# spill", 1388 Matcher::regName[dst_first], 1389 Matcher::regName[src_first]); 1390 #endif 1391 } 1392 } 1393 return 0; 1394 } else if (dst_first_rc == rc_float) { 1395 assert(false, "Illegal spill"); 1396 return 0; 1397 } 1398 } 1399 1400 assert(0," foo "); 1401 Unimplemented(); 1402 return 0; 1403 } 1404 1405 #ifndef PRODUCT 1406 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1407 implementation(nullptr, ra_, false, st); 1408 } 1409 #endif 1410 1411 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1412 implementation(masm, ra_, false, nullptr); 1413 } 1414 1415 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1416 return MachNode::size(ra_); 1417 } 1418 1419 //============================================================================= 1420 #ifndef PRODUCT 1421 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1422 { 1423 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1424 int reg = ra_->get_reg_first(this); 1425 st->print("leaq %s, [rsp + #%d]\t# box lock", 1426 Matcher::regName[reg], offset); 1427 } 1428 #endif 1429 1430 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1431 { 1432 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1433 int reg = ra_->get_encode(this); 1434 1435 __ lea(as_Register(reg), Address(rsp, offset)); 1436 } 1437 1438 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1439 { 1440 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1441 return (offset < 0x80) ? 5 : 8; // REX 1442 } 1443 1444 //============================================================================= 1445 #ifndef PRODUCT 1446 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1447 { 1448 if (UseCompressedClassPointers) { 1449 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1450 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1451 } else { 1452 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1453 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1454 } 1455 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1456 } 1457 #endif 1458 1459 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1460 { 1461 __ ic_check(InteriorEntryAlignment); 1462 } 1463 1464 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1465 { 1466 return MachNode::size(ra_); // too many variables; just compute it 1467 // the hard way 1468 } 1469 1470 1471 //============================================================================= 1472 1473 bool Matcher::supports_vector_calling_convention(void) { 1474 if (EnableVectorSupport && UseVectorStubs) { 1475 return true; 1476 } 1477 return false; 1478 } 1479 1480 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1481 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1482 int lo = XMM0_num; 1483 int hi = XMM0b_num; 1484 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1485 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1486 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1487 return OptoRegPair(hi, lo); 1488 } 1489 1490 // Is this branch offset short enough that a short branch can be used? 1491 // 1492 // NOTE: If the platform does not provide any short branch variants, then 1493 // this method should return false for offset 0. 1494 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1495 // The passed offset is relative to address of the branch. 1496 // On 86 a branch displacement is calculated relative to address 1497 // of a next instruction. 1498 offset -= br_size; 1499 1500 // the short version of jmpConUCF2 contains multiple branches, 1501 // making the reach slightly less 1502 if (rule == jmpConUCF2_rule) 1503 return (-126 <= offset && offset <= 125); 1504 return (-128 <= offset && offset <= 127); 1505 } 1506 1507 // Return whether or not this register is ever used as an argument. 1508 // This function is used on startup to build the trampoline stubs in 1509 // generateOptoStub. Registers not mentioned will be killed by the VM 1510 // call in the trampoline, and arguments in those registers not be 1511 // available to the callee. 1512 bool Matcher::can_be_java_arg(int reg) 1513 { 1514 return 1515 reg == RDI_num || reg == RDI_H_num || 1516 reg == RSI_num || reg == RSI_H_num || 1517 reg == RDX_num || reg == RDX_H_num || 1518 reg == RCX_num || reg == RCX_H_num || 1519 reg == R8_num || reg == R8_H_num || 1520 reg == R9_num || reg == R9_H_num || 1521 reg == R12_num || reg == R12_H_num || 1522 reg == XMM0_num || reg == XMM0b_num || 1523 reg == XMM1_num || reg == XMM1b_num || 1524 reg == XMM2_num || reg == XMM2b_num || 1525 reg == XMM3_num || reg == XMM3b_num || 1526 reg == XMM4_num || reg == XMM4b_num || 1527 reg == XMM5_num || reg == XMM5b_num || 1528 reg == XMM6_num || reg == XMM6b_num || 1529 reg == XMM7_num || reg == XMM7b_num; 1530 } 1531 1532 bool Matcher::is_spillable_arg(int reg) 1533 { 1534 return can_be_java_arg(reg); 1535 } 1536 1537 uint Matcher::int_pressure_limit() 1538 { 1539 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1540 } 1541 1542 uint Matcher::float_pressure_limit() 1543 { 1544 // After experiment around with different values, the following default threshold 1545 // works best for LCM's register pressure scheduling on x64. 1546 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1547 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1548 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1549 } 1550 1551 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1552 // In 64 bit mode a code which use multiply when 1553 // devisor is constant is faster than hardware 1554 // DIV instruction (it uses MulHiL). 1555 return false; 1556 } 1557 1558 // Register for DIVI projection of divmodI 1559 RegMask Matcher::divI_proj_mask() { 1560 return INT_RAX_REG_mask(); 1561 } 1562 1563 // Register for MODI projection of divmodI 1564 RegMask Matcher::modI_proj_mask() { 1565 return INT_RDX_REG_mask(); 1566 } 1567 1568 // Register for DIVL projection of divmodL 1569 RegMask Matcher::divL_proj_mask() { 1570 return LONG_RAX_REG_mask(); 1571 } 1572 1573 // Register for MODL projection of divmodL 1574 RegMask Matcher::modL_proj_mask() { 1575 return LONG_RDX_REG_mask(); 1576 } 1577 1578 // Register for saving SP into on method handle invokes. Not used on x86_64. 1579 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1580 return NO_REG_mask(); 1581 } 1582 1583 %} 1584 1585 //----------ENCODING BLOCK----------------------------------------------------- 1586 // This block specifies the encoding classes used by the compiler to 1587 // output byte streams. Encoding classes are parameterized macros 1588 // used by Machine Instruction Nodes in order to generate the bit 1589 // encoding of the instruction. Operands specify their base encoding 1590 // interface with the interface keyword. There are currently 1591 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1592 // COND_INTER. REG_INTER causes an operand to generate a function 1593 // which returns its register number when queried. CONST_INTER causes 1594 // an operand to generate a function which returns the value of the 1595 // constant when queried. MEMORY_INTER causes an operand to generate 1596 // four functions which return the Base Register, the Index Register, 1597 // the Scale Value, and the Offset Value of the operand when queried. 1598 // COND_INTER causes an operand to generate six functions which return 1599 // the encoding code (ie - encoding bits for the instruction) 1600 // associated with each basic boolean condition for a conditional 1601 // instruction. 1602 // 1603 // Instructions specify two basic values for encoding. Again, a 1604 // function is available to check if the constant displacement is an 1605 // oop. They use the ins_encode keyword to specify their encoding 1606 // classes (which must be a sequence of enc_class names, and their 1607 // parameters, specified in the encoding block), and they use the 1608 // opcode keyword to specify, in order, their primary, secondary, and 1609 // tertiary opcode. Only the opcode sections which a particular 1610 // instruction needs for encoding need to be specified. 1611 encode %{ 1612 enc_class cdql_enc(no_rax_rdx_RegI div) 1613 %{ 1614 // Full implementation of Java idiv and irem; checks for 1615 // special case as described in JVM spec., p.243 & p.271. 1616 // 1617 // normal case special case 1618 // 1619 // input : rax: dividend min_int 1620 // reg: divisor -1 1621 // 1622 // output: rax: quotient (= rax idiv reg) min_int 1623 // rdx: remainder (= rax irem reg) 0 1624 // 1625 // Code sequnce: 1626 // 1627 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1628 // 5: 75 07/08 jne e <normal> 1629 // 7: 33 d2 xor %edx,%edx 1630 // [div >= 8 -> offset + 1] 1631 // [REX_B] 1632 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1633 // c: 74 03/04 je 11 <done> 1634 // 000000000000000e <normal>: 1635 // e: 99 cltd 1636 // [div >= 8 -> offset + 1] 1637 // [REX_B] 1638 // f: f7 f9 idiv $div 1639 // 0000000000000011 <done>: 1640 Label normal; 1641 Label done; 1642 1643 // cmp $0x80000000,%eax 1644 __ cmpl(as_Register(RAX_enc), 0x80000000); 1645 1646 // jne e <normal> 1647 __ jccb(Assembler::notEqual, normal); 1648 1649 // xor %edx,%edx 1650 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1651 1652 // cmp $0xffffffffffffffff,%ecx 1653 __ cmpl($div$$Register, -1); 1654 1655 // je 11 <done> 1656 __ jccb(Assembler::equal, done); 1657 1658 // <normal> 1659 // cltd 1660 __ bind(normal); 1661 __ cdql(); 1662 1663 // idivl 1664 // <done> 1665 __ idivl($div$$Register); 1666 __ bind(done); 1667 %} 1668 1669 enc_class cdqq_enc(no_rax_rdx_RegL div) 1670 %{ 1671 // Full implementation of Java ldiv and lrem; checks for 1672 // special case as described in JVM spec., p.243 & p.271. 1673 // 1674 // normal case special case 1675 // 1676 // input : rax: dividend min_long 1677 // reg: divisor -1 1678 // 1679 // output: rax: quotient (= rax idiv reg) min_long 1680 // rdx: remainder (= rax irem reg) 0 1681 // 1682 // Code sequnce: 1683 // 1684 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1685 // 7: 00 00 80 1686 // a: 48 39 d0 cmp %rdx,%rax 1687 // d: 75 08 jne 17 <normal> 1688 // f: 33 d2 xor %edx,%edx 1689 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1690 // 15: 74 05 je 1c <done> 1691 // 0000000000000017 <normal>: 1692 // 17: 48 99 cqto 1693 // 19: 48 f7 f9 idiv $div 1694 // 000000000000001c <done>: 1695 Label normal; 1696 Label done; 1697 1698 // mov $0x8000000000000000,%rdx 1699 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1700 1701 // cmp %rdx,%rax 1702 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1703 1704 // jne 17 <normal> 1705 __ jccb(Assembler::notEqual, normal); 1706 1707 // xor %edx,%edx 1708 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1709 1710 // cmp $0xffffffffffffffff,$div 1711 __ cmpq($div$$Register, -1); 1712 1713 // je 1e <done> 1714 __ jccb(Assembler::equal, done); 1715 1716 // <normal> 1717 // cqto 1718 __ bind(normal); 1719 __ cdqq(); 1720 1721 // idivq (note: must be emitted by the user of this rule) 1722 // <done> 1723 __ idivq($div$$Register); 1724 __ bind(done); 1725 %} 1726 1727 enc_class enc_PartialSubtypeCheck() 1728 %{ 1729 Register Rrdi = as_Register(RDI_enc); // result register 1730 Register Rrax = as_Register(RAX_enc); // super class 1731 Register Rrcx = as_Register(RCX_enc); // killed 1732 Register Rrsi = as_Register(RSI_enc); // sub class 1733 Label miss; 1734 const bool set_cond_codes = true; 1735 1736 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1737 nullptr, &miss, 1738 /*set_cond_codes:*/ true); 1739 if ($primary) { 1740 __ xorptr(Rrdi, Rrdi); 1741 } 1742 __ bind(miss); 1743 %} 1744 1745 enc_class clear_avx %{ 1746 debug_only(int off0 = __ offset()); 1747 if (generate_vzeroupper(Compile::current())) { 1748 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1749 // Clear upper bits of YMM registers when current compiled code uses 1750 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1751 __ vzeroupper(); 1752 } 1753 debug_only(int off1 = __ offset()); 1754 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1755 %} 1756 1757 enc_class Java_To_Runtime(method meth) %{ 1758 // No relocation needed 1759 if (SCCache::is_on_for_write()) { 1760 // Created runtime_call_type relocation when caching code 1761 __ lea(r10, RuntimeAddress((address)$meth$$method)); 1762 } else { 1763 __ mov64(r10, (int64_t) $meth$$method); 1764 } 1765 __ call(r10); 1766 __ post_call_nop(); 1767 %} 1768 1769 enc_class Java_Static_Call(method meth) 1770 %{ 1771 // JAVA STATIC CALL 1772 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1773 // determine who we intended to call. 1774 if (!_method) { 1775 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1776 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1777 // The NOP here is purely to ensure that eliding a call to 1778 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1779 __ addr_nop_5(); 1780 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1781 } else { 1782 int method_index = resolved_method_index(masm); 1783 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1784 : static_call_Relocation::spec(method_index); 1785 address mark = __ pc(); 1786 int call_offset = __ offset(); 1787 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1788 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1789 // Calls of the same statically bound method can share 1790 // a stub to the interpreter. 1791 __ code()->shared_stub_to_interp_for(_method, call_offset); 1792 } else { 1793 // Emit stubs for static call. 1794 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1795 __ clear_inst_mark(); 1796 if (stub == nullptr) { 1797 ciEnv::current()->record_failure("CodeCache is full"); 1798 return; 1799 } 1800 } 1801 } 1802 __ post_call_nop(); 1803 %} 1804 1805 enc_class Java_Dynamic_Call(method meth) %{ 1806 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1807 __ post_call_nop(); 1808 %} 1809 1810 %} 1811 1812 1813 1814 //----------FRAME-------------------------------------------------------------- 1815 // Definition of frame structure and management information. 1816 // 1817 // S T A C K L A Y O U T Allocators stack-slot number 1818 // | (to get allocators register number 1819 // G Owned by | | v add OptoReg::stack0()) 1820 // r CALLER | | 1821 // o | +--------+ pad to even-align allocators stack-slot 1822 // w V | pad0 | numbers; owned by CALLER 1823 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1824 // h ^ | in | 5 1825 // | | args | 4 Holes in incoming args owned by SELF 1826 // | | | | 3 1827 // | | +--------+ 1828 // V | | old out| Empty on Intel, window on Sparc 1829 // | old |preserve| Must be even aligned. 1830 // | SP-+--------+----> Matcher::_old_SP, even aligned 1831 // | | in | 3 area for Intel ret address 1832 // Owned by |preserve| Empty on Sparc. 1833 // SELF +--------+ 1834 // | | pad2 | 2 pad to align old SP 1835 // | +--------+ 1 1836 // | | locks | 0 1837 // | +--------+----> OptoReg::stack0(), even aligned 1838 // | | pad1 | 11 pad to align new SP 1839 // | +--------+ 1840 // | | | 10 1841 // | | spills | 9 spills 1842 // V | | 8 (pad0 slot for callee) 1843 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1844 // ^ | out | 7 1845 // | | args | 6 Holes in outgoing args owned by CALLEE 1846 // Owned by +--------+ 1847 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1848 // | new |preserve| Must be even-aligned. 1849 // | SP-+--------+----> Matcher::_new_SP, even aligned 1850 // | | | 1851 // 1852 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1853 // known from SELF's arguments and the Java calling convention. 1854 // Region 6-7 is determined per call site. 1855 // Note 2: If the calling convention leaves holes in the incoming argument 1856 // area, those holes are owned by SELF. Holes in the outgoing area 1857 // are owned by the CALLEE. Holes should not be necessary in the 1858 // incoming area, as the Java calling convention is completely under 1859 // the control of the AD file. Doubles can be sorted and packed to 1860 // avoid holes. Holes in the outgoing arguments may be necessary for 1861 // varargs C calling conventions. 1862 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1863 // even aligned with pad0 as needed. 1864 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1865 // region 6-11 is even aligned; it may be padded out more so that 1866 // the region from SP to FP meets the minimum stack alignment. 1867 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1868 // alignment. Region 11, pad1, may be dynamically extended so that 1869 // SP meets the minimum alignment. 1870 1871 frame 1872 %{ 1873 // These three registers define part of the calling convention 1874 // between compiled code and the interpreter. 1875 inline_cache_reg(RAX); // Inline Cache Register 1876 1877 // Optional: name the operand used by cisc-spilling to access 1878 // [stack_pointer + offset] 1879 cisc_spilling_operand_name(indOffset32); 1880 1881 // Number of stack slots consumed by locking an object 1882 sync_stack_slots(2); 1883 1884 // Compiled code's Frame Pointer 1885 frame_pointer(RSP); 1886 1887 // Interpreter stores its frame pointer in a register which is 1888 // stored to the stack by I2CAdaptors. 1889 // I2CAdaptors convert from interpreted java to compiled java. 1890 interpreter_frame_pointer(RBP); 1891 1892 // Stack alignment requirement 1893 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1894 1895 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1896 // for calls to C. Supports the var-args backing area for register parms. 1897 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1898 1899 // The after-PROLOG location of the return address. Location of 1900 // return address specifies a type (REG or STACK) and a number 1901 // representing the register number (i.e. - use a register name) or 1902 // stack slot. 1903 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 1904 // Otherwise, it is above the locks and verification slot and alignment word 1905 return_addr(STACK - 2 + 1906 align_up((Compile::current()->in_preserve_stack_slots() + 1907 Compile::current()->fixed_slots()), 1908 stack_alignment_in_slots())); 1909 1910 // Location of compiled Java return values. Same as C for now. 1911 return_value 1912 %{ 1913 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 1914 "only return normal values"); 1915 1916 static const int lo[Op_RegL + 1] = { 1917 0, 1918 0, 1919 RAX_num, // Op_RegN 1920 RAX_num, // Op_RegI 1921 RAX_num, // Op_RegP 1922 XMM0_num, // Op_RegF 1923 XMM0_num, // Op_RegD 1924 RAX_num // Op_RegL 1925 }; 1926 static const int hi[Op_RegL + 1] = { 1927 0, 1928 0, 1929 OptoReg::Bad, // Op_RegN 1930 OptoReg::Bad, // Op_RegI 1931 RAX_H_num, // Op_RegP 1932 OptoReg::Bad, // Op_RegF 1933 XMM0b_num, // Op_RegD 1934 RAX_H_num // Op_RegL 1935 }; 1936 // Excluded flags and vector registers. 1937 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 1938 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 1939 %} 1940 %} 1941 1942 //----------ATTRIBUTES--------------------------------------------------------- 1943 //----------Operand Attributes------------------------------------------------- 1944 op_attrib op_cost(0); // Required cost attribute 1945 1946 //----------Instruction Attributes--------------------------------------------- 1947 ins_attrib ins_cost(100); // Required cost attribute 1948 ins_attrib ins_size(8); // Required size attribute (in bits) 1949 ins_attrib ins_short_branch(0); // Required flag: is this instruction 1950 // a non-matching short branch variant 1951 // of some long branch? 1952 ins_attrib ins_alignment(1); // Required alignment attribute (must 1953 // be a power of 2) specifies the 1954 // alignment that some part of the 1955 // instruction (not necessarily the 1956 // start) requires. If > 1, a 1957 // compute_padding() function must be 1958 // provided for the instruction 1959 1960 //----------OPERANDS----------------------------------------------------------- 1961 // Operand definitions must precede instruction definitions for correct parsing 1962 // in the ADLC because operands constitute user defined types which are used in 1963 // instruction definitions. 1964 1965 //----------Simple Operands---------------------------------------------------- 1966 // Immediate Operands 1967 // Integer Immediate 1968 operand immI() 1969 %{ 1970 match(ConI); 1971 1972 op_cost(10); 1973 format %{ %} 1974 interface(CONST_INTER); 1975 %} 1976 1977 // Constant for test vs zero 1978 operand immI_0() 1979 %{ 1980 predicate(n->get_int() == 0); 1981 match(ConI); 1982 1983 op_cost(0); 1984 format %{ %} 1985 interface(CONST_INTER); 1986 %} 1987 1988 // Constant for increment 1989 operand immI_1() 1990 %{ 1991 predicate(n->get_int() == 1); 1992 match(ConI); 1993 1994 op_cost(0); 1995 format %{ %} 1996 interface(CONST_INTER); 1997 %} 1998 1999 // Constant for decrement 2000 operand immI_M1() 2001 %{ 2002 predicate(n->get_int() == -1); 2003 match(ConI); 2004 2005 op_cost(0); 2006 format %{ %} 2007 interface(CONST_INTER); 2008 %} 2009 2010 operand immI_2() 2011 %{ 2012 predicate(n->get_int() == 2); 2013 match(ConI); 2014 2015 op_cost(0); 2016 format %{ %} 2017 interface(CONST_INTER); 2018 %} 2019 2020 operand immI_4() 2021 %{ 2022 predicate(n->get_int() == 4); 2023 match(ConI); 2024 2025 op_cost(0); 2026 format %{ %} 2027 interface(CONST_INTER); 2028 %} 2029 2030 operand immI_8() 2031 %{ 2032 predicate(n->get_int() == 8); 2033 match(ConI); 2034 2035 op_cost(0); 2036 format %{ %} 2037 interface(CONST_INTER); 2038 %} 2039 2040 // Valid scale values for addressing modes 2041 operand immI2() 2042 %{ 2043 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2044 match(ConI); 2045 2046 format %{ %} 2047 interface(CONST_INTER); 2048 %} 2049 2050 operand immU7() 2051 %{ 2052 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2053 match(ConI); 2054 2055 op_cost(5); 2056 format %{ %} 2057 interface(CONST_INTER); 2058 %} 2059 2060 operand immI8() 2061 %{ 2062 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2063 match(ConI); 2064 2065 op_cost(5); 2066 format %{ %} 2067 interface(CONST_INTER); 2068 %} 2069 2070 operand immU8() 2071 %{ 2072 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2073 match(ConI); 2074 2075 op_cost(5); 2076 format %{ %} 2077 interface(CONST_INTER); 2078 %} 2079 2080 operand immI16() 2081 %{ 2082 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2083 match(ConI); 2084 2085 op_cost(10); 2086 format %{ %} 2087 interface(CONST_INTER); 2088 %} 2089 2090 // Int Immediate non-negative 2091 operand immU31() 2092 %{ 2093 predicate(n->get_int() >= 0); 2094 match(ConI); 2095 2096 op_cost(0); 2097 format %{ %} 2098 interface(CONST_INTER); 2099 %} 2100 2101 // Pointer Immediate 2102 operand immP() 2103 %{ 2104 match(ConP); 2105 2106 op_cost(10); 2107 format %{ %} 2108 interface(CONST_INTER); 2109 %} 2110 2111 // Null Pointer Immediate 2112 operand immP0() 2113 %{ 2114 predicate(n->get_ptr() == 0); 2115 match(ConP); 2116 2117 op_cost(5); 2118 format %{ %} 2119 interface(CONST_INTER); 2120 %} 2121 2122 // Pointer Immediate 2123 operand immN() %{ 2124 match(ConN); 2125 2126 op_cost(10); 2127 format %{ %} 2128 interface(CONST_INTER); 2129 %} 2130 2131 operand immNKlass() %{ 2132 match(ConNKlass); 2133 2134 op_cost(10); 2135 format %{ %} 2136 interface(CONST_INTER); 2137 %} 2138 2139 // Null Pointer Immediate 2140 operand immN0() %{ 2141 predicate(n->get_narrowcon() == 0); 2142 match(ConN); 2143 2144 op_cost(5); 2145 format %{ %} 2146 interface(CONST_INTER); 2147 %} 2148 2149 operand immP31() 2150 %{ 2151 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2152 && (n->get_ptr() >> 31) == 0); 2153 match(ConP); 2154 2155 op_cost(5); 2156 format %{ %} 2157 interface(CONST_INTER); 2158 %} 2159 2160 2161 // Long Immediate 2162 operand immL() 2163 %{ 2164 match(ConL); 2165 2166 op_cost(20); 2167 format %{ %} 2168 interface(CONST_INTER); 2169 %} 2170 2171 // Long Immediate 8-bit 2172 operand immL8() 2173 %{ 2174 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2175 match(ConL); 2176 2177 op_cost(5); 2178 format %{ %} 2179 interface(CONST_INTER); 2180 %} 2181 2182 // Long Immediate 32-bit unsigned 2183 operand immUL32() 2184 %{ 2185 predicate(n->get_long() == (unsigned int) (n->get_long())); 2186 match(ConL); 2187 2188 op_cost(10); 2189 format %{ %} 2190 interface(CONST_INTER); 2191 %} 2192 2193 // Long Immediate 32-bit signed 2194 operand immL32() 2195 %{ 2196 predicate(n->get_long() == (int) (n->get_long())); 2197 match(ConL); 2198 2199 op_cost(15); 2200 format %{ %} 2201 interface(CONST_INTER); 2202 %} 2203 2204 operand immL_Pow2() 2205 %{ 2206 predicate(is_power_of_2((julong)n->get_long())); 2207 match(ConL); 2208 2209 op_cost(15); 2210 format %{ %} 2211 interface(CONST_INTER); 2212 %} 2213 2214 operand immL_NotPow2() 2215 %{ 2216 predicate(is_power_of_2((julong)~n->get_long())); 2217 match(ConL); 2218 2219 op_cost(15); 2220 format %{ %} 2221 interface(CONST_INTER); 2222 %} 2223 2224 // Long Immediate zero 2225 operand immL0() 2226 %{ 2227 predicate(n->get_long() == 0L); 2228 match(ConL); 2229 2230 op_cost(10); 2231 format %{ %} 2232 interface(CONST_INTER); 2233 %} 2234 2235 // Constant for increment 2236 operand immL1() 2237 %{ 2238 predicate(n->get_long() == 1); 2239 match(ConL); 2240 2241 format %{ %} 2242 interface(CONST_INTER); 2243 %} 2244 2245 // Constant for decrement 2246 operand immL_M1() 2247 %{ 2248 predicate(n->get_long() == -1); 2249 match(ConL); 2250 2251 format %{ %} 2252 interface(CONST_INTER); 2253 %} 2254 2255 // Long Immediate: low 32-bit mask 2256 operand immL_32bits() 2257 %{ 2258 predicate(n->get_long() == 0xFFFFFFFFL); 2259 match(ConL); 2260 op_cost(20); 2261 2262 format %{ %} 2263 interface(CONST_INTER); 2264 %} 2265 2266 // Int Immediate: 2^n-1, positive 2267 operand immI_Pow2M1() 2268 %{ 2269 predicate((n->get_int() > 0) 2270 && is_power_of_2((juint)n->get_int() + 1)); 2271 match(ConI); 2272 2273 op_cost(20); 2274 format %{ %} 2275 interface(CONST_INTER); 2276 %} 2277 2278 // Float Immediate zero 2279 operand immF0() 2280 %{ 2281 predicate(jint_cast(n->getf()) == 0); 2282 match(ConF); 2283 2284 op_cost(5); 2285 format %{ %} 2286 interface(CONST_INTER); 2287 %} 2288 2289 // Float Immediate 2290 operand immF() 2291 %{ 2292 match(ConF); 2293 2294 op_cost(15); 2295 format %{ %} 2296 interface(CONST_INTER); 2297 %} 2298 2299 // Double Immediate zero 2300 operand immD0() 2301 %{ 2302 predicate(jlong_cast(n->getd()) == 0); 2303 match(ConD); 2304 2305 op_cost(5); 2306 format %{ %} 2307 interface(CONST_INTER); 2308 %} 2309 2310 // Double Immediate 2311 operand immD() 2312 %{ 2313 match(ConD); 2314 2315 op_cost(15); 2316 format %{ %} 2317 interface(CONST_INTER); 2318 %} 2319 2320 // Immediates for special shifts (sign extend) 2321 2322 // Constants for increment 2323 operand immI_16() 2324 %{ 2325 predicate(n->get_int() == 16); 2326 match(ConI); 2327 2328 format %{ %} 2329 interface(CONST_INTER); 2330 %} 2331 2332 operand immI_24() 2333 %{ 2334 predicate(n->get_int() == 24); 2335 match(ConI); 2336 2337 format %{ %} 2338 interface(CONST_INTER); 2339 %} 2340 2341 // Constant for byte-wide masking 2342 operand immI_255() 2343 %{ 2344 predicate(n->get_int() == 255); 2345 match(ConI); 2346 2347 format %{ %} 2348 interface(CONST_INTER); 2349 %} 2350 2351 // Constant for short-wide masking 2352 operand immI_65535() 2353 %{ 2354 predicate(n->get_int() == 65535); 2355 match(ConI); 2356 2357 format %{ %} 2358 interface(CONST_INTER); 2359 %} 2360 2361 // Constant for byte-wide masking 2362 operand immL_255() 2363 %{ 2364 predicate(n->get_long() == 255); 2365 match(ConL); 2366 2367 format %{ %} 2368 interface(CONST_INTER); 2369 %} 2370 2371 // Constant for short-wide masking 2372 operand immL_65535() 2373 %{ 2374 predicate(n->get_long() == 65535); 2375 match(ConL); 2376 2377 format %{ %} 2378 interface(CONST_INTER); 2379 %} 2380 2381 operand kReg() 2382 %{ 2383 constraint(ALLOC_IN_RC(vectmask_reg)); 2384 match(RegVectMask); 2385 format %{%} 2386 interface(REG_INTER); 2387 %} 2388 2389 // Register Operands 2390 // Integer Register 2391 operand rRegI() 2392 %{ 2393 constraint(ALLOC_IN_RC(int_reg)); 2394 match(RegI); 2395 2396 match(rax_RegI); 2397 match(rbx_RegI); 2398 match(rcx_RegI); 2399 match(rdx_RegI); 2400 match(rdi_RegI); 2401 2402 format %{ %} 2403 interface(REG_INTER); 2404 %} 2405 2406 // Special Registers 2407 operand rax_RegI() 2408 %{ 2409 constraint(ALLOC_IN_RC(int_rax_reg)); 2410 match(RegI); 2411 match(rRegI); 2412 2413 format %{ "RAX" %} 2414 interface(REG_INTER); 2415 %} 2416 2417 // Special Registers 2418 operand rbx_RegI() 2419 %{ 2420 constraint(ALLOC_IN_RC(int_rbx_reg)); 2421 match(RegI); 2422 match(rRegI); 2423 2424 format %{ "RBX" %} 2425 interface(REG_INTER); 2426 %} 2427 2428 operand rcx_RegI() 2429 %{ 2430 constraint(ALLOC_IN_RC(int_rcx_reg)); 2431 match(RegI); 2432 match(rRegI); 2433 2434 format %{ "RCX" %} 2435 interface(REG_INTER); 2436 %} 2437 2438 operand rdx_RegI() 2439 %{ 2440 constraint(ALLOC_IN_RC(int_rdx_reg)); 2441 match(RegI); 2442 match(rRegI); 2443 2444 format %{ "RDX" %} 2445 interface(REG_INTER); 2446 %} 2447 2448 operand rdi_RegI() 2449 %{ 2450 constraint(ALLOC_IN_RC(int_rdi_reg)); 2451 match(RegI); 2452 match(rRegI); 2453 2454 format %{ "RDI" %} 2455 interface(REG_INTER); 2456 %} 2457 2458 operand no_rax_rdx_RegI() 2459 %{ 2460 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2461 match(RegI); 2462 match(rbx_RegI); 2463 match(rcx_RegI); 2464 match(rdi_RegI); 2465 2466 format %{ %} 2467 interface(REG_INTER); 2468 %} 2469 2470 operand no_rbp_r13_RegI() 2471 %{ 2472 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2473 match(RegI); 2474 match(rRegI); 2475 match(rax_RegI); 2476 match(rbx_RegI); 2477 match(rcx_RegI); 2478 match(rdx_RegI); 2479 match(rdi_RegI); 2480 2481 format %{ %} 2482 interface(REG_INTER); 2483 %} 2484 2485 // Pointer Register 2486 operand any_RegP() 2487 %{ 2488 constraint(ALLOC_IN_RC(any_reg)); 2489 match(RegP); 2490 match(rax_RegP); 2491 match(rbx_RegP); 2492 match(rdi_RegP); 2493 match(rsi_RegP); 2494 match(rbp_RegP); 2495 match(r15_RegP); 2496 match(rRegP); 2497 2498 format %{ %} 2499 interface(REG_INTER); 2500 %} 2501 2502 operand rRegP() 2503 %{ 2504 constraint(ALLOC_IN_RC(ptr_reg)); 2505 match(RegP); 2506 match(rax_RegP); 2507 match(rbx_RegP); 2508 match(rdi_RegP); 2509 match(rsi_RegP); 2510 match(rbp_RegP); // See Q&A below about 2511 match(r15_RegP); // r15_RegP and rbp_RegP. 2512 2513 format %{ %} 2514 interface(REG_INTER); 2515 %} 2516 2517 operand rRegN() %{ 2518 constraint(ALLOC_IN_RC(int_reg)); 2519 match(RegN); 2520 2521 format %{ %} 2522 interface(REG_INTER); 2523 %} 2524 2525 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2526 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2527 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2528 // The output of an instruction is controlled by the allocator, which respects 2529 // register class masks, not match rules. Unless an instruction mentions 2530 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2531 // by the allocator as an input. 2532 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2533 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2534 // result, RBP is not included in the output of the instruction either. 2535 2536 // This operand is not allowed to use RBP even if 2537 // RBP is not used to hold the frame pointer. 2538 operand no_rbp_RegP() 2539 %{ 2540 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2541 match(RegP); 2542 match(rbx_RegP); 2543 match(rsi_RegP); 2544 match(rdi_RegP); 2545 2546 format %{ %} 2547 interface(REG_INTER); 2548 %} 2549 2550 // Special Registers 2551 // Return a pointer value 2552 operand rax_RegP() 2553 %{ 2554 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2555 match(RegP); 2556 match(rRegP); 2557 2558 format %{ %} 2559 interface(REG_INTER); 2560 %} 2561 2562 // Special Registers 2563 // Return a compressed pointer value 2564 operand rax_RegN() 2565 %{ 2566 constraint(ALLOC_IN_RC(int_rax_reg)); 2567 match(RegN); 2568 match(rRegN); 2569 2570 format %{ %} 2571 interface(REG_INTER); 2572 %} 2573 2574 // Used in AtomicAdd 2575 operand rbx_RegP() 2576 %{ 2577 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2578 match(RegP); 2579 match(rRegP); 2580 2581 format %{ %} 2582 interface(REG_INTER); 2583 %} 2584 2585 operand rsi_RegP() 2586 %{ 2587 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2588 match(RegP); 2589 match(rRegP); 2590 2591 format %{ %} 2592 interface(REG_INTER); 2593 %} 2594 2595 operand rbp_RegP() 2596 %{ 2597 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2598 match(RegP); 2599 match(rRegP); 2600 2601 format %{ %} 2602 interface(REG_INTER); 2603 %} 2604 2605 // Used in rep stosq 2606 operand rdi_RegP() 2607 %{ 2608 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2609 match(RegP); 2610 match(rRegP); 2611 2612 format %{ %} 2613 interface(REG_INTER); 2614 %} 2615 2616 operand r15_RegP() 2617 %{ 2618 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2619 match(RegP); 2620 match(rRegP); 2621 2622 format %{ %} 2623 interface(REG_INTER); 2624 %} 2625 2626 operand rRegL() 2627 %{ 2628 constraint(ALLOC_IN_RC(long_reg)); 2629 match(RegL); 2630 match(rax_RegL); 2631 match(rdx_RegL); 2632 2633 format %{ %} 2634 interface(REG_INTER); 2635 %} 2636 2637 // Special Registers 2638 operand no_rax_rdx_RegL() 2639 %{ 2640 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2641 match(RegL); 2642 match(rRegL); 2643 2644 format %{ %} 2645 interface(REG_INTER); 2646 %} 2647 2648 operand rax_RegL() 2649 %{ 2650 constraint(ALLOC_IN_RC(long_rax_reg)); 2651 match(RegL); 2652 match(rRegL); 2653 2654 format %{ "RAX" %} 2655 interface(REG_INTER); 2656 %} 2657 2658 operand rcx_RegL() 2659 %{ 2660 constraint(ALLOC_IN_RC(long_rcx_reg)); 2661 match(RegL); 2662 match(rRegL); 2663 2664 format %{ %} 2665 interface(REG_INTER); 2666 %} 2667 2668 operand rdx_RegL() 2669 %{ 2670 constraint(ALLOC_IN_RC(long_rdx_reg)); 2671 match(RegL); 2672 match(rRegL); 2673 2674 format %{ %} 2675 interface(REG_INTER); 2676 %} 2677 2678 operand r11_RegL() 2679 %{ 2680 constraint(ALLOC_IN_RC(long_r11_reg)); 2681 match(RegL); 2682 match(rRegL); 2683 2684 format %{ %} 2685 interface(REG_INTER); 2686 %} 2687 2688 operand no_rbp_r13_RegL() 2689 %{ 2690 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2691 match(RegL); 2692 match(rRegL); 2693 match(rax_RegL); 2694 match(rcx_RegL); 2695 match(rdx_RegL); 2696 2697 format %{ %} 2698 interface(REG_INTER); 2699 %} 2700 2701 // Flags register, used as output of compare instructions 2702 operand rFlagsReg() 2703 %{ 2704 constraint(ALLOC_IN_RC(int_flags)); 2705 match(RegFlags); 2706 2707 format %{ "RFLAGS" %} 2708 interface(REG_INTER); 2709 %} 2710 2711 // Flags register, used as output of FLOATING POINT compare instructions 2712 operand rFlagsRegU() 2713 %{ 2714 constraint(ALLOC_IN_RC(int_flags)); 2715 match(RegFlags); 2716 2717 format %{ "RFLAGS_U" %} 2718 interface(REG_INTER); 2719 %} 2720 2721 operand rFlagsRegUCF() %{ 2722 constraint(ALLOC_IN_RC(int_flags)); 2723 match(RegFlags); 2724 predicate(false); 2725 2726 format %{ "RFLAGS_U_CF" %} 2727 interface(REG_INTER); 2728 %} 2729 2730 // Float register operands 2731 operand regF() %{ 2732 constraint(ALLOC_IN_RC(float_reg)); 2733 match(RegF); 2734 2735 format %{ %} 2736 interface(REG_INTER); 2737 %} 2738 2739 // Float register operands 2740 operand legRegF() %{ 2741 constraint(ALLOC_IN_RC(float_reg_legacy)); 2742 match(RegF); 2743 2744 format %{ %} 2745 interface(REG_INTER); 2746 %} 2747 2748 // Float register operands 2749 operand vlRegF() %{ 2750 constraint(ALLOC_IN_RC(float_reg_vl)); 2751 match(RegF); 2752 2753 format %{ %} 2754 interface(REG_INTER); 2755 %} 2756 2757 // Double register operands 2758 operand regD() %{ 2759 constraint(ALLOC_IN_RC(double_reg)); 2760 match(RegD); 2761 2762 format %{ %} 2763 interface(REG_INTER); 2764 %} 2765 2766 // Double register operands 2767 operand legRegD() %{ 2768 constraint(ALLOC_IN_RC(double_reg_legacy)); 2769 match(RegD); 2770 2771 format %{ %} 2772 interface(REG_INTER); 2773 %} 2774 2775 // Double register operands 2776 operand vlRegD() %{ 2777 constraint(ALLOC_IN_RC(double_reg_vl)); 2778 match(RegD); 2779 2780 format %{ %} 2781 interface(REG_INTER); 2782 %} 2783 2784 //----------Memory Operands---------------------------------------------------- 2785 // Direct Memory Operand 2786 // operand direct(immP addr) 2787 // %{ 2788 // match(addr); 2789 2790 // format %{ "[$addr]" %} 2791 // interface(MEMORY_INTER) %{ 2792 // base(0xFFFFFFFF); 2793 // index(0x4); 2794 // scale(0x0); 2795 // disp($addr); 2796 // %} 2797 // %} 2798 2799 // Indirect Memory Operand 2800 operand indirect(any_RegP reg) 2801 %{ 2802 constraint(ALLOC_IN_RC(ptr_reg)); 2803 match(reg); 2804 2805 format %{ "[$reg]" %} 2806 interface(MEMORY_INTER) %{ 2807 base($reg); 2808 index(0x4); 2809 scale(0x0); 2810 disp(0x0); 2811 %} 2812 %} 2813 2814 // Indirect Memory Plus Short Offset Operand 2815 operand indOffset8(any_RegP reg, immL8 off) 2816 %{ 2817 constraint(ALLOC_IN_RC(ptr_reg)); 2818 match(AddP reg off); 2819 2820 format %{ "[$reg + $off (8-bit)]" %} 2821 interface(MEMORY_INTER) %{ 2822 base($reg); 2823 index(0x4); 2824 scale(0x0); 2825 disp($off); 2826 %} 2827 %} 2828 2829 // Indirect Memory Plus Long Offset Operand 2830 operand indOffset32(any_RegP reg, immL32 off) 2831 %{ 2832 constraint(ALLOC_IN_RC(ptr_reg)); 2833 match(AddP reg off); 2834 2835 format %{ "[$reg + $off (32-bit)]" %} 2836 interface(MEMORY_INTER) %{ 2837 base($reg); 2838 index(0x4); 2839 scale(0x0); 2840 disp($off); 2841 %} 2842 %} 2843 2844 // Indirect Memory Plus Index Register Plus Offset Operand 2845 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2846 %{ 2847 constraint(ALLOC_IN_RC(ptr_reg)); 2848 match(AddP (AddP reg lreg) off); 2849 2850 op_cost(10); 2851 format %{"[$reg + $off + $lreg]" %} 2852 interface(MEMORY_INTER) %{ 2853 base($reg); 2854 index($lreg); 2855 scale(0x0); 2856 disp($off); 2857 %} 2858 %} 2859 2860 // Indirect Memory Plus Index Register Plus Offset Operand 2861 operand indIndex(any_RegP reg, rRegL lreg) 2862 %{ 2863 constraint(ALLOC_IN_RC(ptr_reg)); 2864 match(AddP reg lreg); 2865 2866 op_cost(10); 2867 format %{"[$reg + $lreg]" %} 2868 interface(MEMORY_INTER) %{ 2869 base($reg); 2870 index($lreg); 2871 scale(0x0); 2872 disp(0x0); 2873 %} 2874 %} 2875 2876 // Indirect Memory Times Scale Plus Index Register 2877 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2878 %{ 2879 constraint(ALLOC_IN_RC(ptr_reg)); 2880 match(AddP reg (LShiftL lreg scale)); 2881 2882 op_cost(10); 2883 format %{"[$reg + $lreg << $scale]" %} 2884 interface(MEMORY_INTER) %{ 2885 base($reg); 2886 index($lreg); 2887 scale($scale); 2888 disp(0x0); 2889 %} 2890 %} 2891 2892 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 2893 %{ 2894 constraint(ALLOC_IN_RC(ptr_reg)); 2895 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 2896 match(AddP reg (LShiftL (ConvI2L idx) scale)); 2897 2898 op_cost(10); 2899 format %{"[$reg + pos $idx << $scale]" %} 2900 interface(MEMORY_INTER) %{ 2901 base($reg); 2902 index($idx); 2903 scale($scale); 2904 disp(0x0); 2905 %} 2906 %} 2907 2908 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 2909 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 2910 %{ 2911 constraint(ALLOC_IN_RC(ptr_reg)); 2912 match(AddP (AddP reg (LShiftL lreg scale)) off); 2913 2914 op_cost(10); 2915 format %{"[$reg + $off + $lreg << $scale]" %} 2916 interface(MEMORY_INTER) %{ 2917 base($reg); 2918 index($lreg); 2919 scale($scale); 2920 disp($off); 2921 %} 2922 %} 2923 2924 // Indirect Memory Plus Positive Index Register Plus Offset Operand 2925 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 2926 %{ 2927 constraint(ALLOC_IN_RC(ptr_reg)); 2928 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 2929 match(AddP (AddP reg (ConvI2L idx)) off); 2930 2931 op_cost(10); 2932 format %{"[$reg + $off + $idx]" %} 2933 interface(MEMORY_INTER) %{ 2934 base($reg); 2935 index($idx); 2936 scale(0x0); 2937 disp($off); 2938 %} 2939 %} 2940 2941 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 2942 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 2943 %{ 2944 constraint(ALLOC_IN_RC(ptr_reg)); 2945 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 2946 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 2947 2948 op_cost(10); 2949 format %{"[$reg + $off + $idx << $scale]" %} 2950 interface(MEMORY_INTER) %{ 2951 base($reg); 2952 index($idx); 2953 scale($scale); 2954 disp($off); 2955 %} 2956 %} 2957 2958 // Indirect Narrow Oop Plus Offset Operand 2959 // Note: x86 architecture doesn't support "scale * index + offset" without a base 2960 // we can't free r12 even with CompressedOops::base() == nullptr. 2961 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 2962 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 2963 constraint(ALLOC_IN_RC(ptr_reg)); 2964 match(AddP (DecodeN reg) off); 2965 2966 op_cost(10); 2967 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 2968 interface(MEMORY_INTER) %{ 2969 base(0xc); // R12 2970 index($reg); 2971 scale(0x3); 2972 disp($off); 2973 %} 2974 %} 2975 2976 // Indirect Memory Operand 2977 operand indirectNarrow(rRegN reg) 2978 %{ 2979 predicate(CompressedOops::shift() == 0); 2980 constraint(ALLOC_IN_RC(ptr_reg)); 2981 match(DecodeN reg); 2982 2983 format %{ "[$reg]" %} 2984 interface(MEMORY_INTER) %{ 2985 base($reg); 2986 index(0x4); 2987 scale(0x0); 2988 disp(0x0); 2989 %} 2990 %} 2991 2992 // Indirect Memory Plus Short Offset Operand 2993 operand indOffset8Narrow(rRegN reg, immL8 off) 2994 %{ 2995 predicate(CompressedOops::shift() == 0); 2996 constraint(ALLOC_IN_RC(ptr_reg)); 2997 match(AddP (DecodeN 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 indOffset32Narrow(rRegN reg, immL32 off) 3010 %{ 3011 predicate(CompressedOops::shift() == 0); 3012 constraint(ALLOC_IN_RC(ptr_reg)); 3013 match(AddP (DecodeN reg) off); 3014 3015 format %{ "[$reg + $off (32-bit)]" %} 3016 interface(MEMORY_INTER) %{ 3017 base($reg); 3018 index(0x4); 3019 scale(0x0); 3020 disp($off); 3021 %} 3022 %} 3023 3024 // Indirect Memory Plus Index Register Plus Offset Operand 3025 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3026 %{ 3027 predicate(CompressedOops::shift() == 0); 3028 constraint(ALLOC_IN_RC(ptr_reg)); 3029 match(AddP (AddP (DecodeN reg) lreg) off); 3030 3031 op_cost(10); 3032 format %{"[$reg + $off + $lreg]" %} 3033 interface(MEMORY_INTER) %{ 3034 base($reg); 3035 index($lreg); 3036 scale(0x0); 3037 disp($off); 3038 %} 3039 %} 3040 3041 // Indirect Memory Plus Index Register Plus Offset Operand 3042 operand indIndexNarrow(rRegN reg, rRegL lreg) 3043 %{ 3044 predicate(CompressedOops::shift() == 0); 3045 constraint(ALLOC_IN_RC(ptr_reg)); 3046 match(AddP (DecodeN reg) lreg); 3047 3048 op_cost(10); 3049 format %{"[$reg + $lreg]" %} 3050 interface(MEMORY_INTER) %{ 3051 base($reg); 3052 index($lreg); 3053 scale(0x0); 3054 disp(0x0); 3055 %} 3056 %} 3057 3058 // Indirect Memory Times Scale Plus Index Register 3059 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3060 %{ 3061 predicate(CompressedOops::shift() == 0); 3062 constraint(ALLOC_IN_RC(ptr_reg)); 3063 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3064 3065 op_cost(10); 3066 format %{"[$reg + $lreg << $scale]" %} 3067 interface(MEMORY_INTER) %{ 3068 base($reg); 3069 index($lreg); 3070 scale($scale); 3071 disp(0x0); 3072 %} 3073 %} 3074 3075 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3076 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3077 %{ 3078 predicate(CompressedOops::shift() == 0); 3079 constraint(ALLOC_IN_RC(ptr_reg)); 3080 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3081 3082 op_cost(10); 3083 format %{"[$reg + $off + $lreg << $scale]" %} 3084 interface(MEMORY_INTER) %{ 3085 base($reg); 3086 index($lreg); 3087 scale($scale); 3088 disp($off); 3089 %} 3090 %} 3091 3092 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3093 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3094 %{ 3095 constraint(ALLOC_IN_RC(ptr_reg)); 3096 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3097 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3098 3099 op_cost(10); 3100 format %{"[$reg + $off + $idx]" %} 3101 interface(MEMORY_INTER) %{ 3102 base($reg); 3103 index($idx); 3104 scale(0x0); 3105 disp($off); 3106 %} 3107 %} 3108 3109 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3110 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3111 %{ 3112 constraint(ALLOC_IN_RC(ptr_reg)); 3113 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3114 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3115 3116 op_cost(10); 3117 format %{"[$reg + $off + $idx << $scale]" %} 3118 interface(MEMORY_INTER) %{ 3119 base($reg); 3120 index($idx); 3121 scale($scale); 3122 disp($off); 3123 %} 3124 %} 3125 3126 //----------Special Memory Operands-------------------------------------------- 3127 // Stack Slot Operand - This operand is used for loading and storing temporary 3128 // values on the stack where a match requires a value to 3129 // flow through memory. 3130 operand stackSlotP(sRegP reg) 3131 %{ 3132 constraint(ALLOC_IN_RC(stack_slots)); 3133 // No match rule because this operand is only generated in matching 3134 3135 format %{ "[$reg]" %} 3136 interface(MEMORY_INTER) %{ 3137 base(0x4); // RSP 3138 index(0x4); // No Index 3139 scale(0x0); // No Scale 3140 disp($reg); // Stack Offset 3141 %} 3142 %} 3143 3144 operand stackSlotI(sRegI reg) 3145 %{ 3146 constraint(ALLOC_IN_RC(stack_slots)); 3147 // No match rule because this operand is only generated in matching 3148 3149 format %{ "[$reg]" %} 3150 interface(MEMORY_INTER) %{ 3151 base(0x4); // RSP 3152 index(0x4); // No Index 3153 scale(0x0); // No Scale 3154 disp($reg); // Stack Offset 3155 %} 3156 %} 3157 3158 operand stackSlotF(sRegF reg) 3159 %{ 3160 constraint(ALLOC_IN_RC(stack_slots)); 3161 // No match rule because this operand is only generated in matching 3162 3163 format %{ "[$reg]" %} 3164 interface(MEMORY_INTER) %{ 3165 base(0x4); // RSP 3166 index(0x4); // No Index 3167 scale(0x0); // No Scale 3168 disp($reg); // Stack Offset 3169 %} 3170 %} 3171 3172 operand stackSlotD(sRegD reg) 3173 %{ 3174 constraint(ALLOC_IN_RC(stack_slots)); 3175 // No match rule because this operand is only generated in matching 3176 3177 format %{ "[$reg]" %} 3178 interface(MEMORY_INTER) %{ 3179 base(0x4); // RSP 3180 index(0x4); // No Index 3181 scale(0x0); // No Scale 3182 disp($reg); // Stack Offset 3183 %} 3184 %} 3185 operand stackSlotL(sRegL reg) 3186 %{ 3187 constraint(ALLOC_IN_RC(stack_slots)); 3188 // No match rule because this operand is only generated in matching 3189 3190 format %{ "[$reg]" %} 3191 interface(MEMORY_INTER) %{ 3192 base(0x4); // RSP 3193 index(0x4); // No Index 3194 scale(0x0); // No Scale 3195 disp($reg); // Stack Offset 3196 %} 3197 %} 3198 3199 //----------Conditional Branch Operands---------------------------------------- 3200 // Comparison Op - This is the operation of the comparison, and is limited to 3201 // the following set of codes: 3202 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3203 // 3204 // Other attributes of the comparison, such as unsignedness, are specified 3205 // by the comparison instruction that sets a condition code flags register. 3206 // That result is represented by a flags operand whose subtype is appropriate 3207 // to the unsignedness (etc.) of the comparison. 3208 // 3209 // Later, the instruction which matches both the Comparison Op (a Bool) and 3210 // the flags (produced by the Cmp) specifies the coding of the comparison op 3211 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3212 3213 // Comparison Code 3214 operand cmpOp() 3215 %{ 3216 match(Bool); 3217 3218 format %{ "" %} 3219 interface(COND_INTER) %{ 3220 equal(0x4, "e"); 3221 not_equal(0x5, "ne"); 3222 less(0xC, "l"); 3223 greater_equal(0xD, "ge"); 3224 less_equal(0xE, "le"); 3225 greater(0xF, "g"); 3226 overflow(0x0, "o"); 3227 no_overflow(0x1, "no"); 3228 %} 3229 %} 3230 3231 // Comparison Code, unsigned compare. Used by FP also, with 3232 // C2 (unordered) turned into GT or LT already. The other bits 3233 // C0 and C3 are turned into Carry & Zero flags. 3234 operand cmpOpU() 3235 %{ 3236 match(Bool); 3237 3238 format %{ "" %} 3239 interface(COND_INTER) %{ 3240 equal(0x4, "e"); 3241 not_equal(0x5, "ne"); 3242 less(0x2, "b"); 3243 greater_equal(0x3, "ae"); 3244 less_equal(0x6, "be"); 3245 greater(0x7, "a"); 3246 overflow(0x0, "o"); 3247 no_overflow(0x1, "no"); 3248 %} 3249 %} 3250 3251 3252 // Floating comparisons that don't require any fixup for the unordered case, 3253 // If both inputs of the comparison are the same, ZF is always set so we 3254 // don't need to use cmpOpUCF2 for eq/ne 3255 operand cmpOpUCF() %{ 3256 match(Bool); 3257 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3258 n->as_Bool()->_test._test == BoolTest::ge || 3259 n->as_Bool()->_test._test == BoolTest::le || 3260 n->as_Bool()->_test._test == BoolTest::gt || 3261 n->in(1)->in(1) == n->in(1)->in(2)); 3262 format %{ "" %} 3263 interface(COND_INTER) %{ 3264 equal(0xb, "np"); 3265 not_equal(0xa, "p"); 3266 less(0x2, "b"); 3267 greater_equal(0x3, "ae"); 3268 less_equal(0x6, "be"); 3269 greater(0x7, "a"); 3270 overflow(0x0, "o"); 3271 no_overflow(0x1, "no"); 3272 %} 3273 %} 3274 3275 3276 // Floating comparisons that can be fixed up with extra conditional jumps 3277 operand cmpOpUCF2() %{ 3278 match(Bool); 3279 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3280 n->as_Bool()->_test._test == BoolTest::eq) && 3281 n->in(1)->in(1) != n->in(1)->in(2)); 3282 format %{ "" %} 3283 interface(COND_INTER) %{ 3284 equal(0x4, "e"); 3285 not_equal(0x5, "ne"); 3286 less(0x2, "b"); 3287 greater_equal(0x3, "ae"); 3288 less_equal(0x6, "be"); 3289 greater(0x7, "a"); 3290 overflow(0x0, "o"); 3291 no_overflow(0x1, "no"); 3292 %} 3293 %} 3294 3295 //----------OPERAND CLASSES---------------------------------------------------- 3296 // Operand Classes are groups of operands that are used as to simplify 3297 // instruction definitions by not requiring the AD writer to specify separate 3298 // instructions for every form of operand when the instruction accepts 3299 // multiple operand types with the same basic encoding and format. The classic 3300 // case of this is memory operands. 3301 3302 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3303 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3304 indCompressedOopOffset, 3305 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3306 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3307 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3308 3309 //----------PIPELINE----------------------------------------------------------- 3310 // Rules which define the behavior of the target architectures pipeline. 3311 pipeline %{ 3312 3313 //----------ATTRIBUTES--------------------------------------------------------- 3314 attributes %{ 3315 variable_size_instructions; // Fixed size instructions 3316 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3317 instruction_unit_size = 1; // An instruction is 1 bytes long 3318 instruction_fetch_unit_size = 16; // The processor fetches one line 3319 instruction_fetch_units = 1; // of 16 bytes 3320 3321 // List of nop instructions 3322 nops( MachNop ); 3323 %} 3324 3325 //----------RESOURCES---------------------------------------------------------- 3326 // Resources are the functional units available to the machine 3327 3328 // Generic P2/P3 pipeline 3329 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3330 // 3 instructions decoded per cycle. 3331 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3332 // 3 ALU op, only ALU0 handles mul instructions. 3333 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3334 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3335 BR, FPU, 3336 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3337 3338 //----------PIPELINE DESCRIPTION----------------------------------------------- 3339 // Pipeline Description specifies the stages in the machine's pipeline 3340 3341 // Generic P2/P3 pipeline 3342 pipe_desc(S0, S1, S2, S3, S4, S5); 3343 3344 //----------PIPELINE CLASSES--------------------------------------------------- 3345 // Pipeline Classes describe the stages in which input and output are 3346 // referenced by the hardware pipeline. 3347 3348 // Naming convention: ialu or fpu 3349 // Then: _reg 3350 // Then: _reg if there is a 2nd register 3351 // Then: _long if it's a pair of instructions implementing a long 3352 // Then: _fat if it requires the big decoder 3353 // Or: _mem if it requires the big decoder and a memory unit. 3354 3355 // Integer ALU reg operation 3356 pipe_class ialu_reg(rRegI dst) 3357 %{ 3358 single_instruction; 3359 dst : S4(write); 3360 dst : S3(read); 3361 DECODE : S0; // any decoder 3362 ALU : S3; // any alu 3363 %} 3364 3365 // Long ALU reg operation 3366 pipe_class ialu_reg_long(rRegL dst) 3367 %{ 3368 instruction_count(2); 3369 dst : S4(write); 3370 dst : S3(read); 3371 DECODE : S0(2); // any 2 decoders 3372 ALU : S3(2); // both alus 3373 %} 3374 3375 // Integer ALU reg operation using big decoder 3376 pipe_class ialu_reg_fat(rRegI dst) 3377 %{ 3378 single_instruction; 3379 dst : S4(write); 3380 dst : S3(read); 3381 D0 : S0; // big decoder only 3382 ALU : S3; // any alu 3383 %} 3384 3385 // Integer ALU reg-reg operation 3386 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3387 %{ 3388 single_instruction; 3389 dst : S4(write); 3390 src : S3(read); 3391 DECODE : S0; // any decoder 3392 ALU : S3; // any alu 3393 %} 3394 3395 // Integer ALU reg-reg operation 3396 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3397 %{ 3398 single_instruction; 3399 dst : S4(write); 3400 src : S3(read); 3401 D0 : S0; // big decoder only 3402 ALU : S3; // any alu 3403 %} 3404 3405 // Integer ALU reg-mem operation 3406 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3407 %{ 3408 single_instruction; 3409 dst : S5(write); 3410 mem : S3(read); 3411 D0 : S0; // big decoder only 3412 ALU : S4; // any alu 3413 MEM : S3; // any mem 3414 %} 3415 3416 // Integer mem operation (prefetch) 3417 pipe_class ialu_mem(memory mem) 3418 %{ 3419 single_instruction; 3420 mem : S3(read); 3421 D0 : S0; // big decoder only 3422 MEM : S3; // any mem 3423 %} 3424 3425 // Integer Store to Memory 3426 pipe_class ialu_mem_reg(memory mem, rRegI src) 3427 %{ 3428 single_instruction; 3429 mem : S3(read); 3430 src : S5(read); 3431 D0 : S0; // big decoder only 3432 ALU : S4; // any alu 3433 MEM : S3; 3434 %} 3435 3436 // // Long Store to Memory 3437 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3438 // %{ 3439 // instruction_count(2); 3440 // mem : S3(read); 3441 // src : S5(read); 3442 // D0 : S0(2); // big decoder only; twice 3443 // ALU : S4(2); // any 2 alus 3444 // MEM : S3(2); // Both mems 3445 // %} 3446 3447 // Integer Store to Memory 3448 pipe_class ialu_mem_imm(memory mem) 3449 %{ 3450 single_instruction; 3451 mem : S3(read); 3452 D0 : S0; // big decoder only 3453 ALU : S4; // any alu 3454 MEM : S3; 3455 %} 3456 3457 // Integer ALU0 reg-reg operation 3458 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3459 %{ 3460 single_instruction; 3461 dst : S4(write); 3462 src : S3(read); 3463 D0 : S0; // Big decoder only 3464 ALU0 : S3; // only alu0 3465 %} 3466 3467 // Integer ALU0 reg-mem operation 3468 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3469 %{ 3470 single_instruction; 3471 dst : S5(write); 3472 mem : S3(read); 3473 D0 : S0; // big decoder only 3474 ALU0 : S4; // ALU0 only 3475 MEM : S3; // any mem 3476 %} 3477 3478 // Integer ALU reg-reg operation 3479 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3480 %{ 3481 single_instruction; 3482 cr : S4(write); 3483 src1 : S3(read); 3484 src2 : S3(read); 3485 DECODE : S0; // any decoder 3486 ALU : S3; // any alu 3487 %} 3488 3489 // Integer ALU reg-imm operation 3490 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3491 %{ 3492 single_instruction; 3493 cr : S4(write); 3494 src1 : S3(read); 3495 DECODE : S0; // any decoder 3496 ALU : S3; // any alu 3497 %} 3498 3499 // Integer ALU reg-mem operation 3500 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3501 %{ 3502 single_instruction; 3503 cr : S4(write); 3504 src1 : S3(read); 3505 src2 : S3(read); 3506 D0 : S0; // big decoder only 3507 ALU : S4; // any alu 3508 MEM : S3; 3509 %} 3510 3511 // Conditional move reg-reg 3512 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3513 %{ 3514 instruction_count(4); 3515 y : S4(read); 3516 q : S3(read); 3517 p : S3(read); 3518 DECODE : S0(4); // any decoder 3519 %} 3520 3521 // Conditional move reg-reg 3522 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3523 %{ 3524 single_instruction; 3525 dst : S4(write); 3526 src : S3(read); 3527 cr : S3(read); 3528 DECODE : S0; // any decoder 3529 %} 3530 3531 // Conditional move reg-mem 3532 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3533 %{ 3534 single_instruction; 3535 dst : S4(write); 3536 src : S3(read); 3537 cr : S3(read); 3538 DECODE : S0; // any decoder 3539 MEM : S3; 3540 %} 3541 3542 // Conditional move reg-reg long 3543 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3544 %{ 3545 single_instruction; 3546 dst : S4(write); 3547 src : S3(read); 3548 cr : S3(read); 3549 DECODE : S0(2); // any 2 decoders 3550 %} 3551 3552 // Float reg-reg operation 3553 pipe_class fpu_reg(regD dst) 3554 %{ 3555 instruction_count(2); 3556 dst : S3(read); 3557 DECODE : S0(2); // any 2 decoders 3558 FPU : S3; 3559 %} 3560 3561 // Float reg-reg operation 3562 pipe_class fpu_reg_reg(regD dst, regD src) 3563 %{ 3564 instruction_count(2); 3565 dst : S4(write); 3566 src : S3(read); 3567 DECODE : S0(2); // any 2 decoders 3568 FPU : S3; 3569 %} 3570 3571 // Float reg-reg operation 3572 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3573 %{ 3574 instruction_count(3); 3575 dst : S4(write); 3576 src1 : S3(read); 3577 src2 : S3(read); 3578 DECODE : S0(3); // any 3 decoders 3579 FPU : S3(2); 3580 %} 3581 3582 // Float reg-reg operation 3583 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3584 %{ 3585 instruction_count(4); 3586 dst : S4(write); 3587 src1 : S3(read); 3588 src2 : S3(read); 3589 src3 : S3(read); 3590 DECODE : S0(4); // any 3 decoders 3591 FPU : S3(2); 3592 %} 3593 3594 // Float reg-reg operation 3595 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3596 %{ 3597 instruction_count(4); 3598 dst : S4(write); 3599 src1 : S3(read); 3600 src2 : S3(read); 3601 src3 : S3(read); 3602 DECODE : S1(3); // any 3 decoders 3603 D0 : S0; // Big decoder only 3604 FPU : S3(2); 3605 MEM : S3; 3606 %} 3607 3608 // Float reg-mem operation 3609 pipe_class fpu_reg_mem(regD dst, memory mem) 3610 %{ 3611 instruction_count(2); 3612 dst : S5(write); 3613 mem : S3(read); 3614 D0 : S0; // big decoder only 3615 DECODE : S1; // any decoder for FPU POP 3616 FPU : S4; 3617 MEM : S3; // any mem 3618 %} 3619 3620 // Float reg-mem operation 3621 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3622 %{ 3623 instruction_count(3); 3624 dst : S5(write); 3625 src1 : S3(read); 3626 mem : S3(read); 3627 D0 : S0; // big decoder only 3628 DECODE : S1(2); // any decoder for FPU POP 3629 FPU : S4; 3630 MEM : S3; // any mem 3631 %} 3632 3633 // Float mem-reg operation 3634 pipe_class fpu_mem_reg(memory mem, regD src) 3635 %{ 3636 instruction_count(2); 3637 src : S5(read); 3638 mem : S3(read); 3639 DECODE : S0; // any decoder for FPU PUSH 3640 D0 : S1; // big decoder only 3641 FPU : S4; 3642 MEM : S3; // any mem 3643 %} 3644 3645 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3646 %{ 3647 instruction_count(3); 3648 src1 : S3(read); 3649 src2 : S3(read); 3650 mem : S3(read); 3651 DECODE : S0(2); // any decoder for FPU PUSH 3652 D0 : S1; // big decoder only 3653 FPU : S4; 3654 MEM : S3; // any mem 3655 %} 3656 3657 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3658 %{ 3659 instruction_count(3); 3660 src1 : S3(read); 3661 src2 : S3(read); 3662 mem : S4(read); 3663 DECODE : S0; // any decoder for FPU PUSH 3664 D0 : S0(2); // big decoder only 3665 FPU : S4; 3666 MEM : S3(2); // any mem 3667 %} 3668 3669 pipe_class fpu_mem_mem(memory dst, memory src1) 3670 %{ 3671 instruction_count(2); 3672 src1 : S3(read); 3673 dst : S4(read); 3674 D0 : S0(2); // big decoder only 3675 MEM : S3(2); // any mem 3676 %} 3677 3678 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3679 %{ 3680 instruction_count(3); 3681 src1 : S3(read); 3682 src2 : S3(read); 3683 dst : S4(read); 3684 D0 : S0(3); // big decoder only 3685 FPU : S4; 3686 MEM : S3(3); // any mem 3687 %} 3688 3689 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3690 %{ 3691 instruction_count(3); 3692 src1 : S4(read); 3693 mem : S4(read); 3694 DECODE : S0; // any decoder for FPU PUSH 3695 D0 : S0(2); // big decoder only 3696 FPU : S4; 3697 MEM : S3(2); // any mem 3698 %} 3699 3700 // Float load constant 3701 pipe_class fpu_reg_con(regD dst) 3702 %{ 3703 instruction_count(2); 3704 dst : S5(write); 3705 D0 : S0; // big decoder only for the load 3706 DECODE : S1; // any decoder for FPU POP 3707 FPU : S4; 3708 MEM : S3; // any mem 3709 %} 3710 3711 // Float load constant 3712 pipe_class fpu_reg_reg_con(regD dst, regD src) 3713 %{ 3714 instruction_count(3); 3715 dst : S5(write); 3716 src : S3(read); 3717 D0 : S0; // big decoder only for the load 3718 DECODE : S1(2); // any decoder for FPU POP 3719 FPU : S4; 3720 MEM : S3; // any mem 3721 %} 3722 3723 // UnConditional branch 3724 pipe_class pipe_jmp(label labl) 3725 %{ 3726 single_instruction; 3727 BR : S3; 3728 %} 3729 3730 // Conditional branch 3731 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3732 %{ 3733 single_instruction; 3734 cr : S1(read); 3735 BR : S3; 3736 %} 3737 3738 // Allocation idiom 3739 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3740 %{ 3741 instruction_count(1); force_serialization; 3742 fixed_latency(6); 3743 heap_ptr : S3(read); 3744 DECODE : S0(3); 3745 D0 : S2; 3746 MEM : S3; 3747 ALU : S3(2); 3748 dst : S5(write); 3749 BR : S5; 3750 %} 3751 3752 // Generic big/slow expanded idiom 3753 pipe_class pipe_slow() 3754 %{ 3755 instruction_count(10); multiple_bundles; force_serialization; 3756 fixed_latency(100); 3757 D0 : S0(2); 3758 MEM : S3(2); 3759 %} 3760 3761 // The real do-nothing guy 3762 pipe_class empty() 3763 %{ 3764 instruction_count(0); 3765 %} 3766 3767 // Define the class for the Nop node 3768 define 3769 %{ 3770 MachNop = empty; 3771 %} 3772 3773 %} 3774 3775 //----------INSTRUCTIONS------------------------------------------------------- 3776 // 3777 // match -- States which machine-independent subtree may be replaced 3778 // by this instruction. 3779 // ins_cost -- The estimated cost of this instruction is used by instruction 3780 // selection to identify a minimum cost tree of machine 3781 // instructions that matches a tree of machine-independent 3782 // instructions. 3783 // format -- A string providing the disassembly for this instruction. 3784 // The value of an instruction's operand may be inserted 3785 // by referring to it with a '$' prefix. 3786 // opcode -- Three instruction opcodes may be provided. These are referred 3787 // to within an encode class as $primary, $secondary, and $tertiary 3788 // rrspectively. The primary opcode is commonly used to 3789 // indicate the type of machine instruction, while secondary 3790 // and tertiary are often used for prefix options or addressing 3791 // modes. 3792 // ins_encode -- A list of encode classes with parameters. The encode class 3793 // name must have been defined in an 'enc_class' specification 3794 // in the encode section of the architecture description. 3795 3796 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3797 // Load Float 3798 instruct MoveF2VL(vlRegF dst, regF src) %{ 3799 match(Set dst src); 3800 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3801 ins_encode %{ 3802 ShouldNotReachHere(); 3803 %} 3804 ins_pipe( fpu_reg_reg ); 3805 %} 3806 3807 // Load Float 3808 instruct MoveF2LEG(legRegF dst, regF src) %{ 3809 match(Set dst src); 3810 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3811 ins_encode %{ 3812 ShouldNotReachHere(); 3813 %} 3814 ins_pipe( fpu_reg_reg ); 3815 %} 3816 3817 // Load Float 3818 instruct MoveVL2F(regF dst, vlRegF src) %{ 3819 match(Set dst src); 3820 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3821 ins_encode %{ 3822 ShouldNotReachHere(); 3823 %} 3824 ins_pipe( fpu_reg_reg ); 3825 %} 3826 3827 // Load Float 3828 instruct MoveLEG2F(regF dst, legRegF src) %{ 3829 match(Set dst src); 3830 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3831 ins_encode %{ 3832 ShouldNotReachHere(); 3833 %} 3834 ins_pipe( fpu_reg_reg ); 3835 %} 3836 3837 // Load Double 3838 instruct MoveD2VL(vlRegD dst, regD src) %{ 3839 match(Set dst src); 3840 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3841 ins_encode %{ 3842 ShouldNotReachHere(); 3843 %} 3844 ins_pipe( fpu_reg_reg ); 3845 %} 3846 3847 // Load Double 3848 instruct MoveD2LEG(legRegD dst, regD src) %{ 3849 match(Set dst src); 3850 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3851 ins_encode %{ 3852 ShouldNotReachHere(); 3853 %} 3854 ins_pipe( fpu_reg_reg ); 3855 %} 3856 3857 // Load Double 3858 instruct MoveVL2D(regD dst, vlRegD src) %{ 3859 match(Set dst src); 3860 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3861 ins_encode %{ 3862 ShouldNotReachHere(); 3863 %} 3864 ins_pipe( fpu_reg_reg ); 3865 %} 3866 3867 // Load Double 3868 instruct MoveLEG2D(regD dst, legRegD src) %{ 3869 match(Set dst src); 3870 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3871 ins_encode %{ 3872 ShouldNotReachHere(); 3873 %} 3874 ins_pipe( fpu_reg_reg ); 3875 %} 3876 3877 //----------Load/Store/Move Instructions--------------------------------------- 3878 //----------Load Instructions-------------------------------------------------- 3879 3880 // Load Byte (8 bit signed) 3881 instruct loadB(rRegI dst, memory mem) 3882 %{ 3883 match(Set dst (LoadB mem)); 3884 3885 ins_cost(125); 3886 format %{ "movsbl $dst, $mem\t# byte" %} 3887 3888 ins_encode %{ 3889 __ movsbl($dst$$Register, $mem$$Address); 3890 %} 3891 3892 ins_pipe(ialu_reg_mem); 3893 %} 3894 3895 // Load Byte (8 bit signed) into Long Register 3896 instruct loadB2L(rRegL dst, memory mem) 3897 %{ 3898 match(Set dst (ConvI2L (LoadB mem))); 3899 3900 ins_cost(125); 3901 format %{ "movsbq $dst, $mem\t# byte -> long" %} 3902 3903 ins_encode %{ 3904 __ movsbq($dst$$Register, $mem$$Address); 3905 %} 3906 3907 ins_pipe(ialu_reg_mem); 3908 %} 3909 3910 // Load Unsigned Byte (8 bit UNsigned) 3911 instruct loadUB(rRegI dst, memory mem) 3912 %{ 3913 match(Set dst (LoadUB mem)); 3914 3915 ins_cost(125); 3916 format %{ "movzbl $dst, $mem\t# ubyte" %} 3917 3918 ins_encode %{ 3919 __ movzbl($dst$$Register, $mem$$Address); 3920 %} 3921 3922 ins_pipe(ialu_reg_mem); 3923 %} 3924 3925 // Load Unsigned Byte (8 bit UNsigned) into Long Register 3926 instruct loadUB2L(rRegL dst, memory mem) 3927 %{ 3928 match(Set dst (ConvI2L (LoadUB mem))); 3929 3930 ins_cost(125); 3931 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 3932 3933 ins_encode %{ 3934 __ movzbq($dst$$Register, $mem$$Address); 3935 %} 3936 3937 ins_pipe(ialu_reg_mem); 3938 %} 3939 3940 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 3941 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 3942 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 3943 effect(KILL cr); 3944 3945 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 3946 "andl $dst, right_n_bits($mask, 8)" %} 3947 ins_encode %{ 3948 Register Rdst = $dst$$Register; 3949 __ movzbq(Rdst, $mem$$Address); 3950 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 3951 %} 3952 ins_pipe(ialu_reg_mem); 3953 %} 3954 3955 // Load Short (16 bit signed) 3956 instruct loadS(rRegI dst, memory mem) 3957 %{ 3958 match(Set dst (LoadS mem)); 3959 3960 ins_cost(125); 3961 format %{ "movswl $dst, $mem\t# short" %} 3962 3963 ins_encode %{ 3964 __ movswl($dst$$Register, $mem$$Address); 3965 %} 3966 3967 ins_pipe(ialu_reg_mem); 3968 %} 3969 3970 // Load Short (16 bit signed) to Byte (8 bit signed) 3971 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 3972 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 3973 3974 ins_cost(125); 3975 format %{ "movsbl $dst, $mem\t# short -> byte" %} 3976 ins_encode %{ 3977 __ movsbl($dst$$Register, $mem$$Address); 3978 %} 3979 ins_pipe(ialu_reg_mem); 3980 %} 3981 3982 // Load Short (16 bit signed) into Long Register 3983 instruct loadS2L(rRegL dst, memory mem) 3984 %{ 3985 match(Set dst (ConvI2L (LoadS mem))); 3986 3987 ins_cost(125); 3988 format %{ "movswq $dst, $mem\t# short -> long" %} 3989 3990 ins_encode %{ 3991 __ movswq($dst$$Register, $mem$$Address); 3992 %} 3993 3994 ins_pipe(ialu_reg_mem); 3995 %} 3996 3997 // Load Unsigned Short/Char (16 bit UNsigned) 3998 instruct loadUS(rRegI dst, memory mem) 3999 %{ 4000 match(Set dst (LoadUS mem)); 4001 4002 ins_cost(125); 4003 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4004 4005 ins_encode %{ 4006 __ movzwl($dst$$Register, $mem$$Address); 4007 %} 4008 4009 ins_pipe(ialu_reg_mem); 4010 %} 4011 4012 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4013 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4014 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4015 4016 ins_cost(125); 4017 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4018 ins_encode %{ 4019 __ movsbl($dst$$Register, $mem$$Address); 4020 %} 4021 ins_pipe(ialu_reg_mem); 4022 %} 4023 4024 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4025 instruct loadUS2L(rRegL dst, memory mem) 4026 %{ 4027 match(Set dst (ConvI2L (LoadUS mem))); 4028 4029 ins_cost(125); 4030 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4031 4032 ins_encode %{ 4033 __ movzwq($dst$$Register, $mem$$Address); 4034 %} 4035 4036 ins_pipe(ialu_reg_mem); 4037 %} 4038 4039 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4040 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4041 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4042 4043 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4044 ins_encode %{ 4045 __ movzbq($dst$$Register, $mem$$Address); 4046 %} 4047 ins_pipe(ialu_reg_mem); 4048 %} 4049 4050 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4051 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4052 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4053 effect(KILL cr); 4054 4055 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4056 "andl $dst, right_n_bits($mask, 16)" %} 4057 ins_encode %{ 4058 Register Rdst = $dst$$Register; 4059 __ movzwq(Rdst, $mem$$Address); 4060 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4061 %} 4062 ins_pipe(ialu_reg_mem); 4063 %} 4064 4065 // Load Integer 4066 instruct loadI(rRegI dst, memory mem) 4067 %{ 4068 match(Set dst (LoadI mem)); 4069 4070 ins_cost(125); 4071 format %{ "movl $dst, $mem\t# int" %} 4072 4073 ins_encode %{ 4074 __ movl($dst$$Register, $mem$$Address); 4075 %} 4076 4077 ins_pipe(ialu_reg_mem); 4078 %} 4079 4080 // Load Integer (32 bit signed) to Byte (8 bit signed) 4081 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4082 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4083 4084 ins_cost(125); 4085 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4086 ins_encode %{ 4087 __ movsbl($dst$$Register, $mem$$Address); 4088 %} 4089 ins_pipe(ialu_reg_mem); 4090 %} 4091 4092 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4093 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4094 match(Set dst (AndI (LoadI mem) mask)); 4095 4096 ins_cost(125); 4097 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4098 ins_encode %{ 4099 __ movzbl($dst$$Register, $mem$$Address); 4100 %} 4101 ins_pipe(ialu_reg_mem); 4102 %} 4103 4104 // Load Integer (32 bit signed) to Short (16 bit signed) 4105 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4106 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4107 4108 ins_cost(125); 4109 format %{ "movswl $dst, $mem\t# int -> short" %} 4110 ins_encode %{ 4111 __ movswl($dst$$Register, $mem$$Address); 4112 %} 4113 ins_pipe(ialu_reg_mem); 4114 %} 4115 4116 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4117 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4118 match(Set dst (AndI (LoadI mem) mask)); 4119 4120 ins_cost(125); 4121 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4122 ins_encode %{ 4123 __ movzwl($dst$$Register, $mem$$Address); 4124 %} 4125 ins_pipe(ialu_reg_mem); 4126 %} 4127 4128 // Load Integer into Long Register 4129 instruct loadI2L(rRegL dst, memory mem) 4130 %{ 4131 match(Set dst (ConvI2L (LoadI mem))); 4132 4133 ins_cost(125); 4134 format %{ "movslq $dst, $mem\t# int -> long" %} 4135 4136 ins_encode %{ 4137 __ movslq($dst$$Register, $mem$$Address); 4138 %} 4139 4140 ins_pipe(ialu_reg_mem); 4141 %} 4142 4143 // Load Integer with mask 0xFF into Long Register 4144 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4145 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4146 4147 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4148 ins_encode %{ 4149 __ movzbq($dst$$Register, $mem$$Address); 4150 %} 4151 ins_pipe(ialu_reg_mem); 4152 %} 4153 4154 // Load Integer with mask 0xFFFF into Long Register 4155 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4156 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4157 4158 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4159 ins_encode %{ 4160 __ movzwq($dst$$Register, $mem$$Address); 4161 %} 4162 ins_pipe(ialu_reg_mem); 4163 %} 4164 4165 // Load Integer with a 31-bit mask into Long Register 4166 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4167 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4168 effect(KILL cr); 4169 4170 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4171 "andl $dst, $mask" %} 4172 ins_encode %{ 4173 Register Rdst = $dst$$Register; 4174 __ movl(Rdst, $mem$$Address); 4175 __ andl(Rdst, $mask$$constant); 4176 %} 4177 ins_pipe(ialu_reg_mem); 4178 %} 4179 4180 // Load Unsigned Integer into Long Register 4181 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4182 %{ 4183 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4184 4185 ins_cost(125); 4186 format %{ "movl $dst, $mem\t# uint -> long" %} 4187 4188 ins_encode %{ 4189 __ movl($dst$$Register, $mem$$Address); 4190 %} 4191 4192 ins_pipe(ialu_reg_mem); 4193 %} 4194 4195 // Load Long 4196 instruct loadL(rRegL dst, memory mem) 4197 %{ 4198 match(Set dst (LoadL mem)); 4199 4200 ins_cost(125); 4201 format %{ "movq $dst, $mem\t# long" %} 4202 4203 ins_encode %{ 4204 __ movq($dst$$Register, $mem$$Address); 4205 %} 4206 4207 ins_pipe(ialu_reg_mem); // XXX 4208 %} 4209 4210 // Load Range 4211 instruct loadRange(rRegI dst, memory mem) 4212 %{ 4213 match(Set dst (LoadRange mem)); 4214 4215 ins_cost(125); // XXX 4216 format %{ "movl $dst, $mem\t# range" %} 4217 ins_encode %{ 4218 __ movl($dst$$Register, $mem$$Address); 4219 %} 4220 ins_pipe(ialu_reg_mem); 4221 %} 4222 4223 // Load Pointer 4224 instruct loadP(rRegP dst, memory mem) 4225 %{ 4226 match(Set dst (LoadP mem)); 4227 predicate(n->as_Load()->barrier_data() == 0); 4228 4229 ins_cost(125); // XXX 4230 format %{ "movq $dst, $mem\t# ptr" %} 4231 ins_encode %{ 4232 __ movq($dst$$Register, $mem$$Address); 4233 %} 4234 ins_pipe(ialu_reg_mem); // XXX 4235 %} 4236 4237 // Load Compressed Pointer 4238 instruct loadN(rRegN dst, memory mem) 4239 %{ 4240 match(Set dst (LoadN mem)); 4241 4242 ins_cost(125); // XXX 4243 format %{ "movl $dst, $mem\t# compressed ptr" %} 4244 ins_encode %{ 4245 __ movl($dst$$Register, $mem$$Address); 4246 %} 4247 ins_pipe(ialu_reg_mem); // XXX 4248 %} 4249 4250 4251 // Load Klass Pointer 4252 instruct loadKlass(rRegP dst, memory mem) 4253 %{ 4254 match(Set dst (LoadKlass mem)); 4255 4256 ins_cost(125); // XXX 4257 format %{ "movq $dst, $mem\t# class" %} 4258 ins_encode %{ 4259 __ movq($dst$$Register, $mem$$Address); 4260 %} 4261 ins_pipe(ialu_reg_mem); // XXX 4262 %} 4263 4264 // Load narrow Klass Pointer 4265 instruct loadNKlass(rRegN dst, memory mem) 4266 %{ 4267 match(Set dst (LoadNKlass mem)); 4268 4269 ins_cost(125); // XXX 4270 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4271 ins_encode %{ 4272 __ movl($dst$$Register, $mem$$Address); 4273 %} 4274 ins_pipe(ialu_reg_mem); // XXX 4275 %} 4276 4277 // Load Float 4278 instruct loadF(regF dst, memory mem) 4279 %{ 4280 match(Set dst (LoadF mem)); 4281 4282 ins_cost(145); // XXX 4283 format %{ "movss $dst, $mem\t# float" %} 4284 ins_encode %{ 4285 __ movflt($dst$$XMMRegister, $mem$$Address); 4286 %} 4287 ins_pipe(pipe_slow); // XXX 4288 %} 4289 4290 // Load Double 4291 instruct loadD_partial(regD dst, memory mem) 4292 %{ 4293 predicate(!UseXmmLoadAndClearUpper); 4294 match(Set dst (LoadD mem)); 4295 4296 ins_cost(145); // XXX 4297 format %{ "movlpd $dst, $mem\t# double" %} 4298 ins_encode %{ 4299 __ movdbl($dst$$XMMRegister, $mem$$Address); 4300 %} 4301 ins_pipe(pipe_slow); // XXX 4302 %} 4303 4304 instruct loadD(regD dst, memory mem) 4305 %{ 4306 predicate(UseXmmLoadAndClearUpper); 4307 match(Set dst (LoadD mem)); 4308 4309 ins_cost(145); // XXX 4310 format %{ "movsd $dst, $mem\t# double" %} 4311 ins_encode %{ 4312 __ movdbl($dst$$XMMRegister, $mem$$Address); 4313 %} 4314 ins_pipe(pipe_slow); // XXX 4315 %} 4316 4317 // max = java.lang.Math.max(float a, float b) 4318 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4319 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4320 match(Set dst (MaxF a b)); 4321 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4322 format %{ "maxF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4323 ins_encode %{ 4324 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4325 %} 4326 ins_pipe( pipe_slow ); 4327 %} 4328 4329 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4330 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4331 match(Set dst (MaxF a b)); 4332 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4333 4334 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 4335 ins_encode %{ 4336 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4337 false /*min*/, true /*single*/); 4338 %} 4339 ins_pipe( pipe_slow ); 4340 %} 4341 4342 // max = java.lang.Math.max(double a, double b) 4343 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4344 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4345 match(Set dst (MaxD a b)); 4346 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4347 format %{ "maxD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4348 ins_encode %{ 4349 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4350 %} 4351 ins_pipe( pipe_slow ); 4352 %} 4353 4354 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4355 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4356 match(Set dst (MaxD a b)); 4357 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4358 4359 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 4360 ins_encode %{ 4361 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4362 false /*min*/, false /*single*/); 4363 %} 4364 ins_pipe( pipe_slow ); 4365 %} 4366 4367 // min = java.lang.Math.min(float a, float b) 4368 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4369 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4370 match(Set dst (MinF a b)); 4371 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4372 format %{ "minF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4373 ins_encode %{ 4374 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4375 %} 4376 ins_pipe( pipe_slow ); 4377 %} 4378 4379 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4380 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4381 match(Set dst (MinF a b)); 4382 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4383 4384 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 4385 ins_encode %{ 4386 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4387 true /*min*/, true /*single*/); 4388 %} 4389 ins_pipe( pipe_slow ); 4390 %} 4391 4392 // min = java.lang.Math.min(double a, double b) 4393 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4394 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4395 match(Set dst (MinD a b)); 4396 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4397 format %{ "minD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4398 ins_encode %{ 4399 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4400 %} 4401 ins_pipe( pipe_slow ); 4402 %} 4403 4404 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4405 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4406 match(Set dst (MinD a b)); 4407 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4408 4409 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 4410 ins_encode %{ 4411 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4412 true /*min*/, false /*single*/); 4413 %} 4414 ins_pipe( pipe_slow ); 4415 %} 4416 4417 // Load Effective Address 4418 instruct leaP8(rRegP dst, indOffset8 mem) 4419 %{ 4420 match(Set dst mem); 4421 4422 ins_cost(110); // XXX 4423 format %{ "leaq $dst, $mem\t# ptr 8" %} 4424 ins_encode %{ 4425 __ leaq($dst$$Register, $mem$$Address); 4426 %} 4427 ins_pipe(ialu_reg_reg_fat); 4428 %} 4429 4430 instruct leaP32(rRegP dst, indOffset32 mem) 4431 %{ 4432 match(Set dst mem); 4433 4434 ins_cost(110); 4435 format %{ "leaq $dst, $mem\t# ptr 32" %} 4436 ins_encode %{ 4437 __ leaq($dst$$Register, $mem$$Address); 4438 %} 4439 ins_pipe(ialu_reg_reg_fat); 4440 %} 4441 4442 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4443 %{ 4444 match(Set dst mem); 4445 4446 ins_cost(110); 4447 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4448 ins_encode %{ 4449 __ leaq($dst$$Register, $mem$$Address); 4450 %} 4451 ins_pipe(ialu_reg_reg_fat); 4452 %} 4453 4454 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4455 %{ 4456 match(Set dst mem); 4457 4458 ins_cost(110); 4459 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4460 ins_encode %{ 4461 __ leaq($dst$$Register, $mem$$Address); 4462 %} 4463 ins_pipe(ialu_reg_reg_fat); 4464 %} 4465 4466 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4467 %{ 4468 match(Set dst mem); 4469 4470 ins_cost(110); 4471 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4472 ins_encode %{ 4473 __ leaq($dst$$Register, $mem$$Address); 4474 %} 4475 ins_pipe(ialu_reg_reg_fat); 4476 %} 4477 4478 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4479 %{ 4480 match(Set dst mem); 4481 4482 ins_cost(110); 4483 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4484 ins_encode %{ 4485 __ leaq($dst$$Register, $mem$$Address); 4486 %} 4487 ins_pipe(ialu_reg_reg_fat); 4488 %} 4489 4490 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4491 %{ 4492 match(Set dst mem); 4493 4494 ins_cost(110); 4495 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4496 ins_encode %{ 4497 __ leaq($dst$$Register, $mem$$Address); 4498 %} 4499 ins_pipe(ialu_reg_reg_fat); 4500 %} 4501 4502 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4503 %{ 4504 match(Set dst mem); 4505 4506 ins_cost(110); 4507 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4508 ins_encode %{ 4509 __ leaq($dst$$Register, $mem$$Address); 4510 %} 4511 ins_pipe(ialu_reg_reg_fat); 4512 %} 4513 4514 // Load Effective Address which uses Narrow (32-bits) oop 4515 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4516 %{ 4517 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4518 match(Set dst mem); 4519 4520 ins_cost(110); 4521 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4522 ins_encode %{ 4523 __ leaq($dst$$Register, $mem$$Address); 4524 %} 4525 ins_pipe(ialu_reg_reg_fat); 4526 %} 4527 4528 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4529 %{ 4530 predicate(CompressedOops::shift() == 0); 4531 match(Set dst mem); 4532 4533 ins_cost(110); // XXX 4534 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4535 ins_encode %{ 4536 __ leaq($dst$$Register, $mem$$Address); 4537 %} 4538 ins_pipe(ialu_reg_reg_fat); 4539 %} 4540 4541 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4542 %{ 4543 predicate(CompressedOops::shift() == 0); 4544 match(Set dst mem); 4545 4546 ins_cost(110); 4547 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4548 ins_encode %{ 4549 __ leaq($dst$$Register, $mem$$Address); 4550 %} 4551 ins_pipe(ialu_reg_reg_fat); 4552 %} 4553 4554 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4555 %{ 4556 predicate(CompressedOops::shift() == 0); 4557 match(Set dst mem); 4558 4559 ins_cost(110); 4560 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4561 ins_encode %{ 4562 __ leaq($dst$$Register, $mem$$Address); 4563 %} 4564 ins_pipe(ialu_reg_reg_fat); 4565 %} 4566 4567 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4568 %{ 4569 predicate(CompressedOops::shift() == 0); 4570 match(Set dst mem); 4571 4572 ins_cost(110); 4573 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4574 ins_encode %{ 4575 __ leaq($dst$$Register, $mem$$Address); 4576 %} 4577 ins_pipe(ialu_reg_reg_fat); 4578 %} 4579 4580 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4581 %{ 4582 predicate(CompressedOops::shift() == 0); 4583 match(Set dst mem); 4584 4585 ins_cost(110); 4586 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4587 ins_encode %{ 4588 __ leaq($dst$$Register, $mem$$Address); 4589 %} 4590 ins_pipe(ialu_reg_reg_fat); 4591 %} 4592 4593 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4594 %{ 4595 predicate(CompressedOops::shift() == 0); 4596 match(Set dst mem); 4597 4598 ins_cost(110); 4599 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4600 ins_encode %{ 4601 __ leaq($dst$$Register, $mem$$Address); 4602 %} 4603 ins_pipe(ialu_reg_reg_fat); 4604 %} 4605 4606 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4607 %{ 4608 predicate(CompressedOops::shift() == 0); 4609 match(Set dst mem); 4610 4611 ins_cost(110); 4612 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4613 ins_encode %{ 4614 __ leaq($dst$$Register, $mem$$Address); 4615 %} 4616 ins_pipe(ialu_reg_reg_fat); 4617 %} 4618 4619 instruct loadConI(rRegI dst, immI src) 4620 %{ 4621 match(Set dst src); 4622 4623 format %{ "movl $dst, $src\t# int" %} 4624 ins_encode %{ 4625 __ movl($dst$$Register, $src$$constant); 4626 %} 4627 ins_pipe(ialu_reg_fat); // XXX 4628 %} 4629 4630 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4631 %{ 4632 match(Set dst src); 4633 effect(KILL cr); 4634 4635 ins_cost(50); 4636 format %{ "xorl $dst, $dst\t# int" %} 4637 ins_encode %{ 4638 __ xorl($dst$$Register, $dst$$Register); 4639 %} 4640 ins_pipe(ialu_reg); 4641 %} 4642 4643 instruct loadConL(rRegL dst, immL src) 4644 %{ 4645 match(Set dst src); 4646 4647 ins_cost(150); 4648 format %{ "movq $dst, $src\t# long" %} 4649 ins_encode %{ 4650 __ mov64($dst$$Register, $src$$constant); 4651 %} 4652 ins_pipe(ialu_reg); 4653 %} 4654 4655 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4656 %{ 4657 match(Set dst src); 4658 effect(KILL cr); 4659 4660 ins_cost(50); 4661 format %{ "xorl $dst, $dst\t# long" %} 4662 ins_encode %{ 4663 __ xorl($dst$$Register, $dst$$Register); 4664 %} 4665 ins_pipe(ialu_reg); // XXX 4666 %} 4667 4668 instruct loadConUL32(rRegL dst, immUL32 src) 4669 %{ 4670 match(Set dst src); 4671 4672 ins_cost(60); 4673 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4674 ins_encode %{ 4675 __ movl($dst$$Register, $src$$constant); 4676 %} 4677 ins_pipe(ialu_reg); 4678 %} 4679 4680 instruct loadConL32(rRegL dst, immL32 src) 4681 %{ 4682 match(Set dst src); 4683 4684 ins_cost(70); 4685 format %{ "movq $dst, $src\t# long (32-bit)" %} 4686 ins_encode %{ 4687 __ movq($dst$$Register, $src$$constant); 4688 %} 4689 ins_pipe(ialu_reg); 4690 %} 4691 4692 instruct loadConP(rRegP dst, immP con) %{ 4693 match(Set dst con); 4694 4695 format %{ "movq $dst, $con\t# ptr" %} 4696 ins_encode %{ 4697 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4698 %} 4699 ins_pipe(ialu_reg_fat); // XXX 4700 %} 4701 4702 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4703 %{ 4704 match(Set dst src); 4705 effect(KILL cr); 4706 4707 ins_cost(50); 4708 format %{ "xorl $dst, $dst\t# ptr" %} 4709 ins_encode %{ 4710 __ xorl($dst$$Register, $dst$$Register); 4711 %} 4712 ins_pipe(ialu_reg); 4713 %} 4714 4715 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4716 %{ 4717 match(Set dst src); 4718 effect(KILL cr); 4719 4720 ins_cost(60); 4721 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4722 ins_encode %{ 4723 __ movl($dst$$Register, $src$$constant); 4724 %} 4725 ins_pipe(ialu_reg); 4726 %} 4727 4728 instruct loadConF(regF dst, immF con) %{ 4729 match(Set dst con); 4730 ins_cost(125); 4731 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4732 ins_encode %{ 4733 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4734 %} 4735 ins_pipe(pipe_slow); 4736 %} 4737 4738 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4739 match(Set dst src); 4740 effect(KILL cr); 4741 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4742 ins_encode %{ 4743 __ xorq($dst$$Register, $dst$$Register); 4744 %} 4745 ins_pipe(ialu_reg); 4746 %} 4747 4748 instruct loadConN(rRegN dst, immN src) %{ 4749 match(Set dst src); 4750 4751 ins_cost(125); 4752 format %{ "movl $dst, $src\t# compressed ptr" %} 4753 ins_encode %{ 4754 address con = (address)$src$$constant; 4755 if (con == nullptr) { 4756 ShouldNotReachHere(); 4757 } else { 4758 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4759 } 4760 %} 4761 ins_pipe(ialu_reg_fat); // XXX 4762 %} 4763 4764 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4765 match(Set dst src); 4766 4767 ins_cost(125); 4768 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4769 ins_encode %{ 4770 address con = (address)$src$$constant; 4771 if (con == nullptr) { 4772 ShouldNotReachHere(); 4773 } else { 4774 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4775 } 4776 %} 4777 ins_pipe(ialu_reg_fat); // XXX 4778 %} 4779 4780 instruct loadConF0(regF dst, immF0 src) 4781 %{ 4782 match(Set dst src); 4783 ins_cost(100); 4784 4785 format %{ "xorps $dst, $dst\t# float 0.0" %} 4786 ins_encode %{ 4787 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4788 %} 4789 ins_pipe(pipe_slow); 4790 %} 4791 4792 // Use the same format since predicate() can not be used here. 4793 instruct loadConD(regD dst, immD con) %{ 4794 match(Set dst con); 4795 ins_cost(125); 4796 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4797 ins_encode %{ 4798 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4799 %} 4800 ins_pipe(pipe_slow); 4801 %} 4802 4803 instruct loadConD0(regD dst, immD0 src) 4804 %{ 4805 match(Set dst src); 4806 ins_cost(100); 4807 4808 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4809 ins_encode %{ 4810 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4811 %} 4812 ins_pipe(pipe_slow); 4813 %} 4814 4815 instruct loadSSI(rRegI dst, stackSlotI src) 4816 %{ 4817 match(Set dst src); 4818 4819 ins_cost(125); 4820 format %{ "movl $dst, $src\t# int stk" %} 4821 ins_encode %{ 4822 __ movl($dst$$Register, $src$$Address); 4823 %} 4824 ins_pipe(ialu_reg_mem); 4825 %} 4826 4827 instruct loadSSL(rRegL dst, stackSlotL src) 4828 %{ 4829 match(Set dst src); 4830 4831 ins_cost(125); 4832 format %{ "movq $dst, $src\t# long stk" %} 4833 ins_encode %{ 4834 __ movq($dst$$Register, $src$$Address); 4835 %} 4836 ins_pipe(ialu_reg_mem); 4837 %} 4838 4839 instruct loadSSP(rRegP dst, stackSlotP src) 4840 %{ 4841 match(Set dst src); 4842 4843 ins_cost(125); 4844 format %{ "movq $dst, $src\t# ptr stk" %} 4845 ins_encode %{ 4846 __ movq($dst$$Register, $src$$Address); 4847 %} 4848 ins_pipe(ialu_reg_mem); 4849 %} 4850 4851 instruct loadSSF(regF dst, stackSlotF src) 4852 %{ 4853 match(Set dst src); 4854 4855 ins_cost(125); 4856 format %{ "movss $dst, $src\t# float stk" %} 4857 ins_encode %{ 4858 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 4859 %} 4860 ins_pipe(pipe_slow); // XXX 4861 %} 4862 4863 // Use the same format since predicate() can not be used here. 4864 instruct loadSSD(regD dst, stackSlotD src) 4865 %{ 4866 match(Set dst src); 4867 4868 ins_cost(125); 4869 format %{ "movsd $dst, $src\t# double stk" %} 4870 ins_encode %{ 4871 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 4872 %} 4873 ins_pipe(pipe_slow); // XXX 4874 %} 4875 4876 // Prefetch instructions for allocation. 4877 // Must be safe to execute with invalid address (cannot fault). 4878 4879 instruct prefetchAlloc( memory mem ) %{ 4880 predicate(AllocatePrefetchInstr==3); 4881 match(PrefetchAllocation mem); 4882 ins_cost(125); 4883 4884 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 4885 ins_encode %{ 4886 __ prefetchw($mem$$Address); 4887 %} 4888 ins_pipe(ialu_mem); 4889 %} 4890 4891 instruct prefetchAllocNTA( memory mem ) %{ 4892 predicate(AllocatePrefetchInstr==0); 4893 match(PrefetchAllocation mem); 4894 ins_cost(125); 4895 4896 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 4897 ins_encode %{ 4898 __ prefetchnta($mem$$Address); 4899 %} 4900 ins_pipe(ialu_mem); 4901 %} 4902 4903 instruct prefetchAllocT0( memory mem ) %{ 4904 predicate(AllocatePrefetchInstr==1); 4905 match(PrefetchAllocation mem); 4906 ins_cost(125); 4907 4908 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 4909 ins_encode %{ 4910 __ prefetcht0($mem$$Address); 4911 %} 4912 ins_pipe(ialu_mem); 4913 %} 4914 4915 instruct prefetchAllocT2( memory mem ) %{ 4916 predicate(AllocatePrefetchInstr==2); 4917 match(PrefetchAllocation mem); 4918 ins_cost(125); 4919 4920 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 4921 ins_encode %{ 4922 __ prefetcht2($mem$$Address); 4923 %} 4924 ins_pipe(ialu_mem); 4925 %} 4926 4927 //----------Store Instructions------------------------------------------------- 4928 4929 // Store Byte 4930 instruct storeB(memory mem, rRegI src) 4931 %{ 4932 match(Set mem (StoreB mem src)); 4933 4934 ins_cost(125); // XXX 4935 format %{ "movb $mem, $src\t# byte" %} 4936 ins_encode %{ 4937 __ movb($mem$$Address, $src$$Register); 4938 %} 4939 ins_pipe(ialu_mem_reg); 4940 %} 4941 4942 // Store Char/Short 4943 instruct storeC(memory mem, rRegI src) 4944 %{ 4945 match(Set mem (StoreC mem src)); 4946 4947 ins_cost(125); // XXX 4948 format %{ "movw $mem, $src\t# char/short" %} 4949 ins_encode %{ 4950 __ movw($mem$$Address, $src$$Register); 4951 %} 4952 ins_pipe(ialu_mem_reg); 4953 %} 4954 4955 // Store Integer 4956 instruct storeI(memory mem, rRegI src) 4957 %{ 4958 match(Set mem (StoreI mem src)); 4959 4960 ins_cost(125); // XXX 4961 format %{ "movl $mem, $src\t# int" %} 4962 ins_encode %{ 4963 __ movl($mem$$Address, $src$$Register); 4964 %} 4965 ins_pipe(ialu_mem_reg); 4966 %} 4967 4968 // Store Long 4969 instruct storeL(memory mem, rRegL src) 4970 %{ 4971 match(Set mem (StoreL mem src)); 4972 4973 ins_cost(125); // XXX 4974 format %{ "movq $mem, $src\t# long" %} 4975 ins_encode %{ 4976 __ movq($mem$$Address, $src$$Register); 4977 %} 4978 ins_pipe(ialu_mem_reg); // XXX 4979 %} 4980 4981 // Store Pointer 4982 instruct storeP(memory mem, any_RegP src) 4983 %{ 4984 predicate(n->as_Store()->barrier_data() == 0); 4985 match(Set mem (StoreP mem src)); 4986 4987 ins_cost(125); // XXX 4988 format %{ "movq $mem, $src\t# ptr" %} 4989 ins_encode %{ 4990 __ movq($mem$$Address, $src$$Register); 4991 %} 4992 ins_pipe(ialu_mem_reg); 4993 %} 4994 4995 instruct storeImmP0(memory mem, immP0 zero) 4996 %{ 4997 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 4998 match(Set mem (StoreP mem zero)); 4999 5000 ins_cost(125); // XXX 5001 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5002 ins_encode %{ 5003 __ movq($mem$$Address, r12); 5004 %} 5005 ins_pipe(ialu_mem_reg); 5006 %} 5007 5008 // Store Null Pointer, mark word, or other simple pointer constant. 5009 instruct storeImmP(memory mem, immP31 src) 5010 %{ 5011 predicate(n->as_Store()->barrier_data() == 0); 5012 match(Set mem (StoreP mem src)); 5013 5014 ins_cost(150); // XXX 5015 format %{ "movq $mem, $src\t# ptr" %} 5016 ins_encode %{ 5017 __ movq($mem$$Address, $src$$constant); 5018 %} 5019 ins_pipe(ialu_mem_imm); 5020 %} 5021 5022 // Store Compressed Pointer 5023 instruct storeN(memory mem, rRegN src) 5024 %{ 5025 match(Set mem (StoreN mem src)); 5026 5027 ins_cost(125); // XXX 5028 format %{ "movl $mem, $src\t# compressed ptr" %} 5029 ins_encode %{ 5030 __ movl($mem$$Address, $src$$Register); 5031 %} 5032 ins_pipe(ialu_mem_reg); 5033 %} 5034 5035 instruct storeNKlass(memory mem, rRegN src) 5036 %{ 5037 match(Set mem (StoreNKlass mem src)); 5038 5039 ins_cost(125); // XXX 5040 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5041 ins_encode %{ 5042 __ movl($mem$$Address, $src$$Register); 5043 %} 5044 ins_pipe(ialu_mem_reg); 5045 %} 5046 5047 instruct storeImmN0(memory mem, immN0 zero) 5048 %{ 5049 predicate(CompressedOops::base() == nullptr); 5050 match(Set mem (StoreN mem zero)); 5051 5052 ins_cost(125); // XXX 5053 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5054 ins_encode %{ 5055 __ movl($mem$$Address, r12); 5056 %} 5057 ins_pipe(ialu_mem_reg); 5058 %} 5059 5060 instruct storeImmN(memory mem, immN src) 5061 %{ 5062 match(Set mem (StoreN mem src)); 5063 5064 ins_cost(150); // XXX 5065 format %{ "movl $mem, $src\t# compressed ptr" %} 5066 ins_encode %{ 5067 address con = (address)$src$$constant; 5068 if (con == nullptr) { 5069 __ movl($mem$$Address, 0); 5070 } else { 5071 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5072 } 5073 %} 5074 ins_pipe(ialu_mem_imm); 5075 %} 5076 5077 instruct storeImmNKlass(memory mem, immNKlass src) 5078 %{ 5079 match(Set mem (StoreNKlass mem src)); 5080 5081 ins_cost(150); // XXX 5082 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5083 ins_encode %{ 5084 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5085 %} 5086 ins_pipe(ialu_mem_imm); 5087 %} 5088 5089 // Store Integer Immediate 5090 instruct storeImmI0(memory mem, immI_0 zero) 5091 %{ 5092 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5093 match(Set mem (StoreI mem zero)); 5094 5095 ins_cost(125); // XXX 5096 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5097 ins_encode %{ 5098 __ movl($mem$$Address, r12); 5099 %} 5100 ins_pipe(ialu_mem_reg); 5101 %} 5102 5103 instruct storeImmI(memory mem, immI src) 5104 %{ 5105 match(Set mem (StoreI mem src)); 5106 5107 ins_cost(150); 5108 format %{ "movl $mem, $src\t# int" %} 5109 ins_encode %{ 5110 __ movl($mem$$Address, $src$$constant); 5111 %} 5112 ins_pipe(ialu_mem_imm); 5113 %} 5114 5115 // Store Long Immediate 5116 instruct storeImmL0(memory mem, immL0 zero) 5117 %{ 5118 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5119 match(Set mem (StoreL mem zero)); 5120 5121 ins_cost(125); // XXX 5122 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5123 ins_encode %{ 5124 __ movq($mem$$Address, r12); 5125 %} 5126 ins_pipe(ialu_mem_reg); 5127 %} 5128 5129 instruct storeImmL(memory mem, immL32 src) 5130 %{ 5131 match(Set mem (StoreL mem src)); 5132 5133 ins_cost(150); 5134 format %{ "movq $mem, $src\t# long" %} 5135 ins_encode %{ 5136 __ movq($mem$$Address, $src$$constant); 5137 %} 5138 ins_pipe(ialu_mem_imm); 5139 %} 5140 5141 // Store Short/Char Immediate 5142 instruct storeImmC0(memory mem, immI_0 zero) 5143 %{ 5144 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5145 match(Set mem (StoreC mem zero)); 5146 5147 ins_cost(125); // XXX 5148 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5149 ins_encode %{ 5150 __ movw($mem$$Address, r12); 5151 %} 5152 ins_pipe(ialu_mem_reg); 5153 %} 5154 5155 instruct storeImmI16(memory mem, immI16 src) 5156 %{ 5157 predicate(UseStoreImmI16); 5158 match(Set mem (StoreC mem src)); 5159 5160 ins_cost(150); 5161 format %{ "movw $mem, $src\t# short/char" %} 5162 ins_encode %{ 5163 __ movw($mem$$Address, $src$$constant); 5164 %} 5165 ins_pipe(ialu_mem_imm); 5166 %} 5167 5168 // Store Byte Immediate 5169 instruct storeImmB0(memory mem, immI_0 zero) 5170 %{ 5171 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5172 match(Set mem (StoreB mem zero)); 5173 5174 ins_cost(125); // XXX 5175 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5176 ins_encode %{ 5177 __ movb($mem$$Address, r12); 5178 %} 5179 ins_pipe(ialu_mem_reg); 5180 %} 5181 5182 instruct storeImmB(memory mem, immI8 src) 5183 %{ 5184 match(Set mem (StoreB mem src)); 5185 5186 ins_cost(150); // XXX 5187 format %{ "movb $mem, $src\t# byte" %} 5188 ins_encode %{ 5189 __ movb($mem$$Address, $src$$constant); 5190 %} 5191 ins_pipe(ialu_mem_imm); 5192 %} 5193 5194 // Store CMS card-mark Immediate 5195 instruct storeImmCM0_reg(memory mem, immI_0 zero) 5196 %{ 5197 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5198 match(Set mem (StoreCM mem zero)); 5199 5200 ins_cost(125); // XXX 5201 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5202 ins_encode %{ 5203 __ movb($mem$$Address, r12); 5204 %} 5205 ins_pipe(ialu_mem_reg); 5206 %} 5207 5208 instruct storeImmCM0(memory mem, immI_0 src) 5209 %{ 5210 match(Set mem (StoreCM mem src)); 5211 5212 ins_cost(150); // XXX 5213 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5214 ins_encode %{ 5215 __ movb($mem$$Address, $src$$constant); 5216 %} 5217 ins_pipe(ialu_mem_imm); 5218 %} 5219 5220 // Store Float 5221 instruct storeF(memory mem, regF src) 5222 %{ 5223 match(Set mem (StoreF mem src)); 5224 5225 ins_cost(95); // XXX 5226 format %{ "movss $mem, $src\t# float" %} 5227 ins_encode %{ 5228 __ movflt($mem$$Address, $src$$XMMRegister); 5229 %} 5230 ins_pipe(pipe_slow); // XXX 5231 %} 5232 5233 // Store immediate Float value (it is faster than store from XMM register) 5234 instruct storeF0(memory mem, immF0 zero) 5235 %{ 5236 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5237 match(Set mem (StoreF mem zero)); 5238 5239 ins_cost(25); // XXX 5240 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5241 ins_encode %{ 5242 __ movl($mem$$Address, r12); 5243 %} 5244 ins_pipe(ialu_mem_reg); 5245 %} 5246 5247 instruct storeF_imm(memory mem, immF src) 5248 %{ 5249 match(Set mem (StoreF mem src)); 5250 5251 ins_cost(50); 5252 format %{ "movl $mem, $src\t# float" %} 5253 ins_encode %{ 5254 __ movl($mem$$Address, jint_cast($src$$constant)); 5255 %} 5256 ins_pipe(ialu_mem_imm); 5257 %} 5258 5259 // Store Double 5260 instruct storeD(memory mem, regD src) 5261 %{ 5262 match(Set mem (StoreD mem src)); 5263 5264 ins_cost(95); // XXX 5265 format %{ "movsd $mem, $src\t# double" %} 5266 ins_encode %{ 5267 __ movdbl($mem$$Address, $src$$XMMRegister); 5268 %} 5269 ins_pipe(pipe_slow); // XXX 5270 %} 5271 5272 // Store immediate double 0.0 (it is faster than store from XMM register) 5273 instruct storeD0_imm(memory mem, immD0 src) 5274 %{ 5275 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5276 match(Set mem (StoreD mem src)); 5277 5278 ins_cost(50); 5279 format %{ "movq $mem, $src\t# double 0." %} 5280 ins_encode %{ 5281 __ movq($mem$$Address, $src$$constant); 5282 %} 5283 ins_pipe(ialu_mem_imm); 5284 %} 5285 5286 instruct storeD0(memory mem, immD0 zero) 5287 %{ 5288 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5289 match(Set mem (StoreD mem zero)); 5290 5291 ins_cost(25); // XXX 5292 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5293 ins_encode %{ 5294 __ movq($mem$$Address, r12); 5295 %} 5296 ins_pipe(ialu_mem_reg); 5297 %} 5298 5299 instruct storeSSI(stackSlotI dst, rRegI src) 5300 %{ 5301 match(Set dst src); 5302 5303 ins_cost(100); 5304 format %{ "movl $dst, $src\t# int stk" %} 5305 ins_encode %{ 5306 __ movl($dst$$Address, $src$$Register); 5307 %} 5308 ins_pipe( ialu_mem_reg ); 5309 %} 5310 5311 instruct storeSSL(stackSlotL dst, rRegL src) 5312 %{ 5313 match(Set dst src); 5314 5315 ins_cost(100); 5316 format %{ "movq $dst, $src\t# long stk" %} 5317 ins_encode %{ 5318 __ movq($dst$$Address, $src$$Register); 5319 %} 5320 ins_pipe(ialu_mem_reg); 5321 %} 5322 5323 instruct storeSSP(stackSlotP dst, rRegP src) 5324 %{ 5325 match(Set dst src); 5326 5327 ins_cost(100); 5328 format %{ "movq $dst, $src\t# ptr stk" %} 5329 ins_encode %{ 5330 __ movq($dst$$Address, $src$$Register); 5331 %} 5332 ins_pipe(ialu_mem_reg); 5333 %} 5334 5335 instruct storeSSF(stackSlotF dst, regF src) 5336 %{ 5337 match(Set dst src); 5338 5339 ins_cost(95); // XXX 5340 format %{ "movss $dst, $src\t# float stk" %} 5341 ins_encode %{ 5342 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5343 %} 5344 ins_pipe(pipe_slow); // XXX 5345 %} 5346 5347 instruct storeSSD(stackSlotD dst, regD src) 5348 %{ 5349 match(Set dst src); 5350 5351 ins_cost(95); // XXX 5352 format %{ "movsd $dst, $src\t# double stk" %} 5353 ins_encode %{ 5354 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5355 %} 5356 ins_pipe(pipe_slow); // XXX 5357 %} 5358 5359 instruct cacheWB(indirect addr) 5360 %{ 5361 predicate(VM_Version::supports_data_cache_line_flush()); 5362 match(CacheWB addr); 5363 5364 ins_cost(100); 5365 format %{"cache wb $addr" %} 5366 ins_encode %{ 5367 assert($addr->index_position() < 0, "should be"); 5368 assert($addr$$disp == 0, "should be"); 5369 __ cache_wb(Address($addr$$base$$Register, 0)); 5370 %} 5371 ins_pipe(pipe_slow); // XXX 5372 %} 5373 5374 instruct cacheWBPreSync() 5375 %{ 5376 predicate(VM_Version::supports_data_cache_line_flush()); 5377 match(CacheWBPreSync); 5378 5379 ins_cost(100); 5380 format %{"cache wb presync" %} 5381 ins_encode %{ 5382 __ cache_wbsync(true); 5383 %} 5384 ins_pipe(pipe_slow); // XXX 5385 %} 5386 5387 instruct cacheWBPostSync() 5388 %{ 5389 predicate(VM_Version::supports_data_cache_line_flush()); 5390 match(CacheWBPostSync); 5391 5392 ins_cost(100); 5393 format %{"cache wb postsync" %} 5394 ins_encode %{ 5395 __ cache_wbsync(false); 5396 %} 5397 ins_pipe(pipe_slow); // XXX 5398 %} 5399 5400 //----------BSWAP Instructions------------------------------------------------- 5401 instruct bytes_reverse_int(rRegI dst) %{ 5402 match(Set dst (ReverseBytesI dst)); 5403 5404 format %{ "bswapl $dst" %} 5405 ins_encode %{ 5406 __ bswapl($dst$$Register); 5407 %} 5408 ins_pipe( ialu_reg ); 5409 %} 5410 5411 instruct bytes_reverse_long(rRegL dst) %{ 5412 match(Set dst (ReverseBytesL dst)); 5413 5414 format %{ "bswapq $dst" %} 5415 ins_encode %{ 5416 __ bswapq($dst$$Register); 5417 %} 5418 ins_pipe( ialu_reg); 5419 %} 5420 5421 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5422 match(Set dst (ReverseBytesUS dst)); 5423 effect(KILL cr); 5424 5425 format %{ "bswapl $dst\n\t" 5426 "shrl $dst,16\n\t" %} 5427 ins_encode %{ 5428 __ bswapl($dst$$Register); 5429 __ shrl($dst$$Register, 16); 5430 %} 5431 ins_pipe( ialu_reg ); 5432 %} 5433 5434 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5435 match(Set dst (ReverseBytesS dst)); 5436 effect(KILL cr); 5437 5438 format %{ "bswapl $dst\n\t" 5439 "sar $dst,16\n\t" %} 5440 ins_encode %{ 5441 __ bswapl($dst$$Register); 5442 __ sarl($dst$$Register, 16); 5443 %} 5444 ins_pipe( ialu_reg ); 5445 %} 5446 5447 //---------- Zeros Count Instructions ------------------------------------------ 5448 5449 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5450 predicate(UseCountLeadingZerosInstruction); 5451 match(Set dst (CountLeadingZerosI src)); 5452 effect(KILL cr); 5453 5454 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5455 ins_encode %{ 5456 __ lzcntl($dst$$Register, $src$$Register); 5457 %} 5458 ins_pipe(ialu_reg); 5459 %} 5460 5461 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5462 predicate(UseCountLeadingZerosInstruction); 5463 match(Set dst (CountLeadingZerosI (LoadI src))); 5464 effect(KILL cr); 5465 ins_cost(175); 5466 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5467 ins_encode %{ 5468 __ lzcntl($dst$$Register, $src$$Address); 5469 %} 5470 ins_pipe(ialu_reg_mem); 5471 %} 5472 5473 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5474 predicate(!UseCountLeadingZerosInstruction); 5475 match(Set dst (CountLeadingZerosI src)); 5476 effect(KILL cr); 5477 5478 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5479 "jnz skip\n\t" 5480 "movl $dst, -1\n" 5481 "skip:\n\t" 5482 "negl $dst\n\t" 5483 "addl $dst, 31" %} 5484 ins_encode %{ 5485 Register Rdst = $dst$$Register; 5486 Register Rsrc = $src$$Register; 5487 Label skip; 5488 __ bsrl(Rdst, Rsrc); 5489 __ jccb(Assembler::notZero, skip); 5490 __ movl(Rdst, -1); 5491 __ bind(skip); 5492 __ negl(Rdst); 5493 __ addl(Rdst, BitsPerInt - 1); 5494 %} 5495 ins_pipe(ialu_reg); 5496 %} 5497 5498 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5499 predicate(UseCountLeadingZerosInstruction); 5500 match(Set dst (CountLeadingZerosL src)); 5501 effect(KILL cr); 5502 5503 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5504 ins_encode %{ 5505 __ lzcntq($dst$$Register, $src$$Register); 5506 %} 5507 ins_pipe(ialu_reg); 5508 %} 5509 5510 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5511 predicate(UseCountLeadingZerosInstruction); 5512 match(Set dst (CountLeadingZerosL (LoadL src))); 5513 effect(KILL cr); 5514 ins_cost(175); 5515 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5516 ins_encode %{ 5517 __ lzcntq($dst$$Register, $src$$Address); 5518 %} 5519 ins_pipe(ialu_reg_mem); 5520 %} 5521 5522 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5523 predicate(!UseCountLeadingZerosInstruction); 5524 match(Set dst (CountLeadingZerosL src)); 5525 effect(KILL cr); 5526 5527 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5528 "jnz skip\n\t" 5529 "movl $dst, -1\n" 5530 "skip:\n\t" 5531 "negl $dst\n\t" 5532 "addl $dst, 63" %} 5533 ins_encode %{ 5534 Register Rdst = $dst$$Register; 5535 Register Rsrc = $src$$Register; 5536 Label skip; 5537 __ bsrq(Rdst, Rsrc); 5538 __ jccb(Assembler::notZero, skip); 5539 __ movl(Rdst, -1); 5540 __ bind(skip); 5541 __ negl(Rdst); 5542 __ addl(Rdst, BitsPerLong - 1); 5543 %} 5544 ins_pipe(ialu_reg); 5545 %} 5546 5547 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5548 predicate(UseCountTrailingZerosInstruction); 5549 match(Set dst (CountTrailingZerosI src)); 5550 effect(KILL cr); 5551 5552 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5553 ins_encode %{ 5554 __ tzcntl($dst$$Register, $src$$Register); 5555 %} 5556 ins_pipe(ialu_reg); 5557 %} 5558 5559 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5560 predicate(UseCountTrailingZerosInstruction); 5561 match(Set dst (CountTrailingZerosI (LoadI src))); 5562 effect(KILL cr); 5563 ins_cost(175); 5564 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5565 ins_encode %{ 5566 __ tzcntl($dst$$Register, $src$$Address); 5567 %} 5568 ins_pipe(ialu_reg_mem); 5569 %} 5570 5571 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5572 predicate(!UseCountTrailingZerosInstruction); 5573 match(Set dst (CountTrailingZerosI src)); 5574 effect(KILL cr); 5575 5576 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5577 "jnz done\n\t" 5578 "movl $dst, 32\n" 5579 "done:" %} 5580 ins_encode %{ 5581 Register Rdst = $dst$$Register; 5582 Label done; 5583 __ bsfl(Rdst, $src$$Register); 5584 __ jccb(Assembler::notZero, done); 5585 __ movl(Rdst, BitsPerInt); 5586 __ bind(done); 5587 %} 5588 ins_pipe(ialu_reg); 5589 %} 5590 5591 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5592 predicate(UseCountTrailingZerosInstruction); 5593 match(Set dst (CountTrailingZerosL src)); 5594 effect(KILL cr); 5595 5596 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5597 ins_encode %{ 5598 __ tzcntq($dst$$Register, $src$$Register); 5599 %} 5600 ins_pipe(ialu_reg); 5601 %} 5602 5603 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5604 predicate(UseCountTrailingZerosInstruction); 5605 match(Set dst (CountTrailingZerosL (LoadL src))); 5606 effect(KILL cr); 5607 ins_cost(175); 5608 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5609 ins_encode %{ 5610 __ tzcntq($dst$$Register, $src$$Address); 5611 %} 5612 ins_pipe(ialu_reg_mem); 5613 %} 5614 5615 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5616 predicate(!UseCountTrailingZerosInstruction); 5617 match(Set dst (CountTrailingZerosL src)); 5618 effect(KILL cr); 5619 5620 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5621 "jnz done\n\t" 5622 "movl $dst, 64\n" 5623 "done:" %} 5624 ins_encode %{ 5625 Register Rdst = $dst$$Register; 5626 Label done; 5627 __ bsfq(Rdst, $src$$Register); 5628 __ jccb(Assembler::notZero, done); 5629 __ movl(Rdst, BitsPerLong); 5630 __ bind(done); 5631 %} 5632 ins_pipe(ialu_reg); 5633 %} 5634 5635 //--------------- Reverse Operation Instructions ---------------- 5636 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5637 predicate(!VM_Version::supports_gfni()); 5638 match(Set dst (ReverseI src)); 5639 effect(TEMP dst, TEMP rtmp, KILL cr); 5640 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5641 ins_encode %{ 5642 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5643 %} 5644 ins_pipe( ialu_reg ); 5645 %} 5646 5647 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5648 predicate(VM_Version::supports_gfni()); 5649 match(Set dst (ReverseI src)); 5650 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5651 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5652 ins_encode %{ 5653 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5654 %} 5655 ins_pipe( ialu_reg ); 5656 %} 5657 5658 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5659 predicate(!VM_Version::supports_gfni()); 5660 match(Set dst (ReverseL src)); 5661 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5662 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5663 ins_encode %{ 5664 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5665 %} 5666 ins_pipe( ialu_reg ); 5667 %} 5668 5669 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5670 predicate(VM_Version::supports_gfni()); 5671 match(Set dst (ReverseL src)); 5672 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5673 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5674 ins_encode %{ 5675 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5676 %} 5677 ins_pipe( ialu_reg ); 5678 %} 5679 5680 //---------- Population Count Instructions ------------------------------------- 5681 5682 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5683 predicate(UsePopCountInstruction); 5684 match(Set dst (PopCountI src)); 5685 effect(KILL cr); 5686 5687 format %{ "popcnt $dst, $src" %} 5688 ins_encode %{ 5689 __ popcntl($dst$$Register, $src$$Register); 5690 %} 5691 ins_pipe(ialu_reg); 5692 %} 5693 5694 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5695 predicate(UsePopCountInstruction); 5696 match(Set dst (PopCountI (LoadI mem))); 5697 effect(KILL cr); 5698 5699 format %{ "popcnt $dst, $mem" %} 5700 ins_encode %{ 5701 __ popcntl($dst$$Register, $mem$$Address); 5702 %} 5703 ins_pipe(ialu_reg); 5704 %} 5705 5706 // Note: Long.bitCount(long) returns an int. 5707 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5708 predicate(UsePopCountInstruction); 5709 match(Set dst (PopCountL src)); 5710 effect(KILL cr); 5711 5712 format %{ "popcnt $dst, $src" %} 5713 ins_encode %{ 5714 __ popcntq($dst$$Register, $src$$Register); 5715 %} 5716 ins_pipe(ialu_reg); 5717 %} 5718 5719 // Note: Long.bitCount(long) returns an int. 5720 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5721 predicate(UsePopCountInstruction); 5722 match(Set dst (PopCountL (LoadL mem))); 5723 effect(KILL cr); 5724 5725 format %{ "popcnt $dst, $mem" %} 5726 ins_encode %{ 5727 __ popcntq($dst$$Register, $mem$$Address); 5728 %} 5729 ins_pipe(ialu_reg); 5730 %} 5731 5732 5733 //----------MemBar Instructions----------------------------------------------- 5734 // Memory barrier flavors 5735 5736 instruct membar_acquire() 5737 %{ 5738 match(MemBarAcquire); 5739 match(LoadFence); 5740 ins_cost(0); 5741 5742 size(0); 5743 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5744 ins_encode(); 5745 ins_pipe(empty); 5746 %} 5747 5748 instruct membar_acquire_lock() 5749 %{ 5750 match(MemBarAcquireLock); 5751 ins_cost(0); 5752 5753 size(0); 5754 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5755 ins_encode(); 5756 ins_pipe(empty); 5757 %} 5758 5759 instruct membar_release() 5760 %{ 5761 match(MemBarRelease); 5762 match(StoreFence); 5763 ins_cost(0); 5764 5765 size(0); 5766 format %{ "MEMBAR-release ! (empty encoding)" %} 5767 ins_encode(); 5768 ins_pipe(empty); 5769 %} 5770 5771 instruct membar_release_lock() 5772 %{ 5773 match(MemBarReleaseLock); 5774 ins_cost(0); 5775 5776 size(0); 5777 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5778 ins_encode(); 5779 ins_pipe(empty); 5780 %} 5781 5782 instruct membar_volatile(rFlagsReg cr) %{ 5783 match(MemBarVolatile); 5784 effect(KILL cr); 5785 ins_cost(400); 5786 5787 format %{ 5788 $$template 5789 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5790 %} 5791 ins_encode %{ 5792 __ membar(Assembler::StoreLoad); 5793 %} 5794 ins_pipe(pipe_slow); 5795 %} 5796 5797 instruct unnecessary_membar_volatile() 5798 %{ 5799 match(MemBarVolatile); 5800 predicate(Matcher::post_store_load_barrier(n)); 5801 ins_cost(0); 5802 5803 size(0); 5804 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5805 ins_encode(); 5806 ins_pipe(empty); 5807 %} 5808 5809 instruct membar_storestore() %{ 5810 match(MemBarStoreStore); 5811 match(StoreStoreFence); 5812 ins_cost(0); 5813 5814 size(0); 5815 format %{ "MEMBAR-storestore (empty encoding)" %} 5816 ins_encode( ); 5817 ins_pipe(empty); 5818 %} 5819 5820 //----------Move Instructions-------------------------------------------------- 5821 5822 instruct castX2P(rRegP dst, rRegL src) 5823 %{ 5824 match(Set dst (CastX2P src)); 5825 5826 format %{ "movq $dst, $src\t# long->ptr" %} 5827 ins_encode %{ 5828 if ($dst$$reg != $src$$reg) { 5829 __ movptr($dst$$Register, $src$$Register); 5830 } 5831 %} 5832 ins_pipe(ialu_reg_reg); // XXX 5833 %} 5834 5835 instruct castP2X(rRegL dst, rRegP src) 5836 %{ 5837 match(Set dst (CastP2X src)); 5838 5839 format %{ "movq $dst, $src\t# ptr -> long" %} 5840 ins_encode %{ 5841 if ($dst$$reg != $src$$reg) { 5842 __ movptr($dst$$Register, $src$$Register); 5843 } 5844 %} 5845 ins_pipe(ialu_reg_reg); // XXX 5846 %} 5847 5848 // Convert oop into int for vectors alignment masking 5849 instruct convP2I(rRegI dst, rRegP src) 5850 %{ 5851 match(Set dst (ConvL2I (CastP2X src))); 5852 5853 format %{ "movl $dst, $src\t# ptr -> int" %} 5854 ins_encode %{ 5855 __ movl($dst$$Register, $src$$Register); 5856 %} 5857 ins_pipe(ialu_reg_reg); // XXX 5858 %} 5859 5860 // Convert compressed oop into int for vectors alignment masking 5861 // in case of 32bit oops (heap < 4Gb). 5862 instruct convN2I(rRegI dst, rRegN src) 5863 %{ 5864 predicate(CompressedOops::shift() == 0); 5865 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5866 5867 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5868 ins_encode %{ 5869 __ movl($dst$$Register, $src$$Register); 5870 %} 5871 ins_pipe(ialu_reg_reg); // XXX 5872 %} 5873 5874 // Convert oop pointer into compressed form 5875 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5876 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5877 match(Set dst (EncodeP src)); 5878 effect(KILL cr); 5879 format %{ "encode_heap_oop $dst,$src" %} 5880 ins_encode %{ 5881 Register s = $src$$Register; 5882 Register d = $dst$$Register; 5883 if (s != d) { 5884 __ movq(d, s); 5885 } 5886 __ encode_heap_oop(d); 5887 %} 5888 ins_pipe(ialu_reg_long); 5889 %} 5890 5891 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5892 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 5893 match(Set dst (EncodeP src)); 5894 effect(KILL cr); 5895 format %{ "encode_heap_oop_not_null $dst,$src" %} 5896 ins_encode %{ 5897 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 5898 %} 5899 ins_pipe(ialu_reg_long); 5900 %} 5901 5902 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 5903 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 5904 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 5905 match(Set dst (DecodeN src)); 5906 effect(KILL cr); 5907 format %{ "decode_heap_oop $dst,$src" %} 5908 ins_encode %{ 5909 Register s = $src$$Register; 5910 Register d = $dst$$Register; 5911 if (s != d) { 5912 __ movq(d, s); 5913 } 5914 __ decode_heap_oop(d); 5915 %} 5916 ins_pipe(ialu_reg_long); 5917 %} 5918 5919 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 5920 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 5921 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 5922 match(Set dst (DecodeN src)); 5923 effect(KILL cr); 5924 format %{ "decode_heap_oop_not_null $dst,$src" %} 5925 ins_encode %{ 5926 Register s = $src$$Register; 5927 Register d = $dst$$Register; 5928 if (s != d) { 5929 __ decode_heap_oop_not_null(d, s); 5930 } else { 5931 __ decode_heap_oop_not_null(d); 5932 } 5933 %} 5934 ins_pipe(ialu_reg_long); 5935 %} 5936 5937 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5938 match(Set dst (EncodePKlass src)); 5939 effect(TEMP dst, KILL cr); 5940 format %{ "encode_and_move_klass_not_null $dst,$src" %} 5941 ins_encode %{ 5942 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 5943 %} 5944 ins_pipe(ialu_reg_long); 5945 %} 5946 5947 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 5948 match(Set dst (DecodeNKlass src)); 5949 effect(TEMP dst, KILL cr); 5950 format %{ "decode_and_move_klass_not_null $dst,$src" %} 5951 ins_encode %{ 5952 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 5953 %} 5954 ins_pipe(ialu_reg_long); 5955 %} 5956 5957 //----------Conditional Move--------------------------------------------------- 5958 // Jump 5959 // dummy instruction for generating temp registers 5960 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 5961 match(Jump (LShiftL switch_val shift)); 5962 ins_cost(350); 5963 predicate(false); 5964 effect(TEMP dest); 5965 5966 format %{ "leaq $dest, [$constantaddress]\n\t" 5967 "jmp [$dest + $switch_val << $shift]\n\t" %} 5968 ins_encode %{ 5969 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 5970 // to do that and the compiler is using that register as one it can allocate. 5971 // So we build it all by hand. 5972 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 5973 // ArrayAddress dispatch(table, index); 5974 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 5975 __ lea($dest$$Register, $constantaddress); 5976 __ jmp(dispatch); 5977 %} 5978 ins_pipe(pipe_jmp); 5979 %} 5980 5981 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 5982 match(Jump (AddL (LShiftL switch_val shift) offset)); 5983 ins_cost(350); 5984 effect(TEMP dest); 5985 5986 format %{ "leaq $dest, [$constantaddress]\n\t" 5987 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 5988 ins_encode %{ 5989 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 5990 // to do that and the compiler is using that register as one it can allocate. 5991 // So we build it all by hand. 5992 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 5993 // ArrayAddress dispatch(table, index); 5994 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 5995 __ lea($dest$$Register, $constantaddress); 5996 __ jmp(dispatch); 5997 %} 5998 ins_pipe(pipe_jmp); 5999 %} 6000 6001 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6002 match(Jump switch_val); 6003 ins_cost(350); 6004 effect(TEMP dest); 6005 6006 format %{ "leaq $dest, [$constantaddress]\n\t" 6007 "jmp [$dest + $switch_val]\n\t" %} 6008 ins_encode %{ 6009 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6010 // to do that and the compiler is using that register as one it can allocate. 6011 // So we build it all by hand. 6012 // Address index(noreg, switch_reg, Address::times_1); 6013 // ArrayAddress dispatch(table, index); 6014 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6015 __ lea($dest$$Register, $constantaddress); 6016 __ jmp(dispatch); 6017 %} 6018 ins_pipe(pipe_jmp); 6019 %} 6020 6021 // Conditional move 6022 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6023 %{ 6024 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6025 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6026 6027 ins_cost(100); // XXX 6028 format %{ "setbn$cop $dst\t# signed, int" %} 6029 ins_encode %{ 6030 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6031 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6032 %} 6033 ins_pipe(ialu_reg); 6034 %} 6035 6036 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6037 %{ 6038 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6039 6040 ins_cost(200); // XXX 6041 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6042 ins_encode %{ 6043 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6044 %} 6045 ins_pipe(pipe_cmov_reg); 6046 %} 6047 6048 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6049 %{ 6050 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6051 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6052 6053 ins_cost(100); // XXX 6054 format %{ "setbn$cop $dst\t# unsigned, int" %} 6055 ins_encode %{ 6056 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6057 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6058 %} 6059 ins_pipe(ialu_reg); 6060 %} 6061 6062 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6063 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6064 6065 ins_cost(200); // XXX 6066 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6067 ins_encode %{ 6068 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6069 %} 6070 ins_pipe(pipe_cmov_reg); 6071 %} 6072 6073 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6074 %{ 6075 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6076 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6077 6078 ins_cost(100); // XXX 6079 format %{ "setbn$cop $dst\t# unsigned, int" %} 6080 ins_encode %{ 6081 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6082 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6083 %} 6084 ins_pipe(ialu_reg); 6085 %} 6086 6087 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6088 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6089 ins_cost(200); 6090 expand %{ 6091 cmovI_regU(cop, cr, dst, src); 6092 %} 6093 %} 6094 6095 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6096 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6097 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6098 6099 ins_cost(200); // XXX 6100 format %{ "cmovpl $dst, $src\n\t" 6101 "cmovnel $dst, $src" %} 6102 ins_encode %{ 6103 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6104 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6105 %} 6106 ins_pipe(pipe_cmov_reg); 6107 %} 6108 6109 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6110 // inputs of the CMove 6111 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6112 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6113 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6114 6115 ins_cost(200); // XXX 6116 format %{ "cmovpl $dst, $src\n\t" 6117 "cmovnel $dst, $src" %} 6118 ins_encode %{ 6119 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6120 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6121 %} 6122 ins_pipe(pipe_cmov_reg); 6123 %} 6124 6125 // Conditional move 6126 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6127 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6128 6129 ins_cost(250); // XXX 6130 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6131 ins_encode %{ 6132 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6133 %} 6134 ins_pipe(pipe_cmov_mem); 6135 %} 6136 6137 // Conditional move 6138 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6139 %{ 6140 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6141 6142 ins_cost(250); // XXX 6143 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6144 ins_encode %{ 6145 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6146 %} 6147 ins_pipe(pipe_cmov_mem); 6148 %} 6149 6150 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6151 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6152 ins_cost(250); 6153 expand %{ 6154 cmovI_memU(cop, cr, dst, src); 6155 %} 6156 %} 6157 6158 // Conditional move 6159 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6160 %{ 6161 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6162 6163 ins_cost(200); // XXX 6164 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6165 ins_encode %{ 6166 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6167 %} 6168 ins_pipe(pipe_cmov_reg); 6169 %} 6170 6171 // Conditional move 6172 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6173 %{ 6174 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6175 6176 ins_cost(200); // XXX 6177 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6178 ins_encode %{ 6179 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6180 %} 6181 ins_pipe(pipe_cmov_reg); 6182 %} 6183 6184 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6185 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6186 ins_cost(200); 6187 expand %{ 6188 cmovN_regU(cop, cr, dst, src); 6189 %} 6190 %} 6191 6192 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6193 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6194 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6195 6196 ins_cost(200); // XXX 6197 format %{ "cmovpl $dst, $src\n\t" 6198 "cmovnel $dst, $src" %} 6199 ins_encode %{ 6200 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6201 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6202 %} 6203 ins_pipe(pipe_cmov_reg); 6204 %} 6205 6206 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6207 // inputs of the CMove 6208 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6209 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6210 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6211 6212 ins_cost(200); // XXX 6213 format %{ "cmovpl $dst, $src\n\t" 6214 "cmovnel $dst, $src" %} 6215 ins_encode %{ 6216 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6217 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6218 %} 6219 ins_pipe(pipe_cmov_reg); 6220 %} 6221 6222 // Conditional move 6223 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6224 %{ 6225 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6226 6227 ins_cost(200); // XXX 6228 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6229 ins_encode %{ 6230 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6231 %} 6232 ins_pipe(pipe_cmov_reg); // XXX 6233 %} 6234 6235 // Conditional move 6236 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6237 %{ 6238 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6239 6240 ins_cost(200); // XXX 6241 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6242 ins_encode %{ 6243 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6244 %} 6245 ins_pipe(pipe_cmov_reg); // XXX 6246 %} 6247 6248 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6249 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6250 ins_cost(200); 6251 expand %{ 6252 cmovP_regU(cop, cr, dst, src); 6253 %} 6254 %} 6255 6256 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6257 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6258 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6259 6260 ins_cost(200); // XXX 6261 format %{ "cmovpq $dst, $src\n\t" 6262 "cmovneq $dst, $src" %} 6263 ins_encode %{ 6264 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6265 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6266 %} 6267 ins_pipe(pipe_cmov_reg); 6268 %} 6269 6270 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6271 // inputs of the CMove 6272 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6273 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6274 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6275 6276 ins_cost(200); // XXX 6277 format %{ "cmovpq $dst, $src\n\t" 6278 "cmovneq $dst, $src" %} 6279 ins_encode %{ 6280 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6281 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6282 %} 6283 ins_pipe(pipe_cmov_reg); 6284 %} 6285 6286 instruct cmovL_imm_01(rRegL dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6287 %{ 6288 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6289 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6290 6291 ins_cost(100); // XXX 6292 format %{ "setbn$cop $dst\t# signed, long" %} 6293 ins_encode %{ 6294 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6295 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6296 %} 6297 ins_pipe(ialu_reg); 6298 %} 6299 6300 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6301 %{ 6302 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6303 6304 ins_cost(200); // XXX 6305 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6306 ins_encode %{ 6307 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6308 %} 6309 ins_pipe(pipe_cmov_reg); // XXX 6310 %} 6311 6312 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6313 %{ 6314 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6315 6316 ins_cost(200); // XXX 6317 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6318 ins_encode %{ 6319 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6320 %} 6321 ins_pipe(pipe_cmov_mem); // XXX 6322 %} 6323 6324 instruct cmovL_imm_01U(rRegL dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6325 %{ 6326 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6327 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6328 6329 ins_cost(100); // XXX 6330 format %{ "setbn$cop $dst\t# unsigned, long" %} 6331 ins_encode %{ 6332 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6333 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6334 %} 6335 ins_pipe(ialu_reg); 6336 %} 6337 6338 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6339 %{ 6340 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6341 6342 ins_cost(200); // XXX 6343 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6344 ins_encode %{ 6345 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6346 %} 6347 ins_pipe(pipe_cmov_reg); // XXX 6348 %} 6349 6350 instruct cmovL_imm_01UCF(rRegL dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6351 %{ 6352 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6353 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6354 6355 ins_cost(100); // XXX 6356 format %{ "setbn$cop $dst\t# unsigned, long" %} 6357 ins_encode %{ 6358 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6359 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6360 %} 6361 ins_pipe(ialu_reg); 6362 %} 6363 6364 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6365 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6366 ins_cost(200); 6367 expand %{ 6368 cmovL_regU(cop, cr, dst, src); 6369 %} 6370 %} 6371 6372 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6373 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6374 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6375 6376 ins_cost(200); // XXX 6377 format %{ "cmovpq $dst, $src\n\t" 6378 "cmovneq $dst, $src" %} 6379 ins_encode %{ 6380 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6381 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6382 %} 6383 ins_pipe(pipe_cmov_reg); 6384 %} 6385 6386 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6387 // inputs of the CMove 6388 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6389 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6390 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6391 6392 ins_cost(200); // XXX 6393 format %{ "cmovpq $dst, $src\n\t" 6394 "cmovneq $dst, $src" %} 6395 ins_encode %{ 6396 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6397 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6398 %} 6399 ins_pipe(pipe_cmov_reg); 6400 %} 6401 6402 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6403 %{ 6404 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6405 6406 ins_cost(200); // XXX 6407 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6408 ins_encode %{ 6409 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6410 %} 6411 ins_pipe(pipe_cmov_mem); // XXX 6412 %} 6413 6414 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6415 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6416 ins_cost(200); 6417 expand %{ 6418 cmovL_memU(cop, cr, dst, src); 6419 %} 6420 %} 6421 6422 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6423 %{ 6424 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6425 6426 ins_cost(200); // XXX 6427 format %{ "jn$cop skip\t# signed cmove float\n\t" 6428 "movss $dst, $src\n" 6429 "skip:" %} 6430 ins_encode %{ 6431 Label Lskip; 6432 // Invert sense of branch from sense of CMOV 6433 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6434 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6435 __ bind(Lskip); 6436 %} 6437 ins_pipe(pipe_slow); 6438 %} 6439 6440 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6441 %{ 6442 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6443 6444 ins_cost(200); // XXX 6445 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6446 "movss $dst, $src\n" 6447 "skip:" %} 6448 ins_encode %{ 6449 Label Lskip; 6450 // Invert sense of branch from sense of CMOV 6451 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6452 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6453 __ bind(Lskip); 6454 %} 6455 ins_pipe(pipe_slow); 6456 %} 6457 6458 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6459 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6460 ins_cost(200); 6461 expand %{ 6462 cmovF_regU(cop, cr, dst, src); 6463 %} 6464 %} 6465 6466 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6467 %{ 6468 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6469 6470 ins_cost(200); // XXX 6471 format %{ "jn$cop skip\t# signed cmove double\n\t" 6472 "movsd $dst, $src\n" 6473 "skip:" %} 6474 ins_encode %{ 6475 Label Lskip; 6476 // Invert sense of branch from sense of CMOV 6477 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6478 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6479 __ bind(Lskip); 6480 %} 6481 ins_pipe(pipe_slow); 6482 %} 6483 6484 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6485 %{ 6486 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6487 6488 ins_cost(200); // XXX 6489 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6490 "movsd $dst, $src\n" 6491 "skip:" %} 6492 ins_encode %{ 6493 Label Lskip; 6494 // Invert sense of branch from sense of CMOV 6495 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6496 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6497 __ bind(Lskip); 6498 %} 6499 ins_pipe(pipe_slow); 6500 %} 6501 6502 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6503 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6504 ins_cost(200); 6505 expand %{ 6506 cmovD_regU(cop, cr, dst, src); 6507 %} 6508 %} 6509 6510 //----------Arithmetic Instructions-------------------------------------------- 6511 //----------Addition Instructions---------------------------------------------- 6512 6513 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6514 %{ 6515 match(Set dst (AddI dst src)); 6516 effect(KILL cr); 6517 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); 6518 format %{ "addl $dst, $src\t# int" %} 6519 ins_encode %{ 6520 __ addl($dst$$Register, $src$$Register); 6521 %} 6522 ins_pipe(ialu_reg_reg); 6523 %} 6524 6525 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6526 %{ 6527 match(Set dst (AddI dst src)); 6528 effect(KILL cr); 6529 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); 6530 6531 format %{ "addl $dst, $src\t# int" %} 6532 ins_encode %{ 6533 __ addl($dst$$Register, $src$$constant); 6534 %} 6535 ins_pipe( ialu_reg ); 6536 %} 6537 6538 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6539 %{ 6540 match(Set dst (AddI dst (LoadI src))); 6541 effect(KILL cr); 6542 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); 6543 6544 ins_cost(150); // XXX 6545 format %{ "addl $dst, $src\t# int" %} 6546 ins_encode %{ 6547 __ addl($dst$$Register, $src$$Address); 6548 %} 6549 ins_pipe(ialu_reg_mem); 6550 %} 6551 6552 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6553 %{ 6554 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6555 effect(KILL cr); 6556 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); 6557 6558 ins_cost(150); // XXX 6559 format %{ "addl $dst, $src\t# int" %} 6560 ins_encode %{ 6561 __ addl($dst$$Address, $src$$Register); 6562 %} 6563 ins_pipe(ialu_mem_reg); 6564 %} 6565 6566 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6567 %{ 6568 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6569 effect(KILL cr); 6570 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); 6571 6572 6573 ins_cost(125); // XXX 6574 format %{ "addl $dst, $src\t# int" %} 6575 ins_encode %{ 6576 __ addl($dst$$Address, $src$$constant); 6577 %} 6578 ins_pipe(ialu_mem_imm); 6579 %} 6580 6581 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6582 %{ 6583 predicate(UseIncDec); 6584 match(Set dst (AddI dst src)); 6585 effect(KILL cr); 6586 6587 format %{ "incl $dst\t# int" %} 6588 ins_encode %{ 6589 __ incrementl($dst$$Register); 6590 %} 6591 ins_pipe(ialu_reg); 6592 %} 6593 6594 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6595 %{ 6596 predicate(UseIncDec); 6597 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6598 effect(KILL cr); 6599 6600 ins_cost(125); // XXX 6601 format %{ "incl $dst\t# int" %} 6602 ins_encode %{ 6603 __ incrementl($dst$$Address); 6604 %} 6605 ins_pipe(ialu_mem_imm); 6606 %} 6607 6608 // XXX why does that use AddI 6609 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6610 %{ 6611 predicate(UseIncDec); 6612 match(Set dst (AddI dst src)); 6613 effect(KILL cr); 6614 6615 format %{ "decl $dst\t# int" %} 6616 ins_encode %{ 6617 __ decrementl($dst$$Register); 6618 %} 6619 ins_pipe(ialu_reg); 6620 %} 6621 6622 // XXX why does that use AddI 6623 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6624 %{ 6625 predicate(UseIncDec); 6626 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6627 effect(KILL cr); 6628 6629 ins_cost(125); // XXX 6630 format %{ "decl $dst\t# int" %} 6631 ins_encode %{ 6632 __ decrementl($dst$$Address); 6633 %} 6634 ins_pipe(ialu_mem_imm); 6635 %} 6636 6637 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6638 %{ 6639 predicate(VM_Version::supports_fast_2op_lea()); 6640 match(Set dst (AddI (LShiftI index scale) disp)); 6641 6642 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6643 ins_encode %{ 6644 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6645 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6646 %} 6647 ins_pipe(ialu_reg_reg); 6648 %} 6649 6650 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6651 %{ 6652 predicate(VM_Version::supports_fast_3op_lea()); 6653 match(Set dst (AddI (AddI base index) disp)); 6654 6655 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6656 ins_encode %{ 6657 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6658 %} 6659 ins_pipe(ialu_reg_reg); 6660 %} 6661 6662 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6663 %{ 6664 predicate(VM_Version::supports_fast_2op_lea()); 6665 match(Set dst (AddI base (LShiftI index scale))); 6666 6667 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6668 ins_encode %{ 6669 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6670 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6671 %} 6672 ins_pipe(ialu_reg_reg); 6673 %} 6674 6675 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6676 %{ 6677 predicate(VM_Version::supports_fast_3op_lea()); 6678 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6679 6680 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6681 ins_encode %{ 6682 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6683 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6684 %} 6685 ins_pipe(ialu_reg_reg); 6686 %} 6687 6688 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6689 %{ 6690 match(Set dst (AddL dst src)); 6691 effect(KILL cr); 6692 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); 6693 6694 format %{ "addq $dst, $src\t# long" %} 6695 ins_encode %{ 6696 __ addq($dst$$Register, $src$$Register); 6697 %} 6698 ins_pipe(ialu_reg_reg); 6699 %} 6700 6701 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6702 %{ 6703 match(Set dst (AddL dst src)); 6704 effect(KILL cr); 6705 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); 6706 6707 format %{ "addq $dst, $src\t# long" %} 6708 ins_encode %{ 6709 __ addq($dst$$Register, $src$$constant); 6710 %} 6711 ins_pipe( ialu_reg ); 6712 %} 6713 6714 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6715 %{ 6716 match(Set dst (AddL dst (LoadL src))); 6717 effect(KILL cr); 6718 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); 6719 6720 ins_cost(150); // XXX 6721 format %{ "addq $dst, $src\t# long" %} 6722 ins_encode %{ 6723 __ addq($dst$$Register, $src$$Address); 6724 %} 6725 ins_pipe(ialu_reg_mem); 6726 %} 6727 6728 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6729 %{ 6730 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6731 effect(KILL cr); 6732 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); 6733 6734 ins_cost(150); // XXX 6735 format %{ "addq $dst, $src\t# long" %} 6736 ins_encode %{ 6737 __ addq($dst$$Address, $src$$Register); 6738 %} 6739 ins_pipe(ialu_mem_reg); 6740 %} 6741 6742 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6743 %{ 6744 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6745 effect(KILL cr); 6746 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); 6747 6748 ins_cost(125); // XXX 6749 format %{ "addq $dst, $src\t# long" %} 6750 ins_encode %{ 6751 __ addq($dst$$Address, $src$$constant); 6752 %} 6753 ins_pipe(ialu_mem_imm); 6754 %} 6755 6756 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6757 %{ 6758 predicate(UseIncDec); 6759 match(Set dst (AddL dst src)); 6760 effect(KILL cr); 6761 6762 format %{ "incq $dst\t# long" %} 6763 ins_encode %{ 6764 __ incrementq($dst$$Register); 6765 %} 6766 ins_pipe(ialu_reg); 6767 %} 6768 6769 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6770 %{ 6771 predicate(UseIncDec); 6772 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6773 effect(KILL cr); 6774 6775 ins_cost(125); // XXX 6776 format %{ "incq $dst\t# long" %} 6777 ins_encode %{ 6778 __ incrementq($dst$$Address); 6779 %} 6780 ins_pipe(ialu_mem_imm); 6781 %} 6782 6783 // XXX why does that use AddL 6784 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6785 %{ 6786 predicate(UseIncDec); 6787 match(Set dst (AddL dst src)); 6788 effect(KILL cr); 6789 6790 format %{ "decq $dst\t# long" %} 6791 ins_encode %{ 6792 __ decrementq($dst$$Register); 6793 %} 6794 ins_pipe(ialu_reg); 6795 %} 6796 6797 // XXX why does that use AddL 6798 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6799 %{ 6800 predicate(UseIncDec); 6801 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6802 effect(KILL cr); 6803 6804 ins_cost(125); // XXX 6805 format %{ "decq $dst\t# long" %} 6806 ins_encode %{ 6807 __ decrementq($dst$$Address); 6808 %} 6809 ins_pipe(ialu_mem_imm); 6810 %} 6811 6812 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6813 %{ 6814 predicate(VM_Version::supports_fast_2op_lea()); 6815 match(Set dst (AddL (LShiftL index scale) disp)); 6816 6817 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6818 ins_encode %{ 6819 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6820 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6821 %} 6822 ins_pipe(ialu_reg_reg); 6823 %} 6824 6825 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6826 %{ 6827 predicate(VM_Version::supports_fast_3op_lea()); 6828 match(Set dst (AddL (AddL base index) disp)); 6829 6830 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6831 ins_encode %{ 6832 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6833 %} 6834 ins_pipe(ialu_reg_reg); 6835 %} 6836 6837 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6838 %{ 6839 predicate(VM_Version::supports_fast_2op_lea()); 6840 match(Set dst (AddL base (LShiftL index scale))); 6841 6842 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6843 ins_encode %{ 6844 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6845 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6846 %} 6847 ins_pipe(ialu_reg_reg); 6848 %} 6849 6850 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6851 %{ 6852 predicate(VM_Version::supports_fast_3op_lea()); 6853 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6854 6855 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6856 ins_encode %{ 6857 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6858 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6859 %} 6860 ins_pipe(ialu_reg_reg); 6861 %} 6862 6863 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6864 %{ 6865 match(Set dst (AddP dst src)); 6866 effect(KILL cr); 6867 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); 6868 6869 format %{ "addq $dst, $src\t# ptr" %} 6870 ins_encode %{ 6871 __ addq($dst$$Register, $src$$Register); 6872 %} 6873 ins_pipe(ialu_reg_reg); 6874 %} 6875 6876 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6877 %{ 6878 match(Set dst (AddP dst src)); 6879 effect(KILL cr); 6880 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); 6881 6882 format %{ "addq $dst, $src\t# ptr" %} 6883 ins_encode %{ 6884 __ addq($dst$$Register, $src$$constant); 6885 %} 6886 ins_pipe( ialu_reg ); 6887 %} 6888 6889 // XXX addP mem ops ???? 6890 6891 instruct checkCastPP(rRegP dst) 6892 %{ 6893 match(Set dst (CheckCastPP dst)); 6894 6895 size(0); 6896 format %{ "# checkcastPP of $dst" %} 6897 ins_encode(/* empty encoding */); 6898 ins_pipe(empty); 6899 %} 6900 6901 instruct castPP(rRegP dst) 6902 %{ 6903 match(Set dst (CastPP dst)); 6904 6905 size(0); 6906 format %{ "# castPP of $dst" %} 6907 ins_encode(/* empty encoding */); 6908 ins_pipe(empty); 6909 %} 6910 6911 instruct castII(rRegI dst) 6912 %{ 6913 match(Set dst (CastII dst)); 6914 6915 size(0); 6916 format %{ "# castII of $dst" %} 6917 ins_encode(/* empty encoding */); 6918 ins_cost(0); 6919 ins_pipe(empty); 6920 %} 6921 6922 instruct castLL(rRegL dst) 6923 %{ 6924 match(Set dst (CastLL dst)); 6925 6926 size(0); 6927 format %{ "# castLL of $dst" %} 6928 ins_encode(/* empty encoding */); 6929 ins_cost(0); 6930 ins_pipe(empty); 6931 %} 6932 6933 instruct castFF(regF dst) 6934 %{ 6935 match(Set dst (CastFF dst)); 6936 6937 size(0); 6938 format %{ "# castFF of $dst" %} 6939 ins_encode(/* empty encoding */); 6940 ins_cost(0); 6941 ins_pipe(empty); 6942 %} 6943 6944 instruct castDD(regD dst) 6945 %{ 6946 match(Set dst (CastDD dst)); 6947 6948 size(0); 6949 format %{ "# castDD of $dst" %} 6950 ins_encode(/* empty encoding */); 6951 ins_cost(0); 6952 ins_pipe(empty); 6953 %} 6954 6955 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 6956 instruct compareAndSwapP(rRegI res, 6957 memory mem_ptr, 6958 rax_RegP oldval, rRegP newval, 6959 rFlagsReg cr) 6960 %{ 6961 predicate(n->as_LoadStore()->barrier_data() == 0); 6962 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 6963 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 6964 effect(KILL cr, KILL oldval); 6965 6966 format %{ "cmpxchgq $mem_ptr,$newval\t# " 6967 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 6968 "sete $res\n\t" 6969 "movzbl $res, $res" %} 6970 ins_encode %{ 6971 __ lock(); 6972 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 6973 __ setb(Assembler::equal, $res$$Register); 6974 __ movzbl($res$$Register, $res$$Register); 6975 %} 6976 ins_pipe( pipe_cmpxchg ); 6977 %} 6978 6979 instruct compareAndSwapL(rRegI res, 6980 memory mem_ptr, 6981 rax_RegL oldval, rRegL newval, 6982 rFlagsReg cr) 6983 %{ 6984 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 6985 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 6986 effect(KILL cr, KILL oldval); 6987 6988 format %{ "cmpxchgq $mem_ptr,$newval\t# " 6989 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 6990 "sete $res\n\t" 6991 "movzbl $res, $res" %} 6992 ins_encode %{ 6993 __ lock(); 6994 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 6995 __ setb(Assembler::equal, $res$$Register); 6996 __ movzbl($res$$Register, $res$$Register); 6997 %} 6998 ins_pipe( pipe_cmpxchg ); 6999 %} 7000 7001 instruct compareAndSwapI(rRegI res, 7002 memory mem_ptr, 7003 rax_RegI oldval, rRegI newval, 7004 rFlagsReg cr) 7005 %{ 7006 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7007 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7008 effect(KILL cr, KILL oldval); 7009 7010 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7011 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7012 "sete $res\n\t" 7013 "movzbl $res, $res" %} 7014 ins_encode %{ 7015 __ lock(); 7016 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7017 __ setb(Assembler::equal, $res$$Register); 7018 __ movzbl($res$$Register, $res$$Register); 7019 %} 7020 ins_pipe( pipe_cmpxchg ); 7021 %} 7022 7023 instruct compareAndSwapB(rRegI res, 7024 memory mem_ptr, 7025 rax_RegI oldval, rRegI newval, 7026 rFlagsReg cr) 7027 %{ 7028 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7029 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7030 effect(KILL cr, KILL oldval); 7031 7032 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7033 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7034 "sete $res\n\t" 7035 "movzbl $res, $res" %} 7036 ins_encode %{ 7037 __ lock(); 7038 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7039 __ setb(Assembler::equal, $res$$Register); 7040 __ movzbl($res$$Register, $res$$Register); 7041 %} 7042 ins_pipe( pipe_cmpxchg ); 7043 %} 7044 7045 instruct compareAndSwapS(rRegI res, 7046 memory mem_ptr, 7047 rax_RegI oldval, rRegI newval, 7048 rFlagsReg cr) 7049 %{ 7050 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7051 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7052 effect(KILL cr, KILL oldval); 7053 7054 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7055 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7056 "sete $res\n\t" 7057 "movzbl $res, $res" %} 7058 ins_encode %{ 7059 __ lock(); 7060 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7061 __ setb(Assembler::equal, $res$$Register); 7062 __ movzbl($res$$Register, $res$$Register); 7063 %} 7064 ins_pipe( pipe_cmpxchg ); 7065 %} 7066 7067 instruct compareAndSwapN(rRegI res, 7068 memory mem_ptr, 7069 rax_RegN oldval, rRegN newval, 7070 rFlagsReg cr) %{ 7071 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7072 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7073 effect(KILL cr, KILL oldval); 7074 7075 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7076 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7077 "sete $res\n\t" 7078 "movzbl $res, $res" %} 7079 ins_encode %{ 7080 __ lock(); 7081 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7082 __ setb(Assembler::equal, $res$$Register); 7083 __ movzbl($res$$Register, $res$$Register); 7084 %} 7085 ins_pipe( pipe_cmpxchg ); 7086 %} 7087 7088 instruct compareAndExchangeB( 7089 memory mem_ptr, 7090 rax_RegI oldval, rRegI newval, 7091 rFlagsReg cr) 7092 %{ 7093 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7094 effect(KILL cr); 7095 7096 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7097 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7098 ins_encode %{ 7099 __ lock(); 7100 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7101 %} 7102 ins_pipe( pipe_cmpxchg ); 7103 %} 7104 7105 instruct compareAndExchangeS( 7106 memory mem_ptr, 7107 rax_RegI oldval, rRegI newval, 7108 rFlagsReg cr) 7109 %{ 7110 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7111 effect(KILL cr); 7112 7113 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7114 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7115 ins_encode %{ 7116 __ lock(); 7117 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7118 %} 7119 ins_pipe( pipe_cmpxchg ); 7120 %} 7121 7122 instruct compareAndExchangeI( 7123 memory mem_ptr, 7124 rax_RegI oldval, rRegI newval, 7125 rFlagsReg cr) 7126 %{ 7127 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7128 effect(KILL cr); 7129 7130 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7131 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7132 ins_encode %{ 7133 __ lock(); 7134 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7135 %} 7136 ins_pipe( pipe_cmpxchg ); 7137 %} 7138 7139 instruct compareAndExchangeL( 7140 memory mem_ptr, 7141 rax_RegL oldval, rRegL newval, 7142 rFlagsReg cr) 7143 %{ 7144 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7145 effect(KILL cr); 7146 7147 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7148 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7149 ins_encode %{ 7150 __ lock(); 7151 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7152 %} 7153 ins_pipe( pipe_cmpxchg ); 7154 %} 7155 7156 instruct compareAndExchangeN( 7157 memory mem_ptr, 7158 rax_RegN oldval, rRegN newval, 7159 rFlagsReg cr) %{ 7160 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7161 effect(KILL cr); 7162 7163 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7164 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7165 ins_encode %{ 7166 __ lock(); 7167 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7168 %} 7169 ins_pipe( pipe_cmpxchg ); 7170 %} 7171 7172 instruct compareAndExchangeP( 7173 memory mem_ptr, 7174 rax_RegP oldval, rRegP newval, 7175 rFlagsReg cr) 7176 %{ 7177 predicate(n->as_LoadStore()->barrier_data() == 0); 7178 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7179 effect(KILL cr); 7180 7181 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7182 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7183 ins_encode %{ 7184 __ lock(); 7185 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7186 %} 7187 ins_pipe( pipe_cmpxchg ); 7188 %} 7189 7190 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7191 predicate(n->as_LoadStore()->result_not_used()); 7192 match(Set dummy (GetAndAddB mem add)); 7193 effect(KILL cr); 7194 format %{ "addb_lock $mem, $add" %} 7195 ins_encode %{ 7196 __ lock(); 7197 __ addb($mem$$Address, $add$$Register); 7198 %} 7199 ins_pipe(pipe_cmpxchg); 7200 %} 7201 7202 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7203 predicate(n->as_LoadStore()->result_not_used()); 7204 match(Set dummy (GetAndAddB mem add)); 7205 effect(KILL cr); 7206 format %{ "addb_lock $mem, $add" %} 7207 ins_encode %{ 7208 __ lock(); 7209 __ addb($mem$$Address, $add$$constant); 7210 %} 7211 ins_pipe(pipe_cmpxchg); 7212 %} 7213 7214 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7215 predicate(!n->as_LoadStore()->result_not_used()); 7216 match(Set newval (GetAndAddB mem newval)); 7217 effect(KILL cr); 7218 format %{ "xaddb_lock $mem, $newval" %} 7219 ins_encode %{ 7220 __ lock(); 7221 __ xaddb($mem$$Address, $newval$$Register); 7222 %} 7223 ins_pipe(pipe_cmpxchg); 7224 %} 7225 7226 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7227 predicate(n->as_LoadStore()->result_not_used()); 7228 match(Set dummy (GetAndAddS mem add)); 7229 effect(KILL cr); 7230 format %{ "addw_lock $mem, $add" %} 7231 ins_encode %{ 7232 __ lock(); 7233 __ addw($mem$$Address, $add$$Register); 7234 %} 7235 ins_pipe(pipe_cmpxchg); 7236 %} 7237 7238 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7239 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7240 match(Set dummy (GetAndAddS mem add)); 7241 effect(KILL cr); 7242 format %{ "addw_lock $mem, $add" %} 7243 ins_encode %{ 7244 __ lock(); 7245 __ addw($mem$$Address, $add$$constant); 7246 %} 7247 ins_pipe(pipe_cmpxchg); 7248 %} 7249 7250 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7251 predicate(!n->as_LoadStore()->result_not_used()); 7252 match(Set newval (GetAndAddS mem newval)); 7253 effect(KILL cr); 7254 format %{ "xaddw_lock $mem, $newval" %} 7255 ins_encode %{ 7256 __ lock(); 7257 __ xaddw($mem$$Address, $newval$$Register); 7258 %} 7259 ins_pipe(pipe_cmpxchg); 7260 %} 7261 7262 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7263 predicate(n->as_LoadStore()->result_not_used()); 7264 match(Set dummy (GetAndAddI mem add)); 7265 effect(KILL cr); 7266 format %{ "addl_lock $mem, $add" %} 7267 ins_encode %{ 7268 __ lock(); 7269 __ addl($mem$$Address, $add$$Register); 7270 %} 7271 ins_pipe(pipe_cmpxchg); 7272 %} 7273 7274 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7275 predicate(n->as_LoadStore()->result_not_used()); 7276 match(Set dummy (GetAndAddI mem add)); 7277 effect(KILL cr); 7278 format %{ "addl_lock $mem, $add" %} 7279 ins_encode %{ 7280 __ lock(); 7281 __ addl($mem$$Address, $add$$constant); 7282 %} 7283 ins_pipe(pipe_cmpxchg); 7284 %} 7285 7286 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7287 predicate(!n->as_LoadStore()->result_not_used()); 7288 match(Set newval (GetAndAddI mem newval)); 7289 effect(KILL cr); 7290 format %{ "xaddl_lock $mem, $newval" %} 7291 ins_encode %{ 7292 __ lock(); 7293 __ xaddl($mem$$Address, $newval$$Register); 7294 %} 7295 ins_pipe(pipe_cmpxchg); 7296 %} 7297 7298 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7299 predicate(n->as_LoadStore()->result_not_used()); 7300 match(Set dummy (GetAndAddL mem add)); 7301 effect(KILL cr); 7302 format %{ "addq_lock $mem, $add" %} 7303 ins_encode %{ 7304 __ lock(); 7305 __ addq($mem$$Address, $add$$Register); 7306 %} 7307 ins_pipe(pipe_cmpxchg); 7308 %} 7309 7310 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7311 predicate(n->as_LoadStore()->result_not_used()); 7312 match(Set dummy (GetAndAddL mem add)); 7313 effect(KILL cr); 7314 format %{ "addq_lock $mem, $add" %} 7315 ins_encode %{ 7316 __ lock(); 7317 __ addq($mem$$Address, $add$$constant); 7318 %} 7319 ins_pipe(pipe_cmpxchg); 7320 %} 7321 7322 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7323 predicate(!n->as_LoadStore()->result_not_used()); 7324 match(Set newval (GetAndAddL mem newval)); 7325 effect(KILL cr); 7326 format %{ "xaddq_lock $mem, $newval" %} 7327 ins_encode %{ 7328 __ lock(); 7329 __ xaddq($mem$$Address, $newval$$Register); 7330 %} 7331 ins_pipe(pipe_cmpxchg); 7332 %} 7333 7334 instruct xchgB( memory mem, rRegI newval) %{ 7335 match(Set newval (GetAndSetB mem newval)); 7336 format %{ "XCHGB $newval,[$mem]" %} 7337 ins_encode %{ 7338 __ xchgb($newval$$Register, $mem$$Address); 7339 %} 7340 ins_pipe( pipe_cmpxchg ); 7341 %} 7342 7343 instruct xchgS( memory mem, rRegI newval) %{ 7344 match(Set newval (GetAndSetS mem newval)); 7345 format %{ "XCHGW $newval,[$mem]" %} 7346 ins_encode %{ 7347 __ xchgw($newval$$Register, $mem$$Address); 7348 %} 7349 ins_pipe( pipe_cmpxchg ); 7350 %} 7351 7352 instruct xchgI( memory mem, rRegI newval) %{ 7353 match(Set newval (GetAndSetI mem newval)); 7354 format %{ "XCHGL $newval,[$mem]" %} 7355 ins_encode %{ 7356 __ xchgl($newval$$Register, $mem$$Address); 7357 %} 7358 ins_pipe( pipe_cmpxchg ); 7359 %} 7360 7361 instruct xchgL( memory mem, rRegL newval) %{ 7362 match(Set newval (GetAndSetL mem newval)); 7363 format %{ "XCHGL $newval,[$mem]" %} 7364 ins_encode %{ 7365 __ xchgq($newval$$Register, $mem$$Address); 7366 %} 7367 ins_pipe( pipe_cmpxchg ); 7368 %} 7369 7370 instruct xchgP( memory mem, rRegP newval) %{ 7371 match(Set newval (GetAndSetP mem newval)); 7372 predicate(n->as_LoadStore()->barrier_data() == 0); 7373 format %{ "XCHGQ $newval,[$mem]" %} 7374 ins_encode %{ 7375 __ xchgq($newval$$Register, $mem$$Address); 7376 %} 7377 ins_pipe( pipe_cmpxchg ); 7378 %} 7379 7380 instruct xchgN( memory mem, rRegN newval) %{ 7381 match(Set newval (GetAndSetN mem newval)); 7382 format %{ "XCHGL $newval,$mem]" %} 7383 ins_encode %{ 7384 __ xchgl($newval$$Register, $mem$$Address); 7385 %} 7386 ins_pipe( pipe_cmpxchg ); 7387 %} 7388 7389 //----------Abs Instructions------------------------------------------- 7390 7391 // Integer Absolute Instructions 7392 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7393 %{ 7394 match(Set dst (AbsI src)); 7395 effect(TEMP dst, KILL cr); 7396 format %{ "xorl $dst, $dst\t# abs int\n\t" 7397 "subl $dst, $src\n\t" 7398 "cmovll $dst, $src" %} 7399 ins_encode %{ 7400 __ xorl($dst$$Register, $dst$$Register); 7401 __ subl($dst$$Register, $src$$Register); 7402 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7403 %} 7404 7405 ins_pipe(ialu_reg_reg); 7406 %} 7407 7408 // Long Absolute Instructions 7409 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7410 %{ 7411 match(Set dst (AbsL src)); 7412 effect(TEMP dst, KILL cr); 7413 format %{ "xorl $dst, $dst\t# abs long\n\t" 7414 "subq $dst, $src\n\t" 7415 "cmovlq $dst, $src" %} 7416 ins_encode %{ 7417 __ xorl($dst$$Register, $dst$$Register); 7418 __ subq($dst$$Register, $src$$Register); 7419 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7420 %} 7421 7422 ins_pipe(ialu_reg_reg); 7423 %} 7424 7425 //----------Subtraction Instructions------------------------------------------- 7426 7427 // Integer Subtraction Instructions 7428 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7429 %{ 7430 match(Set dst (SubI dst src)); 7431 effect(KILL cr); 7432 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); 7433 7434 format %{ "subl $dst, $src\t# int" %} 7435 ins_encode %{ 7436 __ subl($dst$$Register, $src$$Register); 7437 %} 7438 ins_pipe(ialu_reg_reg); 7439 %} 7440 7441 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7442 %{ 7443 match(Set dst (SubI dst (LoadI src))); 7444 effect(KILL cr); 7445 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); 7446 7447 ins_cost(150); 7448 format %{ "subl $dst, $src\t# int" %} 7449 ins_encode %{ 7450 __ subl($dst$$Register, $src$$Address); 7451 %} 7452 ins_pipe(ialu_reg_mem); 7453 %} 7454 7455 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7456 %{ 7457 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7458 effect(KILL cr); 7459 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); 7460 7461 ins_cost(150); 7462 format %{ "subl $dst, $src\t# int" %} 7463 ins_encode %{ 7464 __ subl($dst$$Address, $src$$Register); 7465 %} 7466 ins_pipe(ialu_mem_reg); 7467 %} 7468 7469 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7470 %{ 7471 match(Set dst (SubL dst src)); 7472 effect(KILL cr); 7473 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); 7474 7475 format %{ "subq $dst, $src\t# long" %} 7476 ins_encode %{ 7477 __ subq($dst$$Register, $src$$Register); 7478 %} 7479 ins_pipe(ialu_reg_reg); 7480 %} 7481 7482 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7483 %{ 7484 match(Set dst (SubL dst (LoadL src))); 7485 effect(KILL cr); 7486 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); 7487 7488 ins_cost(150); 7489 format %{ "subq $dst, $src\t# long" %} 7490 ins_encode %{ 7491 __ subq($dst$$Register, $src$$Address); 7492 %} 7493 ins_pipe(ialu_reg_mem); 7494 %} 7495 7496 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7497 %{ 7498 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7499 effect(KILL cr); 7500 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); 7501 7502 ins_cost(150); 7503 format %{ "subq $dst, $src\t# long" %} 7504 ins_encode %{ 7505 __ subq($dst$$Address, $src$$Register); 7506 %} 7507 ins_pipe(ialu_mem_reg); 7508 %} 7509 7510 // Subtract from a pointer 7511 // XXX hmpf??? 7512 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7513 %{ 7514 match(Set dst (AddP dst (SubI zero src))); 7515 effect(KILL cr); 7516 7517 format %{ "subq $dst, $src\t# ptr - int" %} 7518 ins_encode %{ 7519 __ subq($dst$$Register, $src$$Register); 7520 %} 7521 ins_pipe(ialu_reg_reg); 7522 %} 7523 7524 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7525 %{ 7526 match(Set dst (SubI zero dst)); 7527 effect(KILL cr); 7528 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7529 7530 format %{ "negl $dst\t# int" %} 7531 ins_encode %{ 7532 __ negl($dst$$Register); 7533 %} 7534 ins_pipe(ialu_reg); 7535 %} 7536 7537 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7538 %{ 7539 match(Set dst (NegI dst)); 7540 effect(KILL cr); 7541 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7542 7543 format %{ "negl $dst\t# int" %} 7544 ins_encode %{ 7545 __ negl($dst$$Register); 7546 %} 7547 ins_pipe(ialu_reg); 7548 %} 7549 7550 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7551 %{ 7552 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7553 effect(KILL cr); 7554 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7555 7556 format %{ "negl $dst\t# int" %} 7557 ins_encode %{ 7558 __ negl($dst$$Address); 7559 %} 7560 ins_pipe(ialu_reg); 7561 %} 7562 7563 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7564 %{ 7565 match(Set dst (SubL zero dst)); 7566 effect(KILL cr); 7567 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7568 7569 format %{ "negq $dst\t# long" %} 7570 ins_encode %{ 7571 __ negq($dst$$Register); 7572 %} 7573 ins_pipe(ialu_reg); 7574 %} 7575 7576 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7577 %{ 7578 match(Set dst (NegL dst)); 7579 effect(KILL cr); 7580 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7581 7582 format %{ "negq $dst\t# int" %} 7583 ins_encode %{ 7584 __ negq($dst$$Register); 7585 %} 7586 ins_pipe(ialu_reg); 7587 %} 7588 7589 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7590 %{ 7591 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7592 effect(KILL cr); 7593 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7594 7595 format %{ "negq $dst\t# long" %} 7596 ins_encode %{ 7597 __ negq($dst$$Address); 7598 %} 7599 ins_pipe(ialu_reg); 7600 %} 7601 7602 //----------Multiplication/Division Instructions------------------------------- 7603 // Integer Multiplication Instructions 7604 // Multiply Register 7605 7606 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7607 %{ 7608 match(Set dst (MulI dst src)); 7609 effect(KILL cr); 7610 7611 ins_cost(300); 7612 format %{ "imull $dst, $src\t# int" %} 7613 ins_encode %{ 7614 __ imull($dst$$Register, $src$$Register); 7615 %} 7616 ins_pipe(ialu_reg_reg_alu0); 7617 %} 7618 7619 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7620 %{ 7621 match(Set dst (MulI src imm)); 7622 effect(KILL cr); 7623 7624 ins_cost(300); 7625 format %{ "imull $dst, $src, $imm\t# int" %} 7626 ins_encode %{ 7627 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7628 %} 7629 ins_pipe(ialu_reg_reg_alu0); 7630 %} 7631 7632 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7633 %{ 7634 match(Set dst (MulI dst (LoadI src))); 7635 effect(KILL cr); 7636 7637 ins_cost(350); 7638 format %{ "imull $dst, $src\t# int" %} 7639 ins_encode %{ 7640 __ imull($dst$$Register, $src$$Address); 7641 %} 7642 ins_pipe(ialu_reg_mem_alu0); 7643 %} 7644 7645 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7646 %{ 7647 match(Set dst (MulI (LoadI src) imm)); 7648 effect(KILL cr); 7649 7650 ins_cost(300); 7651 format %{ "imull $dst, $src, $imm\t# int" %} 7652 ins_encode %{ 7653 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7654 %} 7655 ins_pipe(ialu_reg_mem_alu0); 7656 %} 7657 7658 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7659 %{ 7660 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7661 effect(KILL cr, KILL src2); 7662 7663 expand %{ mulI_rReg(dst, src1, cr); 7664 mulI_rReg(src2, src3, cr); 7665 addI_rReg(dst, src2, cr); %} 7666 %} 7667 7668 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7669 %{ 7670 match(Set dst (MulL dst src)); 7671 effect(KILL cr); 7672 7673 ins_cost(300); 7674 format %{ "imulq $dst, $src\t# long" %} 7675 ins_encode %{ 7676 __ imulq($dst$$Register, $src$$Register); 7677 %} 7678 ins_pipe(ialu_reg_reg_alu0); 7679 %} 7680 7681 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7682 %{ 7683 match(Set dst (MulL src imm)); 7684 effect(KILL cr); 7685 7686 ins_cost(300); 7687 format %{ "imulq $dst, $src, $imm\t# long" %} 7688 ins_encode %{ 7689 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7690 %} 7691 ins_pipe(ialu_reg_reg_alu0); 7692 %} 7693 7694 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7695 %{ 7696 match(Set dst (MulL dst (LoadL src))); 7697 effect(KILL cr); 7698 7699 ins_cost(350); 7700 format %{ "imulq $dst, $src\t# long" %} 7701 ins_encode %{ 7702 __ imulq($dst$$Register, $src$$Address); 7703 %} 7704 ins_pipe(ialu_reg_mem_alu0); 7705 %} 7706 7707 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7708 %{ 7709 match(Set dst (MulL (LoadL src) imm)); 7710 effect(KILL cr); 7711 7712 ins_cost(300); 7713 format %{ "imulq $dst, $src, $imm\t# long" %} 7714 ins_encode %{ 7715 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7716 %} 7717 ins_pipe(ialu_reg_mem_alu0); 7718 %} 7719 7720 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7721 %{ 7722 match(Set dst (MulHiL src rax)); 7723 effect(USE_KILL rax, KILL cr); 7724 7725 ins_cost(300); 7726 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7727 ins_encode %{ 7728 __ imulq($src$$Register); 7729 %} 7730 ins_pipe(ialu_reg_reg_alu0); 7731 %} 7732 7733 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7734 %{ 7735 match(Set dst (UMulHiL src rax)); 7736 effect(USE_KILL rax, KILL cr); 7737 7738 ins_cost(300); 7739 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7740 ins_encode %{ 7741 __ mulq($src$$Register); 7742 %} 7743 ins_pipe(ialu_reg_reg_alu0); 7744 %} 7745 7746 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7747 rFlagsReg cr) 7748 %{ 7749 match(Set rax (DivI rax div)); 7750 effect(KILL rdx, KILL cr); 7751 7752 ins_cost(30*100+10*100); // XXX 7753 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7754 "jne,s normal\n\t" 7755 "xorl rdx, rdx\n\t" 7756 "cmpl $div, -1\n\t" 7757 "je,s done\n" 7758 "normal: cdql\n\t" 7759 "idivl $div\n" 7760 "done:" %} 7761 ins_encode(cdql_enc(div)); 7762 ins_pipe(ialu_reg_reg_alu0); 7763 %} 7764 7765 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7766 rFlagsReg cr) 7767 %{ 7768 match(Set rax (DivL rax div)); 7769 effect(KILL rdx, KILL cr); 7770 7771 ins_cost(30*100+10*100); // XXX 7772 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7773 "cmpq rax, rdx\n\t" 7774 "jne,s normal\n\t" 7775 "xorl rdx, rdx\n\t" 7776 "cmpq $div, -1\n\t" 7777 "je,s done\n" 7778 "normal: cdqq\n\t" 7779 "idivq $div\n" 7780 "done:" %} 7781 ins_encode(cdqq_enc(div)); 7782 ins_pipe(ialu_reg_reg_alu0); 7783 %} 7784 7785 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7786 %{ 7787 match(Set rax (UDivI rax div)); 7788 effect(KILL rdx, KILL cr); 7789 7790 ins_cost(300); 7791 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7792 ins_encode %{ 7793 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7794 %} 7795 ins_pipe(ialu_reg_reg_alu0); 7796 %} 7797 7798 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7799 %{ 7800 match(Set rax (UDivL rax div)); 7801 effect(KILL rdx, KILL cr); 7802 7803 ins_cost(300); 7804 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7805 ins_encode %{ 7806 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7807 %} 7808 ins_pipe(ialu_reg_reg_alu0); 7809 %} 7810 7811 // Integer DIVMOD with Register, both quotient and mod results 7812 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7813 rFlagsReg cr) 7814 %{ 7815 match(DivModI rax div); 7816 effect(KILL cr); 7817 7818 ins_cost(30*100+10*100); // XXX 7819 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7820 "jne,s normal\n\t" 7821 "xorl rdx, rdx\n\t" 7822 "cmpl $div, -1\n\t" 7823 "je,s done\n" 7824 "normal: cdql\n\t" 7825 "idivl $div\n" 7826 "done:" %} 7827 ins_encode(cdql_enc(div)); 7828 ins_pipe(pipe_slow); 7829 %} 7830 7831 // Long DIVMOD with Register, both quotient and mod results 7832 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7833 rFlagsReg cr) 7834 %{ 7835 match(DivModL rax div); 7836 effect(KILL cr); 7837 7838 ins_cost(30*100+10*100); // XXX 7839 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7840 "cmpq rax, rdx\n\t" 7841 "jne,s normal\n\t" 7842 "xorl rdx, rdx\n\t" 7843 "cmpq $div, -1\n\t" 7844 "je,s done\n" 7845 "normal: cdqq\n\t" 7846 "idivq $div\n" 7847 "done:" %} 7848 ins_encode(cdqq_enc(div)); 7849 ins_pipe(pipe_slow); 7850 %} 7851 7852 // Unsigned integer DIVMOD with Register, both quotient and mod results 7853 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7854 no_rax_rdx_RegI div, rFlagsReg cr) 7855 %{ 7856 match(UDivModI rax div); 7857 effect(TEMP tmp, KILL cr); 7858 7859 ins_cost(300); 7860 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7861 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7862 %} 7863 ins_encode %{ 7864 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7865 %} 7866 ins_pipe(pipe_slow); 7867 %} 7868 7869 // Unsigned long DIVMOD with Register, both quotient and mod results 7870 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7871 no_rax_rdx_RegL div, rFlagsReg cr) 7872 %{ 7873 match(UDivModL rax div); 7874 effect(TEMP tmp, KILL cr); 7875 7876 ins_cost(300); 7877 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7878 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7879 %} 7880 ins_encode %{ 7881 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7882 %} 7883 ins_pipe(pipe_slow); 7884 %} 7885 7886 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7887 rFlagsReg cr) 7888 %{ 7889 match(Set rdx (ModI rax div)); 7890 effect(KILL rax, KILL cr); 7891 7892 ins_cost(300); // XXX 7893 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7894 "jne,s normal\n\t" 7895 "xorl rdx, rdx\n\t" 7896 "cmpl $div, -1\n\t" 7897 "je,s done\n" 7898 "normal: cdql\n\t" 7899 "idivl $div\n" 7900 "done:" %} 7901 ins_encode(cdql_enc(div)); 7902 ins_pipe(ialu_reg_reg_alu0); 7903 %} 7904 7905 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7906 rFlagsReg cr) 7907 %{ 7908 match(Set rdx (ModL rax div)); 7909 effect(KILL rax, KILL cr); 7910 7911 ins_cost(300); // XXX 7912 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7913 "cmpq rax, rdx\n\t" 7914 "jne,s normal\n\t" 7915 "xorl rdx, rdx\n\t" 7916 "cmpq $div, -1\n\t" 7917 "je,s done\n" 7918 "normal: cdqq\n\t" 7919 "idivq $div\n" 7920 "done:" %} 7921 ins_encode(cdqq_enc(div)); 7922 ins_pipe(ialu_reg_reg_alu0); 7923 %} 7924 7925 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 7926 %{ 7927 match(Set rdx (UModI rax div)); 7928 effect(KILL rax, KILL cr); 7929 7930 ins_cost(300); 7931 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 7932 ins_encode %{ 7933 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 7934 %} 7935 ins_pipe(ialu_reg_reg_alu0); 7936 %} 7937 7938 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 7939 %{ 7940 match(Set rdx (UModL rax div)); 7941 effect(KILL rax, KILL cr); 7942 7943 ins_cost(300); 7944 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 7945 ins_encode %{ 7946 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 7947 %} 7948 ins_pipe(ialu_reg_reg_alu0); 7949 %} 7950 7951 // Integer Shift Instructions 7952 // Shift Left by one, two, three 7953 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 7954 %{ 7955 match(Set dst (LShiftI dst shift)); 7956 effect(KILL cr); 7957 7958 format %{ "sall $dst, $shift" %} 7959 ins_encode %{ 7960 __ sall($dst$$Register, $shift$$constant); 7961 %} 7962 ins_pipe(ialu_reg); 7963 %} 7964 7965 // Shift Left by 8-bit immediate 7966 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7967 %{ 7968 match(Set dst (LShiftI dst shift)); 7969 effect(KILL cr); 7970 7971 format %{ "sall $dst, $shift" %} 7972 ins_encode %{ 7973 __ sall($dst$$Register, $shift$$constant); 7974 %} 7975 ins_pipe(ialu_reg); 7976 %} 7977 7978 // Shift Left by 8-bit immediate 7979 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7980 %{ 7981 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7982 effect(KILL cr); 7983 7984 format %{ "sall $dst, $shift" %} 7985 ins_encode %{ 7986 __ sall($dst$$Address, $shift$$constant); 7987 %} 7988 ins_pipe(ialu_mem_imm); 7989 %} 7990 7991 // Shift Left by variable 7992 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7993 %{ 7994 predicate(!VM_Version::supports_bmi2()); 7995 match(Set dst (LShiftI dst shift)); 7996 effect(KILL cr); 7997 7998 format %{ "sall $dst, $shift" %} 7999 ins_encode %{ 8000 __ sall($dst$$Register); 8001 %} 8002 ins_pipe(ialu_reg_reg); 8003 %} 8004 8005 // Shift Left by variable 8006 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8007 %{ 8008 predicate(!VM_Version::supports_bmi2()); 8009 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8010 effect(KILL cr); 8011 8012 format %{ "sall $dst, $shift" %} 8013 ins_encode %{ 8014 __ sall($dst$$Address); 8015 %} 8016 ins_pipe(ialu_mem_reg); 8017 %} 8018 8019 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8020 %{ 8021 predicate(VM_Version::supports_bmi2()); 8022 match(Set dst (LShiftI src shift)); 8023 8024 format %{ "shlxl $dst, $src, $shift" %} 8025 ins_encode %{ 8026 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8027 %} 8028 ins_pipe(ialu_reg_reg); 8029 %} 8030 8031 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8032 %{ 8033 predicate(VM_Version::supports_bmi2()); 8034 match(Set dst (LShiftI (LoadI src) shift)); 8035 ins_cost(175); 8036 format %{ "shlxl $dst, $src, $shift" %} 8037 ins_encode %{ 8038 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8039 %} 8040 ins_pipe(ialu_reg_mem); 8041 %} 8042 8043 // Arithmetic Shift Right by 8-bit immediate 8044 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8045 %{ 8046 match(Set dst (RShiftI dst shift)); 8047 effect(KILL cr); 8048 8049 format %{ "sarl $dst, $shift" %} 8050 ins_encode %{ 8051 __ sarl($dst$$Register, $shift$$constant); 8052 %} 8053 ins_pipe(ialu_mem_imm); 8054 %} 8055 8056 // Arithmetic Shift Right by 8-bit immediate 8057 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8058 %{ 8059 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8060 effect(KILL cr); 8061 8062 format %{ "sarl $dst, $shift" %} 8063 ins_encode %{ 8064 __ sarl($dst$$Address, $shift$$constant); 8065 %} 8066 ins_pipe(ialu_mem_imm); 8067 %} 8068 8069 // Arithmetic Shift Right by variable 8070 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8071 %{ 8072 predicate(!VM_Version::supports_bmi2()); 8073 match(Set dst (RShiftI dst shift)); 8074 effect(KILL cr); 8075 8076 format %{ "sarl $dst, $shift" %} 8077 ins_encode %{ 8078 __ sarl($dst$$Register); 8079 %} 8080 ins_pipe(ialu_reg_reg); 8081 %} 8082 8083 // Arithmetic Shift Right by variable 8084 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8085 %{ 8086 predicate(!VM_Version::supports_bmi2()); 8087 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8088 effect(KILL cr); 8089 8090 format %{ "sarl $dst, $shift" %} 8091 ins_encode %{ 8092 __ sarl($dst$$Address); 8093 %} 8094 ins_pipe(ialu_mem_reg); 8095 %} 8096 8097 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8098 %{ 8099 predicate(VM_Version::supports_bmi2()); 8100 match(Set dst (RShiftI src shift)); 8101 8102 format %{ "sarxl $dst, $src, $shift" %} 8103 ins_encode %{ 8104 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8105 %} 8106 ins_pipe(ialu_reg_reg); 8107 %} 8108 8109 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8110 %{ 8111 predicate(VM_Version::supports_bmi2()); 8112 match(Set dst (RShiftI (LoadI src) shift)); 8113 ins_cost(175); 8114 format %{ "sarxl $dst, $src, $shift" %} 8115 ins_encode %{ 8116 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8117 %} 8118 ins_pipe(ialu_reg_mem); 8119 %} 8120 8121 // Logical Shift Right by 8-bit immediate 8122 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8123 %{ 8124 match(Set dst (URShiftI dst shift)); 8125 effect(KILL cr); 8126 8127 format %{ "shrl $dst, $shift" %} 8128 ins_encode %{ 8129 __ shrl($dst$$Register, $shift$$constant); 8130 %} 8131 ins_pipe(ialu_reg); 8132 %} 8133 8134 // Logical Shift Right by 8-bit immediate 8135 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8136 %{ 8137 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8138 effect(KILL cr); 8139 8140 format %{ "shrl $dst, $shift" %} 8141 ins_encode %{ 8142 __ shrl($dst$$Address, $shift$$constant); 8143 %} 8144 ins_pipe(ialu_mem_imm); 8145 %} 8146 8147 // Logical Shift Right by variable 8148 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8149 %{ 8150 predicate(!VM_Version::supports_bmi2()); 8151 match(Set dst (URShiftI dst shift)); 8152 effect(KILL cr); 8153 8154 format %{ "shrl $dst, $shift" %} 8155 ins_encode %{ 8156 __ shrl($dst$$Register); 8157 %} 8158 ins_pipe(ialu_reg_reg); 8159 %} 8160 8161 // Logical Shift Right by variable 8162 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8163 %{ 8164 predicate(!VM_Version::supports_bmi2()); 8165 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8166 effect(KILL cr); 8167 8168 format %{ "shrl $dst, $shift" %} 8169 ins_encode %{ 8170 __ shrl($dst$$Address); 8171 %} 8172 ins_pipe(ialu_mem_reg); 8173 %} 8174 8175 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8176 %{ 8177 predicate(VM_Version::supports_bmi2()); 8178 match(Set dst (URShiftI src shift)); 8179 8180 format %{ "shrxl $dst, $src, $shift" %} 8181 ins_encode %{ 8182 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8183 %} 8184 ins_pipe(ialu_reg_reg); 8185 %} 8186 8187 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8188 %{ 8189 predicate(VM_Version::supports_bmi2()); 8190 match(Set dst (URShiftI (LoadI src) shift)); 8191 ins_cost(175); 8192 format %{ "shrxl $dst, $src, $shift" %} 8193 ins_encode %{ 8194 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8195 %} 8196 ins_pipe(ialu_reg_mem); 8197 %} 8198 8199 // Long Shift Instructions 8200 // Shift Left by one, two, three 8201 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8202 %{ 8203 match(Set dst (LShiftL dst shift)); 8204 effect(KILL cr); 8205 8206 format %{ "salq $dst, $shift" %} 8207 ins_encode %{ 8208 __ salq($dst$$Register, $shift$$constant); 8209 %} 8210 ins_pipe(ialu_reg); 8211 %} 8212 8213 // Shift Left by 8-bit immediate 8214 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8215 %{ 8216 match(Set dst (LShiftL dst shift)); 8217 effect(KILL cr); 8218 8219 format %{ "salq $dst, $shift" %} 8220 ins_encode %{ 8221 __ salq($dst$$Register, $shift$$constant); 8222 %} 8223 ins_pipe(ialu_reg); 8224 %} 8225 8226 // Shift Left by 8-bit immediate 8227 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8228 %{ 8229 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8230 effect(KILL cr); 8231 8232 format %{ "salq $dst, $shift" %} 8233 ins_encode %{ 8234 __ salq($dst$$Address, $shift$$constant); 8235 %} 8236 ins_pipe(ialu_mem_imm); 8237 %} 8238 8239 // Shift Left by variable 8240 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8241 %{ 8242 predicate(!VM_Version::supports_bmi2()); 8243 match(Set dst (LShiftL dst shift)); 8244 effect(KILL cr); 8245 8246 format %{ "salq $dst, $shift" %} 8247 ins_encode %{ 8248 __ salq($dst$$Register); 8249 %} 8250 ins_pipe(ialu_reg_reg); 8251 %} 8252 8253 // Shift Left by variable 8254 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8255 %{ 8256 predicate(!VM_Version::supports_bmi2()); 8257 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8258 effect(KILL cr); 8259 8260 format %{ "salq $dst, $shift" %} 8261 ins_encode %{ 8262 __ salq($dst$$Address); 8263 %} 8264 ins_pipe(ialu_mem_reg); 8265 %} 8266 8267 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8268 %{ 8269 predicate(VM_Version::supports_bmi2()); 8270 match(Set dst (LShiftL src shift)); 8271 8272 format %{ "shlxq $dst, $src, $shift" %} 8273 ins_encode %{ 8274 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8275 %} 8276 ins_pipe(ialu_reg_reg); 8277 %} 8278 8279 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8280 %{ 8281 predicate(VM_Version::supports_bmi2()); 8282 match(Set dst (LShiftL (LoadL src) shift)); 8283 ins_cost(175); 8284 format %{ "shlxq $dst, $src, $shift" %} 8285 ins_encode %{ 8286 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8287 %} 8288 ins_pipe(ialu_reg_mem); 8289 %} 8290 8291 // Arithmetic Shift Right by 8-bit immediate 8292 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8293 %{ 8294 match(Set dst (RShiftL dst shift)); 8295 effect(KILL cr); 8296 8297 format %{ "sarq $dst, $shift" %} 8298 ins_encode %{ 8299 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8300 %} 8301 ins_pipe(ialu_mem_imm); 8302 %} 8303 8304 // Arithmetic Shift Right by 8-bit immediate 8305 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8306 %{ 8307 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8308 effect(KILL cr); 8309 8310 format %{ "sarq $dst, $shift" %} 8311 ins_encode %{ 8312 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8313 %} 8314 ins_pipe(ialu_mem_imm); 8315 %} 8316 8317 // Arithmetic Shift Right by variable 8318 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8319 %{ 8320 predicate(!VM_Version::supports_bmi2()); 8321 match(Set dst (RShiftL dst shift)); 8322 effect(KILL cr); 8323 8324 format %{ "sarq $dst, $shift" %} 8325 ins_encode %{ 8326 __ sarq($dst$$Register); 8327 %} 8328 ins_pipe(ialu_reg_reg); 8329 %} 8330 8331 // Arithmetic Shift Right by variable 8332 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8333 %{ 8334 predicate(!VM_Version::supports_bmi2()); 8335 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8336 effect(KILL cr); 8337 8338 format %{ "sarq $dst, $shift" %} 8339 ins_encode %{ 8340 __ sarq($dst$$Address); 8341 %} 8342 ins_pipe(ialu_mem_reg); 8343 %} 8344 8345 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8346 %{ 8347 predicate(VM_Version::supports_bmi2()); 8348 match(Set dst (RShiftL src shift)); 8349 8350 format %{ "sarxq $dst, $src, $shift" %} 8351 ins_encode %{ 8352 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8353 %} 8354 ins_pipe(ialu_reg_reg); 8355 %} 8356 8357 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8358 %{ 8359 predicate(VM_Version::supports_bmi2()); 8360 match(Set dst (RShiftL (LoadL src) shift)); 8361 ins_cost(175); 8362 format %{ "sarxq $dst, $src, $shift" %} 8363 ins_encode %{ 8364 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8365 %} 8366 ins_pipe(ialu_reg_mem); 8367 %} 8368 8369 // Logical Shift Right by 8-bit immediate 8370 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8371 %{ 8372 match(Set dst (URShiftL dst shift)); 8373 effect(KILL cr); 8374 8375 format %{ "shrq $dst, $shift" %} 8376 ins_encode %{ 8377 __ shrq($dst$$Register, $shift$$constant); 8378 %} 8379 ins_pipe(ialu_reg); 8380 %} 8381 8382 // Logical Shift Right by 8-bit immediate 8383 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8384 %{ 8385 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8386 effect(KILL cr); 8387 8388 format %{ "shrq $dst, $shift" %} 8389 ins_encode %{ 8390 __ shrq($dst$$Address, $shift$$constant); 8391 %} 8392 ins_pipe(ialu_mem_imm); 8393 %} 8394 8395 // Logical Shift Right by variable 8396 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8397 %{ 8398 predicate(!VM_Version::supports_bmi2()); 8399 match(Set dst (URShiftL dst shift)); 8400 effect(KILL cr); 8401 8402 format %{ "shrq $dst, $shift" %} 8403 ins_encode %{ 8404 __ shrq($dst$$Register); 8405 %} 8406 ins_pipe(ialu_reg_reg); 8407 %} 8408 8409 // Logical Shift Right by variable 8410 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8411 %{ 8412 predicate(!VM_Version::supports_bmi2()); 8413 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8414 effect(KILL cr); 8415 8416 format %{ "shrq $dst, $shift" %} 8417 ins_encode %{ 8418 __ shrq($dst$$Address); 8419 %} 8420 ins_pipe(ialu_mem_reg); 8421 %} 8422 8423 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8424 %{ 8425 predicate(VM_Version::supports_bmi2()); 8426 match(Set dst (URShiftL src shift)); 8427 8428 format %{ "shrxq $dst, $src, $shift" %} 8429 ins_encode %{ 8430 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8431 %} 8432 ins_pipe(ialu_reg_reg); 8433 %} 8434 8435 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8436 %{ 8437 predicate(VM_Version::supports_bmi2()); 8438 match(Set dst (URShiftL (LoadL src) shift)); 8439 ins_cost(175); 8440 format %{ "shrxq $dst, $src, $shift" %} 8441 ins_encode %{ 8442 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8443 %} 8444 ins_pipe(ialu_reg_mem); 8445 %} 8446 8447 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8448 // This idiom is used by the compiler for the i2b bytecode. 8449 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8450 %{ 8451 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8452 8453 format %{ "movsbl $dst, $src\t# i2b" %} 8454 ins_encode %{ 8455 __ movsbl($dst$$Register, $src$$Register); 8456 %} 8457 ins_pipe(ialu_reg_reg); 8458 %} 8459 8460 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8461 // This idiom is used by the compiler the i2s bytecode. 8462 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8463 %{ 8464 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8465 8466 format %{ "movswl $dst, $src\t# i2s" %} 8467 ins_encode %{ 8468 __ movswl($dst$$Register, $src$$Register); 8469 %} 8470 ins_pipe(ialu_reg_reg); 8471 %} 8472 8473 // ROL/ROR instructions 8474 8475 // Rotate left by constant. 8476 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8477 %{ 8478 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8479 match(Set dst (RotateLeft dst shift)); 8480 effect(KILL cr); 8481 format %{ "roll $dst, $shift" %} 8482 ins_encode %{ 8483 __ roll($dst$$Register, $shift$$constant); 8484 %} 8485 ins_pipe(ialu_reg); 8486 %} 8487 8488 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8489 %{ 8490 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8491 match(Set dst (RotateLeft src shift)); 8492 format %{ "rolxl $dst, $src, $shift" %} 8493 ins_encode %{ 8494 int shift = 32 - ($shift$$constant & 31); 8495 __ rorxl($dst$$Register, $src$$Register, shift); 8496 %} 8497 ins_pipe(ialu_reg_reg); 8498 %} 8499 8500 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8501 %{ 8502 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8503 match(Set dst (RotateLeft (LoadI src) shift)); 8504 ins_cost(175); 8505 format %{ "rolxl $dst, $src, $shift" %} 8506 ins_encode %{ 8507 int shift = 32 - ($shift$$constant & 31); 8508 __ rorxl($dst$$Register, $src$$Address, shift); 8509 %} 8510 ins_pipe(ialu_reg_mem); 8511 %} 8512 8513 // Rotate Left by variable 8514 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8515 %{ 8516 predicate(n->bottom_type()->basic_type() == T_INT); 8517 match(Set dst (RotateLeft dst shift)); 8518 effect(KILL cr); 8519 format %{ "roll $dst, $shift" %} 8520 ins_encode %{ 8521 __ roll($dst$$Register); 8522 %} 8523 ins_pipe(ialu_reg_reg); 8524 %} 8525 8526 // Rotate Right by constant. 8527 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8528 %{ 8529 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8530 match(Set dst (RotateRight dst shift)); 8531 effect(KILL cr); 8532 format %{ "rorl $dst, $shift" %} 8533 ins_encode %{ 8534 __ rorl($dst$$Register, $shift$$constant); 8535 %} 8536 ins_pipe(ialu_reg); 8537 %} 8538 8539 // Rotate Right by constant. 8540 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8541 %{ 8542 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8543 match(Set dst (RotateRight src shift)); 8544 format %{ "rorxl $dst, $src, $shift" %} 8545 ins_encode %{ 8546 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8547 %} 8548 ins_pipe(ialu_reg_reg); 8549 %} 8550 8551 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8552 %{ 8553 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8554 match(Set dst (RotateRight (LoadI src) shift)); 8555 ins_cost(175); 8556 format %{ "rorxl $dst, $src, $shift" %} 8557 ins_encode %{ 8558 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8559 %} 8560 ins_pipe(ialu_reg_mem); 8561 %} 8562 8563 // Rotate Right by variable 8564 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8565 %{ 8566 predicate(n->bottom_type()->basic_type() == T_INT); 8567 match(Set dst (RotateRight dst shift)); 8568 effect(KILL cr); 8569 format %{ "rorl $dst, $shift" %} 8570 ins_encode %{ 8571 __ rorl($dst$$Register); 8572 %} 8573 ins_pipe(ialu_reg_reg); 8574 %} 8575 8576 // Rotate Left by constant. 8577 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8578 %{ 8579 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8580 match(Set dst (RotateLeft dst shift)); 8581 effect(KILL cr); 8582 format %{ "rolq $dst, $shift" %} 8583 ins_encode %{ 8584 __ rolq($dst$$Register, $shift$$constant); 8585 %} 8586 ins_pipe(ialu_reg); 8587 %} 8588 8589 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8590 %{ 8591 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8592 match(Set dst (RotateLeft src shift)); 8593 format %{ "rolxq $dst, $src, $shift" %} 8594 ins_encode %{ 8595 int shift = 64 - ($shift$$constant & 63); 8596 __ rorxq($dst$$Register, $src$$Register, shift); 8597 %} 8598 ins_pipe(ialu_reg_reg); 8599 %} 8600 8601 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8602 %{ 8603 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8604 match(Set dst (RotateLeft (LoadL src) shift)); 8605 ins_cost(175); 8606 format %{ "rolxq $dst, $src, $shift" %} 8607 ins_encode %{ 8608 int shift = 64 - ($shift$$constant & 63); 8609 __ rorxq($dst$$Register, $src$$Address, shift); 8610 %} 8611 ins_pipe(ialu_reg_mem); 8612 %} 8613 8614 // Rotate Left by variable 8615 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8616 %{ 8617 predicate(n->bottom_type()->basic_type() == T_LONG); 8618 match(Set dst (RotateLeft dst shift)); 8619 effect(KILL cr); 8620 format %{ "rolq $dst, $shift" %} 8621 ins_encode %{ 8622 __ rolq($dst$$Register); 8623 %} 8624 ins_pipe(ialu_reg_reg); 8625 %} 8626 8627 // Rotate Right by constant. 8628 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8629 %{ 8630 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8631 match(Set dst (RotateRight dst shift)); 8632 effect(KILL cr); 8633 format %{ "rorq $dst, $shift" %} 8634 ins_encode %{ 8635 __ rorq($dst$$Register, $shift$$constant); 8636 %} 8637 ins_pipe(ialu_reg); 8638 %} 8639 8640 // Rotate Right by constant 8641 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8642 %{ 8643 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8644 match(Set dst (RotateRight src shift)); 8645 format %{ "rorxq $dst, $src, $shift" %} 8646 ins_encode %{ 8647 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8648 %} 8649 ins_pipe(ialu_reg_reg); 8650 %} 8651 8652 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8653 %{ 8654 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8655 match(Set dst (RotateRight (LoadL src) shift)); 8656 ins_cost(175); 8657 format %{ "rorxq $dst, $src, $shift" %} 8658 ins_encode %{ 8659 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8660 %} 8661 ins_pipe(ialu_reg_mem); 8662 %} 8663 8664 // Rotate Right by variable 8665 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8666 %{ 8667 predicate(n->bottom_type()->basic_type() == T_LONG); 8668 match(Set dst (RotateRight dst shift)); 8669 effect(KILL cr); 8670 format %{ "rorq $dst, $shift" %} 8671 ins_encode %{ 8672 __ rorq($dst$$Register); 8673 %} 8674 ins_pipe(ialu_reg_reg); 8675 %} 8676 8677 //----------------------------- CompressBits/ExpandBits ------------------------ 8678 8679 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8680 predicate(n->bottom_type()->isa_long()); 8681 match(Set dst (CompressBits src mask)); 8682 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8683 ins_encode %{ 8684 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8685 %} 8686 ins_pipe( pipe_slow ); 8687 %} 8688 8689 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8690 predicate(n->bottom_type()->isa_long()); 8691 match(Set dst (ExpandBits src mask)); 8692 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8693 ins_encode %{ 8694 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8695 %} 8696 ins_pipe( pipe_slow ); 8697 %} 8698 8699 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8700 predicate(n->bottom_type()->isa_long()); 8701 match(Set dst (CompressBits src (LoadL mask))); 8702 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8703 ins_encode %{ 8704 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8705 %} 8706 ins_pipe( pipe_slow ); 8707 %} 8708 8709 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8710 predicate(n->bottom_type()->isa_long()); 8711 match(Set dst (ExpandBits src (LoadL mask))); 8712 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8713 ins_encode %{ 8714 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8715 %} 8716 ins_pipe( pipe_slow ); 8717 %} 8718 8719 8720 // Logical Instructions 8721 8722 // Integer Logical Instructions 8723 8724 // And Instructions 8725 // And Register with Register 8726 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8727 %{ 8728 match(Set dst (AndI dst src)); 8729 effect(KILL cr); 8730 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); 8731 8732 format %{ "andl $dst, $src\t# int" %} 8733 ins_encode %{ 8734 __ andl($dst$$Register, $src$$Register); 8735 %} 8736 ins_pipe(ialu_reg_reg); 8737 %} 8738 8739 // And Register with Immediate 255 8740 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8741 %{ 8742 match(Set dst (AndI src mask)); 8743 8744 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8745 ins_encode %{ 8746 __ movzbl($dst$$Register, $src$$Register); 8747 %} 8748 ins_pipe(ialu_reg); 8749 %} 8750 8751 // And Register with Immediate 255 and promote to long 8752 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8753 %{ 8754 match(Set dst (ConvI2L (AndI src mask))); 8755 8756 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8757 ins_encode %{ 8758 __ movzbl($dst$$Register, $src$$Register); 8759 %} 8760 ins_pipe(ialu_reg); 8761 %} 8762 8763 // And Register with Immediate 65535 8764 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8765 %{ 8766 match(Set dst (AndI src mask)); 8767 8768 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8769 ins_encode %{ 8770 __ movzwl($dst$$Register, $src$$Register); 8771 %} 8772 ins_pipe(ialu_reg); 8773 %} 8774 8775 // And Register with Immediate 65535 and promote to long 8776 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8777 %{ 8778 match(Set dst (ConvI2L (AndI src mask))); 8779 8780 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8781 ins_encode %{ 8782 __ movzwl($dst$$Register, $src$$Register); 8783 %} 8784 ins_pipe(ialu_reg); 8785 %} 8786 8787 // Can skip int2long conversions after AND with small bitmask 8788 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8789 %{ 8790 predicate(VM_Version::supports_bmi2()); 8791 ins_cost(125); 8792 effect(TEMP tmp, KILL cr); 8793 match(Set dst (ConvI2L (AndI src mask))); 8794 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8795 ins_encode %{ 8796 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8797 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8798 %} 8799 ins_pipe(ialu_reg_reg); 8800 %} 8801 8802 // And Register with Immediate 8803 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8804 %{ 8805 match(Set dst (AndI dst src)); 8806 effect(KILL cr); 8807 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); 8808 8809 format %{ "andl $dst, $src\t# int" %} 8810 ins_encode %{ 8811 __ andl($dst$$Register, $src$$constant); 8812 %} 8813 ins_pipe(ialu_reg); 8814 %} 8815 8816 // And Register with Memory 8817 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8818 %{ 8819 match(Set dst (AndI dst (LoadI src))); 8820 effect(KILL cr); 8821 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); 8822 8823 ins_cost(150); 8824 format %{ "andl $dst, $src\t# int" %} 8825 ins_encode %{ 8826 __ andl($dst$$Register, $src$$Address); 8827 %} 8828 ins_pipe(ialu_reg_mem); 8829 %} 8830 8831 // And Memory with Register 8832 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8833 %{ 8834 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8835 effect(KILL cr); 8836 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); 8837 8838 ins_cost(150); 8839 format %{ "andb $dst, $src\t# byte" %} 8840 ins_encode %{ 8841 __ andb($dst$$Address, $src$$Register); 8842 %} 8843 ins_pipe(ialu_mem_reg); 8844 %} 8845 8846 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8847 %{ 8848 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8849 effect(KILL cr); 8850 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); 8851 8852 ins_cost(150); 8853 format %{ "andl $dst, $src\t# int" %} 8854 ins_encode %{ 8855 __ andl($dst$$Address, $src$$Register); 8856 %} 8857 ins_pipe(ialu_mem_reg); 8858 %} 8859 8860 // And Memory with Immediate 8861 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8862 %{ 8863 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8864 effect(KILL cr); 8865 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); 8866 8867 ins_cost(125); 8868 format %{ "andl $dst, $src\t# int" %} 8869 ins_encode %{ 8870 __ andl($dst$$Address, $src$$constant); 8871 %} 8872 ins_pipe(ialu_mem_imm); 8873 %} 8874 8875 // BMI1 instructions 8876 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8877 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8878 predicate(UseBMI1Instructions); 8879 effect(KILL cr); 8880 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8881 8882 ins_cost(125); 8883 format %{ "andnl $dst, $src1, $src2" %} 8884 8885 ins_encode %{ 8886 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8887 %} 8888 ins_pipe(ialu_reg_mem); 8889 %} 8890 8891 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8892 match(Set dst (AndI (XorI src1 minus_1) src2)); 8893 predicate(UseBMI1Instructions); 8894 effect(KILL cr); 8895 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8896 8897 format %{ "andnl $dst, $src1, $src2" %} 8898 8899 ins_encode %{ 8900 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8901 %} 8902 ins_pipe(ialu_reg); 8903 %} 8904 8905 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 8906 match(Set dst (AndI (SubI imm_zero src) src)); 8907 predicate(UseBMI1Instructions); 8908 effect(KILL cr); 8909 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8910 8911 format %{ "blsil $dst, $src" %} 8912 8913 ins_encode %{ 8914 __ blsil($dst$$Register, $src$$Register); 8915 %} 8916 ins_pipe(ialu_reg); 8917 %} 8918 8919 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 8920 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8921 predicate(UseBMI1Instructions); 8922 effect(KILL cr); 8923 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8924 8925 ins_cost(125); 8926 format %{ "blsil $dst, $src" %} 8927 8928 ins_encode %{ 8929 __ blsil($dst$$Register, $src$$Address); 8930 %} 8931 ins_pipe(ialu_reg_mem); 8932 %} 8933 8934 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8935 %{ 8936 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8937 predicate(UseBMI1Instructions); 8938 effect(KILL cr); 8939 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 8940 8941 ins_cost(125); 8942 format %{ "blsmskl $dst, $src" %} 8943 8944 ins_encode %{ 8945 __ blsmskl($dst$$Register, $src$$Address); 8946 %} 8947 ins_pipe(ialu_reg_mem); 8948 %} 8949 8950 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8951 %{ 8952 match(Set dst (XorI (AddI src minus_1) src)); 8953 predicate(UseBMI1Instructions); 8954 effect(KILL cr); 8955 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 8956 8957 format %{ "blsmskl $dst, $src" %} 8958 8959 ins_encode %{ 8960 __ blsmskl($dst$$Register, $src$$Register); 8961 %} 8962 8963 ins_pipe(ialu_reg); 8964 %} 8965 8966 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8967 %{ 8968 match(Set dst (AndI (AddI src minus_1) src) ); 8969 predicate(UseBMI1Instructions); 8970 effect(KILL cr); 8971 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8972 8973 format %{ "blsrl $dst, $src" %} 8974 8975 ins_encode %{ 8976 __ blsrl($dst$$Register, $src$$Register); 8977 %} 8978 8979 ins_pipe(ialu_reg_mem); 8980 %} 8981 8982 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8983 %{ 8984 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8985 predicate(UseBMI1Instructions); 8986 effect(KILL cr); 8987 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8988 8989 ins_cost(125); 8990 format %{ "blsrl $dst, $src" %} 8991 8992 ins_encode %{ 8993 __ blsrl($dst$$Register, $src$$Address); 8994 %} 8995 8996 ins_pipe(ialu_reg); 8997 %} 8998 8999 // Or Instructions 9000 // Or Register with Register 9001 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9002 %{ 9003 match(Set dst (OrI dst src)); 9004 effect(KILL cr); 9005 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); 9006 9007 format %{ "orl $dst, $src\t# int" %} 9008 ins_encode %{ 9009 __ orl($dst$$Register, $src$$Register); 9010 %} 9011 ins_pipe(ialu_reg_reg); 9012 %} 9013 9014 // Or Register with Immediate 9015 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9016 %{ 9017 match(Set dst (OrI dst src)); 9018 effect(KILL cr); 9019 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); 9020 9021 format %{ "orl $dst, $src\t# int" %} 9022 ins_encode %{ 9023 __ orl($dst$$Register, $src$$constant); 9024 %} 9025 ins_pipe(ialu_reg); 9026 %} 9027 9028 // Or Register with Memory 9029 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9030 %{ 9031 match(Set dst (OrI dst (LoadI src))); 9032 effect(KILL cr); 9033 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); 9034 9035 ins_cost(150); 9036 format %{ "orl $dst, $src\t# int" %} 9037 ins_encode %{ 9038 __ orl($dst$$Register, $src$$Address); 9039 %} 9040 ins_pipe(ialu_reg_mem); 9041 %} 9042 9043 // Or Memory with Register 9044 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9045 %{ 9046 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9047 effect(KILL cr); 9048 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); 9049 9050 ins_cost(150); 9051 format %{ "orb $dst, $src\t# byte" %} 9052 ins_encode %{ 9053 __ orb($dst$$Address, $src$$Register); 9054 %} 9055 ins_pipe(ialu_mem_reg); 9056 %} 9057 9058 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9059 %{ 9060 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9061 effect(KILL cr); 9062 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); 9063 9064 ins_cost(150); 9065 format %{ "orl $dst, $src\t# int" %} 9066 ins_encode %{ 9067 __ orl($dst$$Address, $src$$Register); 9068 %} 9069 ins_pipe(ialu_mem_reg); 9070 %} 9071 9072 // Or Memory with Immediate 9073 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9074 %{ 9075 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9076 effect(KILL cr); 9077 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); 9078 9079 ins_cost(125); 9080 format %{ "orl $dst, $src\t# int" %} 9081 ins_encode %{ 9082 __ orl($dst$$Address, $src$$constant); 9083 %} 9084 ins_pipe(ialu_mem_imm); 9085 %} 9086 9087 // Xor Instructions 9088 // Xor Register with Register 9089 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9090 %{ 9091 match(Set dst (XorI dst src)); 9092 effect(KILL cr); 9093 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); 9094 9095 format %{ "xorl $dst, $src\t# int" %} 9096 ins_encode %{ 9097 __ xorl($dst$$Register, $src$$Register); 9098 %} 9099 ins_pipe(ialu_reg_reg); 9100 %} 9101 9102 // Xor Register with Immediate -1 9103 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9104 match(Set dst (XorI dst imm)); 9105 9106 format %{ "not $dst" %} 9107 ins_encode %{ 9108 __ notl($dst$$Register); 9109 %} 9110 ins_pipe(ialu_reg); 9111 %} 9112 9113 // Xor Register with Immediate 9114 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9115 %{ 9116 match(Set dst (XorI dst src)); 9117 effect(KILL cr); 9118 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); 9119 9120 format %{ "xorl $dst, $src\t# int" %} 9121 ins_encode %{ 9122 __ xorl($dst$$Register, $src$$constant); 9123 %} 9124 ins_pipe(ialu_reg); 9125 %} 9126 9127 // Xor Register with Memory 9128 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9129 %{ 9130 match(Set dst (XorI dst (LoadI src))); 9131 effect(KILL cr); 9132 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); 9133 9134 ins_cost(150); 9135 format %{ "xorl $dst, $src\t# int" %} 9136 ins_encode %{ 9137 __ xorl($dst$$Register, $src$$Address); 9138 %} 9139 ins_pipe(ialu_reg_mem); 9140 %} 9141 9142 // Xor Memory with Register 9143 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9144 %{ 9145 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9146 effect(KILL cr); 9147 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); 9148 9149 ins_cost(150); 9150 format %{ "xorb $dst, $src\t# byte" %} 9151 ins_encode %{ 9152 __ xorb($dst$$Address, $src$$Register); 9153 %} 9154 ins_pipe(ialu_mem_reg); 9155 %} 9156 9157 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9158 %{ 9159 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9160 effect(KILL cr); 9161 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); 9162 9163 ins_cost(150); 9164 format %{ "xorl $dst, $src\t# int" %} 9165 ins_encode %{ 9166 __ xorl($dst$$Address, $src$$Register); 9167 %} 9168 ins_pipe(ialu_mem_reg); 9169 %} 9170 9171 // Xor Memory with Immediate 9172 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9173 %{ 9174 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9175 effect(KILL cr); 9176 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); 9177 9178 ins_cost(125); 9179 format %{ "xorl $dst, $src\t# int" %} 9180 ins_encode %{ 9181 __ xorl($dst$$Address, $src$$constant); 9182 %} 9183 ins_pipe(ialu_mem_imm); 9184 %} 9185 9186 9187 // Long Logical Instructions 9188 9189 // And Instructions 9190 // And Register with Register 9191 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9192 %{ 9193 match(Set dst (AndL dst src)); 9194 effect(KILL cr); 9195 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); 9196 9197 format %{ "andq $dst, $src\t# long" %} 9198 ins_encode %{ 9199 __ andq($dst$$Register, $src$$Register); 9200 %} 9201 ins_pipe(ialu_reg_reg); 9202 %} 9203 9204 // And Register with Immediate 255 9205 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9206 %{ 9207 match(Set dst (AndL src mask)); 9208 9209 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9210 ins_encode %{ 9211 // movzbl zeroes out the upper 32-bit and does not need REX.W 9212 __ movzbl($dst$$Register, $src$$Register); 9213 %} 9214 ins_pipe(ialu_reg); 9215 %} 9216 9217 // And Register with Immediate 65535 9218 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9219 %{ 9220 match(Set dst (AndL src mask)); 9221 9222 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9223 ins_encode %{ 9224 // movzwl zeroes out the upper 32-bit and does not need REX.W 9225 __ movzwl($dst$$Register, $src$$Register); 9226 %} 9227 ins_pipe(ialu_reg); 9228 %} 9229 9230 // And Register with Immediate 9231 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9232 %{ 9233 match(Set dst (AndL dst src)); 9234 effect(KILL cr); 9235 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); 9236 9237 format %{ "andq $dst, $src\t# long" %} 9238 ins_encode %{ 9239 __ andq($dst$$Register, $src$$constant); 9240 %} 9241 ins_pipe(ialu_reg); 9242 %} 9243 9244 // And Register with Memory 9245 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9246 %{ 9247 match(Set dst (AndL dst (LoadL src))); 9248 effect(KILL cr); 9249 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); 9250 9251 ins_cost(150); 9252 format %{ "andq $dst, $src\t# long" %} 9253 ins_encode %{ 9254 __ andq($dst$$Register, $src$$Address); 9255 %} 9256 ins_pipe(ialu_reg_mem); 9257 %} 9258 9259 // And Memory with Register 9260 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9261 %{ 9262 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9263 effect(KILL cr); 9264 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); 9265 9266 ins_cost(150); 9267 format %{ "andq $dst, $src\t# long" %} 9268 ins_encode %{ 9269 __ andq($dst$$Address, $src$$Register); 9270 %} 9271 ins_pipe(ialu_mem_reg); 9272 %} 9273 9274 // And Memory with Immediate 9275 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9276 %{ 9277 match(Set dst (StoreL dst (AndL (LoadL 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 ins_cost(125); 9282 format %{ "andq $dst, $src\t# long" %} 9283 ins_encode %{ 9284 __ andq($dst$$Address, $src$$constant); 9285 %} 9286 ins_pipe(ialu_mem_imm); 9287 %} 9288 9289 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9290 %{ 9291 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9292 // because AND/OR works well enough for 8/32-bit values. 9293 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9294 9295 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9296 effect(KILL cr); 9297 9298 ins_cost(125); 9299 format %{ "btrq $dst, log2(not($con))\t# long" %} 9300 ins_encode %{ 9301 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9302 %} 9303 ins_pipe(ialu_mem_imm); 9304 %} 9305 9306 // BMI1 instructions 9307 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9308 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9309 predicate(UseBMI1Instructions); 9310 effect(KILL cr); 9311 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9312 9313 ins_cost(125); 9314 format %{ "andnq $dst, $src1, $src2" %} 9315 9316 ins_encode %{ 9317 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9318 %} 9319 ins_pipe(ialu_reg_mem); 9320 %} 9321 9322 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9323 match(Set dst (AndL (XorL src1 minus_1) src2)); 9324 predicate(UseBMI1Instructions); 9325 effect(KILL cr); 9326 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9327 9328 format %{ "andnq $dst, $src1, $src2" %} 9329 9330 ins_encode %{ 9331 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9332 %} 9333 ins_pipe(ialu_reg_mem); 9334 %} 9335 9336 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9337 match(Set dst (AndL (SubL imm_zero src) src)); 9338 predicate(UseBMI1Instructions); 9339 effect(KILL cr); 9340 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9341 9342 format %{ "blsiq $dst, $src" %} 9343 9344 ins_encode %{ 9345 __ blsiq($dst$$Register, $src$$Register); 9346 %} 9347 ins_pipe(ialu_reg); 9348 %} 9349 9350 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9351 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9352 predicate(UseBMI1Instructions); 9353 effect(KILL cr); 9354 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9355 9356 ins_cost(125); 9357 format %{ "blsiq $dst, $src" %} 9358 9359 ins_encode %{ 9360 __ blsiq($dst$$Register, $src$$Address); 9361 %} 9362 ins_pipe(ialu_reg_mem); 9363 %} 9364 9365 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9366 %{ 9367 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9368 predicate(UseBMI1Instructions); 9369 effect(KILL cr); 9370 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9371 9372 ins_cost(125); 9373 format %{ "blsmskq $dst, $src" %} 9374 9375 ins_encode %{ 9376 __ blsmskq($dst$$Register, $src$$Address); 9377 %} 9378 ins_pipe(ialu_reg_mem); 9379 %} 9380 9381 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9382 %{ 9383 match(Set dst (XorL (AddL src minus_1) src)); 9384 predicate(UseBMI1Instructions); 9385 effect(KILL cr); 9386 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9387 9388 format %{ "blsmskq $dst, $src" %} 9389 9390 ins_encode %{ 9391 __ blsmskq($dst$$Register, $src$$Register); 9392 %} 9393 9394 ins_pipe(ialu_reg); 9395 %} 9396 9397 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9398 %{ 9399 match(Set dst (AndL (AddL src minus_1) src) ); 9400 predicate(UseBMI1Instructions); 9401 effect(KILL cr); 9402 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9403 9404 format %{ "blsrq $dst, $src" %} 9405 9406 ins_encode %{ 9407 __ blsrq($dst$$Register, $src$$Register); 9408 %} 9409 9410 ins_pipe(ialu_reg); 9411 %} 9412 9413 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9414 %{ 9415 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9416 predicate(UseBMI1Instructions); 9417 effect(KILL cr); 9418 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9419 9420 ins_cost(125); 9421 format %{ "blsrq $dst, $src" %} 9422 9423 ins_encode %{ 9424 __ blsrq($dst$$Register, $src$$Address); 9425 %} 9426 9427 ins_pipe(ialu_reg); 9428 %} 9429 9430 // Or Instructions 9431 // Or Register with Register 9432 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9433 %{ 9434 match(Set dst (OrL 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 format %{ "orq $dst, $src\t# long" %} 9439 ins_encode %{ 9440 __ orq($dst$$Register, $src$$Register); 9441 %} 9442 ins_pipe(ialu_reg_reg); 9443 %} 9444 9445 // Use any_RegP to match R15 (TLS register) without spilling. 9446 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9447 match(Set dst (OrL dst (CastP2X src))); 9448 effect(KILL cr); 9449 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); 9450 9451 format %{ "orq $dst, $src\t# long" %} 9452 ins_encode %{ 9453 __ orq($dst$$Register, $src$$Register); 9454 %} 9455 ins_pipe(ialu_reg_reg); 9456 %} 9457 9458 9459 // Or Register with Immediate 9460 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9461 %{ 9462 match(Set dst (OrL dst src)); 9463 effect(KILL cr); 9464 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); 9465 9466 format %{ "orq $dst, $src\t# long" %} 9467 ins_encode %{ 9468 __ orq($dst$$Register, $src$$constant); 9469 %} 9470 ins_pipe(ialu_reg); 9471 %} 9472 9473 // Or Register with Memory 9474 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9475 %{ 9476 match(Set dst (OrL dst (LoadL src))); 9477 effect(KILL cr); 9478 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); 9479 9480 ins_cost(150); 9481 format %{ "orq $dst, $src\t# long" %} 9482 ins_encode %{ 9483 __ orq($dst$$Register, $src$$Address); 9484 %} 9485 ins_pipe(ialu_reg_mem); 9486 %} 9487 9488 // Or Memory with Register 9489 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9490 %{ 9491 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9492 effect(KILL cr); 9493 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); 9494 9495 ins_cost(150); 9496 format %{ "orq $dst, $src\t# long" %} 9497 ins_encode %{ 9498 __ orq($dst$$Address, $src$$Register); 9499 %} 9500 ins_pipe(ialu_mem_reg); 9501 %} 9502 9503 // Or Memory with Immediate 9504 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9505 %{ 9506 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9507 effect(KILL cr); 9508 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); 9509 9510 ins_cost(125); 9511 format %{ "orq $dst, $src\t# long" %} 9512 ins_encode %{ 9513 __ orq($dst$$Address, $src$$constant); 9514 %} 9515 ins_pipe(ialu_mem_imm); 9516 %} 9517 9518 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9519 %{ 9520 // con should be a pure 64-bit power of 2 immediate 9521 // because AND/OR works well enough for 8/32-bit values. 9522 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9523 9524 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9525 effect(KILL cr); 9526 9527 ins_cost(125); 9528 format %{ "btsq $dst, log2($con)\t# long" %} 9529 ins_encode %{ 9530 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9531 %} 9532 ins_pipe(ialu_mem_imm); 9533 %} 9534 9535 // Xor Instructions 9536 // Xor Register with Register 9537 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9538 %{ 9539 match(Set dst (XorL dst src)); 9540 effect(KILL cr); 9541 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); 9542 9543 format %{ "xorq $dst, $src\t# long" %} 9544 ins_encode %{ 9545 __ xorq($dst$$Register, $src$$Register); 9546 %} 9547 ins_pipe(ialu_reg_reg); 9548 %} 9549 9550 // Xor Register with Immediate -1 9551 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9552 match(Set dst (XorL dst imm)); 9553 9554 format %{ "notq $dst" %} 9555 ins_encode %{ 9556 __ notq($dst$$Register); 9557 %} 9558 ins_pipe(ialu_reg); 9559 %} 9560 9561 // Xor Register with Immediate 9562 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9563 %{ 9564 match(Set dst (XorL dst src)); 9565 effect(KILL cr); 9566 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); 9567 9568 format %{ "xorq $dst, $src\t# long" %} 9569 ins_encode %{ 9570 __ xorq($dst$$Register, $src$$constant); 9571 %} 9572 ins_pipe(ialu_reg); 9573 %} 9574 9575 // Xor Register with Memory 9576 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9577 %{ 9578 match(Set dst (XorL dst (LoadL src))); 9579 effect(KILL cr); 9580 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); 9581 9582 ins_cost(150); 9583 format %{ "xorq $dst, $src\t# long" %} 9584 ins_encode %{ 9585 __ xorq($dst$$Register, $src$$Address); 9586 %} 9587 ins_pipe(ialu_reg_mem); 9588 %} 9589 9590 // Xor Memory with Register 9591 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9592 %{ 9593 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9594 effect(KILL cr); 9595 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); 9596 9597 ins_cost(150); 9598 format %{ "xorq $dst, $src\t# long" %} 9599 ins_encode %{ 9600 __ xorq($dst$$Address, $src$$Register); 9601 %} 9602 ins_pipe(ialu_mem_reg); 9603 %} 9604 9605 // Xor Memory with Immediate 9606 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9607 %{ 9608 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9609 effect(KILL cr); 9610 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); 9611 9612 ins_cost(125); 9613 format %{ "xorq $dst, $src\t# long" %} 9614 ins_encode %{ 9615 __ xorq($dst$$Address, $src$$constant); 9616 %} 9617 ins_pipe(ialu_mem_imm); 9618 %} 9619 9620 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9621 %{ 9622 match(Set dst (CmpLTMask p q)); 9623 effect(KILL cr); 9624 9625 ins_cost(400); 9626 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9627 "setlt $dst\n\t" 9628 "movzbl $dst, $dst\n\t" 9629 "negl $dst" %} 9630 ins_encode %{ 9631 __ cmpl($p$$Register, $q$$Register); 9632 __ setb(Assembler::less, $dst$$Register); 9633 __ movzbl($dst$$Register, $dst$$Register); 9634 __ negl($dst$$Register); 9635 %} 9636 ins_pipe(pipe_slow); 9637 %} 9638 9639 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9640 %{ 9641 match(Set dst (CmpLTMask dst zero)); 9642 effect(KILL cr); 9643 9644 ins_cost(100); 9645 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9646 ins_encode %{ 9647 __ sarl($dst$$Register, 31); 9648 %} 9649 ins_pipe(ialu_reg); 9650 %} 9651 9652 /* Better to save a register than avoid a branch */ 9653 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9654 %{ 9655 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9656 effect(KILL cr); 9657 ins_cost(300); 9658 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9659 "jge done\n\t" 9660 "addl $p,$y\n" 9661 "done: " %} 9662 ins_encode %{ 9663 Register Rp = $p$$Register; 9664 Register Rq = $q$$Register; 9665 Register Ry = $y$$Register; 9666 Label done; 9667 __ subl(Rp, Rq); 9668 __ jccb(Assembler::greaterEqual, done); 9669 __ addl(Rp, Ry); 9670 __ bind(done); 9671 %} 9672 ins_pipe(pipe_cmplt); 9673 %} 9674 9675 /* Better to save a register than avoid a branch */ 9676 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9677 %{ 9678 match(Set y (AndI (CmpLTMask p q) y)); 9679 effect(KILL cr); 9680 9681 ins_cost(300); 9682 9683 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9684 "jlt done\n\t" 9685 "xorl $y, $y\n" 9686 "done: " %} 9687 ins_encode %{ 9688 Register Rp = $p$$Register; 9689 Register Rq = $q$$Register; 9690 Register Ry = $y$$Register; 9691 Label done; 9692 __ cmpl(Rp, Rq); 9693 __ jccb(Assembler::less, done); 9694 __ xorl(Ry, Ry); 9695 __ bind(done); 9696 %} 9697 ins_pipe(pipe_cmplt); 9698 %} 9699 9700 9701 //---------- FP Instructions------------------------------------------------ 9702 9703 // Really expensive, avoid 9704 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9705 %{ 9706 match(Set cr (CmpF src1 src2)); 9707 9708 ins_cost(500); 9709 format %{ "ucomiss $src1, $src2\n\t" 9710 "jnp,s exit\n\t" 9711 "pushfq\t# saw NaN, set CF\n\t" 9712 "andq [rsp], #0xffffff2b\n\t" 9713 "popfq\n" 9714 "exit:" %} 9715 ins_encode %{ 9716 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9717 emit_cmpfp_fixup(masm); 9718 %} 9719 ins_pipe(pipe_slow); 9720 %} 9721 9722 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9723 match(Set cr (CmpF src1 src2)); 9724 9725 ins_cost(100); 9726 format %{ "ucomiss $src1, $src2" %} 9727 ins_encode %{ 9728 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9729 %} 9730 ins_pipe(pipe_slow); 9731 %} 9732 9733 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9734 match(Set cr (CmpF src1 (LoadF src2))); 9735 9736 ins_cost(100); 9737 format %{ "ucomiss $src1, $src2" %} 9738 ins_encode %{ 9739 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9740 %} 9741 ins_pipe(pipe_slow); 9742 %} 9743 9744 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9745 match(Set cr (CmpF src con)); 9746 ins_cost(100); 9747 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9748 ins_encode %{ 9749 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9750 %} 9751 ins_pipe(pipe_slow); 9752 %} 9753 9754 // Really expensive, avoid 9755 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9756 %{ 9757 match(Set cr (CmpD src1 src2)); 9758 9759 ins_cost(500); 9760 format %{ "ucomisd $src1, $src2\n\t" 9761 "jnp,s exit\n\t" 9762 "pushfq\t# saw NaN, set CF\n\t" 9763 "andq [rsp], #0xffffff2b\n\t" 9764 "popfq\n" 9765 "exit:" %} 9766 ins_encode %{ 9767 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9768 emit_cmpfp_fixup(masm); 9769 %} 9770 ins_pipe(pipe_slow); 9771 %} 9772 9773 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9774 match(Set cr (CmpD src1 src2)); 9775 9776 ins_cost(100); 9777 format %{ "ucomisd $src1, $src2 test" %} 9778 ins_encode %{ 9779 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9780 %} 9781 ins_pipe(pipe_slow); 9782 %} 9783 9784 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9785 match(Set cr (CmpD src1 (LoadD src2))); 9786 9787 ins_cost(100); 9788 format %{ "ucomisd $src1, $src2" %} 9789 ins_encode %{ 9790 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9791 %} 9792 ins_pipe(pipe_slow); 9793 %} 9794 9795 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9796 match(Set cr (CmpD src con)); 9797 ins_cost(100); 9798 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9799 ins_encode %{ 9800 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9801 %} 9802 ins_pipe(pipe_slow); 9803 %} 9804 9805 // Compare into -1,0,1 9806 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9807 %{ 9808 match(Set dst (CmpF3 src1 src2)); 9809 effect(KILL cr); 9810 9811 ins_cost(275); 9812 format %{ "ucomiss $src1, $src2\n\t" 9813 "movl $dst, #-1\n\t" 9814 "jp,s done\n\t" 9815 "jb,s done\n\t" 9816 "setne $dst\n\t" 9817 "movzbl $dst, $dst\n" 9818 "done:" %} 9819 ins_encode %{ 9820 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9821 emit_cmpfp3(masm, $dst$$Register); 9822 %} 9823 ins_pipe(pipe_slow); 9824 %} 9825 9826 // Compare into -1,0,1 9827 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9828 %{ 9829 match(Set dst (CmpF3 src1 (LoadF src2))); 9830 effect(KILL cr); 9831 9832 ins_cost(275); 9833 format %{ "ucomiss $src1, $src2\n\t" 9834 "movl $dst, #-1\n\t" 9835 "jp,s done\n\t" 9836 "jb,s done\n\t" 9837 "setne $dst\n\t" 9838 "movzbl $dst, $dst\n" 9839 "done:" %} 9840 ins_encode %{ 9841 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9842 emit_cmpfp3(masm, $dst$$Register); 9843 %} 9844 ins_pipe(pipe_slow); 9845 %} 9846 9847 // Compare into -1,0,1 9848 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9849 match(Set dst (CmpF3 src con)); 9850 effect(KILL cr); 9851 9852 ins_cost(275); 9853 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9854 "movl $dst, #-1\n\t" 9855 "jp,s done\n\t" 9856 "jb,s done\n\t" 9857 "setne $dst\n\t" 9858 "movzbl $dst, $dst\n" 9859 "done:" %} 9860 ins_encode %{ 9861 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9862 emit_cmpfp3(masm, $dst$$Register); 9863 %} 9864 ins_pipe(pipe_slow); 9865 %} 9866 9867 // Compare into -1,0,1 9868 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9869 %{ 9870 match(Set dst (CmpD3 src1 src2)); 9871 effect(KILL cr); 9872 9873 ins_cost(275); 9874 format %{ "ucomisd $src1, $src2\n\t" 9875 "movl $dst, #-1\n\t" 9876 "jp,s done\n\t" 9877 "jb,s done\n\t" 9878 "setne $dst\n\t" 9879 "movzbl $dst, $dst\n" 9880 "done:" %} 9881 ins_encode %{ 9882 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9883 emit_cmpfp3(masm, $dst$$Register); 9884 %} 9885 ins_pipe(pipe_slow); 9886 %} 9887 9888 // Compare into -1,0,1 9889 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9890 %{ 9891 match(Set dst (CmpD3 src1 (LoadD src2))); 9892 effect(KILL cr); 9893 9894 ins_cost(275); 9895 format %{ "ucomisd $src1, $src2\n\t" 9896 "movl $dst, #-1\n\t" 9897 "jp,s done\n\t" 9898 "jb,s done\n\t" 9899 "setne $dst\n\t" 9900 "movzbl $dst, $dst\n" 9901 "done:" %} 9902 ins_encode %{ 9903 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9904 emit_cmpfp3(masm, $dst$$Register); 9905 %} 9906 ins_pipe(pipe_slow); 9907 %} 9908 9909 // Compare into -1,0,1 9910 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9911 match(Set dst (CmpD3 src con)); 9912 effect(KILL cr); 9913 9914 ins_cost(275); 9915 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9916 "movl $dst, #-1\n\t" 9917 "jp,s done\n\t" 9918 "jb,s done\n\t" 9919 "setne $dst\n\t" 9920 "movzbl $dst, $dst\n" 9921 "done:" %} 9922 ins_encode %{ 9923 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9924 emit_cmpfp3(masm, $dst$$Register); 9925 %} 9926 ins_pipe(pipe_slow); 9927 %} 9928 9929 //----------Arithmetic Conversion Instructions--------------------------------- 9930 9931 instruct convF2D_reg_reg(regD dst, regF src) 9932 %{ 9933 match(Set dst (ConvF2D src)); 9934 9935 format %{ "cvtss2sd $dst, $src" %} 9936 ins_encode %{ 9937 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9938 %} 9939 ins_pipe(pipe_slow); // XXX 9940 %} 9941 9942 instruct convF2D_reg_mem(regD dst, memory src) 9943 %{ 9944 predicate(UseAVX == 0); 9945 match(Set dst (ConvF2D (LoadF src))); 9946 9947 format %{ "cvtss2sd $dst, $src" %} 9948 ins_encode %{ 9949 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9950 %} 9951 ins_pipe(pipe_slow); // XXX 9952 %} 9953 9954 instruct convD2F_reg_reg(regF dst, regD src) 9955 %{ 9956 match(Set dst (ConvD2F src)); 9957 9958 format %{ "cvtsd2ss $dst, $src" %} 9959 ins_encode %{ 9960 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9961 %} 9962 ins_pipe(pipe_slow); // XXX 9963 %} 9964 9965 instruct convD2F_reg_mem(regF dst, memory src) 9966 %{ 9967 predicate(UseAVX == 0); 9968 match(Set dst (ConvD2F (LoadD src))); 9969 9970 format %{ "cvtsd2ss $dst, $src" %} 9971 ins_encode %{ 9972 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9973 %} 9974 ins_pipe(pipe_slow); // XXX 9975 %} 9976 9977 // XXX do mem variants 9978 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9979 %{ 9980 match(Set dst (ConvF2I src)); 9981 effect(KILL cr); 9982 format %{ "convert_f2i $dst, $src" %} 9983 ins_encode %{ 9984 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 9985 %} 9986 ins_pipe(pipe_slow); 9987 %} 9988 9989 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9990 %{ 9991 match(Set dst (ConvF2L src)); 9992 effect(KILL cr); 9993 format %{ "convert_f2l $dst, $src"%} 9994 ins_encode %{ 9995 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 9996 %} 9997 ins_pipe(pipe_slow); 9998 %} 9999 10000 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10001 %{ 10002 match(Set dst (ConvD2I src)); 10003 effect(KILL cr); 10004 format %{ "convert_d2i $dst, $src"%} 10005 ins_encode %{ 10006 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10007 %} 10008 ins_pipe(pipe_slow); 10009 %} 10010 10011 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10012 %{ 10013 match(Set dst (ConvD2L src)); 10014 effect(KILL cr); 10015 format %{ "convert_d2l $dst, $src"%} 10016 ins_encode %{ 10017 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10018 %} 10019 ins_pipe(pipe_slow); 10020 %} 10021 10022 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10023 %{ 10024 match(Set dst (RoundD src)); 10025 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10026 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10027 ins_encode %{ 10028 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10029 %} 10030 ins_pipe(pipe_slow); 10031 %} 10032 10033 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10034 %{ 10035 match(Set dst (RoundF src)); 10036 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10037 format %{ "round_float $dst,$src" %} 10038 ins_encode %{ 10039 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10040 %} 10041 ins_pipe(pipe_slow); 10042 %} 10043 10044 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10045 %{ 10046 predicate(!UseXmmI2F); 10047 match(Set dst (ConvI2F src)); 10048 10049 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10050 ins_encode %{ 10051 if (UseAVX > 0) { 10052 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10053 } 10054 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10055 %} 10056 ins_pipe(pipe_slow); // XXX 10057 %} 10058 10059 instruct convI2F_reg_mem(regF dst, memory src) 10060 %{ 10061 predicate(UseAVX == 0); 10062 match(Set dst (ConvI2F (LoadI src))); 10063 10064 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10065 ins_encode %{ 10066 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10067 %} 10068 ins_pipe(pipe_slow); // XXX 10069 %} 10070 10071 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10072 %{ 10073 predicate(!UseXmmI2D); 10074 match(Set dst (ConvI2D src)); 10075 10076 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10077 ins_encode %{ 10078 if (UseAVX > 0) { 10079 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10080 } 10081 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10082 %} 10083 ins_pipe(pipe_slow); // XXX 10084 %} 10085 10086 instruct convI2D_reg_mem(regD dst, memory src) 10087 %{ 10088 predicate(UseAVX == 0); 10089 match(Set dst (ConvI2D (LoadI src))); 10090 10091 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10092 ins_encode %{ 10093 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10094 %} 10095 ins_pipe(pipe_slow); // XXX 10096 %} 10097 10098 instruct convXI2F_reg(regF dst, rRegI src) 10099 %{ 10100 predicate(UseXmmI2F); 10101 match(Set dst (ConvI2F src)); 10102 10103 format %{ "movdl $dst, $src\n\t" 10104 "cvtdq2psl $dst, $dst\t# i2f" %} 10105 ins_encode %{ 10106 __ movdl($dst$$XMMRegister, $src$$Register); 10107 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10108 %} 10109 ins_pipe(pipe_slow); // XXX 10110 %} 10111 10112 instruct convXI2D_reg(regD dst, rRegI src) 10113 %{ 10114 predicate(UseXmmI2D); 10115 match(Set dst (ConvI2D src)); 10116 10117 format %{ "movdl $dst, $src\n\t" 10118 "cvtdq2pdl $dst, $dst\t# i2d" %} 10119 ins_encode %{ 10120 __ movdl($dst$$XMMRegister, $src$$Register); 10121 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10122 %} 10123 ins_pipe(pipe_slow); // XXX 10124 %} 10125 10126 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10127 %{ 10128 match(Set dst (ConvL2F src)); 10129 10130 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10131 ins_encode %{ 10132 if (UseAVX > 0) { 10133 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10134 } 10135 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10136 %} 10137 ins_pipe(pipe_slow); // XXX 10138 %} 10139 10140 instruct convL2F_reg_mem(regF dst, memory src) 10141 %{ 10142 predicate(UseAVX == 0); 10143 match(Set dst (ConvL2F (LoadL src))); 10144 10145 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10146 ins_encode %{ 10147 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10148 %} 10149 ins_pipe(pipe_slow); // XXX 10150 %} 10151 10152 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10153 %{ 10154 match(Set dst (ConvL2D src)); 10155 10156 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10157 ins_encode %{ 10158 if (UseAVX > 0) { 10159 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10160 } 10161 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10162 %} 10163 ins_pipe(pipe_slow); // XXX 10164 %} 10165 10166 instruct convL2D_reg_mem(regD dst, memory src) 10167 %{ 10168 predicate(UseAVX == 0); 10169 match(Set dst (ConvL2D (LoadL src))); 10170 10171 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10172 ins_encode %{ 10173 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10174 %} 10175 ins_pipe(pipe_slow); // XXX 10176 %} 10177 10178 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10179 %{ 10180 match(Set dst (ConvI2L src)); 10181 10182 ins_cost(125); 10183 format %{ "movslq $dst, $src\t# i2l" %} 10184 ins_encode %{ 10185 __ movslq($dst$$Register, $src$$Register); 10186 %} 10187 ins_pipe(ialu_reg_reg); 10188 %} 10189 10190 // Zero-extend convert int to long 10191 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10192 %{ 10193 match(Set dst (AndL (ConvI2L src) mask)); 10194 10195 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10196 ins_encode %{ 10197 if ($dst$$reg != $src$$reg) { 10198 __ movl($dst$$Register, $src$$Register); 10199 } 10200 %} 10201 ins_pipe(ialu_reg_reg); 10202 %} 10203 10204 // Zero-extend convert int to long 10205 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10206 %{ 10207 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10208 10209 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10210 ins_encode %{ 10211 __ movl($dst$$Register, $src$$Address); 10212 %} 10213 ins_pipe(ialu_reg_mem); 10214 %} 10215 10216 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10217 %{ 10218 match(Set dst (AndL src mask)); 10219 10220 format %{ "movl $dst, $src\t# zero-extend long" %} 10221 ins_encode %{ 10222 __ movl($dst$$Register, $src$$Register); 10223 %} 10224 ins_pipe(ialu_reg_reg); 10225 %} 10226 10227 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10228 %{ 10229 match(Set dst (ConvL2I src)); 10230 10231 format %{ "movl $dst, $src\t# l2i" %} 10232 ins_encode %{ 10233 __ movl($dst$$Register, $src$$Register); 10234 %} 10235 ins_pipe(ialu_reg_reg); 10236 %} 10237 10238 10239 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10240 match(Set dst (MoveF2I src)); 10241 effect(DEF dst, USE src); 10242 10243 ins_cost(125); 10244 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10245 ins_encode %{ 10246 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10247 %} 10248 ins_pipe(ialu_reg_mem); 10249 %} 10250 10251 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10252 match(Set dst (MoveI2F src)); 10253 effect(DEF dst, USE src); 10254 10255 ins_cost(125); 10256 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10257 ins_encode %{ 10258 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10259 %} 10260 ins_pipe(pipe_slow); 10261 %} 10262 10263 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10264 match(Set dst (MoveD2L src)); 10265 effect(DEF dst, USE src); 10266 10267 ins_cost(125); 10268 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10269 ins_encode %{ 10270 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10271 %} 10272 ins_pipe(ialu_reg_mem); 10273 %} 10274 10275 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10276 predicate(!UseXmmLoadAndClearUpper); 10277 match(Set dst (MoveL2D src)); 10278 effect(DEF dst, USE src); 10279 10280 ins_cost(125); 10281 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10282 ins_encode %{ 10283 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10284 %} 10285 ins_pipe(pipe_slow); 10286 %} 10287 10288 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10289 predicate(UseXmmLoadAndClearUpper); 10290 match(Set dst (MoveL2D src)); 10291 effect(DEF dst, USE src); 10292 10293 ins_cost(125); 10294 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10295 ins_encode %{ 10296 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10297 %} 10298 ins_pipe(pipe_slow); 10299 %} 10300 10301 10302 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10303 match(Set dst (MoveF2I src)); 10304 effect(DEF dst, USE src); 10305 10306 ins_cost(95); // XXX 10307 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10308 ins_encode %{ 10309 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10310 %} 10311 ins_pipe(pipe_slow); 10312 %} 10313 10314 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10315 match(Set dst (MoveI2F src)); 10316 effect(DEF dst, USE src); 10317 10318 ins_cost(100); 10319 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10320 ins_encode %{ 10321 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10322 %} 10323 ins_pipe( ialu_mem_reg ); 10324 %} 10325 10326 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10327 match(Set dst (MoveD2L src)); 10328 effect(DEF dst, USE src); 10329 10330 ins_cost(95); // XXX 10331 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10332 ins_encode %{ 10333 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10334 %} 10335 ins_pipe(pipe_slow); 10336 %} 10337 10338 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10339 match(Set dst (MoveL2D src)); 10340 effect(DEF dst, USE src); 10341 10342 ins_cost(100); 10343 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10344 ins_encode %{ 10345 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10346 %} 10347 ins_pipe(ialu_mem_reg); 10348 %} 10349 10350 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10351 match(Set dst (MoveF2I src)); 10352 effect(DEF dst, USE src); 10353 ins_cost(85); 10354 format %{ "movd $dst,$src\t# MoveF2I" %} 10355 ins_encode %{ 10356 __ movdl($dst$$Register, $src$$XMMRegister); 10357 %} 10358 ins_pipe( pipe_slow ); 10359 %} 10360 10361 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10362 match(Set dst (MoveD2L src)); 10363 effect(DEF dst, USE src); 10364 ins_cost(85); 10365 format %{ "movd $dst,$src\t# MoveD2L" %} 10366 ins_encode %{ 10367 __ movdq($dst$$Register, $src$$XMMRegister); 10368 %} 10369 ins_pipe( pipe_slow ); 10370 %} 10371 10372 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10373 match(Set dst (MoveI2F src)); 10374 effect(DEF dst, USE src); 10375 ins_cost(100); 10376 format %{ "movd $dst,$src\t# MoveI2F" %} 10377 ins_encode %{ 10378 __ movdl($dst$$XMMRegister, $src$$Register); 10379 %} 10380 ins_pipe( pipe_slow ); 10381 %} 10382 10383 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10384 match(Set dst (MoveL2D src)); 10385 effect(DEF dst, USE src); 10386 ins_cost(100); 10387 format %{ "movd $dst,$src\t# MoveL2D" %} 10388 ins_encode %{ 10389 __ movdq($dst$$XMMRegister, $src$$Register); 10390 %} 10391 ins_pipe( pipe_slow ); 10392 %} 10393 10394 // Fast clearing of an array 10395 // Small non-constant lenght ClearArray for non-AVX512 targets. 10396 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10397 Universe dummy, rFlagsReg cr) 10398 %{ 10399 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 10400 match(Set dummy (ClearArray cnt base)); 10401 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10402 10403 format %{ $$template 10404 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10405 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10406 $$emit$$"jg LARGE\n\t" 10407 $$emit$$"dec rcx\n\t" 10408 $$emit$$"js DONE\t# Zero length\n\t" 10409 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10410 $$emit$$"dec rcx\n\t" 10411 $$emit$$"jge LOOP\n\t" 10412 $$emit$$"jmp DONE\n\t" 10413 $$emit$$"# LARGE:\n\t" 10414 if (UseFastStosb) { 10415 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10416 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10417 } else if (UseXMMForObjInit) { 10418 $$emit$$"mov rdi,rax\n\t" 10419 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10420 $$emit$$"jmpq L_zero_64_bytes\n\t" 10421 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10422 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10423 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10424 $$emit$$"add 0x40,rax\n\t" 10425 $$emit$$"# L_zero_64_bytes:\n\t" 10426 $$emit$$"sub 0x8,rcx\n\t" 10427 $$emit$$"jge L_loop\n\t" 10428 $$emit$$"add 0x4,rcx\n\t" 10429 $$emit$$"jl L_tail\n\t" 10430 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10431 $$emit$$"add 0x20,rax\n\t" 10432 $$emit$$"sub 0x4,rcx\n\t" 10433 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10434 $$emit$$"add 0x4,rcx\n\t" 10435 $$emit$$"jle L_end\n\t" 10436 $$emit$$"dec rcx\n\t" 10437 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10438 $$emit$$"vmovq xmm0,(rax)\n\t" 10439 $$emit$$"add 0x8,rax\n\t" 10440 $$emit$$"dec rcx\n\t" 10441 $$emit$$"jge L_sloop\n\t" 10442 $$emit$$"# L_end:\n\t" 10443 } else { 10444 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10445 } 10446 $$emit$$"# DONE" 10447 %} 10448 ins_encode %{ 10449 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10450 $tmp$$XMMRegister, false, knoreg); 10451 %} 10452 ins_pipe(pipe_slow); 10453 %} 10454 10455 // Small non-constant length ClearArray for AVX512 targets. 10456 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10457 Universe dummy, rFlagsReg cr) 10458 %{ 10459 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 10460 match(Set dummy (ClearArray cnt base)); 10461 ins_cost(125); 10462 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10463 10464 format %{ $$template 10465 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10466 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10467 $$emit$$"jg LARGE\n\t" 10468 $$emit$$"dec rcx\n\t" 10469 $$emit$$"js DONE\t# Zero length\n\t" 10470 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10471 $$emit$$"dec rcx\n\t" 10472 $$emit$$"jge LOOP\n\t" 10473 $$emit$$"jmp DONE\n\t" 10474 $$emit$$"# LARGE:\n\t" 10475 if (UseFastStosb) { 10476 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10477 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10478 } else if (UseXMMForObjInit) { 10479 $$emit$$"mov rdi,rax\n\t" 10480 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10481 $$emit$$"jmpq L_zero_64_bytes\n\t" 10482 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10483 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10484 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10485 $$emit$$"add 0x40,rax\n\t" 10486 $$emit$$"# L_zero_64_bytes:\n\t" 10487 $$emit$$"sub 0x8,rcx\n\t" 10488 $$emit$$"jge L_loop\n\t" 10489 $$emit$$"add 0x4,rcx\n\t" 10490 $$emit$$"jl L_tail\n\t" 10491 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10492 $$emit$$"add 0x20,rax\n\t" 10493 $$emit$$"sub 0x4,rcx\n\t" 10494 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10495 $$emit$$"add 0x4,rcx\n\t" 10496 $$emit$$"jle L_end\n\t" 10497 $$emit$$"dec rcx\n\t" 10498 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10499 $$emit$$"vmovq xmm0,(rax)\n\t" 10500 $$emit$$"add 0x8,rax\n\t" 10501 $$emit$$"dec rcx\n\t" 10502 $$emit$$"jge L_sloop\n\t" 10503 $$emit$$"# L_end:\n\t" 10504 } else { 10505 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10506 } 10507 $$emit$$"# DONE" 10508 %} 10509 ins_encode %{ 10510 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10511 $tmp$$XMMRegister, false, $ktmp$$KRegister); 10512 %} 10513 ins_pipe(pipe_slow); 10514 %} 10515 10516 // Large non-constant length ClearArray for non-AVX512 targets. 10517 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10518 Universe dummy, rFlagsReg cr) 10519 %{ 10520 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 10521 match(Set dummy (ClearArray cnt base)); 10522 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10523 10524 format %{ $$template 10525 if (UseFastStosb) { 10526 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10527 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10528 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10529 } else if (UseXMMForObjInit) { 10530 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10531 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10532 $$emit$$"jmpq L_zero_64_bytes\n\t" 10533 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10534 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10535 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10536 $$emit$$"add 0x40,rax\n\t" 10537 $$emit$$"# L_zero_64_bytes:\n\t" 10538 $$emit$$"sub 0x8,rcx\n\t" 10539 $$emit$$"jge L_loop\n\t" 10540 $$emit$$"add 0x4,rcx\n\t" 10541 $$emit$$"jl L_tail\n\t" 10542 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10543 $$emit$$"add 0x20,rax\n\t" 10544 $$emit$$"sub 0x4,rcx\n\t" 10545 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10546 $$emit$$"add 0x4,rcx\n\t" 10547 $$emit$$"jle L_end\n\t" 10548 $$emit$$"dec rcx\n\t" 10549 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10550 $$emit$$"vmovq xmm0,(rax)\n\t" 10551 $$emit$$"add 0x8,rax\n\t" 10552 $$emit$$"dec rcx\n\t" 10553 $$emit$$"jge L_sloop\n\t" 10554 $$emit$$"# L_end:\n\t" 10555 } else { 10556 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10557 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10558 } 10559 %} 10560 ins_encode %{ 10561 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10562 $tmp$$XMMRegister, true, knoreg); 10563 %} 10564 ins_pipe(pipe_slow); 10565 %} 10566 10567 // Large non-constant length ClearArray for AVX512 targets. 10568 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10569 Universe dummy, rFlagsReg cr) 10570 %{ 10571 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 10572 match(Set dummy (ClearArray cnt base)); 10573 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10574 10575 format %{ $$template 10576 if (UseFastStosb) { 10577 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10578 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10579 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10580 } else if (UseXMMForObjInit) { 10581 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10582 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10583 $$emit$$"jmpq L_zero_64_bytes\n\t" 10584 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10585 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10586 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10587 $$emit$$"add 0x40,rax\n\t" 10588 $$emit$$"# L_zero_64_bytes:\n\t" 10589 $$emit$$"sub 0x8,rcx\n\t" 10590 $$emit$$"jge L_loop\n\t" 10591 $$emit$$"add 0x4,rcx\n\t" 10592 $$emit$$"jl L_tail\n\t" 10593 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10594 $$emit$$"add 0x20,rax\n\t" 10595 $$emit$$"sub 0x4,rcx\n\t" 10596 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10597 $$emit$$"add 0x4,rcx\n\t" 10598 $$emit$$"jle L_end\n\t" 10599 $$emit$$"dec rcx\n\t" 10600 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10601 $$emit$$"vmovq xmm0,(rax)\n\t" 10602 $$emit$$"add 0x8,rax\n\t" 10603 $$emit$$"dec rcx\n\t" 10604 $$emit$$"jge L_sloop\n\t" 10605 $$emit$$"# L_end:\n\t" 10606 } else { 10607 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10608 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10609 } 10610 %} 10611 ins_encode %{ 10612 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10613 $tmp$$XMMRegister, true, $ktmp$$KRegister); 10614 %} 10615 ins_pipe(pipe_slow); 10616 %} 10617 10618 // Small constant length ClearArray for AVX512 targets. 10619 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 10620 %{ 10621 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 10622 match(Set dummy (ClearArray cnt base)); 10623 ins_cost(100); 10624 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 10625 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10626 ins_encode %{ 10627 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10628 %} 10629 ins_pipe(pipe_slow); 10630 %} 10631 10632 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10633 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10634 %{ 10635 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10636 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10637 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10638 10639 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10640 ins_encode %{ 10641 __ string_compare($str1$$Register, $str2$$Register, 10642 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10643 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10644 %} 10645 ins_pipe( pipe_slow ); 10646 %} 10647 10648 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10649 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10650 %{ 10651 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10652 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10653 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10654 10655 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10656 ins_encode %{ 10657 __ string_compare($str1$$Register, $str2$$Register, 10658 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10659 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10660 %} 10661 ins_pipe( pipe_slow ); 10662 %} 10663 10664 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10665 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10666 %{ 10667 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10668 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10669 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10670 10671 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10672 ins_encode %{ 10673 __ string_compare($str1$$Register, $str2$$Register, 10674 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10675 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10676 %} 10677 ins_pipe( pipe_slow ); 10678 %} 10679 10680 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10681 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10682 %{ 10683 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10684 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10685 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10686 10687 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10688 ins_encode %{ 10689 __ string_compare($str1$$Register, $str2$$Register, 10690 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10691 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10692 %} 10693 ins_pipe( pipe_slow ); 10694 %} 10695 10696 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10697 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10698 %{ 10699 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10700 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10701 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10702 10703 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10704 ins_encode %{ 10705 __ string_compare($str1$$Register, $str2$$Register, 10706 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10707 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 10708 %} 10709 ins_pipe( pipe_slow ); 10710 %} 10711 10712 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10713 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10714 %{ 10715 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10716 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10717 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10718 10719 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10720 ins_encode %{ 10721 __ string_compare($str1$$Register, $str2$$Register, 10722 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10723 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 10724 %} 10725 ins_pipe( pipe_slow ); 10726 %} 10727 10728 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10729 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10730 %{ 10731 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10732 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10733 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10734 10735 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10736 ins_encode %{ 10737 __ string_compare($str2$$Register, $str1$$Register, 10738 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10739 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 10740 %} 10741 ins_pipe( pipe_slow ); 10742 %} 10743 10744 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10745 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10746 %{ 10747 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10748 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10749 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10750 10751 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10752 ins_encode %{ 10753 __ string_compare($str2$$Register, $str1$$Register, 10754 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10755 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 10756 %} 10757 ins_pipe( pipe_slow ); 10758 %} 10759 10760 // fast search of substring with known size. 10761 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10762 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10763 %{ 10764 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10765 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10766 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10767 10768 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10769 ins_encode %{ 10770 int icnt2 = (int)$int_cnt2$$constant; 10771 if (icnt2 >= 16) { 10772 // IndexOf for constant substrings with size >= 16 elements 10773 // which don't need to be loaded through stack. 10774 __ string_indexofC8($str1$$Register, $str2$$Register, 10775 $cnt1$$Register, $cnt2$$Register, 10776 icnt2, $result$$Register, 10777 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10778 } else { 10779 // Small strings are loaded through stack if they cross page boundary. 10780 __ string_indexof($str1$$Register, $str2$$Register, 10781 $cnt1$$Register, $cnt2$$Register, 10782 icnt2, $result$$Register, 10783 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10784 } 10785 %} 10786 ins_pipe( pipe_slow ); 10787 %} 10788 10789 // fast search of substring with known size. 10790 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10791 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10792 %{ 10793 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10794 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10795 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10796 10797 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10798 ins_encode %{ 10799 int icnt2 = (int)$int_cnt2$$constant; 10800 if (icnt2 >= 8) { 10801 // IndexOf for constant substrings with size >= 8 elements 10802 // which don't need to be loaded through stack. 10803 __ string_indexofC8($str1$$Register, $str2$$Register, 10804 $cnt1$$Register, $cnt2$$Register, 10805 icnt2, $result$$Register, 10806 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10807 } else { 10808 // Small strings are loaded through stack if they cross page boundary. 10809 __ string_indexof($str1$$Register, $str2$$Register, 10810 $cnt1$$Register, $cnt2$$Register, 10811 icnt2, $result$$Register, 10812 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10813 } 10814 %} 10815 ins_pipe( pipe_slow ); 10816 %} 10817 10818 // fast search of substring with known size. 10819 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10820 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10821 %{ 10822 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10823 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10824 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10825 10826 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10827 ins_encode %{ 10828 int icnt2 = (int)$int_cnt2$$constant; 10829 if (icnt2 >= 8) { 10830 // IndexOf for constant substrings with size >= 8 elements 10831 // which don't need to be loaded through stack. 10832 __ string_indexofC8($str1$$Register, $str2$$Register, 10833 $cnt1$$Register, $cnt2$$Register, 10834 icnt2, $result$$Register, 10835 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10836 } else { 10837 // Small strings are loaded through stack if they cross page boundary. 10838 __ string_indexof($str1$$Register, $str2$$Register, 10839 $cnt1$$Register, $cnt2$$Register, 10840 icnt2, $result$$Register, 10841 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10842 } 10843 %} 10844 ins_pipe( pipe_slow ); 10845 %} 10846 10847 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10848 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10849 %{ 10850 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10851 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10852 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10853 10854 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10855 ins_encode %{ 10856 __ string_indexof($str1$$Register, $str2$$Register, 10857 $cnt1$$Register, $cnt2$$Register, 10858 (-1), $result$$Register, 10859 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10860 %} 10861 ins_pipe( pipe_slow ); 10862 %} 10863 10864 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10865 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10866 %{ 10867 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10868 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10869 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10870 10871 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10872 ins_encode %{ 10873 __ string_indexof($str1$$Register, $str2$$Register, 10874 $cnt1$$Register, $cnt2$$Register, 10875 (-1), $result$$Register, 10876 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10877 %} 10878 ins_pipe( pipe_slow ); 10879 %} 10880 10881 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10882 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10883 %{ 10884 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10885 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10886 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10887 10888 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10889 ins_encode %{ 10890 __ string_indexof($str1$$Register, $str2$$Register, 10891 $cnt1$$Register, $cnt2$$Register, 10892 (-1), $result$$Register, 10893 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10894 %} 10895 ins_pipe( pipe_slow ); 10896 %} 10897 10898 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10899 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10900 %{ 10901 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 10902 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10903 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10904 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10905 ins_encode %{ 10906 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10907 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10908 %} 10909 ins_pipe( pipe_slow ); 10910 %} 10911 10912 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10913 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10914 %{ 10915 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 10916 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10917 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10918 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10919 ins_encode %{ 10920 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10921 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10922 %} 10923 ins_pipe( pipe_slow ); 10924 %} 10925 10926 // fast string equals 10927 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10928 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10929 %{ 10930 predicate(!VM_Version::supports_avx512vlbw()); 10931 match(Set result (StrEquals (Binary str1 str2) cnt)); 10932 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10933 10934 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10935 ins_encode %{ 10936 __ arrays_equals(false, $str1$$Register, $str2$$Register, 10937 $cnt$$Register, $result$$Register, $tmp3$$Register, 10938 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 10939 %} 10940 ins_pipe( pipe_slow ); 10941 %} 10942 10943 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10944 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 10945 %{ 10946 predicate(VM_Version::supports_avx512vlbw()); 10947 match(Set result (StrEquals (Binary str1 str2) cnt)); 10948 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10949 10950 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10951 ins_encode %{ 10952 __ arrays_equals(false, $str1$$Register, $str2$$Register, 10953 $cnt$$Register, $result$$Register, $tmp3$$Register, 10954 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 10955 %} 10956 ins_pipe( pipe_slow ); 10957 %} 10958 10959 // fast array equals 10960 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10961 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10962 %{ 10963 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10964 match(Set result (AryEq ary1 ary2)); 10965 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10966 10967 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10968 ins_encode %{ 10969 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 10970 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10971 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 10972 %} 10973 ins_pipe( pipe_slow ); 10974 %} 10975 10976 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10977 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10978 %{ 10979 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10980 match(Set result (AryEq ary1 ary2)); 10981 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10982 10983 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10984 ins_encode %{ 10985 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 10986 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10987 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 10988 %} 10989 ins_pipe( pipe_slow ); 10990 %} 10991 10992 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10993 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10994 %{ 10995 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 10996 match(Set result (AryEq ary1 ary2)); 10997 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10998 10999 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11000 ins_encode %{ 11001 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11002 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11003 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11004 %} 11005 ins_pipe( pipe_slow ); 11006 %} 11007 11008 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11009 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11010 %{ 11011 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11012 match(Set result (AryEq ary1 ary2)); 11013 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11014 11015 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11016 ins_encode %{ 11017 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11018 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11019 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11020 %} 11021 ins_pipe( pipe_slow ); 11022 %} 11023 11024 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11025 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11026 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11027 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11028 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11029 %{ 11030 predicate(UseAVX >= 2); 11031 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11032 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11033 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11034 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11035 USE basic_type, KILL cr); 11036 11037 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11038 ins_encode %{ 11039 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11040 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11041 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11042 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11043 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11044 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11045 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11046 %} 11047 ins_pipe( pipe_slow ); 11048 %} 11049 11050 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11051 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11052 %{ 11053 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11054 match(Set result (CountPositives ary1 len)); 11055 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11056 11057 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11058 ins_encode %{ 11059 __ count_positives($ary1$$Register, $len$$Register, 11060 $result$$Register, $tmp3$$Register, 11061 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11062 %} 11063 ins_pipe( pipe_slow ); 11064 %} 11065 11066 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11067 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11068 %{ 11069 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11070 match(Set result (CountPositives ary1 len)); 11071 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11072 11073 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11074 ins_encode %{ 11075 __ count_positives($ary1$$Register, $len$$Register, 11076 $result$$Register, $tmp3$$Register, 11077 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11078 %} 11079 ins_pipe( pipe_slow ); 11080 %} 11081 11082 // fast char[] to byte[] compression 11083 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11084 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11085 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11086 match(Set result (StrCompressedCopy src (Binary dst len))); 11087 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11088 USE_KILL len, KILL tmp5, KILL cr); 11089 11090 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11091 ins_encode %{ 11092 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11093 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11094 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11095 knoreg, knoreg); 11096 %} 11097 ins_pipe( pipe_slow ); 11098 %} 11099 11100 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11101 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11102 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11103 match(Set result (StrCompressedCopy src (Binary dst len))); 11104 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11105 USE_KILL len, KILL tmp5, KILL cr); 11106 11107 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11108 ins_encode %{ 11109 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11110 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11111 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11112 $ktmp1$$KRegister, $ktmp2$$KRegister); 11113 %} 11114 ins_pipe( pipe_slow ); 11115 %} 11116 // fast byte[] to char[] inflation 11117 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11118 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11119 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11120 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11121 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11122 11123 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11124 ins_encode %{ 11125 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11126 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11127 %} 11128 ins_pipe( pipe_slow ); 11129 %} 11130 11131 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11132 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11133 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11134 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11135 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11136 11137 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11138 ins_encode %{ 11139 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11140 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11141 %} 11142 ins_pipe( pipe_slow ); 11143 %} 11144 11145 // encode char[] to byte[] in ISO_8859_1 11146 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11147 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11148 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11149 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11150 match(Set result (EncodeISOArray src (Binary dst len))); 11151 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11152 11153 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11154 ins_encode %{ 11155 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11156 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11157 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11158 %} 11159 ins_pipe( pipe_slow ); 11160 %} 11161 11162 // encode char[] to byte[] in ASCII 11163 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11164 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11165 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11166 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11167 match(Set result (EncodeISOArray src (Binary dst len))); 11168 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11169 11170 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11171 ins_encode %{ 11172 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11173 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11174 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11175 %} 11176 ins_pipe( pipe_slow ); 11177 %} 11178 11179 //----------Overflow Math Instructions----------------------------------------- 11180 11181 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11182 %{ 11183 match(Set cr (OverflowAddI op1 op2)); 11184 effect(DEF cr, USE_KILL op1, USE op2); 11185 11186 format %{ "addl $op1, $op2\t# overflow check int" %} 11187 11188 ins_encode %{ 11189 __ addl($op1$$Register, $op2$$Register); 11190 %} 11191 ins_pipe(ialu_reg_reg); 11192 %} 11193 11194 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11195 %{ 11196 match(Set cr (OverflowAddI op1 op2)); 11197 effect(DEF cr, USE_KILL op1, USE op2); 11198 11199 format %{ "addl $op1, $op2\t# overflow check int" %} 11200 11201 ins_encode %{ 11202 __ addl($op1$$Register, $op2$$constant); 11203 %} 11204 ins_pipe(ialu_reg_reg); 11205 %} 11206 11207 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11208 %{ 11209 match(Set cr (OverflowAddL op1 op2)); 11210 effect(DEF cr, USE_KILL op1, USE op2); 11211 11212 format %{ "addq $op1, $op2\t# overflow check long" %} 11213 ins_encode %{ 11214 __ addq($op1$$Register, $op2$$Register); 11215 %} 11216 ins_pipe(ialu_reg_reg); 11217 %} 11218 11219 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11220 %{ 11221 match(Set cr (OverflowAddL op1 op2)); 11222 effect(DEF cr, USE_KILL op1, USE op2); 11223 11224 format %{ "addq $op1, $op2\t# overflow check long" %} 11225 ins_encode %{ 11226 __ addq($op1$$Register, $op2$$constant); 11227 %} 11228 ins_pipe(ialu_reg_reg); 11229 %} 11230 11231 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11232 %{ 11233 match(Set cr (OverflowSubI op1 op2)); 11234 11235 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11236 ins_encode %{ 11237 __ cmpl($op1$$Register, $op2$$Register); 11238 %} 11239 ins_pipe(ialu_reg_reg); 11240 %} 11241 11242 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11243 %{ 11244 match(Set cr (OverflowSubI op1 op2)); 11245 11246 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11247 ins_encode %{ 11248 __ cmpl($op1$$Register, $op2$$constant); 11249 %} 11250 ins_pipe(ialu_reg_reg); 11251 %} 11252 11253 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11254 %{ 11255 match(Set cr (OverflowSubL op1 op2)); 11256 11257 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11258 ins_encode %{ 11259 __ cmpq($op1$$Register, $op2$$Register); 11260 %} 11261 ins_pipe(ialu_reg_reg); 11262 %} 11263 11264 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11265 %{ 11266 match(Set cr (OverflowSubL op1 op2)); 11267 11268 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11269 ins_encode %{ 11270 __ cmpq($op1$$Register, $op2$$constant); 11271 %} 11272 ins_pipe(ialu_reg_reg); 11273 %} 11274 11275 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11276 %{ 11277 match(Set cr (OverflowSubI zero op2)); 11278 effect(DEF cr, USE_KILL op2); 11279 11280 format %{ "negl $op2\t# overflow check int" %} 11281 ins_encode %{ 11282 __ negl($op2$$Register); 11283 %} 11284 ins_pipe(ialu_reg_reg); 11285 %} 11286 11287 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11288 %{ 11289 match(Set cr (OverflowSubL zero op2)); 11290 effect(DEF cr, USE_KILL op2); 11291 11292 format %{ "negq $op2\t# overflow check long" %} 11293 ins_encode %{ 11294 __ negq($op2$$Register); 11295 %} 11296 ins_pipe(ialu_reg_reg); 11297 %} 11298 11299 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11300 %{ 11301 match(Set cr (OverflowMulI op1 op2)); 11302 effect(DEF cr, USE_KILL op1, USE op2); 11303 11304 format %{ "imull $op1, $op2\t# overflow check int" %} 11305 ins_encode %{ 11306 __ imull($op1$$Register, $op2$$Register); 11307 %} 11308 ins_pipe(ialu_reg_reg_alu0); 11309 %} 11310 11311 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11312 %{ 11313 match(Set cr (OverflowMulI op1 op2)); 11314 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11315 11316 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11317 ins_encode %{ 11318 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11319 %} 11320 ins_pipe(ialu_reg_reg_alu0); 11321 %} 11322 11323 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11324 %{ 11325 match(Set cr (OverflowMulL op1 op2)); 11326 effect(DEF cr, USE_KILL op1, USE op2); 11327 11328 format %{ "imulq $op1, $op2\t# overflow check long" %} 11329 ins_encode %{ 11330 __ imulq($op1$$Register, $op2$$Register); 11331 %} 11332 ins_pipe(ialu_reg_reg_alu0); 11333 %} 11334 11335 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11336 %{ 11337 match(Set cr (OverflowMulL op1 op2)); 11338 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11339 11340 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11341 ins_encode %{ 11342 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11343 %} 11344 ins_pipe(ialu_reg_reg_alu0); 11345 %} 11346 11347 11348 //----------Control Flow Instructions------------------------------------------ 11349 // Signed compare Instructions 11350 11351 // XXX more variants!! 11352 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11353 %{ 11354 match(Set cr (CmpI op1 op2)); 11355 effect(DEF cr, USE op1, USE op2); 11356 11357 format %{ "cmpl $op1, $op2" %} 11358 ins_encode %{ 11359 __ cmpl($op1$$Register, $op2$$Register); 11360 %} 11361 ins_pipe(ialu_cr_reg_reg); 11362 %} 11363 11364 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11365 %{ 11366 match(Set cr (CmpI op1 op2)); 11367 11368 format %{ "cmpl $op1, $op2" %} 11369 ins_encode %{ 11370 __ cmpl($op1$$Register, $op2$$constant); 11371 %} 11372 ins_pipe(ialu_cr_reg_imm); 11373 %} 11374 11375 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11376 %{ 11377 match(Set cr (CmpI op1 (LoadI op2))); 11378 11379 ins_cost(500); // XXX 11380 format %{ "cmpl $op1, $op2" %} 11381 ins_encode %{ 11382 __ cmpl($op1$$Register, $op2$$Address); 11383 %} 11384 ins_pipe(ialu_cr_reg_mem); 11385 %} 11386 11387 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11388 %{ 11389 match(Set cr (CmpI src zero)); 11390 11391 format %{ "testl $src, $src" %} 11392 ins_encode %{ 11393 __ testl($src$$Register, $src$$Register); 11394 %} 11395 ins_pipe(ialu_cr_reg_imm); 11396 %} 11397 11398 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11399 %{ 11400 match(Set cr (CmpI (AndI src con) zero)); 11401 11402 format %{ "testl $src, $con" %} 11403 ins_encode %{ 11404 __ testl($src$$Register, $con$$constant); 11405 %} 11406 ins_pipe(ialu_cr_reg_imm); 11407 %} 11408 11409 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11410 %{ 11411 match(Set cr (CmpI (AndI src1 src2) zero)); 11412 11413 format %{ "testl $src1, $src2" %} 11414 ins_encode %{ 11415 __ testl($src1$$Register, $src2$$Register); 11416 %} 11417 ins_pipe(ialu_cr_reg_imm); 11418 %} 11419 11420 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11421 %{ 11422 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11423 11424 format %{ "testl $src, $mem" %} 11425 ins_encode %{ 11426 __ testl($src$$Register, $mem$$Address); 11427 %} 11428 ins_pipe(ialu_cr_reg_mem); 11429 %} 11430 11431 // Unsigned compare Instructions; really, same as signed except they 11432 // produce an rFlagsRegU instead of rFlagsReg. 11433 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11434 %{ 11435 match(Set cr (CmpU op1 op2)); 11436 11437 format %{ "cmpl $op1, $op2\t# unsigned" %} 11438 ins_encode %{ 11439 __ cmpl($op1$$Register, $op2$$Register); 11440 %} 11441 ins_pipe(ialu_cr_reg_reg); 11442 %} 11443 11444 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11445 %{ 11446 match(Set cr (CmpU op1 op2)); 11447 11448 format %{ "cmpl $op1, $op2\t# unsigned" %} 11449 ins_encode %{ 11450 __ cmpl($op1$$Register, $op2$$constant); 11451 %} 11452 ins_pipe(ialu_cr_reg_imm); 11453 %} 11454 11455 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11456 %{ 11457 match(Set cr (CmpU op1 (LoadI op2))); 11458 11459 ins_cost(500); // XXX 11460 format %{ "cmpl $op1, $op2\t# unsigned" %} 11461 ins_encode %{ 11462 __ cmpl($op1$$Register, $op2$$Address); 11463 %} 11464 ins_pipe(ialu_cr_reg_mem); 11465 %} 11466 11467 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11468 %{ 11469 match(Set cr (CmpU src zero)); 11470 11471 format %{ "testl $src, $src\t# unsigned" %} 11472 ins_encode %{ 11473 __ testl($src$$Register, $src$$Register); 11474 %} 11475 ins_pipe(ialu_cr_reg_imm); 11476 %} 11477 11478 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11479 %{ 11480 match(Set cr (CmpP op1 op2)); 11481 11482 format %{ "cmpq $op1, $op2\t# ptr" %} 11483 ins_encode %{ 11484 __ cmpq($op1$$Register, $op2$$Register); 11485 %} 11486 ins_pipe(ialu_cr_reg_reg); 11487 %} 11488 11489 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11490 %{ 11491 match(Set cr (CmpP op1 (LoadP op2))); 11492 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11493 11494 ins_cost(500); // XXX 11495 format %{ "cmpq $op1, $op2\t# ptr" %} 11496 ins_encode %{ 11497 __ cmpq($op1$$Register, $op2$$Address); 11498 %} 11499 ins_pipe(ialu_cr_reg_mem); 11500 %} 11501 11502 // XXX this is generalized by compP_rReg_mem??? 11503 // Compare raw pointer (used in out-of-heap check). 11504 // Only works because non-oop pointers must be raw pointers 11505 // and raw pointers have no anti-dependencies. 11506 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11507 %{ 11508 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11509 n->in(2)->as_Load()->barrier_data() == 0); 11510 match(Set cr (CmpP op1 (LoadP op2))); 11511 11512 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11513 ins_encode %{ 11514 __ cmpq($op1$$Register, $op2$$Address); 11515 %} 11516 ins_pipe(ialu_cr_reg_mem); 11517 %} 11518 11519 // This will generate a signed flags result. This should be OK since 11520 // any compare to a zero should be eq/neq. 11521 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11522 %{ 11523 match(Set cr (CmpP src zero)); 11524 11525 format %{ "testq $src, $src\t# ptr" %} 11526 ins_encode %{ 11527 __ testq($src$$Register, $src$$Register); 11528 %} 11529 ins_pipe(ialu_cr_reg_imm); 11530 %} 11531 11532 // This will generate a signed flags result. This should be OK since 11533 // any compare to a zero should be eq/neq. 11534 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11535 %{ 11536 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11537 n->in(1)->as_Load()->barrier_data() == 0); 11538 match(Set cr (CmpP (LoadP op) zero)); 11539 11540 ins_cost(500); // XXX 11541 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11542 ins_encode %{ 11543 __ testq($op$$Address, 0xFFFFFFFF); 11544 %} 11545 ins_pipe(ialu_cr_reg_imm); 11546 %} 11547 11548 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11549 %{ 11550 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11551 n->in(1)->as_Load()->barrier_data() == 0); 11552 match(Set cr (CmpP (LoadP mem) zero)); 11553 11554 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11555 ins_encode %{ 11556 __ cmpq(r12, $mem$$Address); 11557 %} 11558 ins_pipe(ialu_cr_reg_mem); 11559 %} 11560 11561 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11562 %{ 11563 match(Set cr (CmpN op1 op2)); 11564 11565 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11566 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11567 ins_pipe(ialu_cr_reg_reg); 11568 %} 11569 11570 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11571 %{ 11572 match(Set cr (CmpN src (LoadN mem))); 11573 11574 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11575 ins_encode %{ 11576 __ cmpl($src$$Register, $mem$$Address); 11577 %} 11578 ins_pipe(ialu_cr_reg_mem); 11579 %} 11580 11581 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11582 match(Set cr (CmpN op1 op2)); 11583 11584 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11585 ins_encode %{ 11586 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11587 %} 11588 ins_pipe(ialu_cr_reg_imm); 11589 %} 11590 11591 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11592 %{ 11593 match(Set cr (CmpN src (LoadN mem))); 11594 11595 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11596 ins_encode %{ 11597 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11598 %} 11599 ins_pipe(ialu_cr_reg_mem); 11600 %} 11601 11602 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11603 match(Set cr (CmpN op1 op2)); 11604 11605 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11606 ins_encode %{ 11607 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11608 %} 11609 ins_pipe(ialu_cr_reg_imm); 11610 %} 11611 11612 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11613 %{ 11614 match(Set cr (CmpN src (LoadNKlass mem))); 11615 11616 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11617 ins_encode %{ 11618 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11619 %} 11620 ins_pipe(ialu_cr_reg_mem); 11621 %} 11622 11623 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11624 match(Set cr (CmpN src zero)); 11625 11626 format %{ "testl $src, $src\t# compressed ptr" %} 11627 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11628 ins_pipe(ialu_cr_reg_imm); 11629 %} 11630 11631 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11632 %{ 11633 predicate(CompressedOops::base() != nullptr); 11634 match(Set cr (CmpN (LoadN mem) zero)); 11635 11636 ins_cost(500); // XXX 11637 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11638 ins_encode %{ 11639 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11640 %} 11641 ins_pipe(ialu_cr_reg_mem); 11642 %} 11643 11644 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11645 %{ 11646 predicate(CompressedOops::base() == nullptr); 11647 match(Set cr (CmpN (LoadN mem) zero)); 11648 11649 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11650 ins_encode %{ 11651 __ cmpl(r12, $mem$$Address); 11652 %} 11653 ins_pipe(ialu_cr_reg_mem); 11654 %} 11655 11656 // Yanked all unsigned pointer compare operations. 11657 // Pointer compares are done with CmpP which is already unsigned. 11658 11659 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11660 %{ 11661 match(Set cr (CmpL op1 op2)); 11662 11663 format %{ "cmpq $op1, $op2" %} 11664 ins_encode %{ 11665 __ cmpq($op1$$Register, $op2$$Register); 11666 %} 11667 ins_pipe(ialu_cr_reg_reg); 11668 %} 11669 11670 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11671 %{ 11672 match(Set cr (CmpL op1 op2)); 11673 11674 format %{ "cmpq $op1, $op2" %} 11675 ins_encode %{ 11676 __ cmpq($op1$$Register, $op2$$constant); 11677 %} 11678 ins_pipe(ialu_cr_reg_imm); 11679 %} 11680 11681 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11682 %{ 11683 match(Set cr (CmpL op1 (LoadL op2))); 11684 11685 format %{ "cmpq $op1, $op2" %} 11686 ins_encode %{ 11687 __ cmpq($op1$$Register, $op2$$Address); 11688 %} 11689 ins_pipe(ialu_cr_reg_mem); 11690 %} 11691 11692 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11693 %{ 11694 match(Set cr (CmpL src zero)); 11695 11696 format %{ "testq $src, $src" %} 11697 ins_encode %{ 11698 __ testq($src$$Register, $src$$Register); 11699 %} 11700 ins_pipe(ialu_cr_reg_imm); 11701 %} 11702 11703 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11704 %{ 11705 match(Set cr (CmpL (AndL src con) zero)); 11706 11707 format %{ "testq $src, $con\t# long" %} 11708 ins_encode %{ 11709 __ testq($src$$Register, $con$$constant); 11710 %} 11711 ins_pipe(ialu_cr_reg_imm); 11712 %} 11713 11714 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 11715 %{ 11716 match(Set cr (CmpL (AndL src1 src2) zero)); 11717 11718 format %{ "testq $src1, $src2\t# long" %} 11719 ins_encode %{ 11720 __ testq($src1$$Register, $src2$$Register); 11721 %} 11722 ins_pipe(ialu_cr_reg_imm); 11723 %} 11724 11725 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11726 %{ 11727 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11728 11729 format %{ "testq $src, $mem" %} 11730 ins_encode %{ 11731 __ testq($src$$Register, $mem$$Address); 11732 %} 11733 ins_pipe(ialu_cr_reg_mem); 11734 %} 11735 11736 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11737 %{ 11738 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11739 11740 format %{ "testq $src, $mem" %} 11741 ins_encode %{ 11742 __ testq($src$$Register, $mem$$Address); 11743 %} 11744 ins_pipe(ialu_cr_reg_mem); 11745 %} 11746 11747 // Manifest a CmpU result in an integer register. Very painful. 11748 // This is the test to avoid. 11749 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 11750 %{ 11751 match(Set dst (CmpU3 src1 src2)); 11752 effect(KILL flags); 11753 11754 ins_cost(275); // XXX 11755 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 11756 "movl $dst, -1\n\t" 11757 "jb,u done\n\t" 11758 "setne $dst\n\t" 11759 "movzbl $dst, $dst\n\t" 11760 "done:" %} 11761 ins_encode %{ 11762 Label done; 11763 __ cmpl($src1$$Register, $src2$$Register); 11764 __ movl($dst$$Register, -1); 11765 __ jccb(Assembler::below, done); 11766 __ setb(Assembler::notZero, $dst$$Register); 11767 __ movzbl($dst$$Register, $dst$$Register); 11768 __ bind(done); 11769 %} 11770 ins_pipe(pipe_slow); 11771 %} 11772 11773 // Manifest a CmpL result in an integer register. Very painful. 11774 // This is the test to avoid. 11775 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11776 %{ 11777 match(Set dst (CmpL3 src1 src2)); 11778 effect(KILL flags); 11779 11780 ins_cost(275); // XXX 11781 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11782 "movl $dst, -1\n\t" 11783 "jl,s done\n\t" 11784 "setne $dst\n\t" 11785 "movzbl $dst, $dst\n\t" 11786 "done:" %} 11787 ins_encode %{ 11788 Label done; 11789 __ cmpq($src1$$Register, $src2$$Register); 11790 __ movl($dst$$Register, -1); 11791 __ jccb(Assembler::less, done); 11792 __ setb(Assembler::notZero, $dst$$Register); 11793 __ movzbl($dst$$Register, $dst$$Register); 11794 __ bind(done); 11795 %} 11796 ins_pipe(pipe_slow); 11797 %} 11798 11799 // Manifest a CmpUL result in an integer register. Very painful. 11800 // This is the test to avoid. 11801 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11802 %{ 11803 match(Set dst (CmpUL3 src1 src2)); 11804 effect(KILL flags); 11805 11806 ins_cost(275); // XXX 11807 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11808 "movl $dst, -1\n\t" 11809 "jb,u done\n\t" 11810 "setne $dst\n\t" 11811 "movzbl $dst, $dst\n\t" 11812 "done:" %} 11813 ins_encode %{ 11814 Label done; 11815 __ cmpq($src1$$Register, $src2$$Register); 11816 __ movl($dst$$Register, -1); 11817 __ jccb(Assembler::below, done); 11818 __ setb(Assembler::notZero, $dst$$Register); 11819 __ movzbl($dst$$Register, $dst$$Register); 11820 __ bind(done); 11821 %} 11822 ins_pipe(pipe_slow); 11823 %} 11824 11825 // Unsigned long compare Instructions; really, same as signed long except they 11826 // produce an rFlagsRegU instead of rFlagsReg. 11827 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11828 %{ 11829 match(Set cr (CmpUL op1 op2)); 11830 11831 format %{ "cmpq $op1, $op2\t# unsigned" %} 11832 ins_encode %{ 11833 __ cmpq($op1$$Register, $op2$$Register); 11834 %} 11835 ins_pipe(ialu_cr_reg_reg); 11836 %} 11837 11838 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11839 %{ 11840 match(Set cr (CmpUL op1 op2)); 11841 11842 format %{ "cmpq $op1, $op2\t# unsigned" %} 11843 ins_encode %{ 11844 __ cmpq($op1$$Register, $op2$$constant); 11845 %} 11846 ins_pipe(ialu_cr_reg_imm); 11847 %} 11848 11849 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11850 %{ 11851 match(Set cr (CmpUL op1 (LoadL op2))); 11852 11853 format %{ "cmpq $op1, $op2\t# unsigned" %} 11854 ins_encode %{ 11855 __ cmpq($op1$$Register, $op2$$Address); 11856 %} 11857 ins_pipe(ialu_cr_reg_mem); 11858 %} 11859 11860 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11861 %{ 11862 match(Set cr (CmpUL src zero)); 11863 11864 format %{ "testq $src, $src\t# unsigned" %} 11865 ins_encode %{ 11866 __ testq($src$$Register, $src$$Register); 11867 %} 11868 ins_pipe(ialu_cr_reg_imm); 11869 %} 11870 11871 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11872 %{ 11873 match(Set cr (CmpI (LoadB mem) imm)); 11874 11875 ins_cost(125); 11876 format %{ "cmpb $mem, $imm" %} 11877 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11878 ins_pipe(ialu_cr_reg_mem); 11879 %} 11880 11881 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 11882 %{ 11883 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11884 11885 ins_cost(125); 11886 format %{ "testb $mem, $imm\t# ubyte" %} 11887 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11888 ins_pipe(ialu_cr_reg_mem); 11889 %} 11890 11891 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 11892 %{ 11893 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11894 11895 ins_cost(125); 11896 format %{ "testb $mem, $imm\t# byte" %} 11897 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11898 ins_pipe(ialu_cr_reg_mem); 11899 %} 11900 11901 //----------Max and Min-------------------------------------------------------- 11902 // Min Instructions 11903 11904 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11905 %{ 11906 effect(USE_DEF dst, USE src, USE cr); 11907 11908 format %{ "cmovlgt $dst, $src\t# min" %} 11909 ins_encode %{ 11910 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 11911 %} 11912 ins_pipe(pipe_cmov_reg); 11913 %} 11914 11915 11916 instruct minI_rReg(rRegI dst, rRegI src) 11917 %{ 11918 match(Set dst (MinI dst src)); 11919 11920 ins_cost(200); 11921 expand %{ 11922 rFlagsReg cr; 11923 compI_rReg(cr, dst, src); 11924 cmovI_reg_g(dst, src, cr); 11925 %} 11926 %} 11927 11928 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11929 %{ 11930 effect(USE_DEF dst, USE src, USE cr); 11931 11932 format %{ "cmovllt $dst, $src\t# max" %} 11933 ins_encode %{ 11934 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 11935 %} 11936 ins_pipe(pipe_cmov_reg); 11937 %} 11938 11939 11940 instruct maxI_rReg(rRegI dst, rRegI src) 11941 %{ 11942 match(Set dst (MaxI dst src)); 11943 11944 ins_cost(200); 11945 expand %{ 11946 rFlagsReg cr; 11947 compI_rReg(cr, dst, src); 11948 cmovI_reg_l(dst, src, cr); 11949 %} 11950 %} 11951 11952 // ============================================================================ 11953 // Branch Instructions 11954 11955 // Jump Direct - Label defines a relative address from JMP+1 11956 instruct jmpDir(label labl) 11957 %{ 11958 match(Goto); 11959 effect(USE labl); 11960 11961 ins_cost(300); 11962 format %{ "jmp $labl" %} 11963 size(5); 11964 ins_encode %{ 11965 Label* L = $labl$$label; 11966 __ jmp(*L, false); // Always long jump 11967 %} 11968 ins_pipe(pipe_jmp); 11969 %} 11970 11971 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11972 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11973 %{ 11974 match(If cop cr); 11975 effect(USE labl); 11976 11977 ins_cost(300); 11978 format %{ "j$cop $labl" %} 11979 size(6); 11980 ins_encode %{ 11981 Label* L = $labl$$label; 11982 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11983 %} 11984 ins_pipe(pipe_jcc); 11985 %} 11986 11987 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11988 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11989 %{ 11990 match(CountedLoopEnd cop cr); 11991 effect(USE labl); 11992 11993 ins_cost(300); 11994 format %{ "j$cop $labl\t# loop end" %} 11995 size(6); 11996 ins_encode %{ 11997 Label* L = $labl$$label; 11998 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11999 %} 12000 ins_pipe(pipe_jcc); 12001 %} 12002 12003 // Jump Direct Conditional - using unsigned comparison 12004 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12005 match(If cop cmp); 12006 effect(USE labl); 12007 12008 ins_cost(300); 12009 format %{ "j$cop,u $labl" %} 12010 size(6); 12011 ins_encode %{ 12012 Label* L = $labl$$label; 12013 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12014 %} 12015 ins_pipe(pipe_jcc); 12016 %} 12017 12018 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12019 match(If cop cmp); 12020 effect(USE labl); 12021 12022 ins_cost(200); 12023 format %{ "j$cop,u $labl" %} 12024 size(6); 12025 ins_encode %{ 12026 Label* L = $labl$$label; 12027 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12028 %} 12029 ins_pipe(pipe_jcc); 12030 %} 12031 12032 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12033 match(If cop cmp); 12034 effect(USE labl); 12035 12036 ins_cost(200); 12037 format %{ $$template 12038 if ($cop$$cmpcode == Assembler::notEqual) { 12039 $$emit$$"jp,u $labl\n\t" 12040 $$emit$$"j$cop,u $labl" 12041 } else { 12042 $$emit$$"jp,u done\n\t" 12043 $$emit$$"j$cop,u $labl\n\t" 12044 $$emit$$"done:" 12045 } 12046 %} 12047 ins_encode %{ 12048 Label* l = $labl$$label; 12049 if ($cop$$cmpcode == Assembler::notEqual) { 12050 __ jcc(Assembler::parity, *l, false); 12051 __ jcc(Assembler::notEqual, *l, false); 12052 } else if ($cop$$cmpcode == Assembler::equal) { 12053 Label done; 12054 __ jccb(Assembler::parity, done); 12055 __ jcc(Assembler::equal, *l, false); 12056 __ bind(done); 12057 } else { 12058 ShouldNotReachHere(); 12059 } 12060 %} 12061 ins_pipe(pipe_jcc); 12062 %} 12063 12064 // ============================================================================ 12065 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12066 // superklass array for an instance of the superklass. Set a hidden 12067 // internal cache on a hit (cache is checked with exposed code in 12068 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12069 // encoding ALSO sets flags. 12070 12071 instruct partialSubtypeCheck(rdi_RegP result, 12072 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12073 rFlagsReg cr) 12074 %{ 12075 match(Set result (PartialSubtypeCheck sub super)); 12076 effect(KILL rcx, KILL cr); 12077 12078 ins_cost(1100); // slightly larger than the next version 12079 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12080 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12081 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12082 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12083 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12084 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12085 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12086 "miss:\t" %} 12087 12088 opcode(0x1); // Force a XOR of RDI 12089 ins_encode(enc_PartialSubtypeCheck()); 12090 ins_pipe(pipe_slow); 12091 %} 12092 12093 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12094 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12095 rFlagsReg cr) 12096 %{ 12097 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12098 predicate(UseSecondarySupersTable); 12099 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12100 12101 ins_cost(700); // smaller than the next version 12102 format %{ "partialSubtypeCheck $result, $sub, super" %} 12103 12104 ins_encode %{ 12105 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12106 if (InlineSecondarySupersTest) { 12107 __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12108 $temp3$$Register, $temp4$$Register, $result$$Register, 12109 super_klass_slot); 12110 } else { 12111 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12112 } 12113 %} 12114 12115 ins_pipe(pipe_slow); 12116 %} 12117 12118 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12119 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12120 immP0 zero, 12121 rdi_RegP result) 12122 %{ 12123 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12124 effect(KILL rcx, KILL result); 12125 12126 ins_cost(1000); 12127 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12128 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12129 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12130 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12131 "jne,s miss\t\t# Missed: flags nz\n\t" 12132 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12133 "miss:\t" %} 12134 12135 opcode(0x0); // No need to XOR RDI 12136 ins_encode(enc_PartialSubtypeCheck()); 12137 ins_pipe(pipe_slow); 12138 %} 12139 12140 // ============================================================================ 12141 // Branch Instructions -- short offset versions 12142 // 12143 // These instructions are used to replace jumps of a long offset (the default 12144 // match) with jumps of a shorter offset. These instructions are all tagged 12145 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12146 // match rules in general matching. Instead, the ADLC generates a conversion 12147 // method in the MachNode which can be used to do in-place replacement of the 12148 // long variant with the shorter variant. The compiler will determine if a 12149 // branch can be taken by the is_short_branch_offset() predicate in the machine 12150 // specific code section of the file. 12151 12152 // Jump Direct - Label defines a relative address from JMP+1 12153 instruct jmpDir_short(label labl) %{ 12154 match(Goto); 12155 effect(USE labl); 12156 12157 ins_cost(300); 12158 format %{ "jmp,s $labl" %} 12159 size(2); 12160 ins_encode %{ 12161 Label* L = $labl$$label; 12162 __ jmpb(*L); 12163 %} 12164 ins_pipe(pipe_jmp); 12165 ins_short_branch(1); 12166 %} 12167 12168 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12169 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12170 match(If cop cr); 12171 effect(USE labl); 12172 12173 ins_cost(300); 12174 format %{ "j$cop,s $labl" %} 12175 size(2); 12176 ins_encode %{ 12177 Label* L = $labl$$label; 12178 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12179 %} 12180 ins_pipe(pipe_jcc); 12181 ins_short_branch(1); 12182 %} 12183 12184 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12185 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12186 match(CountedLoopEnd cop cr); 12187 effect(USE labl); 12188 12189 ins_cost(300); 12190 format %{ "j$cop,s $labl\t# loop end" %} 12191 size(2); 12192 ins_encode %{ 12193 Label* L = $labl$$label; 12194 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12195 %} 12196 ins_pipe(pipe_jcc); 12197 ins_short_branch(1); 12198 %} 12199 12200 // Jump Direct Conditional - using unsigned comparison 12201 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12202 match(If cop cmp); 12203 effect(USE labl); 12204 12205 ins_cost(300); 12206 format %{ "j$cop,us $labl" %} 12207 size(2); 12208 ins_encode %{ 12209 Label* L = $labl$$label; 12210 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12211 %} 12212 ins_pipe(pipe_jcc); 12213 ins_short_branch(1); 12214 %} 12215 12216 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12217 match(If cop cmp); 12218 effect(USE labl); 12219 12220 ins_cost(300); 12221 format %{ "j$cop,us $labl" %} 12222 size(2); 12223 ins_encode %{ 12224 Label* L = $labl$$label; 12225 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12226 %} 12227 ins_pipe(pipe_jcc); 12228 ins_short_branch(1); 12229 %} 12230 12231 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12232 match(If cop cmp); 12233 effect(USE labl); 12234 12235 ins_cost(300); 12236 format %{ $$template 12237 if ($cop$$cmpcode == Assembler::notEqual) { 12238 $$emit$$"jp,u,s $labl\n\t" 12239 $$emit$$"j$cop,u,s $labl" 12240 } else { 12241 $$emit$$"jp,u,s done\n\t" 12242 $$emit$$"j$cop,u,s $labl\n\t" 12243 $$emit$$"done:" 12244 } 12245 %} 12246 size(4); 12247 ins_encode %{ 12248 Label* l = $labl$$label; 12249 if ($cop$$cmpcode == Assembler::notEqual) { 12250 __ jccb(Assembler::parity, *l); 12251 __ jccb(Assembler::notEqual, *l); 12252 } else if ($cop$$cmpcode == Assembler::equal) { 12253 Label done; 12254 __ jccb(Assembler::parity, done); 12255 __ jccb(Assembler::equal, *l); 12256 __ bind(done); 12257 } else { 12258 ShouldNotReachHere(); 12259 } 12260 %} 12261 ins_pipe(pipe_jcc); 12262 ins_short_branch(1); 12263 %} 12264 12265 // ============================================================================ 12266 // inlined locking and unlocking 12267 12268 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12269 predicate(Compile::current()->use_rtm()); 12270 match(Set cr (FastLock object box)); 12271 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12272 ins_cost(300); 12273 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12274 ins_encode %{ 12275 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12276 $scr$$Register, $cx1$$Register, $cx2$$Register, r15_thread, 12277 _rtm_counters, _stack_rtm_counters, 12278 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12279 true, ra_->C->profile_rtm()); 12280 %} 12281 ins_pipe(pipe_slow); 12282 %} 12283 12284 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12285 predicate(LockingMode != LM_LIGHTWEIGHT && !Compile::current()->use_rtm()); 12286 match(Set cr (FastLock object box)); 12287 effect(TEMP tmp, TEMP scr, USE_KILL box); 12288 ins_cost(300); 12289 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12290 ins_encode %{ 12291 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12292 $scr$$Register, noreg, noreg, r15_thread, nullptr, nullptr, nullptr, false, false); 12293 %} 12294 ins_pipe(pipe_slow); 12295 %} 12296 12297 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12298 predicate(LockingMode != LM_LIGHTWEIGHT); 12299 match(Set cr (FastUnlock object box)); 12300 effect(TEMP tmp, USE_KILL box); 12301 ins_cost(300); 12302 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12303 ins_encode %{ 12304 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12305 %} 12306 ins_pipe(pipe_slow); 12307 %} 12308 12309 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12310 predicate(LockingMode == LM_LIGHTWEIGHT); 12311 match(Set cr (FastLock object box)); 12312 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12313 ins_cost(300); 12314 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12315 ins_encode %{ 12316 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12317 %} 12318 ins_pipe(pipe_slow); 12319 %} 12320 12321 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12322 predicate(LockingMode == LM_LIGHTWEIGHT); 12323 match(Set cr (FastUnlock object rax_reg)); 12324 effect(TEMP tmp, USE_KILL rax_reg); 12325 ins_cost(300); 12326 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12327 ins_encode %{ 12328 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12329 %} 12330 ins_pipe(pipe_slow); 12331 %} 12332 12333 12334 // ============================================================================ 12335 // Safepoint Instructions 12336 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12337 %{ 12338 match(SafePoint poll); 12339 effect(KILL cr, USE poll); 12340 12341 format %{ "testl rax, [$poll]\t" 12342 "# Safepoint: poll for GC" %} 12343 ins_cost(125); 12344 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12345 ins_encode %{ 12346 __ relocate(relocInfo::poll_type); 12347 address pre_pc = __ pc(); 12348 __ testl(rax, Address($poll$$Register, 0)); 12349 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12350 %} 12351 ins_pipe(ialu_reg_mem); 12352 %} 12353 12354 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12355 match(Set dst (MaskAll src)); 12356 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12357 ins_encode %{ 12358 int mask_len = Matcher::vector_length(this); 12359 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12360 %} 12361 ins_pipe( pipe_slow ); 12362 %} 12363 12364 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12365 predicate(Matcher::vector_length(n) > 32); 12366 match(Set dst (MaskAll src)); 12367 effect(TEMP tmp); 12368 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12369 ins_encode %{ 12370 int mask_len = Matcher::vector_length(this); 12371 __ movslq($tmp$$Register, $src$$Register); 12372 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12373 %} 12374 ins_pipe( pipe_slow ); 12375 %} 12376 12377 // ============================================================================ 12378 // Procedure Call/Return Instructions 12379 // Call Java Static Instruction 12380 // Note: If this code changes, the corresponding ret_addr_offset() and 12381 // compute_padding() functions will have to be adjusted. 12382 instruct CallStaticJavaDirect(method meth) %{ 12383 match(CallStaticJava); 12384 effect(USE meth); 12385 12386 ins_cost(300); 12387 format %{ "call,static " %} 12388 opcode(0xE8); /* E8 cd */ 12389 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12390 ins_pipe(pipe_slow); 12391 ins_alignment(4); 12392 %} 12393 12394 // Call Java Dynamic Instruction 12395 // Note: If this code changes, the corresponding ret_addr_offset() and 12396 // compute_padding() functions will have to be adjusted. 12397 instruct CallDynamicJavaDirect(method meth) 12398 %{ 12399 match(CallDynamicJava); 12400 effect(USE meth); 12401 12402 ins_cost(300); 12403 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12404 "call,dynamic " %} 12405 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12406 ins_pipe(pipe_slow); 12407 ins_alignment(4); 12408 %} 12409 12410 // Call Runtime Instruction 12411 instruct CallRuntimeDirect(method meth) 12412 %{ 12413 match(CallRuntime); 12414 effect(USE meth); 12415 12416 ins_cost(300); 12417 format %{ "call,runtime " %} 12418 ins_encode(clear_avx, Java_To_Runtime(meth)); 12419 ins_pipe(pipe_slow); 12420 %} 12421 12422 // Call runtime without safepoint 12423 instruct CallLeafDirect(method meth) 12424 %{ 12425 match(CallLeaf); 12426 effect(USE meth); 12427 12428 ins_cost(300); 12429 format %{ "call_leaf,runtime " %} 12430 ins_encode(clear_avx, Java_To_Runtime(meth)); 12431 ins_pipe(pipe_slow); 12432 %} 12433 12434 // Call runtime without safepoint and with vector arguments 12435 instruct CallLeafDirectVector(method meth) 12436 %{ 12437 match(CallLeafVector); 12438 effect(USE meth); 12439 12440 ins_cost(300); 12441 format %{ "call_leaf,vector " %} 12442 ins_encode(Java_To_Runtime(meth)); 12443 ins_pipe(pipe_slow); 12444 %} 12445 12446 // Call runtime without safepoint 12447 instruct CallLeafNoFPDirect(method meth) 12448 %{ 12449 match(CallLeafNoFP); 12450 effect(USE meth); 12451 12452 ins_cost(300); 12453 format %{ "call_leaf_nofp,runtime " %} 12454 ins_encode(clear_avx, Java_To_Runtime(meth)); 12455 ins_pipe(pipe_slow); 12456 %} 12457 12458 // Return Instruction 12459 // Remove the return address & jump to it. 12460 // Notice: We always emit a nop after a ret to make sure there is room 12461 // for safepoint patching 12462 instruct Ret() 12463 %{ 12464 match(Return); 12465 12466 format %{ "ret" %} 12467 ins_encode %{ 12468 __ ret(0); 12469 %} 12470 ins_pipe(pipe_jmp); 12471 %} 12472 12473 // Tail Call; Jump from runtime stub to Java code. 12474 // Also known as an 'interprocedural jump'. 12475 // Target of jump will eventually return to caller. 12476 // TailJump below removes the return address. 12477 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12478 // emitted just above the TailCall which has reset rbp to the caller state. 12479 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12480 %{ 12481 match(TailCall jump_target method_ptr); 12482 12483 ins_cost(300); 12484 format %{ "jmp $jump_target\t# rbx holds method" %} 12485 ins_encode %{ 12486 __ jmp($jump_target$$Register); 12487 %} 12488 ins_pipe(pipe_jmp); 12489 %} 12490 12491 // Tail Jump; remove the return address; jump to target. 12492 // TailCall above leaves the return address around. 12493 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12494 %{ 12495 match(TailJump jump_target ex_oop); 12496 12497 ins_cost(300); 12498 format %{ "popq rdx\t# pop return address\n\t" 12499 "jmp $jump_target" %} 12500 ins_encode %{ 12501 __ popq(as_Register(RDX_enc)); 12502 __ jmp($jump_target$$Register); 12503 %} 12504 ins_pipe(pipe_jmp); 12505 %} 12506 12507 // Create exception oop: created by stack-crawling runtime code. 12508 // Created exception is now available to this handler, and is setup 12509 // just prior to jumping to this handler. No code emitted. 12510 instruct CreateException(rax_RegP ex_oop) 12511 %{ 12512 match(Set ex_oop (CreateEx)); 12513 12514 size(0); 12515 // use the following format syntax 12516 format %{ "# exception oop is in rax; no code emitted" %} 12517 ins_encode(); 12518 ins_pipe(empty); 12519 %} 12520 12521 // Rethrow exception: 12522 // The exception oop will come in the first argument position. 12523 // Then JUMP (not call) to the rethrow stub code. 12524 instruct RethrowException() 12525 %{ 12526 match(Rethrow); 12527 12528 // use the following format syntax 12529 format %{ "jmp rethrow_stub" %} 12530 ins_encode %{ 12531 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12532 %} 12533 ins_pipe(pipe_jmp); 12534 %} 12535 12536 // ============================================================================ 12537 // This name is KNOWN by the ADLC and cannot be changed. 12538 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12539 // for this guy. 12540 instruct tlsLoadP(r15_RegP dst) %{ 12541 match(Set dst (ThreadLocal)); 12542 effect(DEF dst); 12543 12544 size(0); 12545 format %{ "# TLS is in R15" %} 12546 ins_encode( /*empty encoding*/ ); 12547 ins_pipe(ialu_reg_reg); 12548 %} 12549 12550 12551 //----------PEEPHOLE RULES----------------------------------------------------- 12552 // These must follow all instruction definitions as they use the names 12553 // defined in the instructions definitions. 12554 // 12555 // peeppredicate ( rule_predicate ); 12556 // // the predicate unless which the peephole rule will be ignored 12557 // 12558 // peepmatch ( root_instr_name [preceding_instruction]* ); 12559 // 12560 // peepprocedure ( procedure_name ); 12561 // // provide a procedure name to perform the optimization, the procedure should 12562 // // reside in the architecture dependent peephole file, the method has the 12563 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12564 // // with the arguments being the basic block, the current node index inside the 12565 // // block, the register allocator, the functions upon invoked return a new node 12566 // // defined in peepreplace, and the rules of the nodes appearing in the 12567 // // corresponding peepmatch, the function return true if successful, else 12568 // // return false 12569 // 12570 // peepconstraint %{ 12571 // (instruction_number.operand_name relational_op instruction_number.operand_name 12572 // [, ...] ); 12573 // // instruction numbers are zero-based using left to right order in peepmatch 12574 // 12575 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12576 // // provide an instruction_number.operand_name for each operand that appears 12577 // // in the replacement instruction's match rule 12578 // 12579 // ---------VM FLAGS--------------------------------------------------------- 12580 // 12581 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12582 // 12583 // Each peephole rule is given an identifying number starting with zero and 12584 // increasing by one in the order seen by the parser. An individual peephole 12585 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12586 // on the command-line. 12587 // 12588 // ---------CURRENT LIMITATIONS---------------------------------------------- 12589 // 12590 // Only transformations inside a basic block (do we need more for peephole) 12591 // 12592 // ---------EXAMPLE---------------------------------------------------------- 12593 // 12594 // // pertinent parts of existing instructions in architecture description 12595 // instruct movI(rRegI dst, rRegI src) 12596 // %{ 12597 // match(Set dst (CopyI src)); 12598 // %} 12599 // 12600 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12601 // %{ 12602 // match(Set dst (AddI dst src)); 12603 // effect(KILL cr); 12604 // %} 12605 // 12606 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12607 // %{ 12608 // match(Set dst (AddI dst src)); 12609 // %} 12610 // 12611 // 1. Simple replacement 12612 // - Only match adjacent instructions in same basic block 12613 // - Only equality constraints 12614 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12615 // - Only one replacement instruction 12616 // 12617 // // Change (inc mov) to lea 12618 // peephole %{ 12619 // // lea should only be emitted when beneficial 12620 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12621 // // increment preceded by register-register move 12622 // peepmatch ( incI_rReg movI ); 12623 // // require that the destination register of the increment 12624 // // match the destination register of the move 12625 // peepconstraint ( 0.dst == 1.dst ); 12626 // // construct a replacement instruction that sets 12627 // // the destination to ( move's source register + one ) 12628 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12629 // %} 12630 // 12631 // 2. Procedural replacement 12632 // - More flexible finding relevent nodes 12633 // - More flexible constraints 12634 // - More flexible transformations 12635 // - May utilise architecture-dependent API more effectively 12636 // - Currently only one replacement instruction due to adlc parsing capabilities 12637 // 12638 // // Change (inc mov) to lea 12639 // peephole %{ 12640 // // lea should only be emitted when beneficial 12641 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12642 // // the rule numbers of these nodes inside are passed into the function below 12643 // peepmatch ( incI_rReg movI ); 12644 // // the method that takes the responsibility of transformation 12645 // peepprocedure ( inc_mov_to_lea ); 12646 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12647 // // node is passed into the function above 12648 // peepreplace ( leaI_rReg_immI() ); 12649 // %} 12650 12651 // These instructions is not matched by the matcher but used by the peephole 12652 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12653 %{ 12654 predicate(false); 12655 match(Set dst (AddI src1 src2)); 12656 format %{ "leal $dst, [$src1 + $src2]" %} 12657 ins_encode %{ 12658 Register dst = $dst$$Register; 12659 Register src1 = $src1$$Register; 12660 Register src2 = $src2$$Register; 12661 if (src1 != rbp && src1 != r13) { 12662 __ leal(dst, Address(src1, src2, Address::times_1)); 12663 } else { 12664 assert(src2 != rbp && src2 != r13, ""); 12665 __ leal(dst, Address(src2, src1, Address::times_1)); 12666 } 12667 %} 12668 ins_pipe(ialu_reg_reg); 12669 %} 12670 12671 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 12672 %{ 12673 predicate(false); 12674 match(Set dst (AddI src1 src2)); 12675 format %{ "leal $dst, [$src1 + $src2]" %} 12676 ins_encode %{ 12677 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 12678 %} 12679 ins_pipe(ialu_reg_reg); 12680 %} 12681 12682 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 12683 %{ 12684 predicate(false); 12685 match(Set dst (LShiftI src shift)); 12686 format %{ "leal $dst, [$src << $shift]" %} 12687 ins_encode %{ 12688 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12689 Register src = $src$$Register; 12690 if (scale == Address::times_2 && src != rbp && src != r13) { 12691 __ leal($dst$$Register, Address(src, src, Address::times_1)); 12692 } else { 12693 __ leal($dst$$Register, Address(noreg, src, scale)); 12694 } 12695 %} 12696 ins_pipe(ialu_reg_reg); 12697 %} 12698 12699 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 12700 %{ 12701 predicate(false); 12702 match(Set dst (AddL src1 src2)); 12703 format %{ "leaq $dst, [$src1 + $src2]" %} 12704 ins_encode %{ 12705 Register dst = $dst$$Register; 12706 Register src1 = $src1$$Register; 12707 Register src2 = $src2$$Register; 12708 if (src1 != rbp && src1 != r13) { 12709 __ leaq(dst, Address(src1, src2, Address::times_1)); 12710 } else { 12711 assert(src2 != rbp && src2 != r13, ""); 12712 __ leaq(dst, Address(src2, src1, Address::times_1)); 12713 } 12714 %} 12715 ins_pipe(ialu_reg_reg); 12716 %} 12717 12718 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 12719 %{ 12720 predicate(false); 12721 match(Set dst (AddL src1 src2)); 12722 format %{ "leaq $dst, [$src1 + $src2]" %} 12723 ins_encode %{ 12724 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 12725 %} 12726 ins_pipe(ialu_reg_reg); 12727 %} 12728 12729 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 12730 %{ 12731 predicate(false); 12732 match(Set dst (LShiftL src shift)); 12733 format %{ "leaq $dst, [$src << $shift]" %} 12734 ins_encode %{ 12735 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12736 Register src = $src$$Register; 12737 if (scale == Address::times_2 && src != rbp && src != r13) { 12738 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 12739 } else { 12740 __ leaq($dst$$Register, Address(noreg, src, scale)); 12741 } 12742 %} 12743 ins_pipe(ialu_reg_reg); 12744 %} 12745 12746 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 12747 // sal}) with lea instructions. The {add, sal} rules are beneficial in 12748 // processors with at least partial ALU support for lea 12749 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 12750 // beneficial for processors with full ALU support 12751 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 12752 12753 peephole 12754 %{ 12755 peeppredicate(VM_Version::supports_fast_2op_lea()); 12756 peepmatch (addI_rReg); 12757 peepprocedure (lea_coalesce_reg); 12758 peepreplace (leaI_rReg_rReg_peep()); 12759 %} 12760 12761 peephole 12762 %{ 12763 peeppredicate(VM_Version::supports_fast_2op_lea()); 12764 peepmatch (addI_rReg_imm); 12765 peepprocedure (lea_coalesce_imm); 12766 peepreplace (leaI_rReg_immI_peep()); 12767 %} 12768 12769 peephole 12770 %{ 12771 peeppredicate(VM_Version::supports_fast_3op_lea() || 12772 VM_Version::is_intel_cascade_lake()); 12773 peepmatch (incI_rReg); 12774 peepprocedure (lea_coalesce_imm); 12775 peepreplace (leaI_rReg_immI_peep()); 12776 %} 12777 12778 peephole 12779 %{ 12780 peeppredicate(VM_Version::supports_fast_3op_lea() || 12781 VM_Version::is_intel_cascade_lake()); 12782 peepmatch (decI_rReg); 12783 peepprocedure (lea_coalesce_imm); 12784 peepreplace (leaI_rReg_immI_peep()); 12785 %} 12786 12787 peephole 12788 %{ 12789 peeppredicate(VM_Version::supports_fast_2op_lea()); 12790 peepmatch (salI_rReg_immI2); 12791 peepprocedure (lea_coalesce_imm); 12792 peepreplace (leaI_rReg_immI2_peep()); 12793 %} 12794 12795 peephole 12796 %{ 12797 peeppredicate(VM_Version::supports_fast_2op_lea()); 12798 peepmatch (addL_rReg); 12799 peepprocedure (lea_coalesce_reg); 12800 peepreplace (leaL_rReg_rReg_peep()); 12801 %} 12802 12803 peephole 12804 %{ 12805 peeppredicate(VM_Version::supports_fast_2op_lea()); 12806 peepmatch (addL_rReg_imm); 12807 peepprocedure (lea_coalesce_imm); 12808 peepreplace (leaL_rReg_immL32_peep()); 12809 %} 12810 12811 peephole 12812 %{ 12813 peeppredicate(VM_Version::supports_fast_3op_lea() || 12814 VM_Version::is_intel_cascade_lake()); 12815 peepmatch (incL_rReg); 12816 peepprocedure (lea_coalesce_imm); 12817 peepreplace (leaL_rReg_immL32_peep()); 12818 %} 12819 12820 peephole 12821 %{ 12822 peeppredicate(VM_Version::supports_fast_3op_lea() || 12823 VM_Version::is_intel_cascade_lake()); 12824 peepmatch (decL_rReg); 12825 peepprocedure (lea_coalesce_imm); 12826 peepreplace (leaL_rReg_immL32_peep()); 12827 %} 12828 12829 peephole 12830 %{ 12831 peeppredicate(VM_Version::supports_fast_2op_lea()); 12832 peepmatch (salL_rReg_immI2); 12833 peepprocedure (lea_coalesce_imm); 12834 peepreplace (leaL_rReg_immI2_peep()); 12835 %} 12836 12837 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 12838 // 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 12839 12840 //int variant 12841 peephole 12842 %{ 12843 peepmatch (testI_reg); 12844 peepprocedure (test_may_remove); 12845 %} 12846 12847 //long variant 12848 peephole 12849 %{ 12850 peepmatch (testL_reg); 12851 peepprocedure (test_may_remove); 12852 %} 12853 12854 12855 //----------SMARTSPILL RULES--------------------------------------------------- 12856 // These must follow all instruction definitions as they use the names 12857 // defined in the instructions definitions.