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(), "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 __ mov64(r10, (int64_t) $meth$$method); 1760 __ call(r10); 1761 __ post_call_nop(); 1762 %} 1763 1764 enc_class Java_Static_Call(method meth) 1765 %{ 1766 // JAVA STATIC CALL 1767 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1768 // determine who we intended to call. 1769 if (!_method) { 1770 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1771 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1772 // The NOP here is purely to ensure that eliding a call to 1773 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1774 __ addr_nop_5(); 1775 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1776 } else { 1777 int method_index = resolved_method_index(masm); 1778 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1779 : static_call_Relocation::spec(method_index); 1780 address mark = __ pc(); 1781 int call_offset = __ offset(); 1782 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1783 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1784 // Calls of the same statically bound method can share 1785 // a stub to the interpreter. 1786 __ code()->shared_stub_to_interp_for(_method, call_offset); 1787 } else { 1788 // Emit stubs for static call. 1789 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1790 __ clear_inst_mark(); 1791 if (stub == nullptr) { 1792 ciEnv::current()->record_failure("CodeCache is full"); 1793 return; 1794 } 1795 } 1796 } 1797 __ post_call_nop(); 1798 %} 1799 1800 enc_class Java_Dynamic_Call(method meth) %{ 1801 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1802 __ post_call_nop(); 1803 %} 1804 1805 %} 1806 1807 1808 1809 //----------FRAME-------------------------------------------------------------- 1810 // Definition of frame structure and management information. 1811 // 1812 // S T A C K L A Y O U T Allocators stack-slot number 1813 // | (to get allocators register number 1814 // G Owned by | | v add OptoReg::stack0()) 1815 // r CALLER | | 1816 // o | +--------+ pad to even-align allocators stack-slot 1817 // w V | pad0 | numbers; owned by CALLER 1818 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1819 // h ^ | in | 5 1820 // | | args | 4 Holes in incoming args owned by SELF 1821 // | | | | 3 1822 // | | +--------+ 1823 // V | | old out| Empty on Intel, window on Sparc 1824 // | old |preserve| Must be even aligned. 1825 // | SP-+--------+----> Matcher::_old_SP, even aligned 1826 // | | in | 3 area for Intel ret address 1827 // Owned by |preserve| Empty on Sparc. 1828 // SELF +--------+ 1829 // | | pad2 | 2 pad to align old SP 1830 // | +--------+ 1 1831 // | | locks | 0 1832 // | +--------+----> OptoReg::stack0(), even aligned 1833 // | | pad1 | 11 pad to align new SP 1834 // | +--------+ 1835 // | | | 10 1836 // | | spills | 9 spills 1837 // V | | 8 (pad0 slot for callee) 1838 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1839 // ^ | out | 7 1840 // | | args | 6 Holes in outgoing args owned by CALLEE 1841 // Owned by +--------+ 1842 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1843 // | new |preserve| Must be even-aligned. 1844 // | SP-+--------+----> Matcher::_new_SP, even aligned 1845 // | | | 1846 // 1847 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1848 // known from SELF's arguments and the Java calling convention. 1849 // Region 6-7 is determined per call site. 1850 // Note 2: If the calling convention leaves holes in the incoming argument 1851 // area, those holes are owned by SELF. Holes in the outgoing area 1852 // are owned by the CALLEE. Holes should not be necessary in the 1853 // incoming area, as the Java calling convention is completely under 1854 // the control of the AD file. Doubles can be sorted and packed to 1855 // avoid holes. Holes in the outgoing arguments may be necessary for 1856 // varargs C calling conventions. 1857 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1858 // even aligned with pad0 as needed. 1859 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1860 // region 6-11 is even aligned; it may be padded out more so that 1861 // the region from SP to FP meets the minimum stack alignment. 1862 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1863 // alignment. Region 11, pad1, may be dynamically extended so that 1864 // SP meets the minimum alignment. 1865 1866 frame 1867 %{ 1868 // These three registers define part of the calling convention 1869 // between compiled code and the interpreter. 1870 inline_cache_reg(RAX); // Inline Cache Register 1871 1872 // Optional: name the operand used by cisc-spilling to access 1873 // [stack_pointer + offset] 1874 cisc_spilling_operand_name(indOffset32); 1875 1876 // Number of stack slots consumed by locking an object 1877 sync_stack_slots(2); 1878 1879 // Compiled code's Frame Pointer 1880 frame_pointer(RSP); 1881 1882 // Interpreter stores its frame pointer in a register which is 1883 // stored to the stack by I2CAdaptors. 1884 // I2CAdaptors convert from interpreted java to compiled java. 1885 interpreter_frame_pointer(RBP); 1886 1887 // Stack alignment requirement 1888 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1889 1890 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1891 // for calls to C. Supports the var-args backing area for register parms. 1892 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1893 1894 // The after-PROLOG location of the return address. Location of 1895 // return address specifies a type (REG or STACK) and a number 1896 // representing the register number (i.e. - use a register name) or 1897 // stack slot. 1898 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 1899 // Otherwise, it is above the locks and verification slot and alignment word 1900 return_addr(STACK - 2 + 1901 align_up((Compile::current()->in_preserve_stack_slots() + 1902 Compile::current()->fixed_slots()), 1903 stack_alignment_in_slots())); 1904 1905 // Location of compiled Java return values. Same as C for now. 1906 return_value 1907 %{ 1908 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 1909 "only return normal values"); 1910 1911 static const int lo[Op_RegL + 1] = { 1912 0, 1913 0, 1914 RAX_num, // Op_RegN 1915 RAX_num, // Op_RegI 1916 RAX_num, // Op_RegP 1917 XMM0_num, // Op_RegF 1918 XMM0_num, // Op_RegD 1919 RAX_num // Op_RegL 1920 }; 1921 static const int hi[Op_RegL + 1] = { 1922 0, 1923 0, 1924 OptoReg::Bad, // Op_RegN 1925 OptoReg::Bad, // Op_RegI 1926 RAX_H_num, // Op_RegP 1927 OptoReg::Bad, // Op_RegF 1928 XMM0b_num, // Op_RegD 1929 RAX_H_num // Op_RegL 1930 }; 1931 // Excluded flags and vector registers. 1932 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 1933 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 1934 %} 1935 %} 1936 1937 //----------ATTRIBUTES--------------------------------------------------------- 1938 //----------Operand Attributes------------------------------------------------- 1939 op_attrib op_cost(0); // Required cost attribute 1940 1941 //----------Instruction Attributes--------------------------------------------- 1942 ins_attrib ins_cost(100); // Required cost attribute 1943 ins_attrib ins_size(8); // Required size attribute (in bits) 1944 ins_attrib ins_short_branch(0); // Required flag: is this instruction 1945 // a non-matching short branch variant 1946 // of some long branch? 1947 ins_attrib ins_alignment(1); // Required alignment attribute (must 1948 // be a power of 2) specifies the 1949 // alignment that some part of the 1950 // instruction (not necessarily the 1951 // start) requires. If > 1, a 1952 // compute_padding() function must be 1953 // provided for the instruction 1954 1955 //----------OPERANDS----------------------------------------------------------- 1956 // Operand definitions must precede instruction definitions for correct parsing 1957 // in the ADLC because operands constitute user defined types which are used in 1958 // instruction definitions. 1959 1960 //----------Simple Operands---------------------------------------------------- 1961 // Immediate Operands 1962 // Integer Immediate 1963 operand immI() 1964 %{ 1965 match(ConI); 1966 1967 op_cost(10); 1968 format %{ %} 1969 interface(CONST_INTER); 1970 %} 1971 1972 // Constant for test vs zero 1973 operand immI_0() 1974 %{ 1975 predicate(n->get_int() == 0); 1976 match(ConI); 1977 1978 op_cost(0); 1979 format %{ %} 1980 interface(CONST_INTER); 1981 %} 1982 1983 // Constant for increment 1984 operand immI_1() 1985 %{ 1986 predicate(n->get_int() == 1); 1987 match(ConI); 1988 1989 op_cost(0); 1990 format %{ %} 1991 interface(CONST_INTER); 1992 %} 1993 1994 // Constant for decrement 1995 operand immI_M1() 1996 %{ 1997 predicate(n->get_int() == -1); 1998 match(ConI); 1999 2000 op_cost(0); 2001 format %{ %} 2002 interface(CONST_INTER); 2003 %} 2004 2005 operand immI_2() 2006 %{ 2007 predicate(n->get_int() == 2); 2008 match(ConI); 2009 2010 op_cost(0); 2011 format %{ %} 2012 interface(CONST_INTER); 2013 %} 2014 2015 operand immI_4() 2016 %{ 2017 predicate(n->get_int() == 4); 2018 match(ConI); 2019 2020 op_cost(0); 2021 format %{ %} 2022 interface(CONST_INTER); 2023 %} 2024 2025 operand immI_8() 2026 %{ 2027 predicate(n->get_int() == 8); 2028 match(ConI); 2029 2030 op_cost(0); 2031 format %{ %} 2032 interface(CONST_INTER); 2033 %} 2034 2035 // Valid scale values for addressing modes 2036 operand immI2() 2037 %{ 2038 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2039 match(ConI); 2040 2041 format %{ %} 2042 interface(CONST_INTER); 2043 %} 2044 2045 operand immU7() 2046 %{ 2047 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2048 match(ConI); 2049 2050 op_cost(5); 2051 format %{ %} 2052 interface(CONST_INTER); 2053 %} 2054 2055 operand immI8() 2056 %{ 2057 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2058 match(ConI); 2059 2060 op_cost(5); 2061 format %{ %} 2062 interface(CONST_INTER); 2063 %} 2064 2065 operand immU8() 2066 %{ 2067 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2068 match(ConI); 2069 2070 op_cost(5); 2071 format %{ %} 2072 interface(CONST_INTER); 2073 %} 2074 2075 operand immI16() 2076 %{ 2077 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2078 match(ConI); 2079 2080 op_cost(10); 2081 format %{ %} 2082 interface(CONST_INTER); 2083 %} 2084 2085 // Int Immediate non-negative 2086 operand immU31() 2087 %{ 2088 predicate(n->get_int() >= 0); 2089 match(ConI); 2090 2091 op_cost(0); 2092 format %{ %} 2093 interface(CONST_INTER); 2094 %} 2095 2096 // Pointer Immediate 2097 operand immP() 2098 %{ 2099 match(ConP); 2100 2101 op_cost(10); 2102 format %{ %} 2103 interface(CONST_INTER); 2104 %} 2105 2106 // Null Pointer Immediate 2107 operand immP0() 2108 %{ 2109 predicate(n->get_ptr() == 0); 2110 match(ConP); 2111 2112 op_cost(5); 2113 format %{ %} 2114 interface(CONST_INTER); 2115 %} 2116 2117 // Pointer Immediate 2118 operand immN() %{ 2119 match(ConN); 2120 2121 op_cost(10); 2122 format %{ %} 2123 interface(CONST_INTER); 2124 %} 2125 2126 operand immNKlass() %{ 2127 match(ConNKlass); 2128 2129 op_cost(10); 2130 format %{ %} 2131 interface(CONST_INTER); 2132 %} 2133 2134 // Null Pointer Immediate 2135 operand immN0() %{ 2136 predicate(n->get_narrowcon() == 0); 2137 match(ConN); 2138 2139 op_cost(5); 2140 format %{ %} 2141 interface(CONST_INTER); 2142 %} 2143 2144 operand immP31() 2145 %{ 2146 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2147 && (n->get_ptr() >> 31) == 0); 2148 match(ConP); 2149 2150 op_cost(5); 2151 format %{ %} 2152 interface(CONST_INTER); 2153 %} 2154 2155 2156 // Long Immediate 2157 operand immL() 2158 %{ 2159 match(ConL); 2160 2161 op_cost(20); 2162 format %{ %} 2163 interface(CONST_INTER); 2164 %} 2165 2166 // Long Immediate 8-bit 2167 operand immL8() 2168 %{ 2169 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2170 match(ConL); 2171 2172 op_cost(5); 2173 format %{ %} 2174 interface(CONST_INTER); 2175 %} 2176 2177 // Long Immediate 32-bit unsigned 2178 operand immUL32() 2179 %{ 2180 predicate(n->get_long() == (unsigned int) (n->get_long())); 2181 match(ConL); 2182 2183 op_cost(10); 2184 format %{ %} 2185 interface(CONST_INTER); 2186 %} 2187 2188 // Long Immediate 32-bit signed 2189 operand immL32() 2190 %{ 2191 predicate(n->get_long() == (int) (n->get_long())); 2192 match(ConL); 2193 2194 op_cost(15); 2195 format %{ %} 2196 interface(CONST_INTER); 2197 %} 2198 2199 operand immL_Pow2() 2200 %{ 2201 predicate(is_power_of_2((julong)n->get_long())); 2202 match(ConL); 2203 2204 op_cost(15); 2205 format %{ %} 2206 interface(CONST_INTER); 2207 %} 2208 2209 operand immL_NotPow2() 2210 %{ 2211 predicate(is_power_of_2((julong)~n->get_long())); 2212 match(ConL); 2213 2214 op_cost(15); 2215 format %{ %} 2216 interface(CONST_INTER); 2217 %} 2218 2219 // Long Immediate zero 2220 operand immL0() 2221 %{ 2222 predicate(n->get_long() == 0L); 2223 match(ConL); 2224 2225 op_cost(10); 2226 format %{ %} 2227 interface(CONST_INTER); 2228 %} 2229 2230 // Constant for increment 2231 operand immL1() 2232 %{ 2233 predicate(n->get_long() == 1); 2234 match(ConL); 2235 2236 format %{ %} 2237 interface(CONST_INTER); 2238 %} 2239 2240 // Constant for decrement 2241 operand immL_M1() 2242 %{ 2243 predicate(n->get_long() == -1); 2244 match(ConL); 2245 2246 format %{ %} 2247 interface(CONST_INTER); 2248 %} 2249 2250 // Long Immediate: low 32-bit mask 2251 operand immL_32bits() 2252 %{ 2253 predicate(n->get_long() == 0xFFFFFFFFL); 2254 match(ConL); 2255 op_cost(20); 2256 2257 format %{ %} 2258 interface(CONST_INTER); 2259 %} 2260 2261 // Int Immediate: 2^n-1, positive 2262 operand immI_Pow2M1() 2263 %{ 2264 predicate((n->get_int() > 0) 2265 && is_power_of_2((juint)n->get_int() + 1)); 2266 match(ConI); 2267 2268 op_cost(20); 2269 format %{ %} 2270 interface(CONST_INTER); 2271 %} 2272 2273 // Float Immediate zero 2274 operand immF0() 2275 %{ 2276 predicate(jint_cast(n->getf()) == 0); 2277 match(ConF); 2278 2279 op_cost(5); 2280 format %{ %} 2281 interface(CONST_INTER); 2282 %} 2283 2284 // Float Immediate 2285 operand immF() 2286 %{ 2287 match(ConF); 2288 2289 op_cost(15); 2290 format %{ %} 2291 interface(CONST_INTER); 2292 %} 2293 2294 // Double Immediate zero 2295 operand immD0() 2296 %{ 2297 predicate(jlong_cast(n->getd()) == 0); 2298 match(ConD); 2299 2300 op_cost(5); 2301 format %{ %} 2302 interface(CONST_INTER); 2303 %} 2304 2305 // Double Immediate 2306 operand immD() 2307 %{ 2308 match(ConD); 2309 2310 op_cost(15); 2311 format %{ %} 2312 interface(CONST_INTER); 2313 %} 2314 2315 // Immediates for special shifts (sign extend) 2316 2317 // Constants for increment 2318 operand immI_16() 2319 %{ 2320 predicate(n->get_int() == 16); 2321 match(ConI); 2322 2323 format %{ %} 2324 interface(CONST_INTER); 2325 %} 2326 2327 operand immI_24() 2328 %{ 2329 predicate(n->get_int() == 24); 2330 match(ConI); 2331 2332 format %{ %} 2333 interface(CONST_INTER); 2334 %} 2335 2336 // Constant for byte-wide masking 2337 operand immI_255() 2338 %{ 2339 predicate(n->get_int() == 255); 2340 match(ConI); 2341 2342 format %{ %} 2343 interface(CONST_INTER); 2344 %} 2345 2346 // Constant for short-wide masking 2347 operand immI_65535() 2348 %{ 2349 predicate(n->get_int() == 65535); 2350 match(ConI); 2351 2352 format %{ %} 2353 interface(CONST_INTER); 2354 %} 2355 2356 // Constant for byte-wide masking 2357 operand immL_255() 2358 %{ 2359 predicate(n->get_long() == 255); 2360 match(ConL); 2361 2362 format %{ %} 2363 interface(CONST_INTER); 2364 %} 2365 2366 // Constant for short-wide masking 2367 operand immL_65535() 2368 %{ 2369 predicate(n->get_long() == 65535); 2370 match(ConL); 2371 2372 format %{ %} 2373 interface(CONST_INTER); 2374 %} 2375 2376 operand kReg() 2377 %{ 2378 constraint(ALLOC_IN_RC(vectmask_reg)); 2379 match(RegVectMask); 2380 format %{%} 2381 interface(REG_INTER); 2382 %} 2383 2384 // Register Operands 2385 // Integer Register 2386 operand rRegI() 2387 %{ 2388 constraint(ALLOC_IN_RC(int_reg)); 2389 match(RegI); 2390 2391 match(rax_RegI); 2392 match(rbx_RegI); 2393 match(rcx_RegI); 2394 match(rdx_RegI); 2395 match(rdi_RegI); 2396 2397 format %{ %} 2398 interface(REG_INTER); 2399 %} 2400 2401 // Special Registers 2402 operand rax_RegI() 2403 %{ 2404 constraint(ALLOC_IN_RC(int_rax_reg)); 2405 match(RegI); 2406 match(rRegI); 2407 2408 format %{ "RAX" %} 2409 interface(REG_INTER); 2410 %} 2411 2412 // Special Registers 2413 operand rbx_RegI() 2414 %{ 2415 constraint(ALLOC_IN_RC(int_rbx_reg)); 2416 match(RegI); 2417 match(rRegI); 2418 2419 format %{ "RBX" %} 2420 interface(REG_INTER); 2421 %} 2422 2423 operand rcx_RegI() 2424 %{ 2425 constraint(ALLOC_IN_RC(int_rcx_reg)); 2426 match(RegI); 2427 match(rRegI); 2428 2429 format %{ "RCX" %} 2430 interface(REG_INTER); 2431 %} 2432 2433 operand rdx_RegI() 2434 %{ 2435 constraint(ALLOC_IN_RC(int_rdx_reg)); 2436 match(RegI); 2437 match(rRegI); 2438 2439 format %{ "RDX" %} 2440 interface(REG_INTER); 2441 %} 2442 2443 operand rdi_RegI() 2444 %{ 2445 constraint(ALLOC_IN_RC(int_rdi_reg)); 2446 match(RegI); 2447 match(rRegI); 2448 2449 format %{ "RDI" %} 2450 interface(REG_INTER); 2451 %} 2452 2453 operand no_rax_rdx_RegI() 2454 %{ 2455 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2456 match(RegI); 2457 match(rbx_RegI); 2458 match(rcx_RegI); 2459 match(rdi_RegI); 2460 2461 format %{ %} 2462 interface(REG_INTER); 2463 %} 2464 2465 operand no_rbp_r13_RegI() 2466 %{ 2467 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2468 match(RegI); 2469 match(rRegI); 2470 match(rax_RegI); 2471 match(rbx_RegI); 2472 match(rcx_RegI); 2473 match(rdx_RegI); 2474 match(rdi_RegI); 2475 2476 format %{ %} 2477 interface(REG_INTER); 2478 %} 2479 2480 // Pointer Register 2481 operand any_RegP() 2482 %{ 2483 constraint(ALLOC_IN_RC(any_reg)); 2484 match(RegP); 2485 match(rax_RegP); 2486 match(rbx_RegP); 2487 match(rdi_RegP); 2488 match(rsi_RegP); 2489 match(rbp_RegP); 2490 match(r15_RegP); 2491 match(rRegP); 2492 2493 format %{ %} 2494 interface(REG_INTER); 2495 %} 2496 2497 operand rRegP() 2498 %{ 2499 constraint(ALLOC_IN_RC(ptr_reg)); 2500 match(RegP); 2501 match(rax_RegP); 2502 match(rbx_RegP); 2503 match(rdi_RegP); 2504 match(rsi_RegP); 2505 match(rbp_RegP); // See Q&A below about 2506 match(r15_RegP); // r15_RegP and rbp_RegP. 2507 2508 format %{ %} 2509 interface(REG_INTER); 2510 %} 2511 2512 operand rRegN() %{ 2513 constraint(ALLOC_IN_RC(int_reg)); 2514 match(RegN); 2515 2516 format %{ %} 2517 interface(REG_INTER); 2518 %} 2519 2520 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2521 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2522 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2523 // The output of an instruction is controlled by the allocator, which respects 2524 // register class masks, not match rules. Unless an instruction mentions 2525 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2526 // by the allocator as an input. 2527 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2528 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2529 // result, RBP is not included in the output of the instruction either. 2530 2531 // This operand is not allowed to use RBP even if 2532 // RBP is not used to hold the frame pointer. 2533 operand no_rbp_RegP() 2534 %{ 2535 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2536 match(RegP); 2537 match(rbx_RegP); 2538 match(rsi_RegP); 2539 match(rdi_RegP); 2540 2541 format %{ %} 2542 interface(REG_INTER); 2543 %} 2544 2545 // Special Registers 2546 // Return a pointer value 2547 operand rax_RegP() 2548 %{ 2549 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2550 match(RegP); 2551 match(rRegP); 2552 2553 format %{ %} 2554 interface(REG_INTER); 2555 %} 2556 2557 // Special Registers 2558 // Return a compressed pointer value 2559 operand rax_RegN() 2560 %{ 2561 constraint(ALLOC_IN_RC(int_rax_reg)); 2562 match(RegN); 2563 match(rRegN); 2564 2565 format %{ %} 2566 interface(REG_INTER); 2567 %} 2568 2569 // Used in AtomicAdd 2570 operand rbx_RegP() 2571 %{ 2572 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2573 match(RegP); 2574 match(rRegP); 2575 2576 format %{ %} 2577 interface(REG_INTER); 2578 %} 2579 2580 operand rsi_RegP() 2581 %{ 2582 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2583 match(RegP); 2584 match(rRegP); 2585 2586 format %{ %} 2587 interface(REG_INTER); 2588 %} 2589 2590 operand rbp_RegP() 2591 %{ 2592 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2593 match(RegP); 2594 match(rRegP); 2595 2596 format %{ %} 2597 interface(REG_INTER); 2598 %} 2599 2600 // Used in rep stosq 2601 operand rdi_RegP() 2602 %{ 2603 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2604 match(RegP); 2605 match(rRegP); 2606 2607 format %{ %} 2608 interface(REG_INTER); 2609 %} 2610 2611 operand r15_RegP() 2612 %{ 2613 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2614 match(RegP); 2615 match(rRegP); 2616 2617 format %{ %} 2618 interface(REG_INTER); 2619 %} 2620 2621 operand rRegL() 2622 %{ 2623 constraint(ALLOC_IN_RC(long_reg)); 2624 match(RegL); 2625 match(rax_RegL); 2626 match(rdx_RegL); 2627 2628 format %{ %} 2629 interface(REG_INTER); 2630 %} 2631 2632 // Special Registers 2633 operand no_rax_rdx_RegL() 2634 %{ 2635 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2636 match(RegL); 2637 match(rRegL); 2638 2639 format %{ %} 2640 interface(REG_INTER); 2641 %} 2642 2643 operand rax_RegL() 2644 %{ 2645 constraint(ALLOC_IN_RC(long_rax_reg)); 2646 match(RegL); 2647 match(rRegL); 2648 2649 format %{ "RAX" %} 2650 interface(REG_INTER); 2651 %} 2652 2653 operand rcx_RegL() 2654 %{ 2655 constraint(ALLOC_IN_RC(long_rcx_reg)); 2656 match(RegL); 2657 match(rRegL); 2658 2659 format %{ %} 2660 interface(REG_INTER); 2661 %} 2662 2663 operand rdx_RegL() 2664 %{ 2665 constraint(ALLOC_IN_RC(long_rdx_reg)); 2666 match(RegL); 2667 match(rRegL); 2668 2669 format %{ %} 2670 interface(REG_INTER); 2671 %} 2672 2673 operand r11_RegL() 2674 %{ 2675 constraint(ALLOC_IN_RC(long_r11_reg)); 2676 match(RegL); 2677 match(rRegL); 2678 2679 format %{ %} 2680 interface(REG_INTER); 2681 %} 2682 2683 operand no_rbp_r13_RegL() 2684 %{ 2685 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2686 match(RegL); 2687 match(rRegL); 2688 match(rax_RegL); 2689 match(rcx_RegL); 2690 match(rdx_RegL); 2691 2692 format %{ %} 2693 interface(REG_INTER); 2694 %} 2695 2696 // Flags register, used as output of compare instructions 2697 operand rFlagsReg() 2698 %{ 2699 constraint(ALLOC_IN_RC(int_flags)); 2700 match(RegFlags); 2701 2702 format %{ "RFLAGS" %} 2703 interface(REG_INTER); 2704 %} 2705 2706 // Flags register, used as output of FLOATING POINT compare instructions 2707 operand rFlagsRegU() 2708 %{ 2709 constraint(ALLOC_IN_RC(int_flags)); 2710 match(RegFlags); 2711 2712 format %{ "RFLAGS_U" %} 2713 interface(REG_INTER); 2714 %} 2715 2716 operand rFlagsRegUCF() %{ 2717 constraint(ALLOC_IN_RC(int_flags)); 2718 match(RegFlags); 2719 predicate(false); 2720 2721 format %{ "RFLAGS_U_CF" %} 2722 interface(REG_INTER); 2723 %} 2724 2725 // Float register operands 2726 operand regF() %{ 2727 constraint(ALLOC_IN_RC(float_reg)); 2728 match(RegF); 2729 2730 format %{ %} 2731 interface(REG_INTER); 2732 %} 2733 2734 // Float register operands 2735 operand legRegF() %{ 2736 constraint(ALLOC_IN_RC(float_reg_legacy)); 2737 match(RegF); 2738 2739 format %{ %} 2740 interface(REG_INTER); 2741 %} 2742 2743 // Float register operands 2744 operand vlRegF() %{ 2745 constraint(ALLOC_IN_RC(float_reg_vl)); 2746 match(RegF); 2747 2748 format %{ %} 2749 interface(REG_INTER); 2750 %} 2751 2752 // Double register operands 2753 operand regD() %{ 2754 constraint(ALLOC_IN_RC(double_reg)); 2755 match(RegD); 2756 2757 format %{ %} 2758 interface(REG_INTER); 2759 %} 2760 2761 // Double register operands 2762 operand legRegD() %{ 2763 constraint(ALLOC_IN_RC(double_reg_legacy)); 2764 match(RegD); 2765 2766 format %{ %} 2767 interface(REG_INTER); 2768 %} 2769 2770 // Double register operands 2771 operand vlRegD() %{ 2772 constraint(ALLOC_IN_RC(double_reg_vl)); 2773 match(RegD); 2774 2775 format %{ %} 2776 interface(REG_INTER); 2777 %} 2778 2779 //----------Memory Operands---------------------------------------------------- 2780 // Direct Memory Operand 2781 // operand direct(immP addr) 2782 // %{ 2783 // match(addr); 2784 2785 // format %{ "[$addr]" %} 2786 // interface(MEMORY_INTER) %{ 2787 // base(0xFFFFFFFF); 2788 // index(0x4); 2789 // scale(0x0); 2790 // disp($addr); 2791 // %} 2792 // %} 2793 2794 // Indirect Memory Operand 2795 operand indirect(any_RegP reg) 2796 %{ 2797 constraint(ALLOC_IN_RC(ptr_reg)); 2798 match(reg); 2799 2800 format %{ "[$reg]" %} 2801 interface(MEMORY_INTER) %{ 2802 base($reg); 2803 index(0x4); 2804 scale(0x0); 2805 disp(0x0); 2806 %} 2807 %} 2808 2809 // Indirect Memory Plus Short Offset Operand 2810 operand indOffset8(any_RegP reg, immL8 off) 2811 %{ 2812 constraint(ALLOC_IN_RC(ptr_reg)); 2813 match(AddP reg off); 2814 2815 format %{ "[$reg + $off (8-bit)]" %} 2816 interface(MEMORY_INTER) %{ 2817 base($reg); 2818 index(0x4); 2819 scale(0x0); 2820 disp($off); 2821 %} 2822 %} 2823 2824 // Indirect Memory Plus Long Offset Operand 2825 operand indOffset32(any_RegP reg, immL32 off) 2826 %{ 2827 constraint(ALLOC_IN_RC(ptr_reg)); 2828 match(AddP reg off); 2829 2830 format %{ "[$reg + $off (32-bit)]" %} 2831 interface(MEMORY_INTER) %{ 2832 base($reg); 2833 index(0x4); 2834 scale(0x0); 2835 disp($off); 2836 %} 2837 %} 2838 2839 // Indirect Memory Plus Index Register Plus Offset Operand 2840 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2841 %{ 2842 constraint(ALLOC_IN_RC(ptr_reg)); 2843 match(AddP (AddP reg lreg) off); 2844 2845 op_cost(10); 2846 format %{"[$reg + $off + $lreg]" %} 2847 interface(MEMORY_INTER) %{ 2848 base($reg); 2849 index($lreg); 2850 scale(0x0); 2851 disp($off); 2852 %} 2853 %} 2854 2855 // Indirect Memory Plus Index Register Plus Offset Operand 2856 operand indIndex(any_RegP reg, rRegL lreg) 2857 %{ 2858 constraint(ALLOC_IN_RC(ptr_reg)); 2859 match(AddP reg lreg); 2860 2861 op_cost(10); 2862 format %{"[$reg + $lreg]" %} 2863 interface(MEMORY_INTER) %{ 2864 base($reg); 2865 index($lreg); 2866 scale(0x0); 2867 disp(0x0); 2868 %} 2869 %} 2870 2871 // Indirect Memory Times Scale Plus Index Register 2872 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2873 %{ 2874 constraint(ALLOC_IN_RC(ptr_reg)); 2875 match(AddP reg (LShiftL lreg scale)); 2876 2877 op_cost(10); 2878 format %{"[$reg + $lreg << $scale]" %} 2879 interface(MEMORY_INTER) %{ 2880 base($reg); 2881 index($lreg); 2882 scale($scale); 2883 disp(0x0); 2884 %} 2885 %} 2886 2887 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 2888 %{ 2889 constraint(ALLOC_IN_RC(ptr_reg)); 2890 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 2891 match(AddP reg (LShiftL (ConvI2L idx) scale)); 2892 2893 op_cost(10); 2894 format %{"[$reg + pos $idx << $scale]" %} 2895 interface(MEMORY_INTER) %{ 2896 base($reg); 2897 index($idx); 2898 scale($scale); 2899 disp(0x0); 2900 %} 2901 %} 2902 2903 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 2904 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 2905 %{ 2906 constraint(ALLOC_IN_RC(ptr_reg)); 2907 match(AddP (AddP reg (LShiftL lreg scale)) off); 2908 2909 op_cost(10); 2910 format %{"[$reg + $off + $lreg << $scale]" %} 2911 interface(MEMORY_INTER) %{ 2912 base($reg); 2913 index($lreg); 2914 scale($scale); 2915 disp($off); 2916 %} 2917 %} 2918 2919 // Indirect Memory Plus Positive Index Register Plus Offset Operand 2920 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 2921 %{ 2922 constraint(ALLOC_IN_RC(ptr_reg)); 2923 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 2924 match(AddP (AddP reg (ConvI2L idx)) off); 2925 2926 op_cost(10); 2927 format %{"[$reg + $off + $idx]" %} 2928 interface(MEMORY_INTER) %{ 2929 base($reg); 2930 index($idx); 2931 scale(0x0); 2932 disp($off); 2933 %} 2934 %} 2935 2936 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 2937 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 2938 %{ 2939 constraint(ALLOC_IN_RC(ptr_reg)); 2940 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 2941 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 2942 2943 op_cost(10); 2944 format %{"[$reg + $off + $idx << $scale]" %} 2945 interface(MEMORY_INTER) %{ 2946 base($reg); 2947 index($idx); 2948 scale($scale); 2949 disp($off); 2950 %} 2951 %} 2952 2953 // Indirect Narrow Oop Plus Offset Operand 2954 // Note: x86 architecture doesn't support "scale * index + offset" without a base 2955 // we can't free r12 even with CompressedOops::base() == nullptr. 2956 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 2957 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 2958 constraint(ALLOC_IN_RC(ptr_reg)); 2959 match(AddP (DecodeN reg) off); 2960 2961 op_cost(10); 2962 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 2963 interface(MEMORY_INTER) %{ 2964 base(0xc); // R12 2965 index($reg); 2966 scale(0x3); 2967 disp($off); 2968 %} 2969 %} 2970 2971 // Indirect Memory Operand 2972 operand indirectNarrow(rRegN reg) 2973 %{ 2974 predicate(CompressedOops::shift() == 0); 2975 constraint(ALLOC_IN_RC(ptr_reg)); 2976 match(DecodeN reg); 2977 2978 format %{ "[$reg]" %} 2979 interface(MEMORY_INTER) %{ 2980 base($reg); 2981 index(0x4); 2982 scale(0x0); 2983 disp(0x0); 2984 %} 2985 %} 2986 2987 // Indirect Memory Plus Short Offset Operand 2988 operand indOffset8Narrow(rRegN reg, immL8 off) 2989 %{ 2990 predicate(CompressedOops::shift() == 0); 2991 constraint(ALLOC_IN_RC(ptr_reg)); 2992 match(AddP (DecodeN reg) off); 2993 2994 format %{ "[$reg + $off (8-bit)]" %} 2995 interface(MEMORY_INTER) %{ 2996 base($reg); 2997 index(0x4); 2998 scale(0x0); 2999 disp($off); 3000 %} 3001 %} 3002 3003 // Indirect Memory Plus Long Offset Operand 3004 operand indOffset32Narrow(rRegN reg, immL32 off) 3005 %{ 3006 predicate(CompressedOops::shift() == 0); 3007 constraint(ALLOC_IN_RC(ptr_reg)); 3008 match(AddP (DecodeN reg) off); 3009 3010 format %{ "[$reg + $off (32-bit)]" %} 3011 interface(MEMORY_INTER) %{ 3012 base($reg); 3013 index(0x4); 3014 scale(0x0); 3015 disp($off); 3016 %} 3017 %} 3018 3019 // Indirect Memory Plus Index Register Plus Offset Operand 3020 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3021 %{ 3022 predicate(CompressedOops::shift() == 0); 3023 constraint(ALLOC_IN_RC(ptr_reg)); 3024 match(AddP (AddP (DecodeN reg) lreg) off); 3025 3026 op_cost(10); 3027 format %{"[$reg + $off + $lreg]" %} 3028 interface(MEMORY_INTER) %{ 3029 base($reg); 3030 index($lreg); 3031 scale(0x0); 3032 disp($off); 3033 %} 3034 %} 3035 3036 // Indirect Memory Plus Index Register Plus Offset Operand 3037 operand indIndexNarrow(rRegN reg, rRegL lreg) 3038 %{ 3039 predicate(CompressedOops::shift() == 0); 3040 constraint(ALLOC_IN_RC(ptr_reg)); 3041 match(AddP (DecodeN reg) lreg); 3042 3043 op_cost(10); 3044 format %{"[$reg + $lreg]" %} 3045 interface(MEMORY_INTER) %{ 3046 base($reg); 3047 index($lreg); 3048 scale(0x0); 3049 disp(0x0); 3050 %} 3051 %} 3052 3053 // Indirect Memory Times Scale Plus Index Register 3054 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3055 %{ 3056 predicate(CompressedOops::shift() == 0); 3057 constraint(ALLOC_IN_RC(ptr_reg)); 3058 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3059 3060 op_cost(10); 3061 format %{"[$reg + $lreg << $scale]" %} 3062 interface(MEMORY_INTER) %{ 3063 base($reg); 3064 index($lreg); 3065 scale($scale); 3066 disp(0x0); 3067 %} 3068 %} 3069 3070 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3071 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3072 %{ 3073 predicate(CompressedOops::shift() == 0); 3074 constraint(ALLOC_IN_RC(ptr_reg)); 3075 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3076 3077 op_cost(10); 3078 format %{"[$reg + $off + $lreg << $scale]" %} 3079 interface(MEMORY_INTER) %{ 3080 base($reg); 3081 index($lreg); 3082 scale($scale); 3083 disp($off); 3084 %} 3085 %} 3086 3087 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3088 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3089 %{ 3090 constraint(ALLOC_IN_RC(ptr_reg)); 3091 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3092 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3093 3094 op_cost(10); 3095 format %{"[$reg + $off + $idx]" %} 3096 interface(MEMORY_INTER) %{ 3097 base($reg); 3098 index($idx); 3099 scale(0x0); 3100 disp($off); 3101 %} 3102 %} 3103 3104 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3105 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3106 %{ 3107 constraint(ALLOC_IN_RC(ptr_reg)); 3108 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3109 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3110 3111 op_cost(10); 3112 format %{"[$reg + $off + $idx << $scale]" %} 3113 interface(MEMORY_INTER) %{ 3114 base($reg); 3115 index($idx); 3116 scale($scale); 3117 disp($off); 3118 %} 3119 %} 3120 3121 //----------Special Memory Operands-------------------------------------------- 3122 // Stack Slot Operand - This operand is used for loading and storing temporary 3123 // values on the stack where a match requires a value to 3124 // flow through memory. 3125 operand stackSlotP(sRegP reg) 3126 %{ 3127 constraint(ALLOC_IN_RC(stack_slots)); 3128 // No match rule because this operand is only generated in matching 3129 3130 format %{ "[$reg]" %} 3131 interface(MEMORY_INTER) %{ 3132 base(0x4); // RSP 3133 index(0x4); // No Index 3134 scale(0x0); // No Scale 3135 disp($reg); // Stack Offset 3136 %} 3137 %} 3138 3139 operand stackSlotI(sRegI reg) 3140 %{ 3141 constraint(ALLOC_IN_RC(stack_slots)); 3142 // No match rule because this operand is only generated in matching 3143 3144 format %{ "[$reg]" %} 3145 interface(MEMORY_INTER) %{ 3146 base(0x4); // RSP 3147 index(0x4); // No Index 3148 scale(0x0); // No Scale 3149 disp($reg); // Stack Offset 3150 %} 3151 %} 3152 3153 operand stackSlotF(sRegF reg) 3154 %{ 3155 constraint(ALLOC_IN_RC(stack_slots)); 3156 // No match rule because this operand is only generated in matching 3157 3158 format %{ "[$reg]" %} 3159 interface(MEMORY_INTER) %{ 3160 base(0x4); // RSP 3161 index(0x4); // No Index 3162 scale(0x0); // No Scale 3163 disp($reg); // Stack Offset 3164 %} 3165 %} 3166 3167 operand stackSlotD(sRegD reg) 3168 %{ 3169 constraint(ALLOC_IN_RC(stack_slots)); 3170 // No match rule because this operand is only generated in matching 3171 3172 format %{ "[$reg]" %} 3173 interface(MEMORY_INTER) %{ 3174 base(0x4); // RSP 3175 index(0x4); // No Index 3176 scale(0x0); // No Scale 3177 disp($reg); // Stack Offset 3178 %} 3179 %} 3180 operand stackSlotL(sRegL reg) 3181 %{ 3182 constraint(ALLOC_IN_RC(stack_slots)); 3183 // No match rule because this operand is only generated in matching 3184 3185 format %{ "[$reg]" %} 3186 interface(MEMORY_INTER) %{ 3187 base(0x4); // RSP 3188 index(0x4); // No Index 3189 scale(0x0); // No Scale 3190 disp($reg); // Stack Offset 3191 %} 3192 %} 3193 3194 //----------Conditional Branch Operands---------------------------------------- 3195 // Comparison Op - This is the operation of the comparison, and is limited to 3196 // the following set of codes: 3197 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3198 // 3199 // Other attributes of the comparison, such as unsignedness, are specified 3200 // by the comparison instruction that sets a condition code flags register. 3201 // That result is represented by a flags operand whose subtype is appropriate 3202 // to the unsignedness (etc.) of the comparison. 3203 // 3204 // Later, the instruction which matches both the Comparison Op (a Bool) and 3205 // the flags (produced by the Cmp) specifies the coding of the comparison op 3206 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3207 3208 // Comparison Code 3209 operand cmpOp() 3210 %{ 3211 match(Bool); 3212 3213 format %{ "" %} 3214 interface(COND_INTER) %{ 3215 equal(0x4, "e"); 3216 not_equal(0x5, "ne"); 3217 less(0xC, "l"); 3218 greater_equal(0xD, "ge"); 3219 less_equal(0xE, "le"); 3220 greater(0xF, "g"); 3221 overflow(0x0, "o"); 3222 no_overflow(0x1, "no"); 3223 %} 3224 %} 3225 3226 // Comparison Code, unsigned compare. Used by FP also, with 3227 // C2 (unordered) turned into GT or LT already. The other bits 3228 // C0 and C3 are turned into Carry & Zero flags. 3229 operand cmpOpU() 3230 %{ 3231 match(Bool); 3232 3233 format %{ "" %} 3234 interface(COND_INTER) %{ 3235 equal(0x4, "e"); 3236 not_equal(0x5, "ne"); 3237 less(0x2, "b"); 3238 greater_equal(0x3, "ae"); 3239 less_equal(0x6, "be"); 3240 greater(0x7, "a"); 3241 overflow(0x0, "o"); 3242 no_overflow(0x1, "no"); 3243 %} 3244 %} 3245 3246 3247 // Floating comparisons that don't require any fixup for the unordered case, 3248 // If both inputs of the comparison are the same, ZF is always set so we 3249 // don't need to use cmpOpUCF2 for eq/ne 3250 operand cmpOpUCF() %{ 3251 match(Bool); 3252 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3253 n->as_Bool()->_test._test == BoolTest::ge || 3254 n->as_Bool()->_test._test == BoolTest::le || 3255 n->as_Bool()->_test._test == BoolTest::gt || 3256 n->in(1)->in(1) == n->in(1)->in(2)); 3257 format %{ "" %} 3258 interface(COND_INTER) %{ 3259 equal(0xb, "np"); 3260 not_equal(0xa, "p"); 3261 less(0x2, "b"); 3262 greater_equal(0x3, "ae"); 3263 less_equal(0x6, "be"); 3264 greater(0x7, "a"); 3265 overflow(0x0, "o"); 3266 no_overflow(0x1, "no"); 3267 %} 3268 %} 3269 3270 3271 // Floating comparisons that can be fixed up with extra conditional jumps 3272 operand cmpOpUCF2() %{ 3273 match(Bool); 3274 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3275 n->as_Bool()->_test._test == BoolTest::eq) && 3276 n->in(1)->in(1) != n->in(1)->in(2)); 3277 format %{ "" %} 3278 interface(COND_INTER) %{ 3279 equal(0x4, "e"); 3280 not_equal(0x5, "ne"); 3281 less(0x2, "b"); 3282 greater_equal(0x3, "ae"); 3283 less_equal(0x6, "be"); 3284 greater(0x7, "a"); 3285 overflow(0x0, "o"); 3286 no_overflow(0x1, "no"); 3287 %} 3288 %} 3289 3290 //----------OPERAND CLASSES---------------------------------------------------- 3291 // Operand Classes are groups of operands that are used as to simplify 3292 // instruction definitions by not requiring the AD writer to specify separate 3293 // instructions for every form of operand when the instruction accepts 3294 // multiple operand types with the same basic encoding and format. The classic 3295 // case of this is memory operands. 3296 3297 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3298 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3299 indCompressedOopOffset, 3300 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3301 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3302 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3303 3304 //----------PIPELINE----------------------------------------------------------- 3305 // Rules which define the behavior of the target architectures pipeline. 3306 pipeline %{ 3307 3308 //----------ATTRIBUTES--------------------------------------------------------- 3309 attributes %{ 3310 variable_size_instructions; // Fixed size instructions 3311 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3312 instruction_unit_size = 1; // An instruction is 1 bytes long 3313 instruction_fetch_unit_size = 16; // The processor fetches one line 3314 instruction_fetch_units = 1; // of 16 bytes 3315 3316 // List of nop instructions 3317 nops( MachNop ); 3318 %} 3319 3320 //----------RESOURCES---------------------------------------------------------- 3321 // Resources are the functional units available to the machine 3322 3323 // Generic P2/P3 pipeline 3324 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3325 // 3 instructions decoded per cycle. 3326 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3327 // 3 ALU op, only ALU0 handles mul instructions. 3328 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3329 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3330 BR, FPU, 3331 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3332 3333 //----------PIPELINE DESCRIPTION----------------------------------------------- 3334 // Pipeline Description specifies the stages in the machine's pipeline 3335 3336 // Generic P2/P3 pipeline 3337 pipe_desc(S0, S1, S2, S3, S4, S5); 3338 3339 //----------PIPELINE CLASSES--------------------------------------------------- 3340 // Pipeline Classes describe the stages in which input and output are 3341 // referenced by the hardware pipeline. 3342 3343 // Naming convention: ialu or fpu 3344 // Then: _reg 3345 // Then: _reg if there is a 2nd register 3346 // Then: _long if it's a pair of instructions implementing a long 3347 // Then: _fat if it requires the big decoder 3348 // Or: _mem if it requires the big decoder and a memory unit. 3349 3350 // Integer ALU reg operation 3351 pipe_class ialu_reg(rRegI dst) 3352 %{ 3353 single_instruction; 3354 dst : S4(write); 3355 dst : S3(read); 3356 DECODE : S0; // any decoder 3357 ALU : S3; // any alu 3358 %} 3359 3360 // Long ALU reg operation 3361 pipe_class ialu_reg_long(rRegL dst) 3362 %{ 3363 instruction_count(2); 3364 dst : S4(write); 3365 dst : S3(read); 3366 DECODE : S0(2); // any 2 decoders 3367 ALU : S3(2); // both alus 3368 %} 3369 3370 // Integer ALU reg operation using big decoder 3371 pipe_class ialu_reg_fat(rRegI dst) 3372 %{ 3373 single_instruction; 3374 dst : S4(write); 3375 dst : S3(read); 3376 D0 : S0; // big decoder only 3377 ALU : S3; // any alu 3378 %} 3379 3380 // Integer ALU reg-reg operation 3381 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3382 %{ 3383 single_instruction; 3384 dst : S4(write); 3385 src : S3(read); 3386 DECODE : S0; // any decoder 3387 ALU : S3; // any alu 3388 %} 3389 3390 // Integer ALU reg-reg operation 3391 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3392 %{ 3393 single_instruction; 3394 dst : S4(write); 3395 src : S3(read); 3396 D0 : S0; // big decoder only 3397 ALU : S3; // any alu 3398 %} 3399 3400 // Integer ALU reg-mem operation 3401 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3402 %{ 3403 single_instruction; 3404 dst : S5(write); 3405 mem : S3(read); 3406 D0 : S0; // big decoder only 3407 ALU : S4; // any alu 3408 MEM : S3; // any mem 3409 %} 3410 3411 // Integer mem operation (prefetch) 3412 pipe_class ialu_mem(memory mem) 3413 %{ 3414 single_instruction; 3415 mem : S3(read); 3416 D0 : S0; // big decoder only 3417 MEM : S3; // any mem 3418 %} 3419 3420 // Integer Store to Memory 3421 pipe_class ialu_mem_reg(memory mem, rRegI src) 3422 %{ 3423 single_instruction; 3424 mem : S3(read); 3425 src : S5(read); 3426 D0 : S0; // big decoder only 3427 ALU : S4; // any alu 3428 MEM : S3; 3429 %} 3430 3431 // // Long Store to Memory 3432 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3433 // %{ 3434 // instruction_count(2); 3435 // mem : S3(read); 3436 // src : S5(read); 3437 // D0 : S0(2); // big decoder only; twice 3438 // ALU : S4(2); // any 2 alus 3439 // MEM : S3(2); // Both mems 3440 // %} 3441 3442 // Integer Store to Memory 3443 pipe_class ialu_mem_imm(memory mem) 3444 %{ 3445 single_instruction; 3446 mem : S3(read); 3447 D0 : S0; // big decoder only 3448 ALU : S4; // any alu 3449 MEM : S3; 3450 %} 3451 3452 // Integer ALU0 reg-reg operation 3453 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3454 %{ 3455 single_instruction; 3456 dst : S4(write); 3457 src : S3(read); 3458 D0 : S0; // Big decoder only 3459 ALU0 : S3; // only alu0 3460 %} 3461 3462 // Integer ALU0 reg-mem operation 3463 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3464 %{ 3465 single_instruction; 3466 dst : S5(write); 3467 mem : S3(read); 3468 D0 : S0; // big decoder only 3469 ALU0 : S4; // ALU0 only 3470 MEM : S3; // any mem 3471 %} 3472 3473 // Integer ALU reg-reg operation 3474 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3475 %{ 3476 single_instruction; 3477 cr : S4(write); 3478 src1 : S3(read); 3479 src2 : S3(read); 3480 DECODE : S0; // any decoder 3481 ALU : S3; // any alu 3482 %} 3483 3484 // Integer ALU reg-imm operation 3485 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3486 %{ 3487 single_instruction; 3488 cr : S4(write); 3489 src1 : S3(read); 3490 DECODE : S0; // any decoder 3491 ALU : S3; // any alu 3492 %} 3493 3494 // Integer ALU reg-mem operation 3495 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3496 %{ 3497 single_instruction; 3498 cr : S4(write); 3499 src1 : S3(read); 3500 src2 : S3(read); 3501 D0 : S0; // big decoder only 3502 ALU : S4; // any alu 3503 MEM : S3; 3504 %} 3505 3506 // Conditional move reg-reg 3507 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3508 %{ 3509 instruction_count(4); 3510 y : S4(read); 3511 q : S3(read); 3512 p : S3(read); 3513 DECODE : S0(4); // any decoder 3514 %} 3515 3516 // Conditional move reg-reg 3517 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3518 %{ 3519 single_instruction; 3520 dst : S4(write); 3521 src : S3(read); 3522 cr : S3(read); 3523 DECODE : S0; // any decoder 3524 %} 3525 3526 // Conditional move reg-mem 3527 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3528 %{ 3529 single_instruction; 3530 dst : S4(write); 3531 src : S3(read); 3532 cr : S3(read); 3533 DECODE : S0; // any decoder 3534 MEM : S3; 3535 %} 3536 3537 // Conditional move reg-reg long 3538 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3539 %{ 3540 single_instruction; 3541 dst : S4(write); 3542 src : S3(read); 3543 cr : S3(read); 3544 DECODE : S0(2); // any 2 decoders 3545 %} 3546 3547 // Float reg-reg operation 3548 pipe_class fpu_reg(regD dst) 3549 %{ 3550 instruction_count(2); 3551 dst : S3(read); 3552 DECODE : S0(2); // any 2 decoders 3553 FPU : S3; 3554 %} 3555 3556 // Float reg-reg operation 3557 pipe_class fpu_reg_reg(regD dst, regD src) 3558 %{ 3559 instruction_count(2); 3560 dst : S4(write); 3561 src : S3(read); 3562 DECODE : S0(2); // any 2 decoders 3563 FPU : S3; 3564 %} 3565 3566 // Float reg-reg operation 3567 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3568 %{ 3569 instruction_count(3); 3570 dst : S4(write); 3571 src1 : S3(read); 3572 src2 : S3(read); 3573 DECODE : S0(3); // any 3 decoders 3574 FPU : S3(2); 3575 %} 3576 3577 // Float reg-reg operation 3578 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3579 %{ 3580 instruction_count(4); 3581 dst : S4(write); 3582 src1 : S3(read); 3583 src2 : S3(read); 3584 src3 : S3(read); 3585 DECODE : S0(4); // any 3 decoders 3586 FPU : S3(2); 3587 %} 3588 3589 // Float reg-reg operation 3590 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3591 %{ 3592 instruction_count(4); 3593 dst : S4(write); 3594 src1 : S3(read); 3595 src2 : S3(read); 3596 src3 : S3(read); 3597 DECODE : S1(3); // any 3 decoders 3598 D0 : S0; // Big decoder only 3599 FPU : S3(2); 3600 MEM : S3; 3601 %} 3602 3603 // Float reg-mem operation 3604 pipe_class fpu_reg_mem(regD dst, memory mem) 3605 %{ 3606 instruction_count(2); 3607 dst : S5(write); 3608 mem : S3(read); 3609 D0 : S0; // big decoder only 3610 DECODE : S1; // any decoder for FPU POP 3611 FPU : S4; 3612 MEM : S3; // any mem 3613 %} 3614 3615 // Float reg-mem operation 3616 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3617 %{ 3618 instruction_count(3); 3619 dst : S5(write); 3620 src1 : S3(read); 3621 mem : S3(read); 3622 D0 : S0; // big decoder only 3623 DECODE : S1(2); // any decoder for FPU POP 3624 FPU : S4; 3625 MEM : S3; // any mem 3626 %} 3627 3628 // Float mem-reg operation 3629 pipe_class fpu_mem_reg(memory mem, regD src) 3630 %{ 3631 instruction_count(2); 3632 src : S5(read); 3633 mem : S3(read); 3634 DECODE : S0; // any decoder for FPU PUSH 3635 D0 : S1; // big decoder only 3636 FPU : S4; 3637 MEM : S3; // any mem 3638 %} 3639 3640 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3641 %{ 3642 instruction_count(3); 3643 src1 : S3(read); 3644 src2 : S3(read); 3645 mem : S3(read); 3646 DECODE : S0(2); // any decoder for FPU PUSH 3647 D0 : S1; // big decoder only 3648 FPU : S4; 3649 MEM : S3; // any mem 3650 %} 3651 3652 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3653 %{ 3654 instruction_count(3); 3655 src1 : S3(read); 3656 src2 : S3(read); 3657 mem : S4(read); 3658 DECODE : S0; // any decoder for FPU PUSH 3659 D0 : S0(2); // big decoder only 3660 FPU : S4; 3661 MEM : S3(2); // any mem 3662 %} 3663 3664 pipe_class fpu_mem_mem(memory dst, memory src1) 3665 %{ 3666 instruction_count(2); 3667 src1 : S3(read); 3668 dst : S4(read); 3669 D0 : S0(2); // big decoder only 3670 MEM : S3(2); // any mem 3671 %} 3672 3673 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3674 %{ 3675 instruction_count(3); 3676 src1 : S3(read); 3677 src2 : S3(read); 3678 dst : S4(read); 3679 D0 : S0(3); // big decoder only 3680 FPU : S4; 3681 MEM : S3(3); // any mem 3682 %} 3683 3684 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3685 %{ 3686 instruction_count(3); 3687 src1 : S4(read); 3688 mem : S4(read); 3689 DECODE : S0; // any decoder for FPU PUSH 3690 D0 : S0(2); // big decoder only 3691 FPU : S4; 3692 MEM : S3(2); // any mem 3693 %} 3694 3695 // Float load constant 3696 pipe_class fpu_reg_con(regD dst) 3697 %{ 3698 instruction_count(2); 3699 dst : S5(write); 3700 D0 : S0; // big decoder only for the load 3701 DECODE : S1; // any decoder for FPU POP 3702 FPU : S4; 3703 MEM : S3; // any mem 3704 %} 3705 3706 // Float load constant 3707 pipe_class fpu_reg_reg_con(regD dst, regD src) 3708 %{ 3709 instruction_count(3); 3710 dst : S5(write); 3711 src : S3(read); 3712 D0 : S0; // big decoder only for the load 3713 DECODE : S1(2); // any decoder for FPU POP 3714 FPU : S4; 3715 MEM : S3; // any mem 3716 %} 3717 3718 // UnConditional branch 3719 pipe_class pipe_jmp(label labl) 3720 %{ 3721 single_instruction; 3722 BR : S3; 3723 %} 3724 3725 // Conditional branch 3726 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3727 %{ 3728 single_instruction; 3729 cr : S1(read); 3730 BR : S3; 3731 %} 3732 3733 // Allocation idiom 3734 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3735 %{ 3736 instruction_count(1); force_serialization; 3737 fixed_latency(6); 3738 heap_ptr : S3(read); 3739 DECODE : S0(3); 3740 D0 : S2; 3741 MEM : S3; 3742 ALU : S3(2); 3743 dst : S5(write); 3744 BR : S5; 3745 %} 3746 3747 // Generic big/slow expanded idiom 3748 pipe_class pipe_slow() 3749 %{ 3750 instruction_count(10); multiple_bundles; force_serialization; 3751 fixed_latency(100); 3752 D0 : S0(2); 3753 MEM : S3(2); 3754 %} 3755 3756 // The real do-nothing guy 3757 pipe_class empty() 3758 %{ 3759 instruction_count(0); 3760 %} 3761 3762 // Define the class for the Nop node 3763 define 3764 %{ 3765 MachNop = empty; 3766 %} 3767 3768 %} 3769 3770 //----------INSTRUCTIONS------------------------------------------------------- 3771 // 3772 // match -- States which machine-independent subtree may be replaced 3773 // by this instruction. 3774 // ins_cost -- The estimated cost of this instruction is used by instruction 3775 // selection to identify a minimum cost tree of machine 3776 // instructions that matches a tree of machine-independent 3777 // instructions. 3778 // format -- A string providing the disassembly for this instruction. 3779 // The value of an instruction's operand may be inserted 3780 // by referring to it with a '$' prefix. 3781 // opcode -- Three instruction opcodes may be provided. These are referred 3782 // to within an encode class as $primary, $secondary, and $tertiary 3783 // rrspectively. The primary opcode is commonly used to 3784 // indicate the type of machine instruction, while secondary 3785 // and tertiary are often used for prefix options or addressing 3786 // modes. 3787 // ins_encode -- A list of encode classes with parameters. The encode class 3788 // name must have been defined in an 'enc_class' specification 3789 // in the encode section of the architecture description. 3790 3791 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3792 // Load Float 3793 instruct MoveF2VL(vlRegF dst, regF src) %{ 3794 match(Set dst src); 3795 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3796 ins_encode %{ 3797 ShouldNotReachHere(); 3798 %} 3799 ins_pipe( fpu_reg_reg ); 3800 %} 3801 3802 // Load Float 3803 instruct MoveF2LEG(legRegF dst, regF src) %{ 3804 match(Set dst src); 3805 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3806 ins_encode %{ 3807 ShouldNotReachHere(); 3808 %} 3809 ins_pipe( fpu_reg_reg ); 3810 %} 3811 3812 // Load Float 3813 instruct MoveVL2F(regF dst, vlRegF src) %{ 3814 match(Set dst src); 3815 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3816 ins_encode %{ 3817 ShouldNotReachHere(); 3818 %} 3819 ins_pipe( fpu_reg_reg ); 3820 %} 3821 3822 // Load Float 3823 instruct MoveLEG2F(regF dst, legRegF src) %{ 3824 match(Set dst src); 3825 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3826 ins_encode %{ 3827 ShouldNotReachHere(); 3828 %} 3829 ins_pipe( fpu_reg_reg ); 3830 %} 3831 3832 // Load Double 3833 instruct MoveD2VL(vlRegD dst, regD src) %{ 3834 match(Set dst src); 3835 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3836 ins_encode %{ 3837 ShouldNotReachHere(); 3838 %} 3839 ins_pipe( fpu_reg_reg ); 3840 %} 3841 3842 // Load Double 3843 instruct MoveD2LEG(legRegD dst, regD src) %{ 3844 match(Set dst src); 3845 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3846 ins_encode %{ 3847 ShouldNotReachHere(); 3848 %} 3849 ins_pipe( fpu_reg_reg ); 3850 %} 3851 3852 // Load Double 3853 instruct MoveVL2D(regD dst, vlRegD src) %{ 3854 match(Set dst src); 3855 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3856 ins_encode %{ 3857 ShouldNotReachHere(); 3858 %} 3859 ins_pipe( fpu_reg_reg ); 3860 %} 3861 3862 // Load Double 3863 instruct MoveLEG2D(regD dst, legRegD src) %{ 3864 match(Set dst src); 3865 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3866 ins_encode %{ 3867 ShouldNotReachHere(); 3868 %} 3869 ins_pipe( fpu_reg_reg ); 3870 %} 3871 3872 //----------Load/Store/Move Instructions--------------------------------------- 3873 //----------Load Instructions-------------------------------------------------- 3874 3875 // Load Byte (8 bit signed) 3876 instruct loadB(rRegI dst, memory mem) 3877 %{ 3878 match(Set dst (LoadB mem)); 3879 3880 ins_cost(125); 3881 format %{ "movsbl $dst, $mem\t# byte" %} 3882 3883 ins_encode %{ 3884 __ movsbl($dst$$Register, $mem$$Address); 3885 %} 3886 3887 ins_pipe(ialu_reg_mem); 3888 %} 3889 3890 // Load Byte (8 bit signed) into Long Register 3891 instruct loadB2L(rRegL dst, memory mem) 3892 %{ 3893 match(Set dst (ConvI2L (LoadB mem))); 3894 3895 ins_cost(125); 3896 format %{ "movsbq $dst, $mem\t# byte -> long" %} 3897 3898 ins_encode %{ 3899 __ movsbq($dst$$Register, $mem$$Address); 3900 %} 3901 3902 ins_pipe(ialu_reg_mem); 3903 %} 3904 3905 // Load Unsigned Byte (8 bit UNsigned) 3906 instruct loadUB(rRegI dst, memory mem) 3907 %{ 3908 match(Set dst (LoadUB mem)); 3909 3910 ins_cost(125); 3911 format %{ "movzbl $dst, $mem\t# ubyte" %} 3912 3913 ins_encode %{ 3914 __ movzbl($dst$$Register, $mem$$Address); 3915 %} 3916 3917 ins_pipe(ialu_reg_mem); 3918 %} 3919 3920 // Load Unsigned Byte (8 bit UNsigned) into Long Register 3921 instruct loadUB2L(rRegL dst, memory mem) 3922 %{ 3923 match(Set dst (ConvI2L (LoadUB mem))); 3924 3925 ins_cost(125); 3926 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 3927 3928 ins_encode %{ 3929 __ movzbq($dst$$Register, $mem$$Address); 3930 %} 3931 3932 ins_pipe(ialu_reg_mem); 3933 %} 3934 3935 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 3936 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 3937 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 3938 effect(KILL cr); 3939 3940 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 3941 "andl $dst, right_n_bits($mask, 8)" %} 3942 ins_encode %{ 3943 Register Rdst = $dst$$Register; 3944 __ movzbq(Rdst, $mem$$Address); 3945 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 3946 %} 3947 ins_pipe(ialu_reg_mem); 3948 %} 3949 3950 // Load Short (16 bit signed) 3951 instruct loadS(rRegI dst, memory mem) 3952 %{ 3953 match(Set dst (LoadS mem)); 3954 3955 ins_cost(125); 3956 format %{ "movswl $dst, $mem\t# short" %} 3957 3958 ins_encode %{ 3959 __ movswl($dst$$Register, $mem$$Address); 3960 %} 3961 3962 ins_pipe(ialu_reg_mem); 3963 %} 3964 3965 // Load Short (16 bit signed) to Byte (8 bit signed) 3966 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 3967 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 3968 3969 ins_cost(125); 3970 format %{ "movsbl $dst, $mem\t# short -> byte" %} 3971 ins_encode %{ 3972 __ movsbl($dst$$Register, $mem$$Address); 3973 %} 3974 ins_pipe(ialu_reg_mem); 3975 %} 3976 3977 // Load Short (16 bit signed) into Long Register 3978 instruct loadS2L(rRegL dst, memory mem) 3979 %{ 3980 match(Set dst (ConvI2L (LoadS mem))); 3981 3982 ins_cost(125); 3983 format %{ "movswq $dst, $mem\t# short -> long" %} 3984 3985 ins_encode %{ 3986 __ movswq($dst$$Register, $mem$$Address); 3987 %} 3988 3989 ins_pipe(ialu_reg_mem); 3990 %} 3991 3992 // Load Unsigned Short/Char (16 bit UNsigned) 3993 instruct loadUS(rRegI dst, memory mem) 3994 %{ 3995 match(Set dst (LoadUS mem)); 3996 3997 ins_cost(125); 3998 format %{ "movzwl $dst, $mem\t# ushort/char" %} 3999 4000 ins_encode %{ 4001 __ movzwl($dst$$Register, $mem$$Address); 4002 %} 4003 4004 ins_pipe(ialu_reg_mem); 4005 %} 4006 4007 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4008 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4009 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4010 4011 ins_cost(125); 4012 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4013 ins_encode %{ 4014 __ movsbl($dst$$Register, $mem$$Address); 4015 %} 4016 ins_pipe(ialu_reg_mem); 4017 %} 4018 4019 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4020 instruct loadUS2L(rRegL dst, memory mem) 4021 %{ 4022 match(Set dst (ConvI2L (LoadUS mem))); 4023 4024 ins_cost(125); 4025 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4026 4027 ins_encode %{ 4028 __ movzwq($dst$$Register, $mem$$Address); 4029 %} 4030 4031 ins_pipe(ialu_reg_mem); 4032 %} 4033 4034 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4035 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4036 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4037 4038 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4039 ins_encode %{ 4040 __ movzbq($dst$$Register, $mem$$Address); 4041 %} 4042 ins_pipe(ialu_reg_mem); 4043 %} 4044 4045 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4046 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4047 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4048 effect(KILL cr); 4049 4050 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4051 "andl $dst, right_n_bits($mask, 16)" %} 4052 ins_encode %{ 4053 Register Rdst = $dst$$Register; 4054 __ movzwq(Rdst, $mem$$Address); 4055 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4056 %} 4057 ins_pipe(ialu_reg_mem); 4058 %} 4059 4060 // Load Integer 4061 instruct loadI(rRegI dst, memory mem) 4062 %{ 4063 match(Set dst (LoadI mem)); 4064 4065 ins_cost(125); 4066 format %{ "movl $dst, $mem\t# int" %} 4067 4068 ins_encode %{ 4069 __ movl($dst$$Register, $mem$$Address); 4070 %} 4071 4072 ins_pipe(ialu_reg_mem); 4073 %} 4074 4075 // Load Integer (32 bit signed) to Byte (8 bit signed) 4076 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4077 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4078 4079 ins_cost(125); 4080 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4081 ins_encode %{ 4082 __ movsbl($dst$$Register, $mem$$Address); 4083 %} 4084 ins_pipe(ialu_reg_mem); 4085 %} 4086 4087 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4088 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4089 match(Set dst (AndI (LoadI mem) mask)); 4090 4091 ins_cost(125); 4092 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4093 ins_encode %{ 4094 __ movzbl($dst$$Register, $mem$$Address); 4095 %} 4096 ins_pipe(ialu_reg_mem); 4097 %} 4098 4099 // Load Integer (32 bit signed) to Short (16 bit signed) 4100 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4101 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4102 4103 ins_cost(125); 4104 format %{ "movswl $dst, $mem\t# int -> short" %} 4105 ins_encode %{ 4106 __ movswl($dst$$Register, $mem$$Address); 4107 %} 4108 ins_pipe(ialu_reg_mem); 4109 %} 4110 4111 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4112 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4113 match(Set dst (AndI (LoadI mem) mask)); 4114 4115 ins_cost(125); 4116 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4117 ins_encode %{ 4118 __ movzwl($dst$$Register, $mem$$Address); 4119 %} 4120 ins_pipe(ialu_reg_mem); 4121 %} 4122 4123 // Load Integer into Long Register 4124 instruct loadI2L(rRegL dst, memory mem) 4125 %{ 4126 match(Set dst (ConvI2L (LoadI mem))); 4127 4128 ins_cost(125); 4129 format %{ "movslq $dst, $mem\t# int -> long" %} 4130 4131 ins_encode %{ 4132 __ movslq($dst$$Register, $mem$$Address); 4133 %} 4134 4135 ins_pipe(ialu_reg_mem); 4136 %} 4137 4138 // Load Integer with mask 0xFF into Long Register 4139 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4140 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4141 4142 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4143 ins_encode %{ 4144 __ movzbq($dst$$Register, $mem$$Address); 4145 %} 4146 ins_pipe(ialu_reg_mem); 4147 %} 4148 4149 // Load Integer with mask 0xFFFF into Long Register 4150 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4151 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4152 4153 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4154 ins_encode %{ 4155 __ movzwq($dst$$Register, $mem$$Address); 4156 %} 4157 ins_pipe(ialu_reg_mem); 4158 %} 4159 4160 // Load Integer with a 31-bit mask into Long Register 4161 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4162 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4163 effect(KILL cr); 4164 4165 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4166 "andl $dst, $mask" %} 4167 ins_encode %{ 4168 Register Rdst = $dst$$Register; 4169 __ movl(Rdst, $mem$$Address); 4170 __ andl(Rdst, $mask$$constant); 4171 %} 4172 ins_pipe(ialu_reg_mem); 4173 %} 4174 4175 // Load Unsigned Integer into Long Register 4176 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4177 %{ 4178 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4179 4180 ins_cost(125); 4181 format %{ "movl $dst, $mem\t# uint -> long" %} 4182 4183 ins_encode %{ 4184 __ movl($dst$$Register, $mem$$Address); 4185 %} 4186 4187 ins_pipe(ialu_reg_mem); 4188 %} 4189 4190 // Load Long 4191 instruct loadL(rRegL dst, memory mem) 4192 %{ 4193 match(Set dst (LoadL mem)); 4194 4195 ins_cost(125); 4196 format %{ "movq $dst, $mem\t# long" %} 4197 4198 ins_encode %{ 4199 __ movq($dst$$Register, $mem$$Address); 4200 %} 4201 4202 ins_pipe(ialu_reg_mem); // XXX 4203 %} 4204 4205 // Load Range 4206 instruct loadRange(rRegI dst, memory mem) 4207 %{ 4208 match(Set dst (LoadRange mem)); 4209 4210 ins_cost(125); // XXX 4211 format %{ "movl $dst, $mem\t# range" %} 4212 ins_encode %{ 4213 __ movl($dst$$Register, $mem$$Address); 4214 %} 4215 ins_pipe(ialu_reg_mem); 4216 %} 4217 4218 // Load Pointer 4219 instruct loadP(rRegP dst, memory mem) 4220 %{ 4221 match(Set dst (LoadP mem)); 4222 predicate(n->as_Load()->barrier_data() == 0); 4223 4224 ins_cost(125); // XXX 4225 format %{ "movq $dst, $mem\t# ptr" %} 4226 ins_encode %{ 4227 __ movq($dst$$Register, $mem$$Address); 4228 %} 4229 ins_pipe(ialu_reg_mem); // XXX 4230 %} 4231 4232 // Load Compressed Pointer 4233 instruct loadN(rRegN dst, memory mem) 4234 %{ 4235 match(Set dst (LoadN mem)); 4236 4237 ins_cost(125); // XXX 4238 format %{ "movl $dst, $mem\t# compressed ptr" %} 4239 ins_encode %{ 4240 __ movl($dst$$Register, $mem$$Address); 4241 %} 4242 ins_pipe(ialu_reg_mem); // XXX 4243 %} 4244 4245 4246 // Load Klass Pointer 4247 instruct loadKlass(rRegP dst, memory mem) 4248 %{ 4249 match(Set dst (LoadKlass mem)); 4250 4251 ins_cost(125); // XXX 4252 format %{ "movq $dst, $mem\t# class" %} 4253 ins_encode %{ 4254 __ movq($dst$$Register, $mem$$Address); 4255 %} 4256 ins_pipe(ialu_reg_mem); // XXX 4257 %} 4258 4259 // Load narrow Klass Pointer 4260 instruct loadNKlass(rRegN dst, memory mem) 4261 %{ 4262 predicate(!UseCompactObjectHeaders); 4263 match(Set dst (LoadNKlass mem)); 4264 4265 ins_cost(125); // XXX 4266 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4267 ins_encode %{ 4268 __ movl($dst$$Register, $mem$$Address); 4269 %} 4270 ins_pipe(ialu_reg_mem); // XXX 4271 %} 4272 4273 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4274 %{ 4275 predicate(UseCompactObjectHeaders); 4276 match(Set dst (LoadNKlass mem)); 4277 effect(KILL cr); 4278 ins_cost(125); // XXX 4279 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4280 ins_encode %{ 4281 Register index = $mem$$index != 4 ? $mem$$index$$Register : noreg; 4282 Address::ScaleFactor sf = (index != noreg) ? static_cast<Address::ScaleFactor>($mem$$scale) : Address::no_scale; 4283 __ load_nklass_compact_c2($dst$$Register, $mem$$base$$Register, index, sf, $mem$$disp); 4284 %} 4285 ins_pipe(pipe_slow); // XXX 4286 %} 4287 4288 // Load Float 4289 instruct loadF(regF dst, memory mem) 4290 %{ 4291 match(Set dst (LoadF mem)); 4292 4293 ins_cost(145); // XXX 4294 format %{ "movss $dst, $mem\t# float" %} 4295 ins_encode %{ 4296 __ movflt($dst$$XMMRegister, $mem$$Address); 4297 %} 4298 ins_pipe(pipe_slow); // XXX 4299 %} 4300 4301 // Load Double 4302 instruct loadD_partial(regD dst, memory mem) 4303 %{ 4304 predicate(!UseXmmLoadAndClearUpper); 4305 match(Set dst (LoadD mem)); 4306 4307 ins_cost(145); // XXX 4308 format %{ "movlpd $dst, $mem\t# double" %} 4309 ins_encode %{ 4310 __ movdbl($dst$$XMMRegister, $mem$$Address); 4311 %} 4312 ins_pipe(pipe_slow); // XXX 4313 %} 4314 4315 instruct loadD(regD dst, memory mem) 4316 %{ 4317 predicate(UseXmmLoadAndClearUpper); 4318 match(Set dst (LoadD mem)); 4319 4320 ins_cost(145); // XXX 4321 format %{ "movsd $dst, $mem\t# double" %} 4322 ins_encode %{ 4323 __ movdbl($dst$$XMMRegister, $mem$$Address); 4324 %} 4325 ins_pipe(pipe_slow); // XXX 4326 %} 4327 4328 // max = java.lang.Math.max(float a, float b) 4329 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4330 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4331 match(Set dst (MaxF a b)); 4332 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4333 format %{ "maxF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4334 ins_encode %{ 4335 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4336 %} 4337 ins_pipe( pipe_slow ); 4338 %} 4339 4340 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4341 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4342 match(Set dst (MaxF a b)); 4343 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4344 4345 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 4346 ins_encode %{ 4347 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4348 false /*min*/, true /*single*/); 4349 %} 4350 ins_pipe( pipe_slow ); 4351 %} 4352 4353 // max = java.lang.Math.max(double a, double b) 4354 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4355 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4356 match(Set dst (MaxD a b)); 4357 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4358 format %{ "maxD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4359 ins_encode %{ 4360 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4361 %} 4362 ins_pipe( pipe_slow ); 4363 %} 4364 4365 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4366 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4367 match(Set dst (MaxD a b)); 4368 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4369 4370 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 4371 ins_encode %{ 4372 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4373 false /*min*/, false /*single*/); 4374 %} 4375 ins_pipe( pipe_slow ); 4376 %} 4377 4378 // min = java.lang.Math.min(float a, float b) 4379 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4380 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4381 match(Set dst (MinF a b)); 4382 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4383 format %{ "minF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4384 ins_encode %{ 4385 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4386 %} 4387 ins_pipe( pipe_slow ); 4388 %} 4389 4390 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4391 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4392 match(Set dst (MinF a b)); 4393 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4394 4395 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 4396 ins_encode %{ 4397 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4398 true /*min*/, true /*single*/); 4399 %} 4400 ins_pipe( pipe_slow ); 4401 %} 4402 4403 // min = java.lang.Math.min(double a, double b) 4404 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4405 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4406 match(Set dst (MinD a b)); 4407 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4408 format %{ "minD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4409 ins_encode %{ 4410 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4411 %} 4412 ins_pipe( pipe_slow ); 4413 %} 4414 4415 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4416 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4417 match(Set dst (MinD a b)); 4418 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4419 4420 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 4421 ins_encode %{ 4422 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4423 true /*min*/, false /*single*/); 4424 %} 4425 ins_pipe( pipe_slow ); 4426 %} 4427 4428 // Load Effective Address 4429 instruct leaP8(rRegP dst, indOffset8 mem) 4430 %{ 4431 match(Set dst mem); 4432 4433 ins_cost(110); // XXX 4434 format %{ "leaq $dst, $mem\t# ptr 8" %} 4435 ins_encode %{ 4436 __ leaq($dst$$Register, $mem$$Address); 4437 %} 4438 ins_pipe(ialu_reg_reg_fat); 4439 %} 4440 4441 instruct leaP32(rRegP dst, indOffset32 mem) 4442 %{ 4443 match(Set dst mem); 4444 4445 ins_cost(110); 4446 format %{ "leaq $dst, $mem\t# ptr 32" %} 4447 ins_encode %{ 4448 __ leaq($dst$$Register, $mem$$Address); 4449 %} 4450 ins_pipe(ialu_reg_reg_fat); 4451 %} 4452 4453 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4454 %{ 4455 match(Set dst mem); 4456 4457 ins_cost(110); 4458 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4459 ins_encode %{ 4460 __ leaq($dst$$Register, $mem$$Address); 4461 %} 4462 ins_pipe(ialu_reg_reg_fat); 4463 %} 4464 4465 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4466 %{ 4467 match(Set dst mem); 4468 4469 ins_cost(110); 4470 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4471 ins_encode %{ 4472 __ leaq($dst$$Register, $mem$$Address); 4473 %} 4474 ins_pipe(ialu_reg_reg_fat); 4475 %} 4476 4477 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4478 %{ 4479 match(Set dst mem); 4480 4481 ins_cost(110); 4482 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4483 ins_encode %{ 4484 __ leaq($dst$$Register, $mem$$Address); 4485 %} 4486 ins_pipe(ialu_reg_reg_fat); 4487 %} 4488 4489 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4490 %{ 4491 match(Set dst mem); 4492 4493 ins_cost(110); 4494 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4495 ins_encode %{ 4496 __ leaq($dst$$Register, $mem$$Address); 4497 %} 4498 ins_pipe(ialu_reg_reg_fat); 4499 %} 4500 4501 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4502 %{ 4503 match(Set dst mem); 4504 4505 ins_cost(110); 4506 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4507 ins_encode %{ 4508 __ leaq($dst$$Register, $mem$$Address); 4509 %} 4510 ins_pipe(ialu_reg_reg_fat); 4511 %} 4512 4513 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4514 %{ 4515 match(Set dst mem); 4516 4517 ins_cost(110); 4518 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4519 ins_encode %{ 4520 __ leaq($dst$$Register, $mem$$Address); 4521 %} 4522 ins_pipe(ialu_reg_reg_fat); 4523 %} 4524 4525 // Load Effective Address which uses Narrow (32-bits) oop 4526 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4527 %{ 4528 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4529 match(Set dst mem); 4530 4531 ins_cost(110); 4532 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4533 ins_encode %{ 4534 __ leaq($dst$$Register, $mem$$Address); 4535 %} 4536 ins_pipe(ialu_reg_reg_fat); 4537 %} 4538 4539 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4540 %{ 4541 predicate(CompressedOops::shift() == 0); 4542 match(Set dst mem); 4543 4544 ins_cost(110); // XXX 4545 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4546 ins_encode %{ 4547 __ leaq($dst$$Register, $mem$$Address); 4548 %} 4549 ins_pipe(ialu_reg_reg_fat); 4550 %} 4551 4552 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4553 %{ 4554 predicate(CompressedOops::shift() == 0); 4555 match(Set dst mem); 4556 4557 ins_cost(110); 4558 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4559 ins_encode %{ 4560 __ leaq($dst$$Register, $mem$$Address); 4561 %} 4562 ins_pipe(ialu_reg_reg_fat); 4563 %} 4564 4565 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4566 %{ 4567 predicate(CompressedOops::shift() == 0); 4568 match(Set dst mem); 4569 4570 ins_cost(110); 4571 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4572 ins_encode %{ 4573 __ leaq($dst$$Register, $mem$$Address); 4574 %} 4575 ins_pipe(ialu_reg_reg_fat); 4576 %} 4577 4578 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4579 %{ 4580 predicate(CompressedOops::shift() == 0); 4581 match(Set dst mem); 4582 4583 ins_cost(110); 4584 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4585 ins_encode %{ 4586 __ leaq($dst$$Register, $mem$$Address); 4587 %} 4588 ins_pipe(ialu_reg_reg_fat); 4589 %} 4590 4591 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4592 %{ 4593 predicate(CompressedOops::shift() == 0); 4594 match(Set dst mem); 4595 4596 ins_cost(110); 4597 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4598 ins_encode %{ 4599 __ leaq($dst$$Register, $mem$$Address); 4600 %} 4601 ins_pipe(ialu_reg_reg_fat); 4602 %} 4603 4604 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4605 %{ 4606 predicate(CompressedOops::shift() == 0); 4607 match(Set dst mem); 4608 4609 ins_cost(110); 4610 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4611 ins_encode %{ 4612 __ leaq($dst$$Register, $mem$$Address); 4613 %} 4614 ins_pipe(ialu_reg_reg_fat); 4615 %} 4616 4617 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4618 %{ 4619 predicate(CompressedOops::shift() == 0); 4620 match(Set dst mem); 4621 4622 ins_cost(110); 4623 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4624 ins_encode %{ 4625 __ leaq($dst$$Register, $mem$$Address); 4626 %} 4627 ins_pipe(ialu_reg_reg_fat); 4628 %} 4629 4630 instruct loadConI(rRegI dst, immI src) 4631 %{ 4632 match(Set dst src); 4633 4634 format %{ "movl $dst, $src\t# int" %} 4635 ins_encode %{ 4636 __ movl($dst$$Register, $src$$constant); 4637 %} 4638 ins_pipe(ialu_reg_fat); // XXX 4639 %} 4640 4641 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4642 %{ 4643 match(Set dst src); 4644 effect(KILL cr); 4645 4646 ins_cost(50); 4647 format %{ "xorl $dst, $dst\t# int" %} 4648 ins_encode %{ 4649 __ xorl($dst$$Register, $dst$$Register); 4650 %} 4651 ins_pipe(ialu_reg); 4652 %} 4653 4654 instruct loadConL(rRegL dst, immL src) 4655 %{ 4656 match(Set dst src); 4657 4658 ins_cost(150); 4659 format %{ "movq $dst, $src\t# long" %} 4660 ins_encode %{ 4661 __ mov64($dst$$Register, $src$$constant); 4662 %} 4663 ins_pipe(ialu_reg); 4664 %} 4665 4666 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4667 %{ 4668 match(Set dst src); 4669 effect(KILL cr); 4670 4671 ins_cost(50); 4672 format %{ "xorl $dst, $dst\t# long" %} 4673 ins_encode %{ 4674 __ xorl($dst$$Register, $dst$$Register); 4675 %} 4676 ins_pipe(ialu_reg); // XXX 4677 %} 4678 4679 instruct loadConUL32(rRegL dst, immUL32 src) 4680 %{ 4681 match(Set dst src); 4682 4683 ins_cost(60); 4684 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4685 ins_encode %{ 4686 __ movl($dst$$Register, $src$$constant); 4687 %} 4688 ins_pipe(ialu_reg); 4689 %} 4690 4691 instruct loadConL32(rRegL dst, immL32 src) 4692 %{ 4693 match(Set dst src); 4694 4695 ins_cost(70); 4696 format %{ "movq $dst, $src\t# long (32-bit)" %} 4697 ins_encode %{ 4698 __ movq($dst$$Register, $src$$constant); 4699 %} 4700 ins_pipe(ialu_reg); 4701 %} 4702 4703 instruct loadConP(rRegP dst, immP con) %{ 4704 match(Set dst con); 4705 4706 format %{ "movq $dst, $con\t# ptr" %} 4707 ins_encode %{ 4708 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4709 %} 4710 ins_pipe(ialu_reg_fat); // XXX 4711 %} 4712 4713 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4714 %{ 4715 match(Set dst src); 4716 effect(KILL cr); 4717 4718 ins_cost(50); 4719 format %{ "xorl $dst, $dst\t# ptr" %} 4720 ins_encode %{ 4721 __ xorl($dst$$Register, $dst$$Register); 4722 %} 4723 ins_pipe(ialu_reg); 4724 %} 4725 4726 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4727 %{ 4728 match(Set dst src); 4729 effect(KILL cr); 4730 4731 ins_cost(60); 4732 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4733 ins_encode %{ 4734 __ movl($dst$$Register, $src$$constant); 4735 %} 4736 ins_pipe(ialu_reg); 4737 %} 4738 4739 instruct loadConF(regF dst, immF con) %{ 4740 match(Set dst con); 4741 ins_cost(125); 4742 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4743 ins_encode %{ 4744 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4745 %} 4746 ins_pipe(pipe_slow); 4747 %} 4748 4749 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4750 match(Set dst src); 4751 effect(KILL cr); 4752 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4753 ins_encode %{ 4754 __ xorq($dst$$Register, $dst$$Register); 4755 %} 4756 ins_pipe(ialu_reg); 4757 %} 4758 4759 instruct loadConN(rRegN dst, immN src) %{ 4760 match(Set dst src); 4761 4762 ins_cost(125); 4763 format %{ "movl $dst, $src\t# compressed ptr" %} 4764 ins_encode %{ 4765 address con = (address)$src$$constant; 4766 if (con == nullptr) { 4767 ShouldNotReachHere(); 4768 } else { 4769 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4770 } 4771 %} 4772 ins_pipe(ialu_reg_fat); // XXX 4773 %} 4774 4775 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4776 match(Set dst src); 4777 4778 ins_cost(125); 4779 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4780 ins_encode %{ 4781 address con = (address)$src$$constant; 4782 if (con == nullptr) { 4783 ShouldNotReachHere(); 4784 } else { 4785 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4786 } 4787 %} 4788 ins_pipe(ialu_reg_fat); // XXX 4789 %} 4790 4791 instruct loadConF0(regF dst, immF0 src) 4792 %{ 4793 match(Set dst src); 4794 ins_cost(100); 4795 4796 format %{ "xorps $dst, $dst\t# float 0.0" %} 4797 ins_encode %{ 4798 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4799 %} 4800 ins_pipe(pipe_slow); 4801 %} 4802 4803 // Use the same format since predicate() can not be used here. 4804 instruct loadConD(regD dst, immD con) %{ 4805 match(Set dst con); 4806 ins_cost(125); 4807 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4808 ins_encode %{ 4809 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4810 %} 4811 ins_pipe(pipe_slow); 4812 %} 4813 4814 instruct loadConD0(regD dst, immD0 src) 4815 %{ 4816 match(Set dst src); 4817 ins_cost(100); 4818 4819 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4820 ins_encode %{ 4821 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4822 %} 4823 ins_pipe(pipe_slow); 4824 %} 4825 4826 instruct loadSSI(rRegI dst, stackSlotI src) 4827 %{ 4828 match(Set dst src); 4829 4830 ins_cost(125); 4831 format %{ "movl $dst, $src\t# int stk" %} 4832 ins_encode %{ 4833 __ movl($dst$$Register, $src$$Address); 4834 %} 4835 ins_pipe(ialu_reg_mem); 4836 %} 4837 4838 instruct loadSSL(rRegL dst, stackSlotL src) 4839 %{ 4840 match(Set dst src); 4841 4842 ins_cost(125); 4843 format %{ "movq $dst, $src\t# long stk" %} 4844 ins_encode %{ 4845 __ movq($dst$$Register, $src$$Address); 4846 %} 4847 ins_pipe(ialu_reg_mem); 4848 %} 4849 4850 instruct loadSSP(rRegP dst, stackSlotP src) 4851 %{ 4852 match(Set dst src); 4853 4854 ins_cost(125); 4855 format %{ "movq $dst, $src\t# ptr stk" %} 4856 ins_encode %{ 4857 __ movq($dst$$Register, $src$$Address); 4858 %} 4859 ins_pipe(ialu_reg_mem); 4860 %} 4861 4862 instruct loadSSF(regF dst, stackSlotF src) 4863 %{ 4864 match(Set dst src); 4865 4866 ins_cost(125); 4867 format %{ "movss $dst, $src\t# float stk" %} 4868 ins_encode %{ 4869 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 4870 %} 4871 ins_pipe(pipe_slow); // XXX 4872 %} 4873 4874 // Use the same format since predicate() can not be used here. 4875 instruct loadSSD(regD dst, stackSlotD src) 4876 %{ 4877 match(Set dst src); 4878 4879 ins_cost(125); 4880 format %{ "movsd $dst, $src\t# double stk" %} 4881 ins_encode %{ 4882 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 4883 %} 4884 ins_pipe(pipe_slow); // XXX 4885 %} 4886 4887 // Prefetch instructions for allocation. 4888 // Must be safe to execute with invalid address (cannot fault). 4889 4890 instruct prefetchAlloc( memory mem ) %{ 4891 predicate(AllocatePrefetchInstr==3); 4892 match(PrefetchAllocation mem); 4893 ins_cost(125); 4894 4895 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 4896 ins_encode %{ 4897 __ prefetchw($mem$$Address); 4898 %} 4899 ins_pipe(ialu_mem); 4900 %} 4901 4902 instruct prefetchAllocNTA( memory mem ) %{ 4903 predicate(AllocatePrefetchInstr==0); 4904 match(PrefetchAllocation mem); 4905 ins_cost(125); 4906 4907 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 4908 ins_encode %{ 4909 __ prefetchnta($mem$$Address); 4910 %} 4911 ins_pipe(ialu_mem); 4912 %} 4913 4914 instruct prefetchAllocT0( memory mem ) %{ 4915 predicate(AllocatePrefetchInstr==1); 4916 match(PrefetchAllocation mem); 4917 ins_cost(125); 4918 4919 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 4920 ins_encode %{ 4921 __ prefetcht0($mem$$Address); 4922 %} 4923 ins_pipe(ialu_mem); 4924 %} 4925 4926 instruct prefetchAllocT2( memory mem ) %{ 4927 predicate(AllocatePrefetchInstr==2); 4928 match(PrefetchAllocation mem); 4929 ins_cost(125); 4930 4931 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 4932 ins_encode %{ 4933 __ prefetcht2($mem$$Address); 4934 %} 4935 ins_pipe(ialu_mem); 4936 %} 4937 4938 //----------Store Instructions------------------------------------------------- 4939 4940 // Store Byte 4941 instruct storeB(memory mem, rRegI src) 4942 %{ 4943 match(Set mem (StoreB mem src)); 4944 4945 ins_cost(125); // XXX 4946 format %{ "movb $mem, $src\t# byte" %} 4947 ins_encode %{ 4948 __ movb($mem$$Address, $src$$Register); 4949 %} 4950 ins_pipe(ialu_mem_reg); 4951 %} 4952 4953 // Store Char/Short 4954 instruct storeC(memory mem, rRegI src) 4955 %{ 4956 match(Set mem (StoreC mem src)); 4957 4958 ins_cost(125); // XXX 4959 format %{ "movw $mem, $src\t# char/short" %} 4960 ins_encode %{ 4961 __ movw($mem$$Address, $src$$Register); 4962 %} 4963 ins_pipe(ialu_mem_reg); 4964 %} 4965 4966 // Store Integer 4967 instruct storeI(memory mem, rRegI src) 4968 %{ 4969 match(Set mem (StoreI mem src)); 4970 4971 ins_cost(125); // XXX 4972 format %{ "movl $mem, $src\t# int" %} 4973 ins_encode %{ 4974 __ movl($mem$$Address, $src$$Register); 4975 %} 4976 ins_pipe(ialu_mem_reg); 4977 %} 4978 4979 // Store Long 4980 instruct storeL(memory mem, rRegL src) 4981 %{ 4982 match(Set mem (StoreL mem src)); 4983 4984 ins_cost(125); // XXX 4985 format %{ "movq $mem, $src\t# long" %} 4986 ins_encode %{ 4987 __ movq($mem$$Address, $src$$Register); 4988 %} 4989 ins_pipe(ialu_mem_reg); // XXX 4990 %} 4991 4992 // Store Pointer 4993 instruct storeP(memory mem, any_RegP src) 4994 %{ 4995 predicate(n->as_Store()->barrier_data() == 0); 4996 match(Set mem (StoreP mem src)); 4997 4998 ins_cost(125); // XXX 4999 format %{ "movq $mem, $src\t# ptr" %} 5000 ins_encode %{ 5001 __ movq($mem$$Address, $src$$Register); 5002 %} 5003 ins_pipe(ialu_mem_reg); 5004 %} 5005 5006 instruct storeImmP0(memory mem, immP0 zero) 5007 %{ 5008 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5009 match(Set mem (StoreP mem zero)); 5010 5011 ins_cost(125); // XXX 5012 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5013 ins_encode %{ 5014 __ movq($mem$$Address, r12); 5015 %} 5016 ins_pipe(ialu_mem_reg); 5017 %} 5018 5019 // Store Null Pointer, mark word, or other simple pointer constant. 5020 instruct storeImmP(memory mem, immP31 src) 5021 %{ 5022 predicate(n->as_Store()->barrier_data() == 0); 5023 match(Set mem (StoreP mem src)); 5024 5025 ins_cost(150); // XXX 5026 format %{ "movq $mem, $src\t# ptr" %} 5027 ins_encode %{ 5028 __ movq($mem$$Address, $src$$constant); 5029 %} 5030 ins_pipe(ialu_mem_imm); 5031 %} 5032 5033 // Store Compressed Pointer 5034 instruct storeN(memory mem, rRegN src) 5035 %{ 5036 match(Set mem (StoreN mem src)); 5037 5038 ins_cost(125); // XXX 5039 format %{ "movl $mem, $src\t# compressed ptr" %} 5040 ins_encode %{ 5041 __ movl($mem$$Address, $src$$Register); 5042 %} 5043 ins_pipe(ialu_mem_reg); 5044 %} 5045 5046 instruct storeNKlass(memory mem, rRegN src) 5047 %{ 5048 match(Set mem (StoreNKlass mem src)); 5049 5050 ins_cost(125); // XXX 5051 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5052 ins_encode %{ 5053 __ movl($mem$$Address, $src$$Register); 5054 %} 5055 ins_pipe(ialu_mem_reg); 5056 %} 5057 5058 instruct storeImmN0(memory mem, immN0 zero) 5059 %{ 5060 predicate(CompressedOops::base() == nullptr); 5061 match(Set mem (StoreN mem zero)); 5062 5063 ins_cost(125); // XXX 5064 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5065 ins_encode %{ 5066 __ movl($mem$$Address, r12); 5067 %} 5068 ins_pipe(ialu_mem_reg); 5069 %} 5070 5071 instruct storeImmN(memory mem, immN src) 5072 %{ 5073 match(Set mem (StoreN mem src)); 5074 5075 ins_cost(150); // XXX 5076 format %{ "movl $mem, $src\t# compressed ptr" %} 5077 ins_encode %{ 5078 address con = (address)$src$$constant; 5079 if (con == nullptr) { 5080 __ movl($mem$$Address, 0); 5081 } else { 5082 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5083 } 5084 %} 5085 ins_pipe(ialu_mem_imm); 5086 %} 5087 5088 instruct storeImmNKlass(memory mem, immNKlass src) 5089 %{ 5090 match(Set mem (StoreNKlass mem src)); 5091 5092 ins_cost(150); // XXX 5093 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5094 ins_encode %{ 5095 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5096 %} 5097 ins_pipe(ialu_mem_imm); 5098 %} 5099 5100 // Store Integer Immediate 5101 instruct storeImmI0(memory mem, immI_0 zero) 5102 %{ 5103 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5104 match(Set mem (StoreI mem zero)); 5105 5106 ins_cost(125); // XXX 5107 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5108 ins_encode %{ 5109 __ movl($mem$$Address, r12); 5110 %} 5111 ins_pipe(ialu_mem_reg); 5112 %} 5113 5114 instruct storeImmI(memory mem, immI src) 5115 %{ 5116 match(Set mem (StoreI mem src)); 5117 5118 ins_cost(150); 5119 format %{ "movl $mem, $src\t# int" %} 5120 ins_encode %{ 5121 __ movl($mem$$Address, $src$$constant); 5122 %} 5123 ins_pipe(ialu_mem_imm); 5124 %} 5125 5126 // Store Long Immediate 5127 instruct storeImmL0(memory mem, immL0 zero) 5128 %{ 5129 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5130 match(Set mem (StoreL mem zero)); 5131 5132 ins_cost(125); // XXX 5133 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5134 ins_encode %{ 5135 __ movq($mem$$Address, r12); 5136 %} 5137 ins_pipe(ialu_mem_reg); 5138 %} 5139 5140 instruct storeImmL(memory mem, immL32 src) 5141 %{ 5142 match(Set mem (StoreL mem src)); 5143 5144 ins_cost(150); 5145 format %{ "movq $mem, $src\t# long" %} 5146 ins_encode %{ 5147 __ movq($mem$$Address, $src$$constant); 5148 %} 5149 ins_pipe(ialu_mem_imm); 5150 %} 5151 5152 // Store Short/Char Immediate 5153 instruct storeImmC0(memory mem, immI_0 zero) 5154 %{ 5155 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5156 match(Set mem (StoreC mem zero)); 5157 5158 ins_cost(125); // XXX 5159 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5160 ins_encode %{ 5161 __ movw($mem$$Address, r12); 5162 %} 5163 ins_pipe(ialu_mem_reg); 5164 %} 5165 5166 instruct storeImmI16(memory mem, immI16 src) 5167 %{ 5168 predicate(UseStoreImmI16); 5169 match(Set mem (StoreC mem src)); 5170 5171 ins_cost(150); 5172 format %{ "movw $mem, $src\t# short/char" %} 5173 ins_encode %{ 5174 __ movw($mem$$Address, $src$$constant); 5175 %} 5176 ins_pipe(ialu_mem_imm); 5177 %} 5178 5179 // Store Byte Immediate 5180 instruct storeImmB0(memory mem, immI_0 zero) 5181 %{ 5182 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5183 match(Set mem (StoreB mem zero)); 5184 5185 ins_cost(125); // XXX 5186 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5187 ins_encode %{ 5188 __ movb($mem$$Address, r12); 5189 %} 5190 ins_pipe(ialu_mem_reg); 5191 %} 5192 5193 instruct storeImmB(memory mem, immI8 src) 5194 %{ 5195 match(Set mem (StoreB mem src)); 5196 5197 ins_cost(150); // XXX 5198 format %{ "movb $mem, $src\t# byte" %} 5199 ins_encode %{ 5200 __ movb($mem$$Address, $src$$constant); 5201 %} 5202 ins_pipe(ialu_mem_imm); 5203 %} 5204 5205 // Store CMS card-mark Immediate 5206 instruct storeImmCM0_reg(memory mem, immI_0 zero) 5207 %{ 5208 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5209 match(Set mem (StoreCM mem zero)); 5210 5211 ins_cost(125); // XXX 5212 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5213 ins_encode %{ 5214 __ movb($mem$$Address, r12); 5215 %} 5216 ins_pipe(ialu_mem_reg); 5217 %} 5218 5219 instruct storeImmCM0(memory mem, immI_0 src) 5220 %{ 5221 match(Set mem (StoreCM mem src)); 5222 5223 ins_cost(150); // XXX 5224 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5225 ins_encode %{ 5226 __ movb($mem$$Address, $src$$constant); 5227 %} 5228 ins_pipe(ialu_mem_imm); 5229 %} 5230 5231 // Store Float 5232 instruct storeF(memory mem, regF src) 5233 %{ 5234 match(Set mem (StoreF mem src)); 5235 5236 ins_cost(95); // XXX 5237 format %{ "movss $mem, $src\t# float" %} 5238 ins_encode %{ 5239 __ movflt($mem$$Address, $src$$XMMRegister); 5240 %} 5241 ins_pipe(pipe_slow); // XXX 5242 %} 5243 5244 // Store immediate Float value (it is faster than store from XMM register) 5245 instruct storeF0(memory mem, immF0 zero) 5246 %{ 5247 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5248 match(Set mem (StoreF mem zero)); 5249 5250 ins_cost(25); // XXX 5251 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5252 ins_encode %{ 5253 __ movl($mem$$Address, r12); 5254 %} 5255 ins_pipe(ialu_mem_reg); 5256 %} 5257 5258 instruct storeF_imm(memory mem, immF src) 5259 %{ 5260 match(Set mem (StoreF mem src)); 5261 5262 ins_cost(50); 5263 format %{ "movl $mem, $src\t# float" %} 5264 ins_encode %{ 5265 __ movl($mem$$Address, jint_cast($src$$constant)); 5266 %} 5267 ins_pipe(ialu_mem_imm); 5268 %} 5269 5270 // Store Double 5271 instruct storeD(memory mem, regD src) 5272 %{ 5273 match(Set mem (StoreD mem src)); 5274 5275 ins_cost(95); // XXX 5276 format %{ "movsd $mem, $src\t# double" %} 5277 ins_encode %{ 5278 __ movdbl($mem$$Address, $src$$XMMRegister); 5279 %} 5280 ins_pipe(pipe_slow); // XXX 5281 %} 5282 5283 // Store immediate double 0.0 (it is faster than store from XMM register) 5284 instruct storeD0_imm(memory mem, immD0 src) 5285 %{ 5286 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5287 match(Set mem (StoreD mem src)); 5288 5289 ins_cost(50); 5290 format %{ "movq $mem, $src\t# double 0." %} 5291 ins_encode %{ 5292 __ movq($mem$$Address, $src$$constant); 5293 %} 5294 ins_pipe(ialu_mem_imm); 5295 %} 5296 5297 instruct storeD0(memory mem, immD0 zero) 5298 %{ 5299 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5300 match(Set mem (StoreD mem zero)); 5301 5302 ins_cost(25); // XXX 5303 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5304 ins_encode %{ 5305 __ movq($mem$$Address, r12); 5306 %} 5307 ins_pipe(ialu_mem_reg); 5308 %} 5309 5310 instruct storeSSI(stackSlotI dst, rRegI src) 5311 %{ 5312 match(Set dst src); 5313 5314 ins_cost(100); 5315 format %{ "movl $dst, $src\t# int stk" %} 5316 ins_encode %{ 5317 __ movl($dst$$Address, $src$$Register); 5318 %} 5319 ins_pipe( ialu_mem_reg ); 5320 %} 5321 5322 instruct storeSSL(stackSlotL dst, rRegL src) 5323 %{ 5324 match(Set dst src); 5325 5326 ins_cost(100); 5327 format %{ "movq $dst, $src\t# long stk" %} 5328 ins_encode %{ 5329 __ movq($dst$$Address, $src$$Register); 5330 %} 5331 ins_pipe(ialu_mem_reg); 5332 %} 5333 5334 instruct storeSSP(stackSlotP dst, rRegP src) 5335 %{ 5336 match(Set dst src); 5337 5338 ins_cost(100); 5339 format %{ "movq $dst, $src\t# ptr stk" %} 5340 ins_encode %{ 5341 __ movq($dst$$Address, $src$$Register); 5342 %} 5343 ins_pipe(ialu_mem_reg); 5344 %} 5345 5346 instruct storeSSF(stackSlotF dst, regF src) 5347 %{ 5348 match(Set dst src); 5349 5350 ins_cost(95); // XXX 5351 format %{ "movss $dst, $src\t# float stk" %} 5352 ins_encode %{ 5353 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5354 %} 5355 ins_pipe(pipe_slow); // XXX 5356 %} 5357 5358 instruct storeSSD(stackSlotD dst, regD src) 5359 %{ 5360 match(Set dst src); 5361 5362 ins_cost(95); // XXX 5363 format %{ "movsd $dst, $src\t# double stk" %} 5364 ins_encode %{ 5365 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5366 %} 5367 ins_pipe(pipe_slow); // XXX 5368 %} 5369 5370 instruct cacheWB(indirect addr) 5371 %{ 5372 predicate(VM_Version::supports_data_cache_line_flush()); 5373 match(CacheWB addr); 5374 5375 ins_cost(100); 5376 format %{"cache wb $addr" %} 5377 ins_encode %{ 5378 assert($addr->index_position() < 0, "should be"); 5379 assert($addr$$disp == 0, "should be"); 5380 __ cache_wb(Address($addr$$base$$Register, 0)); 5381 %} 5382 ins_pipe(pipe_slow); // XXX 5383 %} 5384 5385 instruct cacheWBPreSync() 5386 %{ 5387 predicate(VM_Version::supports_data_cache_line_flush()); 5388 match(CacheWBPreSync); 5389 5390 ins_cost(100); 5391 format %{"cache wb presync" %} 5392 ins_encode %{ 5393 __ cache_wbsync(true); 5394 %} 5395 ins_pipe(pipe_slow); // XXX 5396 %} 5397 5398 instruct cacheWBPostSync() 5399 %{ 5400 predicate(VM_Version::supports_data_cache_line_flush()); 5401 match(CacheWBPostSync); 5402 5403 ins_cost(100); 5404 format %{"cache wb postsync" %} 5405 ins_encode %{ 5406 __ cache_wbsync(false); 5407 %} 5408 ins_pipe(pipe_slow); // XXX 5409 %} 5410 5411 //----------BSWAP Instructions------------------------------------------------- 5412 instruct bytes_reverse_int(rRegI dst) %{ 5413 match(Set dst (ReverseBytesI dst)); 5414 5415 format %{ "bswapl $dst" %} 5416 ins_encode %{ 5417 __ bswapl($dst$$Register); 5418 %} 5419 ins_pipe( ialu_reg ); 5420 %} 5421 5422 instruct bytes_reverse_long(rRegL dst) %{ 5423 match(Set dst (ReverseBytesL dst)); 5424 5425 format %{ "bswapq $dst" %} 5426 ins_encode %{ 5427 __ bswapq($dst$$Register); 5428 %} 5429 ins_pipe( ialu_reg); 5430 %} 5431 5432 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5433 match(Set dst (ReverseBytesUS dst)); 5434 effect(KILL cr); 5435 5436 format %{ "bswapl $dst\n\t" 5437 "shrl $dst,16\n\t" %} 5438 ins_encode %{ 5439 __ bswapl($dst$$Register); 5440 __ shrl($dst$$Register, 16); 5441 %} 5442 ins_pipe( ialu_reg ); 5443 %} 5444 5445 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5446 match(Set dst (ReverseBytesS dst)); 5447 effect(KILL cr); 5448 5449 format %{ "bswapl $dst\n\t" 5450 "sar $dst,16\n\t" %} 5451 ins_encode %{ 5452 __ bswapl($dst$$Register); 5453 __ sarl($dst$$Register, 16); 5454 %} 5455 ins_pipe( ialu_reg ); 5456 %} 5457 5458 //---------- Zeros Count Instructions ------------------------------------------ 5459 5460 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5461 predicate(UseCountLeadingZerosInstruction); 5462 match(Set dst (CountLeadingZerosI src)); 5463 effect(KILL cr); 5464 5465 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5466 ins_encode %{ 5467 __ lzcntl($dst$$Register, $src$$Register); 5468 %} 5469 ins_pipe(ialu_reg); 5470 %} 5471 5472 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5473 predicate(UseCountLeadingZerosInstruction); 5474 match(Set dst (CountLeadingZerosI (LoadI src))); 5475 effect(KILL cr); 5476 ins_cost(175); 5477 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5478 ins_encode %{ 5479 __ lzcntl($dst$$Register, $src$$Address); 5480 %} 5481 ins_pipe(ialu_reg_mem); 5482 %} 5483 5484 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5485 predicate(!UseCountLeadingZerosInstruction); 5486 match(Set dst (CountLeadingZerosI src)); 5487 effect(KILL cr); 5488 5489 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5490 "jnz skip\n\t" 5491 "movl $dst, -1\n" 5492 "skip:\n\t" 5493 "negl $dst\n\t" 5494 "addl $dst, 31" %} 5495 ins_encode %{ 5496 Register Rdst = $dst$$Register; 5497 Register Rsrc = $src$$Register; 5498 Label skip; 5499 __ bsrl(Rdst, Rsrc); 5500 __ jccb(Assembler::notZero, skip); 5501 __ movl(Rdst, -1); 5502 __ bind(skip); 5503 __ negl(Rdst); 5504 __ addl(Rdst, BitsPerInt - 1); 5505 %} 5506 ins_pipe(ialu_reg); 5507 %} 5508 5509 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5510 predicate(UseCountLeadingZerosInstruction); 5511 match(Set dst (CountLeadingZerosL src)); 5512 effect(KILL cr); 5513 5514 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5515 ins_encode %{ 5516 __ lzcntq($dst$$Register, $src$$Register); 5517 %} 5518 ins_pipe(ialu_reg); 5519 %} 5520 5521 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5522 predicate(UseCountLeadingZerosInstruction); 5523 match(Set dst (CountLeadingZerosL (LoadL src))); 5524 effect(KILL cr); 5525 ins_cost(175); 5526 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5527 ins_encode %{ 5528 __ lzcntq($dst$$Register, $src$$Address); 5529 %} 5530 ins_pipe(ialu_reg_mem); 5531 %} 5532 5533 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5534 predicate(!UseCountLeadingZerosInstruction); 5535 match(Set dst (CountLeadingZerosL src)); 5536 effect(KILL cr); 5537 5538 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5539 "jnz skip\n\t" 5540 "movl $dst, -1\n" 5541 "skip:\n\t" 5542 "negl $dst\n\t" 5543 "addl $dst, 63" %} 5544 ins_encode %{ 5545 Register Rdst = $dst$$Register; 5546 Register Rsrc = $src$$Register; 5547 Label skip; 5548 __ bsrq(Rdst, Rsrc); 5549 __ jccb(Assembler::notZero, skip); 5550 __ movl(Rdst, -1); 5551 __ bind(skip); 5552 __ negl(Rdst); 5553 __ addl(Rdst, BitsPerLong - 1); 5554 %} 5555 ins_pipe(ialu_reg); 5556 %} 5557 5558 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5559 predicate(UseCountTrailingZerosInstruction); 5560 match(Set dst (CountTrailingZerosI src)); 5561 effect(KILL cr); 5562 5563 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5564 ins_encode %{ 5565 __ tzcntl($dst$$Register, $src$$Register); 5566 %} 5567 ins_pipe(ialu_reg); 5568 %} 5569 5570 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5571 predicate(UseCountTrailingZerosInstruction); 5572 match(Set dst (CountTrailingZerosI (LoadI src))); 5573 effect(KILL cr); 5574 ins_cost(175); 5575 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5576 ins_encode %{ 5577 __ tzcntl($dst$$Register, $src$$Address); 5578 %} 5579 ins_pipe(ialu_reg_mem); 5580 %} 5581 5582 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5583 predicate(!UseCountTrailingZerosInstruction); 5584 match(Set dst (CountTrailingZerosI src)); 5585 effect(KILL cr); 5586 5587 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5588 "jnz done\n\t" 5589 "movl $dst, 32\n" 5590 "done:" %} 5591 ins_encode %{ 5592 Register Rdst = $dst$$Register; 5593 Label done; 5594 __ bsfl(Rdst, $src$$Register); 5595 __ jccb(Assembler::notZero, done); 5596 __ movl(Rdst, BitsPerInt); 5597 __ bind(done); 5598 %} 5599 ins_pipe(ialu_reg); 5600 %} 5601 5602 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5603 predicate(UseCountTrailingZerosInstruction); 5604 match(Set dst (CountTrailingZerosL src)); 5605 effect(KILL cr); 5606 5607 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5608 ins_encode %{ 5609 __ tzcntq($dst$$Register, $src$$Register); 5610 %} 5611 ins_pipe(ialu_reg); 5612 %} 5613 5614 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5615 predicate(UseCountTrailingZerosInstruction); 5616 match(Set dst (CountTrailingZerosL (LoadL src))); 5617 effect(KILL cr); 5618 ins_cost(175); 5619 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5620 ins_encode %{ 5621 __ tzcntq($dst$$Register, $src$$Address); 5622 %} 5623 ins_pipe(ialu_reg_mem); 5624 %} 5625 5626 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5627 predicate(!UseCountTrailingZerosInstruction); 5628 match(Set dst (CountTrailingZerosL src)); 5629 effect(KILL cr); 5630 5631 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5632 "jnz done\n\t" 5633 "movl $dst, 64\n" 5634 "done:" %} 5635 ins_encode %{ 5636 Register Rdst = $dst$$Register; 5637 Label done; 5638 __ bsfq(Rdst, $src$$Register); 5639 __ jccb(Assembler::notZero, done); 5640 __ movl(Rdst, BitsPerLong); 5641 __ bind(done); 5642 %} 5643 ins_pipe(ialu_reg); 5644 %} 5645 5646 //--------------- Reverse Operation Instructions ---------------- 5647 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5648 predicate(!VM_Version::supports_gfni()); 5649 match(Set dst (ReverseI src)); 5650 effect(TEMP dst, TEMP rtmp, KILL cr); 5651 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5652 ins_encode %{ 5653 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5654 %} 5655 ins_pipe( ialu_reg ); 5656 %} 5657 5658 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5659 predicate(VM_Version::supports_gfni()); 5660 match(Set dst (ReverseI src)); 5661 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5662 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5663 ins_encode %{ 5664 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5665 %} 5666 ins_pipe( ialu_reg ); 5667 %} 5668 5669 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5670 predicate(!VM_Version::supports_gfni()); 5671 match(Set dst (ReverseL src)); 5672 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5673 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5674 ins_encode %{ 5675 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5676 %} 5677 ins_pipe( ialu_reg ); 5678 %} 5679 5680 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5681 predicate(VM_Version::supports_gfni()); 5682 match(Set dst (ReverseL src)); 5683 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5684 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5685 ins_encode %{ 5686 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5687 %} 5688 ins_pipe( ialu_reg ); 5689 %} 5690 5691 //---------- Population Count Instructions ------------------------------------- 5692 5693 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5694 predicate(UsePopCountInstruction); 5695 match(Set dst (PopCountI src)); 5696 effect(KILL cr); 5697 5698 format %{ "popcnt $dst, $src" %} 5699 ins_encode %{ 5700 __ popcntl($dst$$Register, $src$$Register); 5701 %} 5702 ins_pipe(ialu_reg); 5703 %} 5704 5705 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5706 predicate(UsePopCountInstruction); 5707 match(Set dst (PopCountI (LoadI mem))); 5708 effect(KILL cr); 5709 5710 format %{ "popcnt $dst, $mem" %} 5711 ins_encode %{ 5712 __ popcntl($dst$$Register, $mem$$Address); 5713 %} 5714 ins_pipe(ialu_reg); 5715 %} 5716 5717 // Note: Long.bitCount(long) returns an int. 5718 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5719 predicate(UsePopCountInstruction); 5720 match(Set dst (PopCountL src)); 5721 effect(KILL cr); 5722 5723 format %{ "popcnt $dst, $src" %} 5724 ins_encode %{ 5725 __ popcntq($dst$$Register, $src$$Register); 5726 %} 5727 ins_pipe(ialu_reg); 5728 %} 5729 5730 // Note: Long.bitCount(long) returns an int. 5731 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5732 predicate(UsePopCountInstruction); 5733 match(Set dst (PopCountL (LoadL mem))); 5734 effect(KILL cr); 5735 5736 format %{ "popcnt $dst, $mem" %} 5737 ins_encode %{ 5738 __ popcntq($dst$$Register, $mem$$Address); 5739 %} 5740 ins_pipe(ialu_reg); 5741 %} 5742 5743 5744 //----------MemBar Instructions----------------------------------------------- 5745 // Memory barrier flavors 5746 5747 instruct membar_acquire() 5748 %{ 5749 match(MemBarAcquire); 5750 match(LoadFence); 5751 ins_cost(0); 5752 5753 size(0); 5754 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5755 ins_encode(); 5756 ins_pipe(empty); 5757 %} 5758 5759 instruct membar_acquire_lock() 5760 %{ 5761 match(MemBarAcquireLock); 5762 ins_cost(0); 5763 5764 size(0); 5765 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5766 ins_encode(); 5767 ins_pipe(empty); 5768 %} 5769 5770 instruct membar_release() 5771 %{ 5772 match(MemBarRelease); 5773 match(StoreFence); 5774 ins_cost(0); 5775 5776 size(0); 5777 format %{ "MEMBAR-release ! (empty encoding)" %} 5778 ins_encode(); 5779 ins_pipe(empty); 5780 %} 5781 5782 instruct membar_release_lock() 5783 %{ 5784 match(MemBarReleaseLock); 5785 ins_cost(0); 5786 5787 size(0); 5788 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5789 ins_encode(); 5790 ins_pipe(empty); 5791 %} 5792 5793 instruct membar_volatile(rFlagsReg cr) %{ 5794 match(MemBarVolatile); 5795 effect(KILL cr); 5796 ins_cost(400); 5797 5798 format %{ 5799 $$template 5800 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5801 %} 5802 ins_encode %{ 5803 __ membar(Assembler::StoreLoad); 5804 %} 5805 ins_pipe(pipe_slow); 5806 %} 5807 5808 instruct unnecessary_membar_volatile() 5809 %{ 5810 match(MemBarVolatile); 5811 predicate(Matcher::post_store_load_barrier(n)); 5812 ins_cost(0); 5813 5814 size(0); 5815 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5816 ins_encode(); 5817 ins_pipe(empty); 5818 %} 5819 5820 instruct membar_storestore() %{ 5821 match(MemBarStoreStore); 5822 match(StoreStoreFence); 5823 ins_cost(0); 5824 5825 size(0); 5826 format %{ "MEMBAR-storestore (empty encoding)" %} 5827 ins_encode( ); 5828 ins_pipe(empty); 5829 %} 5830 5831 //----------Move Instructions-------------------------------------------------- 5832 5833 instruct castX2P(rRegP dst, rRegL src) 5834 %{ 5835 match(Set dst (CastX2P src)); 5836 5837 format %{ "movq $dst, $src\t# long->ptr" %} 5838 ins_encode %{ 5839 if ($dst$$reg != $src$$reg) { 5840 __ movptr($dst$$Register, $src$$Register); 5841 } 5842 %} 5843 ins_pipe(ialu_reg_reg); // XXX 5844 %} 5845 5846 instruct castP2X(rRegL dst, rRegP src) 5847 %{ 5848 match(Set dst (CastP2X src)); 5849 5850 format %{ "movq $dst, $src\t# ptr -> long" %} 5851 ins_encode %{ 5852 if ($dst$$reg != $src$$reg) { 5853 __ movptr($dst$$Register, $src$$Register); 5854 } 5855 %} 5856 ins_pipe(ialu_reg_reg); // XXX 5857 %} 5858 5859 // Convert oop into int for vectors alignment masking 5860 instruct convP2I(rRegI dst, rRegP src) 5861 %{ 5862 match(Set dst (ConvL2I (CastP2X src))); 5863 5864 format %{ "movl $dst, $src\t# ptr -> int" %} 5865 ins_encode %{ 5866 __ movl($dst$$Register, $src$$Register); 5867 %} 5868 ins_pipe(ialu_reg_reg); // XXX 5869 %} 5870 5871 // Convert compressed oop into int for vectors alignment masking 5872 // in case of 32bit oops (heap < 4Gb). 5873 instruct convN2I(rRegI dst, rRegN src) 5874 %{ 5875 predicate(CompressedOops::shift() == 0); 5876 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5877 5878 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5879 ins_encode %{ 5880 __ movl($dst$$Register, $src$$Register); 5881 %} 5882 ins_pipe(ialu_reg_reg); // XXX 5883 %} 5884 5885 // Convert oop pointer into compressed form 5886 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5887 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5888 match(Set dst (EncodeP src)); 5889 effect(KILL cr); 5890 format %{ "encode_heap_oop $dst,$src" %} 5891 ins_encode %{ 5892 Register s = $src$$Register; 5893 Register d = $dst$$Register; 5894 if (s != d) { 5895 __ movq(d, s); 5896 } 5897 __ encode_heap_oop(d); 5898 %} 5899 ins_pipe(ialu_reg_long); 5900 %} 5901 5902 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5903 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 5904 match(Set dst (EncodeP src)); 5905 effect(KILL cr); 5906 format %{ "encode_heap_oop_not_null $dst,$src" %} 5907 ins_encode %{ 5908 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 5909 %} 5910 ins_pipe(ialu_reg_long); 5911 %} 5912 5913 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 5914 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 5915 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 5916 match(Set dst (DecodeN src)); 5917 effect(KILL cr); 5918 format %{ "decode_heap_oop $dst,$src" %} 5919 ins_encode %{ 5920 Register s = $src$$Register; 5921 Register d = $dst$$Register; 5922 if (s != d) { 5923 __ movq(d, s); 5924 } 5925 __ decode_heap_oop(d); 5926 %} 5927 ins_pipe(ialu_reg_long); 5928 %} 5929 5930 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 5931 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 5932 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 5933 match(Set dst (DecodeN src)); 5934 effect(KILL cr); 5935 format %{ "decode_heap_oop_not_null $dst,$src" %} 5936 ins_encode %{ 5937 Register s = $src$$Register; 5938 Register d = $dst$$Register; 5939 if (s != d) { 5940 __ decode_heap_oop_not_null(d, s); 5941 } else { 5942 __ decode_heap_oop_not_null(d); 5943 } 5944 %} 5945 ins_pipe(ialu_reg_long); 5946 %} 5947 5948 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5949 match(Set dst (EncodePKlass src)); 5950 effect(TEMP dst, KILL cr); 5951 format %{ "encode_and_move_klass_not_null $dst,$src" %} 5952 ins_encode %{ 5953 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 5954 %} 5955 ins_pipe(ialu_reg_long); 5956 %} 5957 5958 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 5959 match(Set dst (DecodeNKlass src)); 5960 effect(TEMP dst, KILL cr); 5961 format %{ "decode_and_move_klass_not_null $dst,$src" %} 5962 ins_encode %{ 5963 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 5964 %} 5965 ins_pipe(ialu_reg_long); 5966 %} 5967 5968 //----------Conditional Move--------------------------------------------------- 5969 // Jump 5970 // dummy instruction for generating temp registers 5971 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 5972 match(Jump (LShiftL switch_val shift)); 5973 ins_cost(350); 5974 predicate(false); 5975 effect(TEMP dest); 5976 5977 format %{ "leaq $dest, [$constantaddress]\n\t" 5978 "jmp [$dest + $switch_val << $shift]\n\t" %} 5979 ins_encode %{ 5980 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 5981 // to do that and the compiler is using that register as one it can allocate. 5982 // So we build it all by hand. 5983 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 5984 // ArrayAddress dispatch(table, index); 5985 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 5986 __ lea($dest$$Register, $constantaddress); 5987 __ jmp(dispatch); 5988 %} 5989 ins_pipe(pipe_jmp); 5990 %} 5991 5992 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 5993 match(Jump (AddL (LShiftL switch_val shift) offset)); 5994 ins_cost(350); 5995 effect(TEMP dest); 5996 5997 format %{ "leaq $dest, [$constantaddress]\n\t" 5998 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 5999 ins_encode %{ 6000 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6001 // to do that and the compiler is using that register as one it can allocate. 6002 // So we build it all by hand. 6003 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6004 // ArrayAddress dispatch(table, index); 6005 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6006 __ lea($dest$$Register, $constantaddress); 6007 __ jmp(dispatch); 6008 %} 6009 ins_pipe(pipe_jmp); 6010 %} 6011 6012 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6013 match(Jump switch_val); 6014 ins_cost(350); 6015 effect(TEMP dest); 6016 6017 format %{ "leaq $dest, [$constantaddress]\n\t" 6018 "jmp [$dest + $switch_val]\n\t" %} 6019 ins_encode %{ 6020 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6021 // to do that and the compiler is using that register as one it can allocate. 6022 // So we build it all by hand. 6023 // Address index(noreg, switch_reg, Address::times_1); 6024 // ArrayAddress dispatch(table, index); 6025 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6026 __ lea($dest$$Register, $constantaddress); 6027 __ jmp(dispatch); 6028 %} 6029 ins_pipe(pipe_jmp); 6030 %} 6031 6032 // Conditional move 6033 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6034 %{ 6035 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6036 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6037 6038 ins_cost(100); // XXX 6039 format %{ "setbn$cop $dst\t# signed, int" %} 6040 ins_encode %{ 6041 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6042 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6043 %} 6044 ins_pipe(ialu_reg); 6045 %} 6046 6047 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6048 %{ 6049 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6050 6051 ins_cost(200); // XXX 6052 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6053 ins_encode %{ 6054 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6055 %} 6056 ins_pipe(pipe_cmov_reg); 6057 %} 6058 6059 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6060 %{ 6061 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6062 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6063 6064 ins_cost(100); // XXX 6065 format %{ "setbn$cop $dst\t# unsigned, int" %} 6066 ins_encode %{ 6067 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6068 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6069 %} 6070 ins_pipe(ialu_reg); 6071 %} 6072 6073 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6074 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6075 6076 ins_cost(200); // XXX 6077 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6078 ins_encode %{ 6079 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6080 %} 6081 ins_pipe(pipe_cmov_reg); 6082 %} 6083 6084 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6085 %{ 6086 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6087 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6088 6089 ins_cost(100); // XXX 6090 format %{ "setbn$cop $dst\t# unsigned, int" %} 6091 ins_encode %{ 6092 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6093 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6094 %} 6095 ins_pipe(ialu_reg); 6096 %} 6097 6098 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6099 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6100 ins_cost(200); 6101 expand %{ 6102 cmovI_regU(cop, cr, dst, src); 6103 %} 6104 %} 6105 6106 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6107 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6108 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6109 6110 ins_cost(200); // XXX 6111 format %{ "cmovpl $dst, $src\n\t" 6112 "cmovnel $dst, $src" %} 6113 ins_encode %{ 6114 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6115 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6116 %} 6117 ins_pipe(pipe_cmov_reg); 6118 %} 6119 6120 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6121 // inputs of the CMove 6122 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6123 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6124 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6125 6126 ins_cost(200); // XXX 6127 format %{ "cmovpl $dst, $src\n\t" 6128 "cmovnel $dst, $src" %} 6129 ins_encode %{ 6130 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6131 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6132 %} 6133 ins_pipe(pipe_cmov_reg); 6134 %} 6135 6136 // Conditional move 6137 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6138 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6139 6140 ins_cost(250); // XXX 6141 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6142 ins_encode %{ 6143 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6144 %} 6145 ins_pipe(pipe_cmov_mem); 6146 %} 6147 6148 // Conditional move 6149 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6150 %{ 6151 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6152 6153 ins_cost(250); // XXX 6154 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6155 ins_encode %{ 6156 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6157 %} 6158 ins_pipe(pipe_cmov_mem); 6159 %} 6160 6161 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6162 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6163 ins_cost(250); 6164 expand %{ 6165 cmovI_memU(cop, cr, dst, src); 6166 %} 6167 %} 6168 6169 // Conditional move 6170 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6171 %{ 6172 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6173 6174 ins_cost(200); // XXX 6175 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6176 ins_encode %{ 6177 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6178 %} 6179 ins_pipe(pipe_cmov_reg); 6180 %} 6181 6182 // Conditional move 6183 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6184 %{ 6185 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6186 6187 ins_cost(200); // XXX 6188 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6189 ins_encode %{ 6190 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6191 %} 6192 ins_pipe(pipe_cmov_reg); 6193 %} 6194 6195 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6196 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6197 ins_cost(200); 6198 expand %{ 6199 cmovN_regU(cop, cr, dst, src); 6200 %} 6201 %} 6202 6203 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6204 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6205 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6206 6207 ins_cost(200); // XXX 6208 format %{ "cmovpl $dst, $src\n\t" 6209 "cmovnel $dst, $src" %} 6210 ins_encode %{ 6211 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6212 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6213 %} 6214 ins_pipe(pipe_cmov_reg); 6215 %} 6216 6217 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6218 // inputs of the CMove 6219 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6220 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6221 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6222 6223 ins_cost(200); // XXX 6224 format %{ "cmovpl $dst, $src\n\t" 6225 "cmovnel $dst, $src" %} 6226 ins_encode %{ 6227 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6228 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6229 %} 6230 ins_pipe(pipe_cmov_reg); 6231 %} 6232 6233 // Conditional move 6234 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6235 %{ 6236 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6237 6238 ins_cost(200); // XXX 6239 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6240 ins_encode %{ 6241 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6242 %} 6243 ins_pipe(pipe_cmov_reg); // XXX 6244 %} 6245 6246 // Conditional move 6247 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6248 %{ 6249 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6250 6251 ins_cost(200); // XXX 6252 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6253 ins_encode %{ 6254 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6255 %} 6256 ins_pipe(pipe_cmov_reg); // XXX 6257 %} 6258 6259 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6260 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6261 ins_cost(200); 6262 expand %{ 6263 cmovP_regU(cop, cr, dst, src); 6264 %} 6265 %} 6266 6267 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6268 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6269 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6270 6271 ins_cost(200); // XXX 6272 format %{ "cmovpq $dst, $src\n\t" 6273 "cmovneq $dst, $src" %} 6274 ins_encode %{ 6275 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6276 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6277 %} 6278 ins_pipe(pipe_cmov_reg); 6279 %} 6280 6281 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6282 // inputs of the CMove 6283 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6284 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6285 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6286 6287 ins_cost(200); // XXX 6288 format %{ "cmovpq $dst, $src\n\t" 6289 "cmovneq $dst, $src" %} 6290 ins_encode %{ 6291 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6292 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6293 %} 6294 ins_pipe(pipe_cmov_reg); 6295 %} 6296 6297 instruct cmovL_imm_01(rRegL dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6298 %{ 6299 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6300 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6301 6302 ins_cost(100); // XXX 6303 format %{ "setbn$cop $dst\t# signed, long" %} 6304 ins_encode %{ 6305 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6306 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6307 %} 6308 ins_pipe(ialu_reg); 6309 %} 6310 6311 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6312 %{ 6313 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6314 6315 ins_cost(200); // XXX 6316 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6317 ins_encode %{ 6318 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6319 %} 6320 ins_pipe(pipe_cmov_reg); // XXX 6321 %} 6322 6323 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6324 %{ 6325 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6326 6327 ins_cost(200); // XXX 6328 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6329 ins_encode %{ 6330 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6331 %} 6332 ins_pipe(pipe_cmov_mem); // XXX 6333 %} 6334 6335 instruct cmovL_imm_01U(rRegL dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6336 %{ 6337 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6338 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6339 6340 ins_cost(100); // XXX 6341 format %{ "setbn$cop $dst\t# unsigned, long" %} 6342 ins_encode %{ 6343 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6344 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6345 %} 6346 ins_pipe(ialu_reg); 6347 %} 6348 6349 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6350 %{ 6351 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6352 6353 ins_cost(200); // XXX 6354 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6355 ins_encode %{ 6356 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6357 %} 6358 ins_pipe(pipe_cmov_reg); // XXX 6359 %} 6360 6361 instruct cmovL_imm_01UCF(rRegL dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6362 %{ 6363 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6364 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6365 6366 ins_cost(100); // XXX 6367 format %{ "setbn$cop $dst\t# unsigned, long" %} 6368 ins_encode %{ 6369 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6370 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6371 %} 6372 ins_pipe(ialu_reg); 6373 %} 6374 6375 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6376 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6377 ins_cost(200); 6378 expand %{ 6379 cmovL_regU(cop, cr, dst, src); 6380 %} 6381 %} 6382 6383 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6384 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6385 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6386 6387 ins_cost(200); // XXX 6388 format %{ "cmovpq $dst, $src\n\t" 6389 "cmovneq $dst, $src" %} 6390 ins_encode %{ 6391 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6392 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6393 %} 6394 ins_pipe(pipe_cmov_reg); 6395 %} 6396 6397 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6398 // inputs of the CMove 6399 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6400 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6401 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6402 6403 ins_cost(200); // XXX 6404 format %{ "cmovpq $dst, $src\n\t" 6405 "cmovneq $dst, $src" %} 6406 ins_encode %{ 6407 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6408 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6409 %} 6410 ins_pipe(pipe_cmov_reg); 6411 %} 6412 6413 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6414 %{ 6415 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6416 6417 ins_cost(200); // XXX 6418 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6419 ins_encode %{ 6420 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6421 %} 6422 ins_pipe(pipe_cmov_mem); // XXX 6423 %} 6424 6425 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6426 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6427 ins_cost(200); 6428 expand %{ 6429 cmovL_memU(cop, cr, dst, src); 6430 %} 6431 %} 6432 6433 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6434 %{ 6435 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6436 6437 ins_cost(200); // XXX 6438 format %{ "jn$cop skip\t# signed cmove float\n\t" 6439 "movss $dst, $src\n" 6440 "skip:" %} 6441 ins_encode %{ 6442 Label Lskip; 6443 // Invert sense of branch from sense of CMOV 6444 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6445 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6446 __ bind(Lskip); 6447 %} 6448 ins_pipe(pipe_slow); 6449 %} 6450 6451 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6452 %{ 6453 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6454 6455 ins_cost(200); // XXX 6456 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6457 "movss $dst, $src\n" 6458 "skip:" %} 6459 ins_encode %{ 6460 Label Lskip; 6461 // Invert sense of branch from sense of CMOV 6462 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6463 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6464 __ bind(Lskip); 6465 %} 6466 ins_pipe(pipe_slow); 6467 %} 6468 6469 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6470 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6471 ins_cost(200); 6472 expand %{ 6473 cmovF_regU(cop, cr, dst, src); 6474 %} 6475 %} 6476 6477 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6478 %{ 6479 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6480 6481 ins_cost(200); // XXX 6482 format %{ "jn$cop skip\t# signed cmove double\n\t" 6483 "movsd $dst, $src\n" 6484 "skip:" %} 6485 ins_encode %{ 6486 Label Lskip; 6487 // Invert sense of branch from sense of CMOV 6488 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6489 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6490 __ bind(Lskip); 6491 %} 6492 ins_pipe(pipe_slow); 6493 %} 6494 6495 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6496 %{ 6497 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6498 6499 ins_cost(200); // XXX 6500 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6501 "movsd $dst, $src\n" 6502 "skip:" %} 6503 ins_encode %{ 6504 Label Lskip; 6505 // Invert sense of branch from sense of CMOV 6506 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6507 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6508 __ bind(Lskip); 6509 %} 6510 ins_pipe(pipe_slow); 6511 %} 6512 6513 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6514 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6515 ins_cost(200); 6516 expand %{ 6517 cmovD_regU(cop, cr, dst, src); 6518 %} 6519 %} 6520 6521 //----------Arithmetic Instructions-------------------------------------------- 6522 //----------Addition Instructions---------------------------------------------- 6523 6524 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6525 %{ 6526 match(Set dst (AddI dst src)); 6527 effect(KILL cr); 6528 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); 6529 format %{ "addl $dst, $src\t# int" %} 6530 ins_encode %{ 6531 __ addl($dst$$Register, $src$$Register); 6532 %} 6533 ins_pipe(ialu_reg_reg); 6534 %} 6535 6536 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6537 %{ 6538 match(Set dst (AddI dst src)); 6539 effect(KILL cr); 6540 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); 6541 6542 format %{ "addl $dst, $src\t# int" %} 6543 ins_encode %{ 6544 __ addl($dst$$Register, $src$$constant); 6545 %} 6546 ins_pipe( ialu_reg ); 6547 %} 6548 6549 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6550 %{ 6551 match(Set dst (AddI dst (LoadI src))); 6552 effect(KILL cr); 6553 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); 6554 6555 ins_cost(150); // XXX 6556 format %{ "addl $dst, $src\t# int" %} 6557 ins_encode %{ 6558 __ addl($dst$$Register, $src$$Address); 6559 %} 6560 ins_pipe(ialu_reg_mem); 6561 %} 6562 6563 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6564 %{ 6565 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6566 effect(KILL cr); 6567 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); 6568 6569 ins_cost(150); // XXX 6570 format %{ "addl $dst, $src\t# int" %} 6571 ins_encode %{ 6572 __ addl($dst$$Address, $src$$Register); 6573 %} 6574 ins_pipe(ialu_mem_reg); 6575 %} 6576 6577 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6578 %{ 6579 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6580 effect(KILL cr); 6581 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); 6582 6583 6584 ins_cost(125); // XXX 6585 format %{ "addl $dst, $src\t# int" %} 6586 ins_encode %{ 6587 __ addl($dst$$Address, $src$$constant); 6588 %} 6589 ins_pipe(ialu_mem_imm); 6590 %} 6591 6592 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6593 %{ 6594 predicate(UseIncDec); 6595 match(Set dst (AddI dst src)); 6596 effect(KILL cr); 6597 6598 format %{ "incl $dst\t# int" %} 6599 ins_encode %{ 6600 __ incrementl($dst$$Register); 6601 %} 6602 ins_pipe(ialu_reg); 6603 %} 6604 6605 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6606 %{ 6607 predicate(UseIncDec); 6608 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6609 effect(KILL cr); 6610 6611 ins_cost(125); // XXX 6612 format %{ "incl $dst\t# int" %} 6613 ins_encode %{ 6614 __ incrementl($dst$$Address); 6615 %} 6616 ins_pipe(ialu_mem_imm); 6617 %} 6618 6619 // XXX why does that use AddI 6620 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6621 %{ 6622 predicate(UseIncDec); 6623 match(Set dst (AddI dst src)); 6624 effect(KILL cr); 6625 6626 format %{ "decl $dst\t# int" %} 6627 ins_encode %{ 6628 __ decrementl($dst$$Register); 6629 %} 6630 ins_pipe(ialu_reg); 6631 %} 6632 6633 // XXX why does that use AddI 6634 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6635 %{ 6636 predicate(UseIncDec); 6637 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6638 effect(KILL cr); 6639 6640 ins_cost(125); // XXX 6641 format %{ "decl $dst\t# int" %} 6642 ins_encode %{ 6643 __ decrementl($dst$$Address); 6644 %} 6645 ins_pipe(ialu_mem_imm); 6646 %} 6647 6648 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6649 %{ 6650 predicate(VM_Version::supports_fast_2op_lea()); 6651 match(Set dst (AddI (LShiftI index scale) disp)); 6652 6653 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6654 ins_encode %{ 6655 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6656 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6657 %} 6658 ins_pipe(ialu_reg_reg); 6659 %} 6660 6661 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6662 %{ 6663 predicate(VM_Version::supports_fast_3op_lea()); 6664 match(Set dst (AddI (AddI base index) disp)); 6665 6666 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6667 ins_encode %{ 6668 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6669 %} 6670 ins_pipe(ialu_reg_reg); 6671 %} 6672 6673 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6674 %{ 6675 predicate(VM_Version::supports_fast_2op_lea()); 6676 match(Set dst (AddI base (LShiftI index scale))); 6677 6678 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6679 ins_encode %{ 6680 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6681 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6682 %} 6683 ins_pipe(ialu_reg_reg); 6684 %} 6685 6686 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6687 %{ 6688 predicate(VM_Version::supports_fast_3op_lea()); 6689 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6690 6691 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6692 ins_encode %{ 6693 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6694 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6695 %} 6696 ins_pipe(ialu_reg_reg); 6697 %} 6698 6699 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6700 %{ 6701 match(Set dst (AddL dst src)); 6702 effect(KILL cr); 6703 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); 6704 6705 format %{ "addq $dst, $src\t# long" %} 6706 ins_encode %{ 6707 __ addq($dst$$Register, $src$$Register); 6708 %} 6709 ins_pipe(ialu_reg_reg); 6710 %} 6711 6712 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6713 %{ 6714 match(Set dst (AddL dst src)); 6715 effect(KILL cr); 6716 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); 6717 6718 format %{ "addq $dst, $src\t# long" %} 6719 ins_encode %{ 6720 __ addq($dst$$Register, $src$$constant); 6721 %} 6722 ins_pipe( ialu_reg ); 6723 %} 6724 6725 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6726 %{ 6727 match(Set dst (AddL dst (LoadL src))); 6728 effect(KILL cr); 6729 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); 6730 6731 ins_cost(150); // XXX 6732 format %{ "addq $dst, $src\t# long" %} 6733 ins_encode %{ 6734 __ addq($dst$$Register, $src$$Address); 6735 %} 6736 ins_pipe(ialu_reg_mem); 6737 %} 6738 6739 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6740 %{ 6741 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6742 effect(KILL cr); 6743 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); 6744 6745 ins_cost(150); // XXX 6746 format %{ "addq $dst, $src\t# long" %} 6747 ins_encode %{ 6748 __ addq($dst$$Address, $src$$Register); 6749 %} 6750 ins_pipe(ialu_mem_reg); 6751 %} 6752 6753 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6754 %{ 6755 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6756 effect(KILL cr); 6757 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); 6758 6759 ins_cost(125); // XXX 6760 format %{ "addq $dst, $src\t# long" %} 6761 ins_encode %{ 6762 __ addq($dst$$Address, $src$$constant); 6763 %} 6764 ins_pipe(ialu_mem_imm); 6765 %} 6766 6767 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6768 %{ 6769 predicate(UseIncDec); 6770 match(Set dst (AddL dst src)); 6771 effect(KILL cr); 6772 6773 format %{ "incq $dst\t# long" %} 6774 ins_encode %{ 6775 __ incrementq($dst$$Register); 6776 %} 6777 ins_pipe(ialu_reg); 6778 %} 6779 6780 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6781 %{ 6782 predicate(UseIncDec); 6783 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6784 effect(KILL cr); 6785 6786 ins_cost(125); // XXX 6787 format %{ "incq $dst\t# long" %} 6788 ins_encode %{ 6789 __ incrementq($dst$$Address); 6790 %} 6791 ins_pipe(ialu_mem_imm); 6792 %} 6793 6794 // XXX why does that use AddL 6795 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6796 %{ 6797 predicate(UseIncDec); 6798 match(Set dst (AddL dst src)); 6799 effect(KILL cr); 6800 6801 format %{ "decq $dst\t# long" %} 6802 ins_encode %{ 6803 __ decrementq($dst$$Register); 6804 %} 6805 ins_pipe(ialu_reg); 6806 %} 6807 6808 // XXX why does that use AddL 6809 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6810 %{ 6811 predicate(UseIncDec); 6812 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6813 effect(KILL cr); 6814 6815 ins_cost(125); // XXX 6816 format %{ "decq $dst\t# long" %} 6817 ins_encode %{ 6818 __ decrementq($dst$$Address); 6819 %} 6820 ins_pipe(ialu_mem_imm); 6821 %} 6822 6823 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6824 %{ 6825 predicate(VM_Version::supports_fast_2op_lea()); 6826 match(Set dst (AddL (LShiftL index scale) disp)); 6827 6828 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6829 ins_encode %{ 6830 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6831 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6832 %} 6833 ins_pipe(ialu_reg_reg); 6834 %} 6835 6836 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6837 %{ 6838 predicate(VM_Version::supports_fast_3op_lea()); 6839 match(Set dst (AddL (AddL base index) disp)); 6840 6841 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6842 ins_encode %{ 6843 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6844 %} 6845 ins_pipe(ialu_reg_reg); 6846 %} 6847 6848 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6849 %{ 6850 predicate(VM_Version::supports_fast_2op_lea()); 6851 match(Set dst (AddL base (LShiftL index scale))); 6852 6853 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6854 ins_encode %{ 6855 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6856 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6857 %} 6858 ins_pipe(ialu_reg_reg); 6859 %} 6860 6861 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6862 %{ 6863 predicate(VM_Version::supports_fast_3op_lea()); 6864 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6865 6866 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6867 ins_encode %{ 6868 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6869 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6870 %} 6871 ins_pipe(ialu_reg_reg); 6872 %} 6873 6874 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6875 %{ 6876 match(Set dst (AddP dst src)); 6877 effect(KILL cr); 6878 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); 6879 6880 format %{ "addq $dst, $src\t# ptr" %} 6881 ins_encode %{ 6882 __ addq($dst$$Register, $src$$Register); 6883 %} 6884 ins_pipe(ialu_reg_reg); 6885 %} 6886 6887 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6888 %{ 6889 match(Set dst (AddP dst src)); 6890 effect(KILL cr); 6891 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); 6892 6893 format %{ "addq $dst, $src\t# ptr" %} 6894 ins_encode %{ 6895 __ addq($dst$$Register, $src$$constant); 6896 %} 6897 ins_pipe( ialu_reg ); 6898 %} 6899 6900 // XXX addP mem ops ???? 6901 6902 instruct checkCastPP(rRegP dst) 6903 %{ 6904 match(Set dst (CheckCastPP dst)); 6905 6906 size(0); 6907 format %{ "# checkcastPP of $dst" %} 6908 ins_encode(/* empty encoding */); 6909 ins_pipe(empty); 6910 %} 6911 6912 instruct castPP(rRegP dst) 6913 %{ 6914 match(Set dst (CastPP dst)); 6915 6916 size(0); 6917 format %{ "# castPP of $dst" %} 6918 ins_encode(/* empty encoding */); 6919 ins_pipe(empty); 6920 %} 6921 6922 instruct castII(rRegI dst) 6923 %{ 6924 match(Set dst (CastII dst)); 6925 6926 size(0); 6927 format %{ "# castII of $dst" %} 6928 ins_encode(/* empty encoding */); 6929 ins_cost(0); 6930 ins_pipe(empty); 6931 %} 6932 6933 instruct castLL(rRegL dst) 6934 %{ 6935 match(Set dst (CastLL dst)); 6936 6937 size(0); 6938 format %{ "# castLL of $dst" %} 6939 ins_encode(/* empty encoding */); 6940 ins_cost(0); 6941 ins_pipe(empty); 6942 %} 6943 6944 instruct castFF(regF dst) 6945 %{ 6946 match(Set dst (CastFF dst)); 6947 6948 size(0); 6949 format %{ "# castFF of $dst" %} 6950 ins_encode(/* empty encoding */); 6951 ins_cost(0); 6952 ins_pipe(empty); 6953 %} 6954 6955 instruct castDD(regD dst) 6956 %{ 6957 match(Set dst (CastDD dst)); 6958 6959 size(0); 6960 format %{ "# castDD of $dst" %} 6961 ins_encode(/* empty encoding */); 6962 ins_cost(0); 6963 ins_pipe(empty); 6964 %} 6965 6966 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 6967 instruct compareAndSwapP(rRegI res, 6968 memory mem_ptr, 6969 rax_RegP oldval, rRegP newval, 6970 rFlagsReg cr) 6971 %{ 6972 predicate(n->as_LoadStore()->barrier_data() == 0); 6973 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 6974 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 6975 effect(KILL cr, KILL oldval); 6976 6977 format %{ "cmpxchgq $mem_ptr,$newval\t# " 6978 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 6979 "sete $res\n\t" 6980 "movzbl $res, $res" %} 6981 ins_encode %{ 6982 __ lock(); 6983 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 6984 __ setb(Assembler::equal, $res$$Register); 6985 __ movzbl($res$$Register, $res$$Register); 6986 %} 6987 ins_pipe( pipe_cmpxchg ); 6988 %} 6989 6990 instruct compareAndSwapL(rRegI res, 6991 memory mem_ptr, 6992 rax_RegL oldval, rRegL newval, 6993 rFlagsReg cr) 6994 %{ 6995 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 6996 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 6997 effect(KILL cr, KILL oldval); 6998 6999 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7000 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7001 "sete $res\n\t" 7002 "movzbl $res, $res" %} 7003 ins_encode %{ 7004 __ lock(); 7005 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7006 __ setb(Assembler::equal, $res$$Register); 7007 __ movzbl($res$$Register, $res$$Register); 7008 %} 7009 ins_pipe( pipe_cmpxchg ); 7010 %} 7011 7012 instruct compareAndSwapI(rRegI res, 7013 memory mem_ptr, 7014 rax_RegI oldval, rRegI newval, 7015 rFlagsReg cr) 7016 %{ 7017 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7018 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7019 effect(KILL cr, KILL oldval); 7020 7021 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7022 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7023 "sete $res\n\t" 7024 "movzbl $res, $res" %} 7025 ins_encode %{ 7026 __ lock(); 7027 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7028 __ setb(Assembler::equal, $res$$Register); 7029 __ movzbl($res$$Register, $res$$Register); 7030 %} 7031 ins_pipe( pipe_cmpxchg ); 7032 %} 7033 7034 instruct compareAndSwapB(rRegI res, 7035 memory mem_ptr, 7036 rax_RegI oldval, rRegI newval, 7037 rFlagsReg cr) 7038 %{ 7039 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7040 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7041 effect(KILL cr, KILL oldval); 7042 7043 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7044 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7045 "sete $res\n\t" 7046 "movzbl $res, $res" %} 7047 ins_encode %{ 7048 __ lock(); 7049 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7050 __ setb(Assembler::equal, $res$$Register); 7051 __ movzbl($res$$Register, $res$$Register); 7052 %} 7053 ins_pipe( pipe_cmpxchg ); 7054 %} 7055 7056 instruct compareAndSwapS(rRegI res, 7057 memory mem_ptr, 7058 rax_RegI oldval, rRegI newval, 7059 rFlagsReg cr) 7060 %{ 7061 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7062 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7063 effect(KILL cr, KILL oldval); 7064 7065 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7066 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7067 "sete $res\n\t" 7068 "movzbl $res, $res" %} 7069 ins_encode %{ 7070 __ lock(); 7071 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7072 __ setb(Assembler::equal, $res$$Register); 7073 __ movzbl($res$$Register, $res$$Register); 7074 %} 7075 ins_pipe( pipe_cmpxchg ); 7076 %} 7077 7078 instruct compareAndSwapN(rRegI res, 7079 memory mem_ptr, 7080 rax_RegN oldval, rRegN newval, 7081 rFlagsReg cr) %{ 7082 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7083 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7084 effect(KILL cr, KILL oldval); 7085 7086 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7087 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7088 "sete $res\n\t" 7089 "movzbl $res, $res" %} 7090 ins_encode %{ 7091 __ lock(); 7092 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7093 __ setb(Assembler::equal, $res$$Register); 7094 __ movzbl($res$$Register, $res$$Register); 7095 %} 7096 ins_pipe( pipe_cmpxchg ); 7097 %} 7098 7099 instruct compareAndExchangeB( 7100 memory mem_ptr, 7101 rax_RegI oldval, rRegI newval, 7102 rFlagsReg cr) 7103 %{ 7104 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7105 effect(KILL cr); 7106 7107 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7108 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7109 ins_encode %{ 7110 __ lock(); 7111 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7112 %} 7113 ins_pipe( pipe_cmpxchg ); 7114 %} 7115 7116 instruct compareAndExchangeS( 7117 memory mem_ptr, 7118 rax_RegI oldval, rRegI newval, 7119 rFlagsReg cr) 7120 %{ 7121 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7122 effect(KILL cr); 7123 7124 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7125 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7126 ins_encode %{ 7127 __ lock(); 7128 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7129 %} 7130 ins_pipe( pipe_cmpxchg ); 7131 %} 7132 7133 instruct compareAndExchangeI( 7134 memory mem_ptr, 7135 rax_RegI oldval, rRegI newval, 7136 rFlagsReg cr) 7137 %{ 7138 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7139 effect(KILL cr); 7140 7141 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7142 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7143 ins_encode %{ 7144 __ lock(); 7145 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7146 %} 7147 ins_pipe( pipe_cmpxchg ); 7148 %} 7149 7150 instruct compareAndExchangeL( 7151 memory mem_ptr, 7152 rax_RegL oldval, rRegL newval, 7153 rFlagsReg cr) 7154 %{ 7155 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7156 effect(KILL cr); 7157 7158 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7159 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7160 ins_encode %{ 7161 __ lock(); 7162 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7163 %} 7164 ins_pipe( pipe_cmpxchg ); 7165 %} 7166 7167 instruct compareAndExchangeN( 7168 memory mem_ptr, 7169 rax_RegN oldval, rRegN newval, 7170 rFlagsReg cr) %{ 7171 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7172 effect(KILL cr); 7173 7174 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7175 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7176 ins_encode %{ 7177 __ lock(); 7178 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7179 %} 7180 ins_pipe( pipe_cmpxchg ); 7181 %} 7182 7183 instruct compareAndExchangeP( 7184 memory mem_ptr, 7185 rax_RegP oldval, rRegP newval, 7186 rFlagsReg cr) 7187 %{ 7188 predicate(n->as_LoadStore()->barrier_data() == 0); 7189 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7190 effect(KILL cr); 7191 7192 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7193 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7194 ins_encode %{ 7195 __ lock(); 7196 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7197 %} 7198 ins_pipe( pipe_cmpxchg ); 7199 %} 7200 7201 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7202 predicate(n->as_LoadStore()->result_not_used()); 7203 match(Set dummy (GetAndAddB mem add)); 7204 effect(KILL cr); 7205 format %{ "addb_lock $mem, $add" %} 7206 ins_encode %{ 7207 __ lock(); 7208 __ addb($mem$$Address, $add$$Register); 7209 %} 7210 ins_pipe(pipe_cmpxchg); 7211 %} 7212 7213 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7214 predicate(n->as_LoadStore()->result_not_used()); 7215 match(Set dummy (GetAndAddB mem add)); 7216 effect(KILL cr); 7217 format %{ "addb_lock $mem, $add" %} 7218 ins_encode %{ 7219 __ lock(); 7220 __ addb($mem$$Address, $add$$constant); 7221 %} 7222 ins_pipe(pipe_cmpxchg); 7223 %} 7224 7225 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7226 predicate(!n->as_LoadStore()->result_not_used()); 7227 match(Set newval (GetAndAddB mem newval)); 7228 effect(KILL cr); 7229 format %{ "xaddb_lock $mem, $newval" %} 7230 ins_encode %{ 7231 __ lock(); 7232 __ xaddb($mem$$Address, $newval$$Register); 7233 %} 7234 ins_pipe(pipe_cmpxchg); 7235 %} 7236 7237 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7238 predicate(n->as_LoadStore()->result_not_used()); 7239 match(Set dummy (GetAndAddS mem add)); 7240 effect(KILL cr); 7241 format %{ "addw_lock $mem, $add" %} 7242 ins_encode %{ 7243 __ lock(); 7244 __ addw($mem$$Address, $add$$Register); 7245 %} 7246 ins_pipe(pipe_cmpxchg); 7247 %} 7248 7249 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7250 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7251 match(Set dummy (GetAndAddS mem add)); 7252 effect(KILL cr); 7253 format %{ "addw_lock $mem, $add" %} 7254 ins_encode %{ 7255 __ lock(); 7256 __ addw($mem$$Address, $add$$constant); 7257 %} 7258 ins_pipe(pipe_cmpxchg); 7259 %} 7260 7261 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7262 predicate(!n->as_LoadStore()->result_not_used()); 7263 match(Set newval (GetAndAddS mem newval)); 7264 effect(KILL cr); 7265 format %{ "xaddw_lock $mem, $newval" %} 7266 ins_encode %{ 7267 __ lock(); 7268 __ xaddw($mem$$Address, $newval$$Register); 7269 %} 7270 ins_pipe(pipe_cmpxchg); 7271 %} 7272 7273 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7274 predicate(n->as_LoadStore()->result_not_used()); 7275 match(Set dummy (GetAndAddI mem add)); 7276 effect(KILL cr); 7277 format %{ "addl_lock $mem, $add" %} 7278 ins_encode %{ 7279 __ lock(); 7280 __ addl($mem$$Address, $add$$Register); 7281 %} 7282 ins_pipe(pipe_cmpxchg); 7283 %} 7284 7285 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7286 predicate(n->as_LoadStore()->result_not_used()); 7287 match(Set dummy (GetAndAddI mem add)); 7288 effect(KILL cr); 7289 format %{ "addl_lock $mem, $add" %} 7290 ins_encode %{ 7291 __ lock(); 7292 __ addl($mem$$Address, $add$$constant); 7293 %} 7294 ins_pipe(pipe_cmpxchg); 7295 %} 7296 7297 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7298 predicate(!n->as_LoadStore()->result_not_used()); 7299 match(Set newval (GetAndAddI mem newval)); 7300 effect(KILL cr); 7301 format %{ "xaddl_lock $mem, $newval" %} 7302 ins_encode %{ 7303 __ lock(); 7304 __ xaddl($mem$$Address, $newval$$Register); 7305 %} 7306 ins_pipe(pipe_cmpxchg); 7307 %} 7308 7309 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7310 predicate(n->as_LoadStore()->result_not_used()); 7311 match(Set dummy (GetAndAddL mem add)); 7312 effect(KILL cr); 7313 format %{ "addq_lock $mem, $add" %} 7314 ins_encode %{ 7315 __ lock(); 7316 __ addq($mem$$Address, $add$$Register); 7317 %} 7318 ins_pipe(pipe_cmpxchg); 7319 %} 7320 7321 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7322 predicate(n->as_LoadStore()->result_not_used()); 7323 match(Set dummy (GetAndAddL mem add)); 7324 effect(KILL cr); 7325 format %{ "addq_lock $mem, $add" %} 7326 ins_encode %{ 7327 __ lock(); 7328 __ addq($mem$$Address, $add$$constant); 7329 %} 7330 ins_pipe(pipe_cmpxchg); 7331 %} 7332 7333 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7334 predicate(!n->as_LoadStore()->result_not_used()); 7335 match(Set newval (GetAndAddL mem newval)); 7336 effect(KILL cr); 7337 format %{ "xaddq_lock $mem, $newval" %} 7338 ins_encode %{ 7339 __ lock(); 7340 __ xaddq($mem$$Address, $newval$$Register); 7341 %} 7342 ins_pipe(pipe_cmpxchg); 7343 %} 7344 7345 instruct xchgB( memory mem, rRegI newval) %{ 7346 match(Set newval (GetAndSetB mem newval)); 7347 format %{ "XCHGB $newval,[$mem]" %} 7348 ins_encode %{ 7349 __ xchgb($newval$$Register, $mem$$Address); 7350 %} 7351 ins_pipe( pipe_cmpxchg ); 7352 %} 7353 7354 instruct xchgS( memory mem, rRegI newval) %{ 7355 match(Set newval (GetAndSetS mem newval)); 7356 format %{ "XCHGW $newval,[$mem]" %} 7357 ins_encode %{ 7358 __ xchgw($newval$$Register, $mem$$Address); 7359 %} 7360 ins_pipe( pipe_cmpxchg ); 7361 %} 7362 7363 instruct xchgI( memory mem, rRegI newval) %{ 7364 match(Set newval (GetAndSetI mem newval)); 7365 format %{ "XCHGL $newval,[$mem]" %} 7366 ins_encode %{ 7367 __ xchgl($newval$$Register, $mem$$Address); 7368 %} 7369 ins_pipe( pipe_cmpxchg ); 7370 %} 7371 7372 instruct xchgL( memory mem, rRegL newval) %{ 7373 match(Set newval (GetAndSetL mem newval)); 7374 format %{ "XCHGL $newval,[$mem]" %} 7375 ins_encode %{ 7376 __ xchgq($newval$$Register, $mem$$Address); 7377 %} 7378 ins_pipe( pipe_cmpxchg ); 7379 %} 7380 7381 instruct xchgP( memory mem, rRegP newval) %{ 7382 match(Set newval (GetAndSetP mem newval)); 7383 predicate(n->as_LoadStore()->barrier_data() == 0); 7384 format %{ "XCHGQ $newval,[$mem]" %} 7385 ins_encode %{ 7386 __ xchgq($newval$$Register, $mem$$Address); 7387 %} 7388 ins_pipe( pipe_cmpxchg ); 7389 %} 7390 7391 instruct xchgN( memory mem, rRegN newval) %{ 7392 match(Set newval (GetAndSetN mem newval)); 7393 format %{ "XCHGL $newval,$mem]" %} 7394 ins_encode %{ 7395 __ xchgl($newval$$Register, $mem$$Address); 7396 %} 7397 ins_pipe( pipe_cmpxchg ); 7398 %} 7399 7400 //----------Abs Instructions------------------------------------------- 7401 7402 // Integer Absolute Instructions 7403 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7404 %{ 7405 match(Set dst (AbsI src)); 7406 effect(TEMP dst, KILL cr); 7407 format %{ "xorl $dst, $dst\t# abs int\n\t" 7408 "subl $dst, $src\n\t" 7409 "cmovll $dst, $src" %} 7410 ins_encode %{ 7411 __ xorl($dst$$Register, $dst$$Register); 7412 __ subl($dst$$Register, $src$$Register); 7413 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7414 %} 7415 7416 ins_pipe(ialu_reg_reg); 7417 %} 7418 7419 // Long Absolute Instructions 7420 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7421 %{ 7422 match(Set dst (AbsL src)); 7423 effect(TEMP dst, KILL cr); 7424 format %{ "xorl $dst, $dst\t# abs long\n\t" 7425 "subq $dst, $src\n\t" 7426 "cmovlq $dst, $src" %} 7427 ins_encode %{ 7428 __ xorl($dst$$Register, $dst$$Register); 7429 __ subq($dst$$Register, $src$$Register); 7430 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7431 %} 7432 7433 ins_pipe(ialu_reg_reg); 7434 %} 7435 7436 //----------Subtraction Instructions------------------------------------------- 7437 7438 // Integer Subtraction Instructions 7439 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7440 %{ 7441 match(Set dst (SubI dst src)); 7442 effect(KILL cr); 7443 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); 7444 7445 format %{ "subl $dst, $src\t# int" %} 7446 ins_encode %{ 7447 __ subl($dst$$Register, $src$$Register); 7448 %} 7449 ins_pipe(ialu_reg_reg); 7450 %} 7451 7452 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7453 %{ 7454 match(Set dst (SubI dst (LoadI src))); 7455 effect(KILL cr); 7456 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); 7457 7458 ins_cost(150); 7459 format %{ "subl $dst, $src\t# int" %} 7460 ins_encode %{ 7461 __ subl($dst$$Register, $src$$Address); 7462 %} 7463 ins_pipe(ialu_reg_mem); 7464 %} 7465 7466 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7467 %{ 7468 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7469 effect(KILL cr); 7470 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); 7471 7472 ins_cost(150); 7473 format %{ "subl $dst, $src\t# int" %} 7474 ins_encode %{ 7475 __ subl($dst$$Address, $src$$Register); 7476 %} 7477 ins_pipe(ialu_mem_reg); 7478 %} 7479 7480 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7481 %{ 7482 match(Set dst (SubL dst src)); 7483 effect(KILL cr); 7484 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); 7485 7486 format %{ "subq $dst, $src\t# long" %} 7487 ins_encode %{ 7488 __ subq($dst$$Register, $src$$Register); 7489 %} 7490 ins_pipe(ialu_reg_reg); 7491 %} 7492 7493 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7494 %{ 7495 match(Set dst (SubL dst (LoadL src))); 7496 effect(KILL cr); 7497 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); 7498 7499 ins_cost(150); 7500 format %{ "subq $dst, $src\t# long" %} 7501 ins_encode %{ 7502 __ subq($dst$$Register, $src$$Address); 7503 %} 7504 ins_pipe(ialu_reg_mem); 7505 %} 7506 7507 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7508 %{ 7509 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7510 effect(KILL cr); 7511 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); 7512 7513 ins_cost(150); 7514 format %{ "subq $dst, $src\t# long" %} 7515 ins_encode %{ 7516 __ subq($dst$$Address, $src$$Register); 7517 %} 7518 ins_pipe(ialu_mem_reg); 7519 %} 7520 7521 // Subtract from a pointer 7522 // XXX hmpf??? 7523 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7524 %{ 7525 match(Set dst (AddP dst (SubI zero src))); 7526 effect(KILL cr); 7527 7528 format %{ "subq $dst, $src\t# ptr - int" %} 7529 ins_encode %{ 7530 __ subq($dst$$Register, $src$$Register); 7531 %} 7532 ins_pipe(ialu_reg_reg); 7533 %} 7534 7535 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7536 %{ 7537 match(Set dst (SubI zero dst)); 7538 effect(KILL cr); 7539 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7540 7541 format %{ "negl $dst\t# int" %} 7542 ins_encode %{ 7543 __ negl($dst$$Register); 7544 %} 7545 ins_pipe(ialu_reg); 7546 %} 7547 7548 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7549 %{ 7550 match(Set dst (NegI dst)); 7551 effect(KILL cr); 7552 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7553 7554 format %{ "negl $dst\t# int" %} 7555 ins_encode %{ 7556 __ negl($dst$$Register); 7557 %} 7558 ins_pipe(ialu_reg); 7559 %} 7560 7561 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7562 %{ 7563 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7564 effect(KILL cr); 7565 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7566 7567 format %{ "negl $dst\t# int" %} 7568 ins_encode %{ 7569 __ negl($dst$$Address); 7570 %} 7571 ins_pipe(ialu_reg); 7572 %} 7573 7574 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7575 %{ 7576 match(Set dst (SubL zero dst)); 7577 effect(KILL cr); 7578 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7579 7580 format %{ "negq $dst\t# long" %} 7581 ins_encode %{ 7582 __ negq($dst$$Register); 7583 %} 7584 ins_pipe(ialu_reg); 7585 %} 7586 7587 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7588 %{ 7589 match(Set dst (NegL dst)); 7590 effect(KILL cr); 7591 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7592 7593 format %{ "negq $dst\t# int" %} 7594 ins_encode %{ 7595 __ negq($dst$$Register); 7596 %} 7597 ins_pipe(ialu_reg); 7598 %} 7599 7600 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7601 %{ 7602 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7603 effect(KILL cr); 7604 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7605 7606 format %{ "negq $dst\t# long" %} 7607 ins_encode %{ 7608 __ negq($dst$$Address); 7609 %} 7610 ins_pipe(ialu_reg); 7611 %} 7612 7613 //----------Multiplication/Division Instructions------------------------------- 7614 // Integer Multiplication Instructions 7615 // Multiply Register 7616 7617 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7618 %{ 7619 match(Set dst (MulI dst src)); 7620 effect(KILL cr); 7621 7622 ins_cost(300); 7623 format %{ "imull $dst, $src\t# int" %} 7624 ins_encode %{ 7625 __ imull($dst$$Register, $src$$Register); 7626 %} 7627 ins_pipe(ialu_reg_reg_alu0); 7628 %} 7629 7630 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7631 %{ 7632 match(Set dst (MulI src imm)); 7633 effect(KILL cr); 7634 7635 ins_cost(300); 7636 format %{ "imull $dst, $src, $imm\t# int" %} 7637 ins_encode %{ 7638 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7639 %} 7640 ins_pipe(ialu_reg_reg_alu0); 7641 %} 7642 7643 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7644 %{ 7645 match(Set dst (MulI dst (LoadI src))); 7646 effect(KILL cr); 7647 7648 ins_cost(350); 7649 format %{ "imull $dst, $src\t# int" %} 7650 ins_encode %{ 7651 __ imull($dst$$Register, $src$$Address); 7652 %} 7653 ins_pipe(ialu_reg_mem_alu0); 7654 %} 7655 7656 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7657 %{ 7658 match(Set dst (MulI (LoadI src) imm)); 7659 effect(KILL cr); 7660 7661 ins_cost(300); 7662 format %{ "imull $dst, $src, $imm\t# int" %} 7663 ins_encode %{ 7664 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7665 %} 7666 ins_pipe(ialu_reg_mem_alu0); 7667 %} 7668 7669 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7670 %{ 7671 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7672 effect(KILL cr, KILL src2); 7673 7674 expand %{ mulI_rReg(dst, src1, cr); 7675 mulI_rReg(src2, src3, cr); 7676 addI_rReg(dst, src2, cr); %} 7677 %} 7678 7679 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7680 %{ 7681 match(Set dst (MulL dst src)); 7682 effect(KILL cr); 7683 7684 ins_cost(300); 7685 format %{ "imulq $dst, $src\t# long" %} 7686 ins_encode %{ 7687 __ imulq($dst$$Register, $src$$Register); 7688 %} 7689 ins_pipe(ialu_reg_reg_alu0); 7690 %} 7691 7692 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7693 %{ 7694 match(Set dst (MulL src imm)); 7695 effect(KILL cr); 7696 7697 ins_cost(300); 7698 format %{ "imulq $dst, $src, $imm\t# long" %} 7699 ins_encode %{ 7700 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7701 %} 7702 ins_pipe(ialu_reg_reg_alu0); 7703 %} 7704 7705 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7706 %{ 7707 match(Set dst (MulL dst (LoadL src))); 7708 effect(KILL cr); 7709 7710 ins_cost(350); 7711 format %{ "imulq $dst, $src\t# long" %} 7712 ins_encode %{ 7713 __ imulq($dst$$Register, $src$$Address); 7714 %} 7715 ins_pipe(ialu_reg_mem_alu0); 7716 %} 7717 7718 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7719 %{ 7720 match(Set dst (MulL (LoadL src) imm)); 7721 effect(KILL cr); 7722 7723 ins_cost(300); 7724 format %{ "imulq $dst, $src, $imm\t# long" %} 7725 ins_encode %{ 7726 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7727 %} 7728 ins_pipe(ialu_reg_mem_alu0); 7729 %} 7730 7731 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7732 %{ 7733 match(Set dst (MulHiL src rax)); 7734 effect(USE_KILL rax, KILL cr); 7735 7736 ins_cost(300); 7737 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7738 ins_encode %{ 7739 __ imulq($src$$Register); 7740 %} 7741 ins_pipe(ialu_reg_reg_alu0); 7742 %} 7743 7744 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7745 %{ 7746 match(Set dst (UMulHiL src rax)); 7747 effect(USE_KILL rax, KILL cr); 7748 7749 ins_cost(300); 7750 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7751 ins_encode %{ 7752 __ mulq($src$$Register); 7753 %} 7754 ins_pipe(ialu_reg_reg_alu0); 7755 %} 7756 7757 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7758 rFlagsReg cr) 7759 %{ 7760 match(Set rax (DivI rax div)); 7761 effect(KILL rdx, KILL cr); 7762 7763 ins_cost(30*100+10*100); // XXX 7764 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7765 "jne,s normal\n\t" 7766 "xorl rdx, rdx\n\t" 7767 "cmpl $div, -1\n\t" 7768 "je,s done\n" 7769 "normal: cdql\n\t" 7770 "idivl $div\n" 7771 "done:" %} 7772 ins_encode(cdql_enc(div)); 7773 ins_pipe(ialu_reg_reg_alu0); 7774 %} 7775 7776 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7777 rFlagsReg cr) 7778 %{ 7779 match(Set rax (DivL rax div)); 7780 effect(KILL rdx, KILL cr); 7781 7782 ins_cost(30*100+10*100); // XXX 7783 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7784 "cmpq rax, rdx\n\t" 7785 "jne,s normal\n\t" 7786 "xorl rdx, rdx\n\t" 7787 "cmpq $div, -1\n\t" 7788 "je,s done\n" 7789 "normal: cdqq\n\t" 7790 "idivq $div\n" 7791 "done:" %} 7792 ins_encode(cdqq_enc(div)); 7793 ins_pipe(ialu_reg_reg_alu0); 7794 %} 7795 7796 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7797 %{ 7798 match(Set rax (UDivI rax div)); 7799 effect(KILL rdx, KILL cr); 7800 7801 ins_cost(300); 7802 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7803 ins_encode %{ 7804 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7805 %} 7806 ins_pipe(ialu_reg_reg_alu0); 7807 %} 7808 7809 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7810 %{ 7811 match(Set rax (UDivL rax div)); 7812 effect(KILL rdx, KILL cr); 7813 7814 ins_cost(300); 7815 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7816 ins_encode %{ 7817 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7818 %} 7819 ins_pipe(ialu_reg_reg_alu0); 7820 %} 7821 7822 // Integer DIVMOD with Register, both quotient and mod results 7823 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7824 rFlagsReg cr) 7825 %{ 7826 match(DivModI rax div); 7827 effect(KILL cr); 7828 7829 ins_cost(30*100+10*100); // XXX 7830 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7831 "jne,s normal\n\t" 7832 "xorl rdx, rdx\n\t" 7833 "cmpl $div, -1\n\t" 7834 "je,s done\n" 7835 "normal: cdql\n\t" 7836 "idivl $div\n" 7837 "done:" %} 7838 ins_encode(cdql_enc(div)); 7839 ins_pipe(pipe_slow); 7840 %} 7841 7842 // Long DIVMOD with Register, both quotient and mod results 7843 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7844 rFlagsReg cr) 7845 %{ 7846 match(DivModL rax div); 7847 effect(KILL cr); 7848 7849 ins_cost(30*100+10*100); // XXX 7850 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7851 "cmpq rax, rdx\n\t" 7852 "jne,s normal\n\t" 7853 "xorl rdx, rdx\n\t" 7854 "cmpq $div, -1\n\t" 7855 "je,s done\n" 7856 "normal: cdqq\n\t" 7857 "idivq $div\n" 7858 "done:" %} 7859 ins_encode(cdqq_enc(div)); 7860 ins_pipe(pipe_slow); 7861 %} 7862 7863 // Unsigned integer DIVMOD with Register, both quotient and mod results 7864 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7865 no_rax_rdx_RegI div, rFlagsReg cr) 7866 %{ 7867 match(UDivModI rax div); 7868 effect(TEMP tmp, KILL cr); 7869 7870 ins_cost(300); 7871 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7872 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7873 %} 7874 ins_encode %{ 7875 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7876 %} 7877 ins_pipe(pipe_slow); 7878 %} 7879 7880 // Unsigned long DIVMOD with Register, both quotient and mod results 7881 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7882 no_rax_rdx_RegL div, rFlagsReg cr) 7883 %{ 7884 match(UDivModL rax div); 7885 effect(TEMP tmp, KILL cr); 7886 7887 ins_cost(300); 7888 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7889 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7890 %} 7891 ins_encode %{ 7892 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7893 %} 7894 ins_pipe(pipe_slow); 7895 %} 7896 7897 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7898 rFlagsReg cr) 7899 %{ 7900 match(Set rdx (ModI rax div)); 7901 effect(KILL rax, KILL cr); 7902 7903 ins_cost(300); // XXX 7904 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7905 "jne,s normal\n\t" 7906 "xorl rdx, rdx\n\t" 7907 "cmpl $div, -1\n\t" 7908 "je,s done\n" 7909 "normal: cdql\n\t" 7910 "idivl $div\n" 7911 "done:" %} 7912 ins_encode(cdql_enc(div)); 7913 ins_pipe(ialu_reg_reg_alu0); 7914 %} 7915 7916 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7917 rFlagsReg cr) 7918 %{ 7919 match(Set rdx (ModL rax div)); 7920 effect(KILL rax, KILL cr); 7921 7922 ins_cost(300); // XXX 7923 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7924 "cmpq rax, rdx\n\t" 7925 "jne,s normal\n\t" 7926 "xorl rdx, rdx\n\t" 7927 "cmpq $div, -1\n\t" 7928 "je,s done\n" 7929 "normal: cdqq\n\t" 7930 "idivq $div\n" 7931 "done:" %} 7932 ins_encode(cdqq_enc(div)); 7933 ins_pipe(ialu_reg_reg_alu0); 7934 %} 7935 7936 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 7937 %{ 7938 match(Set rdx (UModI rax div)); 7939 effect(KILL rax, KILL cr); 7940 7941 ins_cost(300); 7942 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 7943 ins_encode %{ 7944 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 7945 %} 7946 ins_pipe(ialu_reg_reg_alu0); 7947 %} 7948 7949 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 7950 %{ 7951 match(Set rdx (UModL rax div)); 7952 effect(KILL rax, KILL cr); 7953 7954 ins_cost(300); 7955 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 7956 ins_encode %{ 7957 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 7958 %} 7959 ins_pipe(ialu_reg_reg_alu0); 7960 %} 7961 7962 // Integer Shift Instructions 7963 // Shift Left by one, two, three 7964 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 7965 %{ 7966 match(Set dst (LShiftI dst shift)); 7967 effect(KILL cr); 7968 7969 format %{ "sall $dst, $shift" %} 7970 ins_encode %{ 7971 __ sall($dst$$Register, $shift$$constant); 7972 %} 7973 ins_pipe(ialu_reg); 7974 %} 7975 7976 // Shift Left by 8-bit immediate 7977 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7978 %{ 7979 match(Set dst (LShiftI dst shift)); 7980 effect(KILL cr); 7981 7982 format %{ "sall $dst, $shift" %} 7983 ins_encode %{ 7984 __ sall($dst$$Register, $shift$$constant); 7985 %} 7986 ins_pipe(ialu_reg); 7987 %} 7988 7989 // Shift Left by 8-bit immediate 7990 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7991 %{ 7992 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7993 effect(KILL cr); 7994 7995 format %{ "sall $dst, $shift" %} 7996 ins_encode %{ 7997 __ sall($dst$$Address, $shift$$constant); 7998 %} 7999 ins_pipe(ialu_mem_imm); 8000 %} 8001 8002 // Shift Left by variable 8003 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8004 %{ 8005 predicate(!VM_Version::supports_bmi2()); 8006 match(Set dst (LShiftI dst shift)); 8007 effect(KILL cr); 8008 8009 format %{ "sall $dst, $shift" %} 8010 ins_encode %{ 8011 __ sall($dst$$Register); 8012 %} 8013 ins_pipe(ialu_reg_reg); 8014 %} 8015 8016 // Shift Left by variable 8017 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8018 %{ 8019 predicate(!VM_Version::supports_bmi2()); 8020 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8021 effect(KILL cr); 8022 8023 format %{ "sall $dst, $shift" %} 8024 ins_encode %{ 8025 __ sall($dst$$Address); 8026 %} 8027 ins_pipe(ialu_mem_reg); 8028 %} 8029 8030 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8031 %{ 8032 predicate(VM_Version::supports_bmi2()); 8033 match(Set dst (LShiftI src shift)); 8034 8035 format %{ "shlxl $dst, $src, $shift" %} 8036 ins_encode %{ 8037 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8038 %} 8039 ins_pipe(ialu_reg_reg); 8040 %} 8041 8042 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8043 %{ 8044 predicate(VM_Version::supports_bmi2()); 8045 match(Set dst (LShiftI (LoadI src) shift)); 8046 ins_cost(175); 8047 format %{ "shlxl $dst, $src, $shift" %} 8048 ins_encode %{ 8049 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8050 %} 8051 ins_pipe(ialu_reg_mem); 8052 %} 8053 8054 // Arithmetic Shift Right by 8-bit immediate 8055 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8056 %{ 8057 match(Set dst (RShiftI dst shift)); 8058 effect(KILL cr); 8059 8060 format %{ "sarl $dst, $shift" %} 8061 ins_encode %{ 8062 __ sarl($dst$$Register, $shift$$constant); 8063 %} 8064 ins_pipe(ialu_mem_imm); 8065 %} 8066 8067 // Arithmetic Shift Right by 8-bit immediate 8068 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8069 %{ 8070 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8071 effect(KILL cr); 8072 8073 format %{ "sarl $dst, $shift" %} 8074 ins_encode %{ 8075 __ sarl($dst$$Address, $shift$$constant); 8076 %} 8077 ins_pipe(ialu_mem_imm); 8078 %} 8079 8080 // Arithmetic Shift Right by variable 8081 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8082 %{ 8083 predicate(!VM_Version::supports_bmi2()); 8084 match(Set dst (RShiftI dst shift)); 8085 effect(KILL cr); 8086 8087 format %{ "sarl $dst, $shift" %} 8088 ins_encode %{ 8089 __ sarl($dst$$Register); 8090 %} 8091 ins_pipe(ialu_reg_reg); 8092 %} 8093 8094 // Arithmetic Shift Right by variable 8095 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8096 %{ 8097 predicate(!VM_Version::supports_bmi2()); 8098 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8099 effect(KILL cr); 8100 8101 format %{ "sarl $dst, $shift" %} 8102 ins_encode %{ 8103 __ sarl($dst$$Address); 8104 %} 8105 ins_pipe(ialu_mem_reg); 8106 %} 8107 8108 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8109 %{ 8110 predicate(VM_Version::supports_bmi2()); 8111 match(Set dst (RShiftI src shift)); 8112 8113 format %{ "sarxl $dst, $src, $shift" %} 8114 ins_encode %{ 8115 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8116 %} 8117 ins_pipe(ialu_reg_reg); 8118 %} 8119 8120 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8121 %{ 8122 predicate(VM_Version::supports_bmi2()); 8123 match(Set dst (RShiftI (LoadI src) shift)); 8124 ins_cost(175); 8125 format %{ "sarxl $dst, $src, $shift" %} 8126 ins_encode %{ 8127 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8128 %} 8129 ins_pipe(ialu_reg_mem); 8130 %} 8131 8132 // Logical Shift Right by 8-bit immediate 8133 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8134 %{ 8135 match(Set dst (URShiftI dst shift)); 8136 effect(KILL cr); 8137 8138 format %{ "shrl $dst, $shift" %} 8139 ins_encode %{ 8140 __ shrl($dst$$Register, $shift$$constant); 8141 %} 8142 ins_pipe(ialu_reg); 8143 %} 8144 8145 // Logical Shift Right by 8-bit immediate 8146 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8147 %{ 8148 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8149 effect(KILL cr); 8150 8151 format %{ "shrl $dst, $shift" %} 8152 ins_encode %{ 8153 __ shrl($dst$$Address, $shift$$constant); 8154 %} 8155 ins_pipe(ialu_mem_imm); 8156 %} 8157 8158 // Logical Shift Right by variable 8159 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8160 %{ 8161 predicate(!VM_Version::supports_bmi2()); 8162 match(Set dst (URShiftI dst shift)); 8163 effect(KILL cr); 8164 8165 format %{ "shrl $dst, $shift" %} 8166 ins_encode %{ 8167 __ shrl($dst$$Register); 8168 %} 8169 ins_pipe(ialu_reg_reg); 8170 %} 8171 8172 // Logical Shift Right by variable 8173 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8174 %{ 8175 predicate(!VM_Version::supports_bmi2()); 8176 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8177 effect(KILL cr); 8178 8179 format %{ "shrl $dst, $shift" %} 8180 ins_encode %{ 8181 __ shrl($dst$$Address); 8182 %} 8183 ins_pipe(ialu_mem_reg); 8184 %} 8185 8186 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8187 %{ 8188 predicate(VM_Version::supports_bmi2()); 8189 match(Set dst (URShiftI src shift)); 8190 8191 format %{ "shrxl $dst, $src, $shift" %} 8192 ins_encode %{ 8193 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8194 %} 8195 ins_pipe(ialu_reg_reg); 8196 %} 8197 8198 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8199 %{ 8200 predicate(VM_Version::supports_bmi2()); 8201 match(Set dst (URShiftI (LoadI src) shift)); 8202 ins_cost(175); 8203 format %{ "shrxl $dst, $src, $shift" %} 8204 ins_encode %{ 8205 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8206 %} 8207 ins_pipe(ialu_reg_mem); 8208 %} 8209 8210 // Long Shift Instructions 8211 // Shift Left by one, two, three 8212 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8213 %{ 8214 match(Set dst (LShiftL dst shift)); 8215 effect(KILL cr); 8216 8217 format %{ "salq $dst, $shift" %} 8218 ins_encode %{ 8219 __ salq($dst$$Register, $shift$$constant); 8220 %} 8221 ins_pipe(ialu_reg); 8222 %} 8223 8224 // Shift Left by 8-bit immediate 8225 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8226 %{ 8227 match(Set dst (LShiftL dst shift)); 8228 effect(KILL cr); 8229 8230 format %{ "salq $dst, $shift" %} 8231 ins_encode %{ 8232 __ salq($dst$$Register, $shift$$constant); 8233 %} 8234 ins_pipe(ialu_reg); 8235 %} 8236 8237 // Shift Left by 8-bit immediate 8238 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8239 %{ 8240 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8241 effect(KILL cr); 8242 8243 format %{ "salq $dst, $shift" %} 8244 ins_encode %{ 8245 __ salq($dst$$Address, $shift$$constant); 8246 %} 8247 ins_pipe(ialu_mem_imm); 8248 %} 8249 8250 // Shift Left by variable 8251 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8252 %{ 8253 predicate(!VM_Version::supports_bmi2()); 8254 match(Set dst (LShiftL dst shift)); 8255 effect(KILL cr); 8256 8257 format %{ "salq $dst, $shift" %} 8258 ins_encode %{ 8259 __ salq($dst$$Register); 8260 %} 8261 ins_pipe(ialu_reg_reg); 8262 %} 8263 8264 // Shift Left by variable 8265 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8266 %{ 8267 predicate(!VM_Version::supports_bmi2()); 8268 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8269 effect(KILL cr); 8270 8271 format %{ "salq $dst, $shift" %} 8272 ins_encode %{ 8273 __ salq($dst$$Address); 8274 %} 8275 ins_pipe(ialu_mem_reg); 8276 %} 8277 8278 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8279 %{ 8280 predicate(VM_Version::supports_bmi2()); 8281 match(Set dst (LShiftL src shift)); 8282 8283 format %{ "shlxq $dst, $src, $shift" %} 8284 ins_encode %{ 8285 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8286 %} 8287 ins_pipe(ialu_reg_reg); 8288 %} 8289 8290 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8291 %{ 8292 predicate(VM_Version::supports_bmi2()); 8293 match(Set dst (LShiftL (LoadL src) shift)); 8294 ins_cost(175); 8295 format %{ "shlxq $dst, $src, $shift" %} 8296 ins_encode %{ 8297 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8298 %} 8299 ins_pipe(ialu_reg_mem); 8300 %} 8301 8302 // Arithmetic Shift Right by 8-bit immediate 8303 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8304 %{ 8305 match(Set dst (RShiftL dst shift)); 8306 effect(KILL cr); 8307 8308 format %{ "sarq $dst, $shift" %} 8309 ins_encode %{ 8310 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8311 %} 8312 ins_pipe(ialu_mem_imm); 8313 %} 8314 8315 // Arithmetic Shift Right by 8-bit immediate 8316 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8317 %{ 8318 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8319 effect(KILL cr); 8320 8321 format %{ "sarq $dst, $shift" %} 8322 ins_encode %{ 8323 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8324 %} 8325 ins_pipe(ialu_mem_imm); 8326 %} 8327 8328 // Arithmetic Shift Right by variable 8329 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8330 %{ 8331 predicate(!VM_Version::supports_bmi2()); 8332 match(Set dst (RShiftL dst shift)); 8333 effect(KILL cr); 8334 8335 format %{ "sarq $dst, $shift" %} 8336 ins_encode %{ 8337 __ sarq($dst$$Register); 8338 %} 8339 ins_pipe(ialu_reg_reg); 8340 %} 8341 8342 // Arithmetic Shift Right by variable 8343 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8344 %{ 8345 predicate(!VM_Version::supports_bmi2()); 8346 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8347 effect(KILL cr); 8348 8349 format %{ "sarq $dst, $shift" %} 8350 ins_encode %{ 8351 __ sarq($dst$$Address); 8352 %} 8353 ins_pipe(ialu_mem_reg); 8354 %} 8355 8356 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8357 %{ 8358 predicate(VM_Version::supports_bmi2()); 8359 match(Set dst (RShiftL src shift)); 8360 8361 format %{ "sarxq $dst, $src, $shift" %} 8362 ins_encode %{ 8363 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8364 %} 8365 ins_pipe(ialu_reg_reg); 8366 %} 8367 8368 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8369 %{ 8370 predicate(VM_Version::supports_bmi2()); 8371 match(Set dst (RShiftL (LoadL src) shift)); 8372 ins_cost(175); 8373 format %{ "sarxq $dst, $src, $shift" %} 8374 ins_encode %{ 8375 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8376 %} 8377 ins_pipe(ialu_reg_mem); 8378 %} 8379 8380 // Logical Shift Right by 8-bit immediate 8381 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8382 %{ 8383 match(Set dst (URShiftL dst shift)); 8384 effect(KILL cr); 8385 8386 format %{ "shrq $dst, $shift" %} 8387 ins_encode %{ 8388 __ shrq($dst$$Register, $shift$$constant); 8389 %} 8390 ins_pipe(ialu_reg); 8391 %} 8392 8393 // Logical Shift Right by 8-bit immediate 8394 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8395 %{ 8396 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8397 effect(KILL cr); 8398 8399 format %{ "shrq $dst, $shift" %} 8400 ins_encode %{ 8401 __ shrq($dst$$Address, $shift$$constant); 8402 %} 8403 ins_pipe(ialu_mem_imm); 8404 %} 8405 8406 // Logical Shift Right by variable 8407 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8408 %{ 8409 predicate(!VM_Version::supports_bmi2()); 8410 match(Set dst (URShiftL dst shift)); 8411 effect(KILL cr); 8412 8413 format %{ "shrq $dst, $shift" %} 8414 ins_encode %{ 8415 __ shrq($dst$$Register); 8416 %} 8417 ins_pipe(ialu_reg_reg); 8418 %} 8419 8420 // Logical Shift Right by variable 8421 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8422 %{ 8423 predicate(!VM_Version::supports_bmi2()); 8424 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8425 effect(KILL cr); 8426 8427 format %{ "shrq $dst, $shift" %} 8428 ins_encode %{ 8429 __ shrq($dst$$Address); 8430 %} 8431 ins_pipe(ialu_mem_reg); 8432 %} 8433 8434 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8435 %{ 8436 predicate(VM_Version::supports_bmi2()); 8437 match(Set dst (URShiftL src shift)); 8438 8439 format %{ "shrxq $dst, $src, $shift" %} 8440 ins_encode %{ 8441 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8442 %} 8443 ins_pipe(ialu_reg_reg); 8444 %} 8445 8446 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8447 %{ 8448 predicate(VM_Version::supports_bmi2()); 8449 match(Set dst (URShiftL (LoadL src) shift)); 8450 ins_cost(175); 8451 format %{ "shrxq $dst, $src, $shift" %} 8452 ins_encode %{ 8453 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8454 %} 8455 ins_pipe(ialu_reg_mem); 8456 %} 8457 8458 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8459 // This idiom is used by the compiler for the i2b bytecode. 8460 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8461 %{ 8462 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8463 8464 format %{ "movsbl $dst, $src\t# i2b" %} 8465 ins_encode %{ 8466 __ movsbl($dst$$Register, $src$$Register); 8467 %} 8468 ins_pipe(ialu_reg_reg); 8469 %} 8470 8471 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8472 // This idiom is used by the compiler the i2s bytecode. 8473 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8474 %{ 8475 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8476 8477 format %{ "movswl $dst, $src\t# i2s" %} 8478 ins_encode %{ 8479 __ movswl($dst$$Register, $src$$Register); 8480 %} 8481 ins_pipe(ialu_reg_reg); 8482 %} 8483 8484 // ROL/ROR instructions 8485 8486 // Rotate left by constant. 8487 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8488 %{ 8489 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8490 match(Set dst (RotateLeft dst shift)); 8491 effect(KILL cr); 8492 format %{ "roll $dst, $shift" %} 8493 ins_encode %{ 8494 __ roll($dst$$Register, $shift$$constant); 8495 %} 8496 ins_pipe(ialu_reg); 8497 %} 8498 8499 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8500 %{ 8501 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8502 match(Set dst (RotateLeft src shift)); 8503 format %{ "rolxl $dst, $src, $shift" %} 8504 ins_encode %{ 8505 int shift = 32 - ($shift$$constant & 31); 8506 __ rorxl($dst$$Register, $src$$Register, shift); 8507 %} 8508 ins_pipe(ialu_reg_reg); 8509 %} 8510 8511 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8512 %{ 8513 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8514 match(Set dst (RotateLeft (LoadI src) shift)); 8515 ins_cost(175); 8516 format %{ "rolxl $dst, $src, $shift" %} 8517 ins_encode %{ 8518 int shift = 32 - ($shift$$constant & 31); 8519 __ rorxl($dst$$Register, $src$$Address, shift); 8520 %} 8521 ins_pipe(ialu_reg_mem); 8522 %} 8523 8524 // Rotate Left by variable 8525 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8526 %{ 8527 predicate(n->bottom_type()->basic_type() == T_INT); 8528 match(Set dst (RotateLeft dst shift)); 8529 effect(KILL cr); 8530 format %{ "roll $dst, $shift" %} 8531 ins_encode %{ 8532 __ roll($dst$$Register); 8533 %} 8534 ins_pipe(ialu_reg_reg); 8535 %} 8536 8537 // Rotate Right by constant. 8538 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8539 %{ 8540 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8541 match(Set dst (RotateRight dst shift)); 8542 effect(KILL cr); 8543 format %{ "rorl $dst, $shift" %} 8544 ins_encode %{ 8545 __ rorl($dst$$Register, $shift$$constant); 8546 %} 8547 ins_pipe(ialu_reg); 8548 %} 8549 8550 // Rotate Right by constant. 8551 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8552 %{ 8553 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8554 match(Set dst (RotateRight src shift)); 8555 format %{ "rorxl $dst, $src, $shift" %} 8556 ins_encode %{ 8557 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8558 %} 8559 ins_pipe(ialu_reg_reg); 8560 %} 8561 8562 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8563 %{ 8564 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8565 match(Set dst (RotateRight (LoadI src) shift)); 8566 ins_cost(175); 8567 format %{ "rorxl $dst, $src, $shift" %} 8568 ins_encode %{ 8569 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8570 %} 8571 ins_pipe(ialu_reg_mem); 8572 %} 8573 8574 // Rotate Right by variable 8575 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8576 %{ 8577 predicate(n->bottom_type()->basic_type() == T_INT); 8578 match(Set dst (RotateRight dst shift)); 8579 effect(KILL cr); 8580 format %{ "rorl $dst, $shift" %} 8581 ins_encode %{ 8582 __ rorl($dst$$Register); 8583 %} 8584 ins_pipe(ialu_reg_reg); 8585 %} 8586 8587 // Rotate Left by constant. 8588 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8589 %{ 8590 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8591 match(Set dst (RotateLeft dst shift)); 8592 effect(KILL cr); 8593 format %{ "rolq $dst, $shift" %} 8594 ins_encode %{ 8595 __ rolq($dst$$Register, $shift$$constant); 8596 %} 8597 ins_pipe(ialu_reg); 8598 %} 8599 8600 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8601 %{ 8602 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8603 match(Set dst (RotateLeft src shift)); 8604 format %{ "rolxq $dst, $src, $shift" %} 8605 ins_encode %{ 8606 int shift = 64 - ($shift$$constant & 63); 8607 __ rorxq($dst$$Register, $src$$Register, shift); 8608 %} 8609 ins_pipe(ialu_reg_reg); 8610 %} 8611 8612 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8613 %{ 8614 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8615 match(Set dst (RotateLeft (LoadL src) shift)); 8616 ins_cost(175); 8617 format %{ "rolxq $dst, $src, $shift" %} 8618 ins_encode %{ 8619 int shift = 64 - ($shift$$constant & 63); 8620 __ rorxq($dst$$Register, $src$$Address, shift); 8621 %} 8622 ins_pipe(ialu_reg_mem); 8623 %} 8624 8625 // Rotate Left by variable 8626 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8627 %{ 8628 predicate(n->bottom_type()->basic_type() == T_LONG); 8629 match(Set dst (RotateLeft dst shift)); 8630 effect(KILL cr); 8631 format %{ "rolq $dst, $shift" %} 8632 ins_encode %{ 8633 __ rolq($dst$$Register); 8634 %} 8635 ins_pipe(ialu_reg_reg); 8636 %} 8637 8638 // Rotate Right by constant. 8639 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8640 %{ 8641 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8642 match(Set dst (RotateRight dst shift)); 8643 effect(KILL cr); 8644 format %{ "rorq $dst, $shift" %} 8645 ins_encode %{ 8646 __ rorq($dst$$Register, $shift$$constant); 8647 %} 8648 ins_pipe(ialu_reg); 8649 %} 8650 8651 // Rotate Right by constant 8652 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8653 %{ 8654 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8655 match(Set dst (RotateRight src shift)); 8656 format %{ "rorxq $dst, $src, $shift" %} 8657 ins_encode %{ 8658 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8659 %} 8660 ins_pipe(ialu_reg_reg); 8661 %} 8662 8663 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8664 %{ 8665 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8666 match(Set dst (RotateRight (LoadL src) shift)); 8667 ins_cost(175); 8668 format %{ "rorxq $dst, $src, $shift" %} 8669 ins_encode %{ 8670 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8671 %} 8672 ins_pipe(ialu_reg_mem); 8673 %} 8674 8675 // Rotate Right by variable 8676 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8677 %{ 8678 predicate(n->bottom_type()->basic_type() == T_LONG); 8679 match(Set dst (RotateRight dst shift)); 8680 effect(KILL cr); 8681 format %{ "rorq $dst, $shift" %} 8682 ins_encode %{ 8683 __ rorq($dst$$Register); 8684 %} 8685 ins_pipe(ialu_reg_reg); 8686 %} 8687 8688 //----------------------------- CompressBits/ExpandBits ------------------------ 8689 8690 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8691 predicate(n->bottom_type()->isa_long()); 8692 match(Set dst (CompressBits src mask)); 8693 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8694 ins_encode %{ 8695 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8696 %} 8697 ins_pipe( pipe_slow ); 8698 %} 8699 8700 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8701 predicate(n->bottom_type()->isa_long()); 8702 match(Set dst (ExpandBits src mask)); 8703 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8704 ins_encode %{ 8705 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8706 %} 8707 ins_pipe( pipe_slow ); 8708 %} 8709 8710 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8711 predicate(n->bottom_type()->isa_long()); 8712 match(Set dst (CompressBits src (LoadL mask))); 8713 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8714 ins_encode %{ 8715 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8716 %} 8717 ins_pipe( pipe_slow ); 8718 %} 8719 8720 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8721 predicate(n->bottom_type()->isa_long()); 8722 match(Set dst (ExpandBits src (LoadL mask))); 8723 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8724 ins_encode %{ 8725 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8726 %} 8727 ins_pipe( pipe_slow ); 8728 %} 8729 8730 8731 // Logical Instructions 8732 8733 // Integer Logical Instructions 8734 8735 // And Instructions 8736 // And Register with Register 8737 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8738 %{ 8739 match(Set dst (AndI dst src)); 8740 effect(KILL cr); 8741 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); 8742 8743 format %{ "andl $dst, $src\t# int" %} 8744 ins_encode %{ 8745 __ andl($dst$$Register, $src$$Register); 8746 %} 8747 ins_pipe(ialu_reg_reg); 8748 %} 8749 8750 // And Register with Immediate 255 8751 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8752 %{ 8753 match(Set dst (AndI src mask)); 8754 8755 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8756 ins_encode %{ 8757 __ movzbl($dst$$Register, $src$$Register); 8758 %} 8759 ins_pipe(ialu_reg); 8760 %} 8761 8762 // And Register with Immediate 255 and promote to long 8763 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8764 %{ 8765 match(Set dst (ConvI2L (AndI src mask))); 8766 8767 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8768 ins_encode %{ 8769 __ movzbl($dst$$Register, $src$$Register); 8770 %} 8771 ins_pipe(ialu_reg); 8772 %} 8773 8774 // And Register with Immediate 65535 8775 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8776 %{ 8777 match(Set dst (AndI src mask)); 8778 8779 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8780 ins_encode %{ 8781 __ movzwl($dst$$Register, $src$$Register); 8782 %} 8783 ins_pipe(ialu_reg); 8784 %} 8785 8786 // And Register with Immediate 65535 and promote to long 8787 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8788 %{ 8789 match(Set dst (ConvI2L (AndI src mask))); 8790 8791 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8792 ins_encode %{ 8793 __ movzwl($dst$$Register, $src$$Register); 8794 %} 8795 ins_pipe(ialu_reg); 8796 %} 8797 8798 // Can skip int2long conversions after AND with small bitmask 8799 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8800 %{ 8801 predicate(VM_Version::supports_bmi2()); 8802 ins_cost(125); 8803 effect(TEMP tmp, KILL cr); 8804 match(Set dst (ConvI2L (AndI src mask))); 8805 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8806 ins_encode %{ 8807 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8808 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8809 %} 8810 ins_pipe(ialu_reg_reg); 8811 %} 8812 8813 // And Register with Immediate 8814 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8815 %{ 8816 match(Set dst (AndI dst src)); 8817 effect(KILL cr); 8818 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); 8819 8820 format %{ "andl $dst, $src\t# int" %} 8821 ins_encode %{ 8822 __ andl($dst$$Register, $src$$constant); 8823 %} 8824 ins_pipe(ialu_reg); 8825 %} 8826 8827 // And Register with Memory 8828 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8829 %{ 8830 match(Set dst (AndI dst (LoadI src))); 8831 effect(KILL cr); 8832 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); 8833 8834 ins_cost(150); 8835 format %{ "andl $dst, $src\t# int" %} 8836 ins_encode %{ 8837 __ andl($dst$$Register, $src$$Address); 8838 %} 8839 ins_pipe(ialu_reg_mem); 8840 %} 8841 8842 // And Memory with Register 8843 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8844 %{ 8845 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8846 effect(KILL cr); 8847 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); 8848 8849 ins_cost(150); 8850 format %{ "andb $dst, $src\t# byte" %} 8851 ins_encode %{ 8852 __ andb($dst$$Address, $src$$Register); 8853 %} 8854 ins_pipe(ialu_mem_reg); 8855 %} 8856 8857 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8858 %{ 8859 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8860 effect(KILL cr); 8861 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); 8862 8863 ins_cost(150); 8864 format %{ "andl $dst, $src\t# int" %} 8865 ins_encode %{ 8866 __ andl($dst$$Address, $src$$Register); 8867 %} 8868 ins_pipe(ialu_mem_reg); 8869 %} 8870 8871 // And Memory with Immediate 8872 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8873 %{ 8874 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8875 effect(KILL cr); 8876 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); 8877 8878 ins_cost(125); 8879 format %{ "andl $dst, $src\t# int" %} 8880 ins_encode %{ 8881 __ andl($dst$$Address, $src$$constant); 8882 %} 8883 ins_pipe(ialu_mem_imm); 8884 %} 8885 8886 // BMI1 instructions 8887 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8888 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8889 predicate(UseBMI1Instructions); 8890 effect(KILL cr); 8891 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8892 8893 ins_cost(125); 8894 format %{ "andnl $dst, $src1, $src2" %} 8895 8896 ins_encode %{ 8897 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8898 %} 8899 ins_pipe(ialu_reg_mem); 8900 %} 8901 8902 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8903 match(Set dst (AndI (XorI src1 minus_1) src2)); 8904 predicate(UseBMI1Instructions); 8905 effect(KILL cr); 8906 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8907 8908 format %{ "andnl $dst, $src1, $src2" %} 8909 8910 ins_encode %{ 8911 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8912 %} 8913 ins_pipe(ialu_reg); 8914 %} 8915 8916 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 8917 match(Set dst (AndI (SubI imm_zero src) src)); 8918 predicate(UseBMI1Instructions); 8919 effect(KILL cr); 8920 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8921 8922 format %{ "blsil $dst, $src" %} 8923 8924 ins_encode %{ 8925 __ blsil($dst$$Register, $src$$Register); 8926 %} 8927 ins_pipe(ialu_reg); 8928 %} 8929 8930 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 8931 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8932 predicate(UseBMI1Instructions); 8933 effect(KILL cr); 8934 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8935 8936 ins_cost(125); 8937 format %{ "blsil $dst, $src" %} 8938 8939 ins_encode %{ 8940 __ blsil($dst$$Register, $src$$Address); 8941 %} 8942 ins_pipe(ialu_reg_mem); 8943 %} 8944 8945 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8946 %{ 8947 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8948 predicate(UseBMI1Instructions); 8949 effect(KILL cr); 8950 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 8951 8952 ins_cost(125); 8953 format %{ "blsmskl $dst, $src" %} 8954 8955 ins_encode %{ 8956 __ blsmskl($dst$$Register, $src$$Address); 8957 %} 8958 ins_pipe(ialu_reg_mem); 8959 %} 8960 8961 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8962 %{ 8963 match(Set dst (XorI (AddI src minus_1) src)); 8964 predicate(UseBMI1Instructions); 8965 effect(KILL cr); 8966 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 8967 8968 format %{ "blsmskl $dst, $src" %} 8969 8970 ins_encode %{ 8971 __ blsmskl($dst$$Register, $src$$Register); 8972 %} 8973 8974 ins_pipe(ialu_reg); 8975 %} 8976 8977 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8978 %{ 8979 match(Set dst (AndI (AddI src minus_1) src) ); 8980 predicate(UseBMI1Instructions); 8981 effect(KILL cr); 8982 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8983 8984 format %{ "blsrl $dst, $src" %} 8985 8986 ins_encode %{ 8987 __ blsrl($dst$$Register, $src$$Register); 8988 %} 8989 8990 ins_pipe(ialu_reg_mem); 8991 %} 8992 8993 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8994 %{ 8995 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8996 predicate(UseBMI1Instructions); 8997 effect(KILL cr); 8998 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8999 9000 ins_cost(125); 9001 format %{ "blsrl $dst, $src" %} 9002 9003 ins_encode %{ 9004 __ blsrl($dst$$Register, $src$$Address); 9005 %} 9006 9007 ins_pipe(ialu_reg); 9008 %} 9009 9010 // Or Instructions 9011 // Or Register with Register 9012 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9013 %{ 9014 match(Set dst (OrI dst src)); 9015 effect(KILL cr); 9016 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); 9017 9018 format %{ "orl $dst, $src\t# int" %} 9019 ins_encode %{ 9020 __ orl($dst$$Register, $src$$Register); 9021 %} 9022 ins_pipe(ialu_reg_reg); 9023 %} 9024 9025 // Or Register with Immediate 9026 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9027 %{ 9028 match(Set dst (OrI dst src)); 9029 effect(KILL cr); 9030 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); 9031 9032 format %{ "orl $dst, $src\t# int" %} 9033 ins_encode %{ 9034 __ orl($dst$$Register, $src$$constant); 9035 %} 9036 ins_pipe(ialu_reg); 9037 %} 9038 9039 // Or Register with Memory 9040 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9041 %{ 9042 match(Set dst (OrI dst (LoadI src))); 9043 effect(KILL cr); 9044 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); 9045 9046 ins_cost(150); 9047 format %{ "orl $dst, $src\t# int" %} 9048 ins_encode %{ 9049 __ orl($dst$$Register, $src$$Address); 9050 %} 9051 ins_pipe(ialu_reg_mem); 9052 %} 9053 9054 // Or Memory with Register 9055 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9056 %{ 9057 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9058 effect(KILL cr); 9059 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); 9060 9061 ins_cost(150); 9062 format %{ "orb $dst, $src\t# byte" %} 9063 ins_encode %{ 9064 __ orb($dst$$Address, $src$$Register); 9065 %} 9066 ins_pipe(ialu_mem_reg); 9067 %} 9068 9069 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9070 %{ 9071 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9072 effect(KILL cr); 9073 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); 9074 9075 ins_cost(150); 9076 format %{ "orl $dst, $src\t# int" %} 9077 ins_encode %{ 9078 __ orl($dst$$Address, $src$$Register); 9079 %} 9080 ins_pipe(ialu_mem_reg); 9081 %} 9082 9083 // Or Memory with Immediate 9084 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9085 %{ 9086 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9087 effect(KILL cr); 9088 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); 9089 9090 ins_cost(125); 9091 format %{ "orl $dst, $src\t# int" %} 9092 ins_encode %{ 9093 __ orl($dst$$Address, $src$$constant); 9094 %} 9095 ins_pipe(ialu_mem_imm); 9096 %} 9097 9098 // Xor Instructions 9099 // Xor Register with Register 9100 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9101 %{ 9102 match(Set dst (XorI dst src)); 9103 effect(KILL cr); 9104 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); 9105 9106 format %{ "xorl $dst, $src\t# int" %} 9107 ins_encode %{ 9108 __ xorl($dst$$Register, $src$$Register); 9109 %} 9110 ins_pipe(ialu_reg_reg); 9111 %} 9112 9113 // Xor Register with Immediate -1 9114 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9115 match(Set dst (XorI dst imm)); 9116 9117 format %{ "not $dst" %} 9118 ins_encode %{ 9119 __ notl($dst$$Register); 9120 %} 9121 ins_pipe(ialu_reg); 9122 %} 9123 9124 // Xor Register with Immediate 9125 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9126 %{ 9127 match(Set dst (XorI dst src)); 9128 effect(KILL cr); 9129 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); 9130 9131 format %{ "xorl $dst, $src\t# int" %} 9132 ins_encode %{ 9133 __ xorl($dst$$Register, $src$$constant); 9134 %} 9135 ins_pipe(ialu_reg); 9136 %} 9137 9138 // Xor Register with Memory 9139 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9140 %{ 9141 match(Set dst (XorI dst (LoadI src))); 9142 effect(KILL cr); 9143 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); 9144 9145 ins_cost(150); 9146 format %{ "xorl $dst, $src\t# int" %} 9147 ins_encode %{ 9148 __ xorl($dst$$Register, $src$$Address); 9149 %} 9150 ins_pipe(ialu_reg_mem); 9151 %} 9152 9153 // Xor Memory with Register 9154 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9155 %{ 9156 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9157 effect(KILL cr); 9158 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); 9159 9160 ins_cost(150); 9161 format %{ "xorb $dst, $src\t# byte" %} 9162 ins_encode %{ 9163 __ xorb($dst$$Address, $src$$Register); 9164 %} 9165 ins_pipe(ialu_mem_reg); 9166 %} 9167 9168 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9169 %{ 9170 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9171 effect(KILL cr); 9172 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); 9173 9174 ins_cost(150); 9175 format %{ "xorl $dst, $src\t# int" %} 9176 ins_encode %{ 9177 __ xorl($dst$$Address, $src$$Register); 9178 %} 9179 ins_pipe(ialu_mem_reg); 9180 %} 9181 9182 // Xor Memory with Immediate 9183 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9184 %{ 9185 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9186 effect(KILL cr); 9187 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); 9188 9189 ins_cost(125); 9190 format %{ "xorl $dst, $src\t# int" %} 9191 ins_encode %{ 9192 __ xorl($dst$$Address, $src$$constant); 9193 %} 9194 ins_pipe(ialu_mem_imm); 9195 %} 9196 9197 9198 // Long Logical Instructions 9199 9200 // And Instructions 9201 // And Register with Register 9202 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9203 %{ 9204 match(Set dst (AndL dst src)); 9205 effect(KILL cr); 9206 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); 9207 9208 format %{ "andq $dst, $src\t# long" %} 9209 ins_encode %{ 9210 __ andq($dst$$Register, $src$$Register); 9211 %} 9212 ins_pipe(ialu_reg_reg); 9213 %} 9214 9215 // And Register with Immediate 255 9216 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9217 %{ 9218 match(Set dst (AndL src mask)); 9219 9220 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9221 ins_encode %{ 9222 // movzbl zeroes out the upper 32-bit and does not need REX.W 9223 __ movzbl($dst$$Register, $src$$Register); 9224 %} 9225 ins_pipe(ialu_reg); 9226 %} 9227 9228 // And Register with Immediate 65535 9229 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9230 %{ 9231 match(Set dst (AndL src mask)); 9232 9233 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9234 ins_encode %{ 9235 // movzwl zeroes out the upper 32-bit and does not need REX.W 9236 __ movzwl($dst$$Register, $src$$Register); 9237 %} 9238 ins_pipe(ialu_reg); 9239 %} 9240 9241 // And Register with Immediate 9242 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9243 %{ 9244 match(Set dst (AndL dst src)); 9245 effect(KILL cr); 9246 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); 9247 9248 format %{ "andq $dst, $src\t# long" %} 9249 ins_encode %{ 9250 __ andq($dst$$Register, $src$$constant); 9251 %} 9252 ins_pipe(ialu_reg); 9253 %} 9254 9255 // And Register with Memory 9256 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9257 %{ 9258 match(Set dst (AndL dst (LoadL src))); 9259 effect(KILL cr); 9260 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); 9261 9262 ins_cost(150); 9263 format %{ "andq $dst, $src\t# long" %} 9264 ins_encode %{ 9265 __ andq($dst$$Register, $src$$Address); 9266 %} 9267 ins_pipe(ialu_reg_mem); 9268 %} 9269 9270 // And Memory with Register 9271 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9272 %{ 9273 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9274 effect(KILL cr); 9275 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); 9276 9277 ins_cost(150); 9278 format %{ "andq $dst, $src\t# long" %} 9279 ins_encode %{ 9280 __ andq($dst$$Address, $src$$Register); 9281 %} 9282 ins_pipe(ialu_mem_reg); 9283 %} 9284 9285 // And Memory with Immediate 9286 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9287 %{ 9288 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9289 effect(KILL cr); 9290 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); 9291 9292 ins_cost(125); 9293 format %{ "andq $dst, $src\t# long" %} 9294 ins_encode %{ 9295 __ andq($dst$$Address, $src$$constant); 9296 %} 9297 ins_pipe(ialu_mem_imm); 9298 %} 9299 9300 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9301 %{ 9302 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9303 // because AND/OR works well enough for 8/32-bit values. 9304 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9305 9306 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9307 effect(KILL cr); 9308 9309 ins_cost(125); 9310 format %{ "btrq $dst, log2(not($con))\t# long" %} 9311 ins_encode %{ 9312 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9313 %} 9314 ins_pipe(ialu_mem_imm); 9315 %} 9316 9317 // BMI1 instructions 9318 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9319 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9320 predicate(UseBMI1Instructions); 9321 effect(KILL cr); 9322 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9323 9324 ins_cost(125); 9325 format %{ "andnq $dst, $src1, $src2" %} 9326 9327 ins_encode %{ 9328 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9329 %} 9330 ins_pipe(ialu_reg_mem); 9331 %} 9332 9333 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9334 match(Set dst (AndL (XorL src1 minus_1) src2)); 9335 predicate(UseBMI1Instructions); 9336 effect(KILL cr); 9337 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9338 9339 format %{ "andnq $dst, $src1, $src2" %} 9340 9341 ins_encode %{ 9342 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9343 %} 9344 ins_pipe(ialu_reg_mem); 9345 %} 9346 9347 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9348 match(Set dst (AndL (SubL imm_zero src) src)); 9349 predicate(UseBMI1Instructions); 9350 effect(KILL cr); 9351 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9352 9353 format %{ "blsiq $dst, $src" %} 9354 9355 ins_encode %{ 9356 __ blsiq($dst$$Register, $src$$Register); 9357 %} 9358 ins_pipe(ialu_reg); 9359 %} 9360 9361 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9362 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9363 predicate(UseBMI1Instructions); 9364 effect(KILL cr); 9365 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9366 9367 ins_cost(125); 9368 format %{ "blsiq $dst, $src" %} 9369 9370 ins_encode %{ 9371 __ blsiq($dst$$Register, $src$$Address); 9372 %} 9373 ins_pipe(ialu_reg_mem); 9374 %} 9375 9376 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9377 %{ 9378 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9379 predicate(UseBMI1Instructions); 9380 effect(KILL cr); 9381 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9382 9383 ins_cost(125); 9384 format %{ "blsmskq $dst, $src" %} 9385 9386 ins_encode %{ 9387 __ blsmskq($dst$$Register, $src$$Address); 9388 %} 9389 ins_pipe(ialu_reg_mem); 9390 %} 9391 9392 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9393 %{ 9394 match(Set dst (XorL (AddL src minus_1) src)); 9395 predicate(UseBMI1Instructions); 9396 effect(KILL cr); 9397 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9398 9399 format %{ "blsmskq $dst, $src" %} 9400 9401 ins_encode %{ 9402 __ blsmskq($dst$$Register, $src$$Register); 9403 %} 9404 9405 ins_pipe(ialu_reg); 9406 %} 9407 9408 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9409 %{ 9410 match(Set dst (AndL (AddL src minus_1) src) ); 9411 predicate(UseBMI1Instructions); 9412 effect(KILL cr); 9413 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9414 9415 format %{ "blsrq $dst, $src" %} 9416 9417 ins_encode %{ 9418 __ blsrq($dst$$Register, $src$$Register); 9419 %} 9420 9421 ins_pipe(ialu_reg); 9422 %} 9423 9424 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9425 %{ 9426 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9427 predicate(UseBMI1Instructions); 9428 effect(KILL cr); 9429 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9430 9431 ins_cost(125); 9432 format %{ "blsrq $dst, $src" %} 9433 9434 ins_encode %{ 9435 __ blsrq($dst$$Register, $src$$Address); 9436 %} 9437 9438 ins_pipe(ialu_reg); 9439 %} 9440 9441 // Or Instructions 9442 // Or Register with Register 9443 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9444 %{ 9445 match(Set dst (OrL dst src)); 9446 effect(KILL cr); 9447 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); 9448 9449 format %{ "orq $dst, $src\t# long" %} 9450 ins_encode %{ 9451 __ orq($dst$$Register, $src$$Register); 9452 %} 9453 ins_pipe(ialu_reg_reg); 9454 %} 9455 9456 // Use any_RegP to match R15 (TLS register) without spilling. 9457 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9458 match(Set dst (OrL dst (CastP2X src))); 9459 effect(KILL cr); 9460 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); 9461 9462 format %{ "orq $dst, $src\t# long" %} 9463 ins_encode %{ 9464 __ orq($dst$$Register, $src$$Register); 9465 %} 9466 ins_pipe(ialu_reg_reg); 9467 %} 9468 9469 9470 // Or Register with Immediate 9471 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9472 %{ 9473 match(Set dst (OrL dst src)); 9474 effect(KILL cr); 9475 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); 9476 9477 format %{ "orq $dst, $src\t# long" %} 9478 ins_encode %{ 9479 __ orq($dst$$Register, $src$$constant); 9480 %} 9481 ins_pipe(ialu_reg); 9482 %} 9483 9484 // Or Register with Memory 9485 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9486 %{ 9487 match(Set dst (OrL dst (LoadL src))); 9488 effect(KILL cr); 9489 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); 9490 9491 ins_cost(150); 9492 format %{ "orq $dst, $src\t# long" %} 9493 ins_encode %{ 9494 __ orq($dst$$Register, $src$$Address); 9495 %} 9496 ins_pipe(ialu_reg_mem); 9497 %} 9498 9499 // Or Memory with Register 9500 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9501 %{ 9502 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9503 effect(KILL cr); 9504 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); 9505 9506 ins_cost(150); 9507 format %{ "orq $dst, $src\t# long" %} 9508 ins_encode %{ 9509 __ orq($dst$$Address, $src$$Register); 9510 %} 9511 ins_pipe(ialu_mem_reg); 9512 %} 9513 9514 // Or Memory with Immediate 9515 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9516 %{ 9517 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9518 effect(KILL cr); 9519 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); 9520 9521 ins_cost(125); 9522 format %{ "orq $dst, $src\t# long" %} 9523 ins_encode %{ 9524 __ orq($dst$$Address, $src$$constant); 9525 %} 9526 ins_pipe(ialu_mem_imm); 9527 %} 9528 9529 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9530 %{ 9531 // con should be a pure 64-bit power of 2 immediate 9532 // because AND/OR works well enough for 8/32-bit values. 9533 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9534 9535 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9536 effect(KILL cr); 9537 9538 ins_cost(125); 9539 format %{ "btsq $dst, log2($con)\t# long" %} 9540 ins_encode %{ 9541 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9542 %} 9543 ins_pipe(ialu_mem_imm); 9544 %} 9545 9546 // Xor Instructions 9547 // Xor Register with Register 9548 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9549 %{ 9550 match(Set dst (XorL dst src)); 9551 effect(KILL cr); 9552 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); 9553 9554 format %{ "xorq $dst, $src\t# long" %} 9555 ins_encode %{ 9556 __ xorq($dst$$Register, $src$$Register); 9557 %} 9558 ins_pipe(ialu_reg_reg); 9559 %} 9560 9561 // Xor Register with Immediate -1 9562 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9563 match(Set dst (XorL dst imm)); 9564 9565 format %{ "notq $dst" %} 9566 ins_encode %{ 9567 __ notq($dst$$Register); 9568 %} 9569 ins_pipe(ialu_reg); 9570 %} 9571 9572 // Xor Register with Immediate 9573 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9574 %{ 9575 match(Set dst (XorL dst src)); 9576 effect(KILL cr); 9577 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); 9578 9579 format %{ "xorq $dst, $src\t# long" %} 9580 ins_encode %{ 9581 __ xorq($dst$$Register, $src$$constant); 9582 %} 9583 ins_pipe(ialu_reg); 9584 %} 9585 9586 // Xor Register with Memory 9587 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9588 %{ 9589 match(Set dst (XorL dst (LoadL src))); 9590 effect(KILL cr); 9591 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); 9592 9593 ins_cost(150); 9594 format %{ "xorq $dst, $src\t# long" %} 9595 ins_encode %{ 9596 __ xorq($dst$$Register, $src$$Address); 9597 %} 9598 ins_pipe(ialu_reg_mem); 9599 %} 9600 9601 // Xor Memory with Register 9602 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9603 %{ 9604 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9605 effect(KILL cr); 9606 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); 9607 9608 ins_cost(150); 9609 format %{ "xorq $dst, $src\t# long" %} 9610 ins_encode %{ 9611 __ xorq($dst$$Address, $src$$Register); 9612 %} 9613 ins_pipe(ialu_mem_reg); 9614 %} 9615 9616 // Xor Memory with Immediate 9617 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9618 %{ 9619 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9620 effect(KILL cr); 9621 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); 9622 9623 ins_cost(125); 9624 format %{ "xorq $dst, $src\t# long" %} 9625 ins_encode %{ 9626 __ xorq($dst$$Address, $src$$constant); 9627 %} 9628 ins_pipe(ialu_mem_imm); 9629 %} 9630 9631 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9632 %{ 9633 match(Set dst (CmpLTMask p q)); 9634 effect(KILL cr); 9635 9636 ins_cost(400); 9637 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9638 "setlt $dst\n\t" 9639 "movzbl $dst, $dst\n\t" 9640 "negl $dst" %} 9641 ins_encode %{ 9642 __ cmpl($p$$Register, $q$$Register); 9643 __ setb(Assembler::less, $dst$$Register); 9644 __ movzbl($dst$$Register, $dst$$Register); 9645 __ negl($dst$$Register); 9646 %} 9647 ins_pipe(pipe_slow); 9648 %} 9649 9650 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9651 %{ 9652 match(Set dst (CmpLTMask dst zero)); 9653 effect(KILL cr); 9654 9655 ins_cost(100); 9656 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9657 ins_encode %{ 9658 __ sarl($dst$$Register, 31); 9659 %} 9660 ins_pipe(ialu_reg); 9661 %} 9662 9663 /* Better to save a register than avoid a branch */ 9664 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9665 %{ 9666 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9667 effect(KILL cr); 9668 ins_cost(300); 9669 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9670 "jge done\n\t" 9671 "addl $p,$y\n" 9672 "done: " %} 9673 ins_encode %{ 9674 Register Rp = $p$$Register; 9675 Register Rq = $q$$Register; 9676 Register Ry = $y$$Register; 9677 Label done; 9678 __ subl(Rp, Rq); 9679 __ jccb(Assembler::greaterEqual, done); 9680 __ addl(Rp, Ry); 9681 __ bind(done); 9682 %} 9683 ins_pipe(pipe_cmplt); 9684 %} 9685 9686 /* Better to save a register than avoid a branch */ 9687 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9688 %{ 9689 match(Set y (AndI (CmpLTMask p q) y)); 9690 effect(KILL cr); 9691 9692 ins_cost(300); 9693 9694 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9695 "jlt done\n\t" 9696 "xorl $y, $y\n" 9697 "done: " %} 9698 ins_encode %{ 9699 Register Rp = $p$$Register; 9700 Register Rq = $q$$Register; 9701 Register Ry = $y$$Register; 9702 Label done; 9703 __ cmpl(Rp, Rq); 9704 __ jccb(Assembler::less, done); 9705 __ xorl(Ry, Ry); 9706 __ bind(done); 9707 %} 9708 ins_pipe(pipe_cmplt); 9709 %} 9710 9711 9712 //---------- FP Instructions------------------------------------------------ 9713 9714 // Really expensive, avoid 9715 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9716 %{ 9717 match(Set cr (CmpF src1 src2)); 9718 9719 ins_cost(500); 9720 format %{ "ucomiss $src1, $src2\n\t" 9721 "jnp,s exit\n\t" 9722 "pushfq\t# saw NaN, set CF\n\t" 9723 "andq [rsp], #0xffffff2b\n\t" 9724 "popfq\n" 9725 "exit:" %} 9726 ins_encode %{ 9727 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9728 emit_cmpfp_fixup(masm); 9729 %} 9730 ins_pipe(pipe_slow); 9731 %} 9732 9733 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9734 match(Set cr (CmpF src1 src2)); 9735 9736 ins_cost(100); 9737 format %{ "ucomiss $src1, $src2" %} 9738 ins_encode %{ 9739 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9740 %} 9741 ins_pipe(pipe_slow); 9742 %} 9743 9744 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9745 match(Set cr (CmpF src1 (LoadF src2))); 9746 9747 ins_cost(100); 9748 format %{ "ucomiss $src1, $src2" %} 9749 ins_encode %{ 9750 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9751 %} 9752 ins_pipe(pipe_slow); 9753 %} 9754 9755 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9756 match(Set cr (CmpF src con)); 9757 ins_cost(100); 9758 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9759 ins_encode %{ 9760 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9761 %} 9762 ins_pipe(pipe_slow); 9763 %} 9764 9765 // Really expensive, avoid 9766 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9767 %{ 9768 match(Set cr (CmpD src1 src2)); 9769 9770 ins_cost(500); 9771 format %{ "ucomisd $src1, $src2\n\t" 9772 "jnp,s exit\n\t" 9773 "pushfq\t# saw NaN, set CF\n\t" 9774 "andq [rsp], #0xffffff2b\n\t" 9775 "popfq\n" 9776 "exit:" %} 9777 ins_encode %{ 9778 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9779 emit_cmpfp_fixup(masm); 9780 %} 9781 ins_pipe(pipe_slow); 9782 %} 9783 9784 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9785 match(Set cr (CmpD src1 src2)); 9786 9787 ins_cost(100); 9788 format %{ "ucomisd $src1, $src2 test" %} 9789 ins_encode %{ 9790 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9791 %} 9792 ins_pipe(pipe_slow); 9793 %} 9794 9795 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9796 match(Set cr (CmpD src1 (LoadD src2))); 9797 9798 ins_cost(100); 9799 format %{ "ucomisd $src1, $src2" %} 9800 ins_encode %{ 9801 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9802 %} 9803 ins_pipe(pipe_slow); 9804 %} 9805 9806 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9807 match(Set cr (CmpD src con)); 9808 ins_cost(100); 9809 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9810 ins_encode %{ 9811 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9812 %} 9813 ins_pipe(pipe_slow); 9814 %} 9815 9816 // Compare into -1,0,1 9817 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9818 %{ 9819 match(Set dst (CmpF3 src1 src2)); 9820 effect(KILL cr); 9821 9822 ins_cost(275); 9823 format %{ "ucomiss $src1, $src2\n\t" 9824 "movl $dst, #-1\n\t" 9825 "jp,s done\n\t" 9826 "jb,s done\n\t" 9827 "setne $dst\n\t" 9828 "movzbl $dst, $dst\n" 9829 "done:" %} 9830 ins_encode %{ 9831 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9832 emit_cmpfp3(masm, $dst$$Register); 9833 %} 9834 ins_pipe(pipe_slow); 9835 %} 9836 9837 // Compare into -1,0,1 9838 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9839 %{ 9840 match(Set dst (CmpF3 src1 (LoadF src2))); 9841 effect(KILL cr); 9842 9843 ins_cost(275); 9844 format %{ "ucomiss $src1, $src2\n\t" 9845 "movl $dst, #-1\n\t" 9846 "jp,s done\n\t" 9847 "jb,s done\n\t" 9848 "setne $dst\n\t" 9849 "movzbl $dst, $dst\n" 9850 "done:" %} 9851 ins_encode %{ 9852 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9853 emit_cmpfp3(masm, $dst$$Register); 9854 %} 9855 ins_pipe(pipe_slow); 9856 %} 9857 9858 // Compare into -1,0,1 9859 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9860 match(Set dst (CmpF3 src con)); 9861 effect(KILL cr); 9862 9863 ins_cost(275); 9864 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9865 "movl $dst, #-1\n\t" 9866 "jp,s done\n\t" 9867 "jb,s done\n\t" 9868 "setne $dst\n\t" 9869 "movzbl $dst, $dst\n" 9870 "done:" %} 9871 ins_encode %{ 9872 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9873 emit_cmpfp3(masm, $dst$$Register); 9874 %} 9875 ins_pipe(pipe_slow); 9876 %} 9877 9878 // Compare into -1,0,1 9879 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9880 %{ 9881 match(Set dst (CmpD3 src1 src2)); 9882 effect(KILL cr); 9883 9884 ins_cost(275); 9885 format %{ "ucomisd $src1, $src2\n\t" 9886 "movl $dst, #-1\n\t" 9887 "jp,s done\n\t" 9888 "jb,s done\n\t" 9889 "setne $dst\n\t" 9890 "movzbl $dst, $dst\n" 9891 "done:" %} 9892 ins_encode %{ 9893 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9894 emit_cmpfp3(masm, $dst$$Register); 9895 %} 9896 ins_pipe(pipe_slow); 9897 %} 9898 9899 // Compare into -1,0,1 9900 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9901 %{ 9902 match(Set dst (CmpD3 src1 (LoadD src2))); 9903 effect(KILL cr); 9904 9905 ins_cost(275); 9906 format %{ "ucomisd $src1, $src2\n\t" 9907 "movl $dst, #-1\n\t" 9908 "jp,s done\n\t" 9909 "jb,s done\n\t" 9910 "setne $dst\n\t" 9911 "movzbl $dst, $dst\n" 9912 "done:" %} 9913 ins_encode %{ 9914 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9915 emit_cmpfp3(masm, $dst$$Register); 9916 %} 9917 ins_pipe(pipe_slow); 9918 %} 9919 9920 // Compare into -1,0,1 9921 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9922 match(Set dst (CmpD3 src con)); 9923 effect(KILL cr); 9924 9925 ins_cost(275); 9926 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9927 "movl $dst, #-1\n\t" 9928 "jp,s done\n\t" 9929 "jb,s done\n\t" 9930 "setne $dst\n\t" 9931 "movzbl $dst, $dst\n" 9932 "done:" %} 9933 ins_encode %{ 9934 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9935 emit_cmpfp3(masm, $dst$$Register); 9936 %} 9937 ins_pipe(pipe_slow); 9938 %} 9939 9940 //----------Arithmetic Conversion Instructions--------------------------------- 9941 9942 instruct convF2D_reg_reg(regD dst, regF src) 9943 %{ 9944 match(Set dst (ConvF2D src)); 9945 9946 format %{ "cvtss2sd $dst, $src" %} 9947 ins_encode %{ 9948 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9949 %} 9950 ins_pipe(pipe_slow); // XXX 9951 %} 9952 9953 instruct convF2D_reg_mem(regD dst, memory src) 9954 %{ 9955 predicate(UseAVX == 0); 9956 match(Set dst (ConvF2D (LoadF src))); 9957 9958 format %{ "cvtss2sd $dst, $src" %} 9959 ins_encode %{ 9960 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9961 %} 9962 ins_pipe(pipe_slow); // XXX 9963 %} 9964 9965 instruct convD2F_reg_reg(regF dst, regD src) 9966 %{ 9967 match(Set dst (ConvD2F src)); 9968 9969 format %{ "cvtsd2ss $dst, $src" %} 9970 ins_encode %{ 9971 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9972 %} 9973 ins_pipe(pipe_slow); // XXX 9974 %} 9975 9976 instruct convD2F_reg_mem(regF dst, memory src) 9977 %{ 9978 predicate(UseAVX == 0); 9979 match(Set dst (ConvD2F (LoadD src))); 9980 9981 format %{ "cvtsd2ss $dst, $src" %} 9982 ins_encode %{ 9983 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9984 %} 9985 ins_pipe(pipe_slow); // XXX 9986 %} 9987 9988 // XXX do mem variants 9989 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9990 %{ 9991 match(Set dst (ConvF2I src)); 9992 effect(KILL cr); 9993 format %{ "convert_f2i $dst, $src" %} 9994 ins_encode %{ 9995 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 9996 %} 9997 ins_pipe(pipe_slow); 9998 %} 9999 10000 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10001 %{ 10002 match(Set dst (ConvF2L src)); 10003 effect(KILL cr); 10004 format %{ "convert_f2l $dst, $src"%} 10005 ins_encode %{ 10006 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10007 %} 10008 ins_pipe(pipe_slow); 10009 %} 10010 10011 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10012 %{ 10013 match(Set dst (ConvD2I src)); 10014 effect(KILL cr); 10015 format %{ "convert_d2i $dst, $src"%} 10016 ins_encode %{ 10017 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10018 %} 10019 ins_pipe(pipe_slow); 10020 %} 10021 10022 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10023 %{ 10024 match(Set dst (ConvD2L src)); 10025 effect(KILL cr); 10026 format %{ "convert_d2l $dst, $src"%} 10027 ins_encode %{ 10028 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10029 %} 10030 ins_pipe(pipe_slow); 10031 %} 10032 10033 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10034 %{ 10035 match(Set dst (RoundD src)); 10036 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10037 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10038 ins_encode %{ 10039 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10040 %} 10041 ins_pipe(pipe_slow); 10042 %} 10043 10044 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10045 %{ 10046 match(Set dst (RoundF src)); 10047 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10048 format %{ "round_float $dst,$src" %} 10049 ins_encode %{ 10050 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10051 %} 10052 ins_pipe(pipe_slow); 10053 %} 10054 10055 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10056 %{ 10057 predicate(!UseXmmI2F); 10058 match(Set dst (ConvI2F src)); 10059 10060 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10061 ins_encode %{ 10062 if (UseAVX > 0) { 10063 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10064 } 10065 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10066 %} 10067 ins_pipe(pipe_slow); // XXX 10068 %} 10069 10070 instruct convI2F_reg_mem(regF dst, memory src) 10071 %{ 10072 predicate(UseAVX == 0); 10073 match(Set dst (ConvI2F (LoadI src))); 10074 10075 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10076 ins_encode %{ 10077 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10078 %} 10079 ins_pipe(pipe_slow); // XXX 10080 %} 10081 10082 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10083 %{ 10084 predicate(!UseXmmI2D); 10085 match(Set dst (ConvI2D src)); 10086 10087 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10088 ins_encode %{ 10089 if (UseAVX > 0) { 10090 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10091 } 10092 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10093 %} 10094 ins_pipe(pipe_slow); // XXX 10095 %} 10096 10097 instruct convI2D_reg_mem(regD dst, memory src) 10098 %{ 10099 predicate(UseAVX == 0); 10100 match(Set dst (ConvI2D (LoadI src))); 10101 10102 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10103 ins_encode %{ 10104 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10105 %} 10106 ins_pipe(pipe_slow); // XXX 10107 %} 10108 10109 instruct convXI2F_reg(regF dst, rRegI src) 10110 %{ 10111 predicate(UseXmmI2F); 10112 match(Set dst (ConvI2F src)); 10113 10114 format %{ "movdl $dst, $src\n\t" 10115 "cvtdq2psl $dst, $dst\t# i2f" %} 10116 ins_encode %{ 10117 __ movdl($dst$$XMMRegister, $src$$Register); 10118 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10119 %} 10120 ins_pipe(pipe_slow); // XXX 10121 %} 10122 10123 instruct convXI2D_reg(regD dst, rRegI src) 10124 %{ 10125 predicate(UseXmmI2D); 10126 match(Set dst (ConvI2D src)); 10127 10128 format %{ "movdl $dst, $src\n\t" 10129 "cvtdq2pdl $dst, $dst\t# i2d" %} 10130 ins_encode %{ 10131 __ movdl($dst$$XMMRegister, $src$$Register); 10132 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10133 %} 10134 ins_pipe(pipe_slow); // XXX 10135 %} 10136 10137 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10138 %{ 10139 match(Set dst (ConvL2F src)); 10140 10141 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10142 ins_encode %{ 10143 if (UseAVX > 0) { 10144 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10145 } 10146 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10147 %} 10148 ins_pipe(pipe_slow); // XXX 10149 %} 10150 10151 instruct convL2F_reg_mem(regF dst, memory src) 10152 %{ 10153 predicate(UseAVX == 0); 10154 match(Set dst (ConvL2F (LoadL src))); 10155 10156 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10157 ins_encode %{ 10158 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10159 %} 10160 ins_pipe(pipe_slow); // XXX 10161 %} 10162 10163 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10164 %{ 10165 match(Set dst (ConvL2D src)); 10166 10167 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10168 ins_encode %{ 10169 if (UseAVX > 0) { 10170 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10171 } 10172 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10173 %} 10174 ins_pipe(pipe_slow); // XXX 10175 %} 10176 10177 instruct convL2D_reg_mem(regD dst, memory src) 10178 %{ 10179 predicate(UseAVX == 0); 10180 match(Set dst (ConvL2D (LoadL src))); 10181 10182 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10183 ins_encode %{ 10184 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10185 %} 10186 ins_pipe(pipe_slow); // XXX 10187 %} 10188 10189 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10190 %{ 10191 match(Set dst (ConvI2L src)); 10192 10193 ins_cost(125); 10194 format %{ "movslq $dst, $src\t# i2l" %} 10195 ins_encode %{ 10196 __ movslq($dst$$Register, $src$$Register); 10197 %} 10198 ins_pipe(ialu_reg_reg); 10199 %} 10200 10201 // Zero-extend convert int to long 10202 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10203 %{ 10204 match(Set dst (AndL (ConvI2L src) mask)); 10205 10206 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10207 ins_encode %{ 10208 if ($dst$$reg != $src$$reg) { 10209 __ movl($dst$$Register, $src$$Register); 10210 } 10211 %} 10212 ins_pipe(ialu_reg_reg); 10213 %} 10214 10215 // Zero-extend convert int to long 10216 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10217 %{ 10218 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10219 10220 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10221 ins_encode %{ 10222 __ movl($dst$$Register, $src$$Address); 10223 %} 10224 ins_pipe(ialu_reg_mem); 10225 %} 10226 10227 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10228 %{ 10229 match(Set dst (AndL src mask)); 10230 10231 format %{ "movl $dst, $src\t# zero-extend long" %} 10232 ins_encode %{ 10233 __ movl($dst$$Register, $src$$Register); 10234 %} 10235 ins_pipe(ialu_reg_reg); 10236 %} 10237 10238 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10239 %{ 10240 match(Set dst (ConvL2I src)); 10241 10242 format %{ "movl $dst, $src\t# l2i" %} 10243 ins_encode %{ 10244 __ movl($dst$$Register, $src$$Register); 10245 %} 10246 ins_pipe(ialu_reg_reg); 10247 %} 10248 10249 10250 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10251 match(Set dst (MoveF2I src)); 10252 effect(DEF dst, USE src); 10253 10254 ins_cost(125); 10255 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10256 ins_encode %{ 10257 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10258 %} 10259 ins_pipe(ialu_reg_mem); 10260 %} 10261 10262 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10263 match(Set dst (MoveI2F src)); 10264 effect(DEF dst, USE src); 10265 10266 ins_cost(125); 10267 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10268 ins_encode %{ 10269 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10270 %} 10271 ins_pipe(pipe_slow); 10272 %} 10273 10274 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10275 match(Set dst (MoveD2L src)); 10276 effect(DEF dst, USE src); 10277 10278 ins_cost(125); 10279 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10280 ins_encode %{ 10281 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10282 %} 10283 ins_pipe(ialu_reg_mem); 10284 %} 10285 10286 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10287 predicate(!UseXmmLoadAndClearUpper); 10288 match(Set dst (MoveL2D src)); 10289 effect(DEF dst, USE src); 10290 10291 ins_cost(125); 10292 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10293 ins_encode %{ 10294 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10295 %} 10296 ins_pipe(pipe_slow); 10297 %} 10298 10299 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10300 predicate(UseXmmLoadAndClearUpper); 10301 match(Set dst (MoveL2D src)); 10302 effect(DEF dst, USE src); 10303 10304 ins_cost(125); 10305 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10306 ins_encode %{ 10307 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10308 %} 10309 ins_pipe(pipe_slow); 10310 %} 10311 10312 10313 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10314 match(Set dst (MoveF2I src)); 10315 effect(DEF dst, USE src); 10316 10317 ins_cost(95); // XXX 10318 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10319 ins_encode %{ 10320 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10321 %} 10322 ins_pipe(pipe_slow); 10323 %} 10324 10325 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10326 match(Set dst (MoveI2F src)); 10327 effect(DEF dst, USE src); 10328 10329 ins_cost(100); 10330 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10331 ins_encode %{ 10332 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10333 %} 10334 ins_pipe( ialu_mem_reg ); 10335 %} 10336 10337 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10338 match(Set dst (MoveD2L src)); 10339 effect(DEF dst, USE src); 10340 10341 ins_cost(95); // XXX 10342 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10343 ins_encode %{ 10344 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10345 %} 10346 ins_pipe(pipe_slow); 10347 %} 10348 10349 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10350 match(Set dst (MoveL2D src)); 10351 effect(DEF dst, USE src); 10352 10353 ins_cost(100); 10354 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10355 ins_encode %{ 10356 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10357 %} 10358 ins_pipe(ialu_mem_reg); 10359 %} 10360 10361 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10362 match(Set dst (MoveF2I src)); 10363 effect(DEF dst, USE src); 10364 ins_cost(85); 10365 format %{ "movd $dst,$src\t# MoveF2I" %} 10366 ins_encode %{ 10367 __ movdl($dst$$Register, $src$$XMMRegister); 10368 %} 10369 ins_pipe( pipe_slow ); 10370 %} 10371 10372 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10373 match(Set dst (MoveD2L src)); 10374 effect(DEF dst, USE src); 10375 ins_cost(85); 10376 format %{ "movd $dst,$src\t# MoveD2L" %} 10377 ins_encode %{ 10378 __ movdq($dst$$Register, $src$$XMMRegister); 10379 %} 10380 ins_pipe( pipe_slow ); 10381 %} 10382 10383 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10384 match(Set dst (MoveI2F src)); 10385 effect(DEF dst, USE src); 10386 ins_cost(100); 10387 format %{ "movd $dst,$src\t# MoveI2F" %} 10388 ins_encode %{ 10389 __ movdl($dst$$XMMRegister, $src$$Register); 10390 %} 10391 ins_pipe( pipe_slow ); 10392 %} 10393 10394 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10395 match(Set dst (MoveL2D src)); 10396 effect(DEF dst, USE src); 10397 ins_cost(100); 10398 format %{ "movd $dst,$src\t# MoveL2D" %} 10399 ins_encode %{ 10400 __ movdq($dst$$XMMRegister, $src$$Register); 10401 %} 10402 ins_pipe( pipe_slow ); 10403 %} 10404 10405 // Fast clearing of an array 10406 // Small non-constant lenght ClearArray for non-AVX512 targets. 10407 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10408 Universe dummy, rFlagsReg cr) 10409 %{ 10410 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 10411 match(Set dummy (ClearArray cnt base)); 10412 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10413 10414 format %{ $$template 10415 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10416 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10417 $$emit$$"jg LARGE\n\t" 10418 $$emit$$"dec rcx\n\t" 10419 $$emit$$"js DONE\t# Zero length\n\t" 10420 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10421 $$emit$$"dec rcx\n\t" 10422 $$emit$$"jge LOOP\n\t" 10423 $$emit$$"jmp DONE\n\t" 10424 $$emit$$"# LARGE:\n\t" 10425 if (UseFastStosb) { 10426 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10427 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10428 } else if (UseXMMForObjInit) { 10429 $$emit$$"mov rdi,rax\n\t" 10430 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10431 $$emit$$"jmpq L_zero_64_bytes\n\t" 10432 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10433 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10434 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10435 $$emit$$"add 0x40,rax\n\t" 10436 $$emit$$"# L_zero_64_bytes:\n\t" 10437 $$emit$$"sub 0x8,rcx\n\t" 10438 $$emit$$"jge L_loop\n\t" 10439 $$emit$$"add 0x4,rcx\n\t" 10440 $$emit$$"jl L_tail\n\t" 10441 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10442 $$emit$$"add 0x20,rax\n\t" 10443 $$emit$$"sub 0x4,rcx\n\t" 10444 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10445 $$emit$$"add 0x4,rcx\n\t" 10446 $$emit$$"jle L_end\n\t" 10447 $$emit$$"dec rcx\n\t" 10448 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10449 $$emit$$"vmovq xmm0,(rax)\n\t" 10450 $$emit$$"add 0x8,rax\n\t" 10451 $$emit$$"dec rcx\n\t" 10452 $$emit$$"jge L_sloop\n\t" 10453 $$emit$$"# L_end:\n\t" 10454 } else { 10455 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10456 } 10457 $$emit$$"# DONE" 10458 %} 10459 ins_encode %{ 10460 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10461 $tmp$$XMMRegister, false, knoreg); 10462 %} 10463 ins_pipe(pipe_slow); 10464 %} 10465 10466 // Small non-constant length ClearArray for AVX512 targets. 10467 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10468 Universe dummy, rFlagsReg cr) 10469 %{ 10470 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 10471 match(Set dummy (ClearArray cnt base)); 10472 ins_cost(125); 10473 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10474 10475 format %{ $$template 10476 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10477 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10478 $$emit$$"jg LARGE\n\t" 10479 $$emit$$"dec rcx\n\t" 10480 $$emit$$"js DONE\t# Zero length\n\t" 10481 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10482 $$emit$$"dec rcx\n\t" 10483 $$emit$$"jge LOOP\n\t" 10484 $$emit$$"jmp DONE\n\t" 10485 $$emit$$"# LARGE:\n\t" 10486 if (UseFastStosb) { 10487 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10488 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10489 } else if (UseXMMForObjInit) { 10490 $$emit$$"mov rdi,rax\n\t" 10491 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10492 $$emit$$"jmpq L_zero_64_bytes\n\t" 10493 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10494 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10495 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10496 $$emit$$"add 0x40,rax\n\t" 10497 $$emit$$"# L_zero_64_bytes:\n\t" 10498 $$emit$$"sub 0x8,rcx\n\t" 10499 $$emit$$"jge L_loop\n\t" 10500 $$emit$$"add 0x4,rcx\n\t" 10501 $$emit$$"jl L_tail\n\t" 10502 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10503 $$emit$$"add 0x20,rax\n\t" 10504 $$emit$$"sub 0x4,rcx\n\t" 10505 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10506 $$emit$$"add 0x4,rcx\n\t" 10507 $$emit$$"jle L_end\n\t" 10508 $$emit$$"dec rcx\n\t" 10509 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10510 $$emit$$"vmovq xmm0,(rax)\n\t" 10511 $$emit$$"add 0x8,rax\n\t" 10512 $$emit$$"dec rcx\n\t" 10513 $$emit$$"jge L_sloop\n\t" 10514 $$emit$$"# L_end:\n\t" 10515 } else { 10516 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10517 } 10518 $$emit$$"# DONE" 10519 %} 10520 ins_encode %{ 10521 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10522 $tmp$$XMMRegister, false, $ktmp$$KRegister); 10523 %} 10524 ins_pipe(pipe_slow); 10525 %} 10526 10527 // Large non-constant length ClearArray for non-AVX512 targets. 10528 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10529 Universe dummy, rFlagsReg cr) 10530 %{ 10531 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 10532 match(Set dummy (ClearArray cnt base)); 10533 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10534 10535 format %{ $$template 10536 if (UseFastStosb) { 10537 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10538 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10539 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10540 } else if (UseXMMForObjInit) { 10541 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10542 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10543 $$emit$$"jmpq L_zero_64_bytes\n\t" 10544 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10545 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10546 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10547 $$emit$$"add 0x40,rax\n\t" 10548 $$emit$$"# L_zero_64_bytes:\n\t" 10549 $$emit$$"sub 0x8,rcx\n\t" 10550 $$emit$$"jge L_loop\n\t" 10551 $$emit$$"add 0x4,rcx\n\t" 10552 $$emit$$"jl L_tail\n\t" 10553 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10554 $$emit$$"add 0x20,rax\n\t" 10555 $$emit$$"sub 0x4,rcx\n\t" 10556 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10557 $$emit$$"add 0x4,rcx\n\t" 10558 $$emit$$"jle L_end\n\t" 10559 $$emit$$"dec rcx\n\t" 10560 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10561 $$emit$$"vmovq xmm0,(rax)\n\t" 10562 $$emit$$"add 0x8,rax\n\t" 10563 $$emit$$"dec rcx\n\t" 10564 $$emit$$"jge L_sloop\n\t" 10565 $$emit$$"# L_end:\n\t" 10566 } else { 10567 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10568 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10569 } 10570 %} 10571 ins_encode %{ 10572 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10573 $tmp$$XMMRegister, true, knoreg); 10574 %} 10575 ins_pipe(pipe_slow); 10576 %} 10577 10578 // Large non-constant length ClearArray for AVX512 targets. 10579 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10580 Universe dummy, rFlagsReg cr) 10581 %{ 10582 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 10583 match(Set dummy (ClearArray cnt base)); 10584 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10585 10586 format %{ $$template 10587 if (UseFastStosb) { 10588 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10589 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10590 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10591 } else if (UseXMMForObjInit) { 10592 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10593 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10594 $$emit$$"jmpq L_zero_64_bytes\n\t" 10595 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10596 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10597 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10598 $$emit$$"add 0x40,rax\n\t" 10599 $$emit$$"# L_zero_64_bytes:\n\t" 10600 $$emit$$"sub 0x8,rcx\n\t" 10601 $$emit$$"jge L_loop\n\t" 10602 $$emit$$"add 0x4,rcx\n\t" 10603 $$emit$$"jl L_tail\n\t" 10604 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10605 $$emit$$"add 0x20,rax\n\t" 10606 $$emit$$"sub 0x4,rcx\n\t" 10607 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10608 $$emit$$"add 0x4,rcx\n\t" 10609 $$emit$$"jle L_end\n\t" 10610 $$emit$$"dec rcx\n\t" 10611 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10612 $$emit$$"vmovq xmm0,(rax)\n\t" 10613 $$emit$$"add 0x8,rax\n\t" 10614 $$emit$$"dec rcx\n\t" 10615 $$emit$$"jge L_sloop\n\t" 10616 $$emit$$"# L_end:\n\t" 10617 } else { 10618 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10619 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10620 } 10621 %} 10622 ins_encode %{ 10623 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10624 $tmp$$XMMRegister, true, $ktmp$$KRegister); 10625 %} 10626 ins_pipe(pipe_slow); 10627 %} 10628 10629 // Small constant length ClearArray for AVX512 targets. 10630 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 10631 %{ 10632 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 10633 match(Set dummy (ClearArray cnt base)); 10634 ins_cost(100); 10635 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 10636 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10637 ins_encode %{ 10638 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10639 %} 10640 ins_pipe(pipe_slow); 10641 %} 10642 10643 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10644 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10645 %{ 10646 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10647 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10648 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10649 10650 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10651 ins_encode %{ 10652 __ string_compare($str1$$Register, $str2$$Register, 10653 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10654 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10655 %} 10656 ins_pipe( pipe_slow ); 10657 %} 10658 10659 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10660 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10661 %{ 10662 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10663 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10664 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10665 10666 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10667 ins_encode %{ 10668 __ string_compare($str1$$Register, $str2$$Register, 10669 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10670 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10671 %} 10672 ins_pipe( pipe_slow ); 10673 %} 10674 10675 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10676 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10677 %{ 10678 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10679 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10680 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10681 10682 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10683 ins_encode %{ 10684 __ string_compare($str1$$Register, $str2$$Register, 10685 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10686 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10687 %} 10688 ins_pipe( pipe_slow ); 10689 %} 10690 10691 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10692 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10693 %{ 10694 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10695 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10696 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10697 10698 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10699 ins_encode %{ 10700 __ string_compare($str1$$Register, $str2$$Register, 10701 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10702 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10703 %} 10704 ins_pipe( pipe_slow ); 10705 %} 10706 10707 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10708 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10709 %{ 10710 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10711 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10712 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10713 10714 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10715 ins_encode %{ 10716 __ string_compare($str1$$Register, $str2$$Register, 10717 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10718 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 10719 %} 10720 ins_pipe( pipe_slow ); 10721 %} 10722 10723 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10724 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10725 %{ 10726 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10727 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10728 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10729 10730 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10731 ins_encode %{ 10732 __ string_compare($str1$$Register, $str2$$Register, 10733 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10734 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 10735 %} 10736 ins_pipe( pipe_slow ); 10737 %} 10738 10739 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10740 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10741 %{ 10742 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10743 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10744 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10745 10746 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10747 ins_encode %{ 10748 __ string_compare($str2$$Register, $str1$$Register, 10749 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10750 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 10751 %} 10752 ins_pipe( pipe_slow ); 10753 %} 10754 10755 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10756 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10757 %{ 10758 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10759 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10760 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10761 10762 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10763 ins_encode %{ 10764 __ string_compare($str2$$Register, $str1$$Register, 10765 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10766 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 10767 %} 10768 ins_pipe( pipe_slow ); 10769 %} 10770 10771 // fast search of substring with known size. 10772 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10773 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10774 %{ 10775 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10776 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10777 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10778 10779 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10780 ins_encode %{ 10781 int icnt2 = (int)$int_cnt2$$constant; 10782 if (icnt2 >= 16) { 10783 // IndexOf for constant substrings with size >= 16 elements 10784 // which don't need to be loaded through stack. 10785 __ string_indexofC8($str1$$Register, $str2$$Register, 10786 $cnt1$$Register, $cnt2$$Register, 10787 icnt2, $result$$Register, 10788 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10789 } else { 10790 // Small strings are loaded through stack if they cross page boundary. 10791 __ string_indexof($str1$$Register, $str2$$Register, 10792 $cnt1$$Register, $cnt2$$Register, 10793 icnt2, $result$$Register, 10794 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10795 } 10796 %} 10797 ins_pipe( pipe_slow ); 10798 %} 10799 10800 // fast search of substring with known size. 10801 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10802 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10803 %{ 10804 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10805 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10806 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10807 10808 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10809 ins_encode %{ 10810 int icnt2 = (int)$int_cnt2$$constant; 10811 if (icnt2 >= 8) { 10812 // IndexOf for constant substrings with size >= 8 elements 10813 // which don't need to be loaded through stack. 10814 __ string_indexofC8($str1$$Register, $str2$$Register, 10815 $cnt1$$Register, $cnt2$$Register, 10816 icnt2, $result$$Register, 10817 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10818 } else { 10819 // Small strings are loaded through stack if they cross page boundary. 10820 __ string_indexof($str1$$Register, $str2$$Register, 10821 $cnt1$$Register, $cnt2$$Register, 10822 icnt2, $result$$Register, 10823 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10824 } 10825 %} 10826 ins_pipe( pipe_slow ); 10827 %} 10828 10829 // fast search of substring with known size. 10830 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10831 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10832 %{ 10833 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10834 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10835 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10836 10837 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10838 ins_encode %{ 10839 int icnt2 = (int)$int_cnt2$$constant; 10840 if (icnt2 >= 8) { 10841 // IndexOf for constant substrings with size >= 8 elements 10842 // which don't need to be loaded through stack. 10843 __ string_indexofC8($str1$$Register, $str2$$Register, 10844 $cnt1$$Register, $cnt2$$Register, 10845 icnt2, $result$$Register, 10846 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10847 } else { 10848 // Small strings are loaded through stack if they cross page boundary. 10849 __ string_indexof($str1$$Register, $str2$$Register, 10850 $cnt1$$Register, $cnt2$$Register, 10851 icnt2, $result$$Register, 10852 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10853 } 10854 %} 10855 ins_pipe( pipe_slow ); 10856 %} 10857 10858 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10859 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10860 %{ 10861 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10862 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10863 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10864 10865 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10866 ins_encode %{ 10867 __ string_indexof($str1$$Register, $str2$$Register, 10868 $cnt1$$Register, $cnt2$$Register, 10869 (-1), $result$$Register, 10870 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10871 %} 10872 ins_pipe( pipe_slow ); 10873 %} 10874 10875 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10876 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10877 %{ 10878 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10879 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10880 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10881 10882 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10883 ins_encode %{ 10884 __ string_indexof($str1$$Register, $str2$$Register, 10885 $cnt1$$Register, $cnt2$$Register, 10886 (-1), $result$$Register, 10887 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10888 %} 10889 ins_pipe( pipe_slow ); 10890 %} 10891 10892 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10893 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10894 %{ 10895 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10896 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10897 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10898 10899 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10900 ins_encode %{ 10901 __ string_indexof($str1$$Register, $str2$$Register, 10902 $cnt1$$Register, $cnt2$$Register, 10903 (-1), $result$$Register, 10904 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10905 %} 10906 ins_pipe( pipe_slow ); 10907 %} 10908 10909 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10910 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10911 %{ 10912 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 10913 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10914 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10915 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10916 ins_encode %{ 10917 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10918 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10919 %} 10920 ins_pipe( pipe_slow ); 10921 %} 10922 10923 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10924 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10925 %{ 10926 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 10927 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10928 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10929 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10930 ins_encode %{ 10931 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10932 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10933 %} 10934 ins_pipe( pipe_slow ); 10935 %} 10936 10937 // fast string equals 10938 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10939 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10940 %{ 10941 predicate(!VM_Version::supports_avx512vlbw()); 10942 match(Set result (StrEquals (Binary str1 str2) cnt)); 10943 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10944 10945 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10946 ins_encode %{ 10947 __ arrays_equals(false, $str1$$Register, $str2$$Register, 10948 $cnt$$Register, $result$$Register, $tmp3$$Register, 10949 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 10950 %} 10951 ins_pipe( pipe_slow ); 10952 %} 10953 10954 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10955 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 10956 %{ 10957 predicate(VM_Version::supports_avx512vlbw()); 10958 match(Set result (StrEquals (Binary str1 str2) cnt)); 10959 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10960 10961 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10962 ins_encode %{ 10963 __ arrays_equals(false, $str1$$Register, $str2$$Register, 10964 $cnt$$Register, $result$$Register, $tmp3$$Register, 10965 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 10966 %} 10967 ins_pipe( pipe_slow ); 10968 %} 10969 10970 // fast array equals 10971 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10972 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10973 %{ 10974 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10975 match(Set result (AryEq ary1 ary2)); 10976 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10977 10978 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10979 ins_encode %{ 10980 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 10981 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10982 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 10983 %} 10984 ins_pipe( pipe_slow ); 10985 %} 10986 10987 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10988 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10989 %{ 10990 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10991 match(Set result (AryEq ary1 ary2)); 10992 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10993 10994 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10995 ins_encode %{ 10996 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 10997 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10998 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 10999 %} 11000 ins_pipe( pipe_slow ); 11001 %} 11002 11003 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11004 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11005 %{ 11006 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11007 match(Set result (AryEq ary1 ary2)); 11008 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11009 11010 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11011 ins_encode %{ 11012 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11013 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11014 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11015 %} 11016 ins_pipe( pipe_slow ); 11017 %} 11018 11019 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11020 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11021 %{ 11022 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11023 match(Set result (AryEq ary1 ary2)); 11024 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11025 11026 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11027 ins_encode %{ 11028 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11029 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11030 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11031 %} 11032 ins_pipe( pipe_slow ); 11033 %} 11034 11035 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11036 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11037 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11038 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11039 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11040 %{ 11041 predicate(UseAVX >= 2); 11042 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11043 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11044 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11045 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11046 USE basic_type, KILL cr); 11047 11048 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11049 ins_encode %{ 11050 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11051 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11052 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11053 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11054 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11055 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11056 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11057 %} 11058 ins_pipe( pipe_slow ); 11059 %} 11060 11061 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11062 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11063 %{ 11064 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11065 match(Set result (CountPositives ary1 len)); 11066 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11067 11068 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11069 ins_encode %{ 11070 __ count_positives($ary1$$Register, $len$$Register, 11071 $result$$Register, $tmp3$$Register, 11072 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11073 %} 11074 ins_pipe( pipe_slow ); 11075 %} 11076 11077 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11078 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11079 %{ 11080 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11081 match(Set result (CountPositives ary1 len)); 11082 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11083 11084 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11085 ins_encode %{ 11086 __ count_positives($ary1$$Register, $len$$Register, 11087 $result$$Register, $tmp3$$Register, 11088 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11089 %} 11090 ins_pipe( pipe_slow ); 11091 %} 11092 11093 // fast char[] to byte[] compression 11094 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11095 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11096 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11097 match(Set result (StrCompressedCopy src (Binary dst len))); 11098 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11099 USE_KILL len, KILL tmp5, KILL cr); 11100 11101 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11102 ins_encode %{ 11103 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11104 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11105 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11106 knoreg, knoreg); 11107 %} 11108 ins_pipe( pipe_slow ); 11109 %} 11110 11111 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11112 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11113 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11114 match(Set result (StrCompressedCopy src (Binary dst len))); 11115 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11116 USE_KILL len, KILL tmp5, KILL cr); 11117 11118 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11119 ins_encode %{ 11120 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11121 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11122 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11123 $ktmp1$$KRegister, $ktmp2$$KRegister); 11124 %} 11125 ins_pipe( pipe_slow ); 11126 %} 11127 // fast byte[] to char[] inflation 11128 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11129 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11130 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11131 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11132 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11133 11134 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11135 ins_encode %{ 11136 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11137 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11138 %} 11139 ins_pipe( pipe_slow ); 11140 %} 11141 11142 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11143 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11144 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11145 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11146 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11147 11148 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11149 ins_encode %{ 11150 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11151 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11152 %} 11153 ins_pipe( pipe_slow ); 11154 %} 11155 11156 // encode char[] to byte[] in ISO_8859_1 11157 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11158 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11159 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11160 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11161 match(Set result (EncodeISOArray src (Binary dst len))); 11162 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11163 11164 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11165 ins_encode %{ 11166 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11167 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11168 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11169 %} 11170 ins_pipe( pipe_slow ); 11171 %} 11172 11173 // encode char[] to byte[] in ASCII 11174 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11175 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11176 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11177 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11178 match(Set result (EncodeISOArray src (Binary dst len))); 11179 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11180 11181 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11182 ins_encode %{ 11183 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11184 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11185 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11186 %} 11187 ins_pipe( pipe_slow ); 11188 %} 11189 11190 //----------Overflow Math Instructions----------------------------------------- 11191 11192 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11193 %{ 11194 match(Set cr (OverflowAddI op1 op2)); 11195 effect(DEF cr, USE_KILL op1, USE op2); 11196 11197 format %{ "addl $op1, $op2\t# overflow check int" %} 11198 11199 ins_encode %{ 11200 __ addl($op1$$Register, $op2$$Register); 11201 %} 11202 ins_pipe(ialu_reg_reg); 11203 %} 11204 11205 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11206 %{ 11207 match(Set cr (OverflowAddI op1 op2)); 11208 effect(DEF cr, USE_KILL op1, USE op2); 11209 11210 format %{ "addl $op1, $op2\t# overflow check int" %} 11211 11212 ins_encode %{ 11213 __ addl($op1$$Register, $op2$$constant); 11214 %} 11215 ins_pipe(ialu_reg_reg); 11216 %} 11217 11218 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11219 %{ 11220 match(Set cr (OverflowAddL op1 op2)); 11221 effect(DEF cr, USE_KILL op1, USE op2); 11222 11223 format %{ "addq $op1, $op2\t# overflow check long" %} 11224 ins_encode %{ 11225 __ addq($op1$$Register, $op2$$Register); 11226 %} 11227 ins_pipe(ialu_reg_reg); 11228 %} 11229 11230 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11231 %{ 11232 match(Set cr (OverflowAddL op1 op2)); 11233 effect(DEF cr, USE_KILL op1, USE op2); 11234 11235 format %{ "addq $op1, $op2\t# overflow check long" %} 11236 ins_encode %{ 11237 __ addq($op1$$Register, $op2$$constant); 11238 %} 11239 ins_pipe(ialu_reg_reg); 11240 %} 11241 11242 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI 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$$Register); 11249 %} 11250 ins_pipe(ialu_reg_reg); 11251 %} 11252 11253 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11254 %{ 11255 match(Set cr (OverflowSubI op1 op2)); 11256 11257 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11258 ins_encode %{ 11259 __ cmpl($op1$$Register, $op2$$constant); 11260 %} 11261 ins_pipe(ialu_reg_reg); 11262 %} 11263 11264 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL 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$$Register); 11271 %} 11272 ins_pipe(ialu_reg_reg); 11273 %} 11274 11275 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11276 %{ 11277 match(Set cr (OverflowSubL op1 op2)); 11278 11279 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11280 ins_encode %{ 11281 __ cmpq($op1$$Register, $op2$$constant); 11282 %} 11283 ins_pipe(ialu_reg_reg); 11284 %} 11285 11286 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11287 %{ 11288 match(Set cr (OverflowSubI zero op2)); 11289 effect(DEF cr, USE_KILL op2); 11290 11291 format %{ "negl $op2\t# overflow check int" %} 11292 ins_encode %{ 11293 __ negl($op2$$Register); 11294 %} 11295 ins_pipe(ialu_reg_reg); 11296 %} 11297 11298 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11299 %{ 11300 match(Set cr (OverflowSubL zero op2)); 11301 effect(DEF cr, USE_KILL op2); 11302 11303 format %{ "negq $op2\t# overflow check long" %} 11304 ins_encode %{ 11305 __ negq($op2$$Register); 11306 %} 11307 ins_pipe(ialu_reg_reg); 11308 %} 11309 11310 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11311 %{ 11312 match(Set cr (OverflowMulI op1 op2)); 11313 effect(DEF cr, USE_KILL op1, USE op2); 11314 11315 format %{ "imull $op1, $op2\t# overflow check int" %} 11316 ins_encode %{ 11317 __ imull($op1$$Register, $op2$$Register); 11318 %} 11319 ins_pipe(ialu_reg_reg_alu0); 11320 %} 11321 11322 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11323 %{ 11324 match(Set cr (OverflowMulI op1 op2)); 11325 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11326 11327 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11328 ins_encode %{ 11329 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11330 %} 11331 ins_pipe(ialu_reg_reg_alu0); 11332 %} 11333 11334 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11335 %{ 11336 match(Set cr (OverflowMulL op1 op2)); 11337 effect(DEF cr, USE_KILL op1, USE op2); 11338 11339 format %{ "imulq $op1, $op2\t# overflow check long" %} 11340 ins_encode %{ 11341 __ imulq($op1$$Register, $op2$$Register); 11342 %} 11343 ins_pipe(ialu_reg_reg_alu0); 11344 %} 11345 11346 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11347 %{ 11348 match(Set cr (OverflowMulL op1 op2)); 11349 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11350 11351 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11352 ins_encode %{ 11353 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11354 %} 11355 ins_pipe(ialu_reg_reg_alu0); 11356 %} 11357 11358 11359 //----------Control Flow Instructions------------------------------------------ 11360 // Signed compare Instructions 11361 11362 // XXX more variants!! 11363 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11364 %{ 11365 match(Set cr (CmpI op1 op2)); 11366 effect(DEF cr, USE op1, USE op2); 11367 11368 format %{ "cmpl $op1, $op2" %} 11369 ins_encode %{ 11370 __ cmpl($op1$$Register, $op2$$Register); 11371 %} 11372 ins_pipe(ialu_cr_reg_reg); 11373 %} 11374 11375 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11376 %{ 11377 match(Set cr (CmpI op1 op2)); 11378 11379 format %{ "cmpl $op1, $op2" %} 11380 ins_encode %{ 11381 __ cmpl($op1$$Register, $op2$$constant); 11382 %} 11383 ins_pipe(ialu_cr_reg_imm); 11384 %} 11385 11386 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11387 %{ 11388 match(Set cr (CmpI op1 (LoadI op2))); 11389 11390 ins_cost(500); // XXX 11391 format %{ "cmpl $op1, $op2" %} 11392 ins_encode %{ 11393 __ cmpl($op1$$Register, $op2$$Address); 11394 %} 11395 ins_pipe(ialu_cr_reg_mem); 11396 %} 11397 11398 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11399 %{ 11400 match(Set cr (CmpI src zero)); 11401 11402 format %{ "testl $src, $src" %} 11403 ins_encode %{ 11404 __ testl($src$$Register, $src$$Register); 11405 %} 11406 ins_pipe(ialu_cr_reg_imm); 11407 %} 11408 11409 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11410 %{ 11411 match(Set cr (CmpI (AndI src con) zero)); 11412 11413 format %{ "testl $src, $con" %} 11414 ins_encode %{ 11415 __ testl($src$$Register, $con$$constant); 11416 %} 11417 ins_pipe(ialu_cr_reg_imm); 11418 %} 11419 11420 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11421 %{ 11422 match(Set cr (CmpI (AndI src1 src2) zero)); 11423 11424 format %{ "testl $src1, $src2" %} 11425 ins_encode %{ 11426 __ testl($src1$$Register, $src2$$Register); 11427 %} 11428 ins_pipe(ialu_cr_reg_imm); 11429 %} 11430 11431 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11432 %{ 11433 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11434 11435 format %{ "testl $src, $mem" %} 11436 ins_encode %{ 11437 __ testl($src$$Register, $mem$$Address); 11438 %} 11439 ins_pipe(ialu_cr_reg_mem); 11440 %} 11441 11442 // Unsigned compare Instructions; really, same as signed except they 11443 // produce an rFlagsRegU instead of rFlagsReg. 11444 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI 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$$Register); 11451 %} 11452 ins_pipe(ialu_cr_reg_reg); 11453 %} 11454 11455 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11456 %{ 11457 match(Set cr (CmpU op1 op2)); 11458 11459 format %{ "cmpl $op1, $op2\t# unsigned" %} 11460 ins_encode %{ 11461 __ cmpl($op1$$Register, $op2$$constant); 11462 %} 11463 ins_pipe(ialu_cr_reg_imm); 11464 %} 11465 11466 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11467 %{ 11468 match(Set cr (CmpU op1 (LoadI op2))); 11469 11470 ins_cost(500); // XXX 11471 format %{ "cmpl $op1, $op2\t# unsigned" %} 11472 ins_encode %{ 11473 __ cmpl($op1$$Register, $op2$$Address); 11474 %} 11475 ins_pipe(ialu_cr_reg_mem); 11476 %} 11477 11478 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11479 %{ 11480 match(Set cr (CmpU src zero)); 11481 11482 format %{ "testl $src, $src\t# unsigned" %} 11483 ins_encode %{ 11484 __ testl($src$$Register, $src$$Register); 11485 %} 11486 ins_pipe(ialu_cr_reg_imm); 11487 %} 11488 11489 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11490 %{ 11491 match(Set cr (CmpP op1 op2)); 11492 11493 format %{ "cmpq $op1, $op2\t# ptr" %} 11494 ins_encode %{ 11495 __ cmpq($op1$$Register, $op2$$Register); 11496 %} 11497 ins_pipe(ialu_cr_reg_reg); 11498 %} 11499 11500 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11501 %{ 11502 match(Set cr (CmpP op1 (LoadP op2))); 11503 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11504 11505 ins_cost(500); // XXX 11506 format %{ "cmpq $op1, $op2\t# ptr" %} 11507 ins_encode %{ 11508 __ cmpq($op1$$Register, $op2$$Address); 11509 %} 11510 ins_pipe(ialu_cr_reg_mem); 11511 %} 11512 11513 // XXX this is generalized by compP_rReg_mem??? 11514 // Compare raw pointer (used in out-of-heap check). 11515 // Only works because non-oop pointers must be raw pointers 11516 // and raw pointers have no anti-dependencies. 11517 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11518 %{ 11519 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11520 n->in(2)->as_Load()->barrier_data() == 0); 11521 match(Set cr (CmpP op1 (LoadP op2))); 11522 11523 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11524 ins_encode %{ 11525 __ cmpq($op1$$Register, $op2$$Address); 11526 %} 11527 ins_pipe(ialu_cr_reg_mem); 11528 %} 11529 11530 // This will generate a signed flags result. This should be OK since 11531 // any compare to a zero should be eq/neq. 11532 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11533 %{ 11534 match(Set cr (CmpP src zero)); 11535 11536 format %{ "testq $src, $src\t# ptr" %} 11537 ins_encode %{ 11538 __ testq($src$$Register, $src$$Register); 11539 %} 11540 ins_pipe(ialu_cr_reg_imm); 11541 %} 11542 11543 // This will generate a signed flags result. This should be OK since 11544 // any compare to a zero should be eq/neq. 11545 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11546 %{ 11547 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11548 n->in(1)->as_Load()->barrier_data() == 0); 11549 match(Set cr (CmpP (LoadP op) zero)); 11550 11551 ins_cost(500); // XXX 11552 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11553 ins_encode %{ 11554 __ testq($op$$Address, 0xFFFFFFFF); 11555 %} 11556 ins_pipe(ialu_cr_reg_imm); 11557 %} 11558 11559 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11560 %{ 11561 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11562 n->in(1)->as_Load()->barrier_data() == 0); 11563 match(Set cr (CmpP (LoadP mem) zero)); 11564 11565 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11566 ins_encode %{ 11567 __ cmpq(r12, $mem$$Address); 11568 %} 11569 ins_pipe(ialu_cr_reg_mem); 11570 %} 11571 11572 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11573 %{ 11574 match(Set cr (CmpN op1 op2)); 11575 11576 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11577 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11578 ins_pipe(ialu_cr_reg_reg); 11579 %} 11580 11581 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11582 %{ 11583 match(Set cr (CmpN src (LoadN mem))); 11584 11585 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11586 ins_encode %{ 11587 __ cmpl($src$$Register, $mem$$Address); 11588 %} 11589 ins_pipe(ialu_cr_reg_mem); 11590 %} 11591 11592 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11593 match(Set cr (CmpN op1 op2)); 11594 11595 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11596 ins_encode %{ 11597 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11598 %} 11599 ins_pipe(ialu_cr_reg_imm); 11600 %} 11601 11602 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11603 %{ 11604 match(Set cr (CmpN src (LoadN mem))); 11605 11606 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11607 ins_encode %{ 11608 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11609 %} 11610 ins_pipe(ialu_cr_reg_mem); 11611 %} 11612 11613 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11614 match(Set cr (CmpN op1 op2)); 11615 11616 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11617 ins_encode %{ 11618 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11619 %} 11620 ins_pipe(ialu_cr_reg_imm); 11621 %} 11622 11623 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11624 %{ 11625 predicate(!UseCompactObjectHeaders); 11626 match(Set cr (CmpN src (LoadNKlass mem))); 11627 11628 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11629 ins_encode %{ 11630 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11631 %} 11632 ins_pipe(ialu_cr_reg_mem); 11633 %} 11634 11635 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11636 match(Set cr (CmpN src zero)); 11637 11638 format %{ "testl $src, $src\t# compressed ptr" %} 11639 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11640 ins_pipe(ialu_cr_reg_imm); 11641 %} 11642 11643 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11644 %{ 11645 predicate(CompressedOops::base() != nullptr); 11646 match(Set cr (CmpN (LoadN mem) zero)); 11647 11648 ins_cost(500); // XXX 11649 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11650 ins_encode %{ 11651 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11652 %} 11653 ins_pipe(ialu_cr_reg_mem); 11654 %} 11655 11656 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11657 %{ 11658 predicate(CompressedOops::base() == nullptr); 11659 match(Set cr (CmpN (LoadN mem) zero)); 11660 11661 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11662 ins_encode %{ 11663 __ cmpl(r12, $mem$$Address); 11664 %} 11665 ins_pipe(ialu_cr_reg_mem); 11666 %} 11667 11668 // Yanked all unsigned pointer compare operations. 11669 // Pointer compares are done with CmpP which is already unsigned. 11670 11671 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11672 %{ 11673 match(Set cr (CmpL op1 op2)); 11674 11675 format %{ "cmpq $op1, $op2" %} 11676 ins_encode %{ 11677 __ cmpq($op1$$Register, $op2$$Register); 11678 %} 11679 ins_pipe(ialu_cr_reg_reg); 11680 %} 11681 11682 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11683 %{ 11684 match(Set cr (CmpL op1 op2)); 11685 11686 format %{ "cmpq $op1, $op2" %} 11687 ins_encode %{ 11688 __ cmpq($op1$$Register, $op2$$constant); 11689 %} 11690 ins_pipe(ialu_cr_reg_imm); 11691 %} 11692 11693 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11694 %{ 11695 match(Set cr (CmpL op1 (LoadL op2))); 11696 11697 format %{ "cmpq $op1, $op2" %} 11698 ins_encode %{ 11699 __ cmpq($op1$$Register, $op2$$Address); 11700 %} 11701 ins_pipe(ialu_cr_reg_mem); 11702 %} 11703 11704 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11705 %{ 11706 match(Set cr (CmpL src zero)); 11707 11708 format %{ "testq $src, $src" %} 11709 ins_encode %{ 11710 __ testq($src$$Register, $src$$Register); 11711 %} 11712 ins_pipe(ialu_cr_reg_imm); 11713 %} 11714 11715 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11716 %{ 11717 match(Set cr (CmpL (AndL src con) zero)); 11718 11719 format %{ "testq $src, $con\t# long" %} 11720 ins_encode %{ 11721 __ testq($src$$Register, $con$$constant); 11722 %} 11723 ins_pipe(ialu_cr_reg_imm); 11724 %} 11725 11726 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 11727 %{ 11728 match(Set cr (CmpL (AndL src1 src2) zero)); 11729 11730 format %{ "testq $src1, $src2\t# long" %} 11731 ins_encode %{ 11732 __ testq($src1$$Register, $src2$$Register); 11733 %} 11734 ins_pipe(ialu_cr_reg_imm); 11735 %} 11736 11737 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11738 %{ 11739 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11740 11741 format %{ "testq $src, $mem" %} 11742 ins_encode %{ 11743 __ testq($src$$Register, $mem$$Address); 11744 %} 11745 ins_pipe(ialu_cr_reg_mem); 11746 %} 11747 11748 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11749 %{ 11750 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11751 11752 format %{ "testq $src, $mem" %} 11753 ins_encode %{ 11754 __ testq($src$$Register, $mem$$Address); 11755 %} 11756 ins_pipe(ialu_cr_reg_mem); 11757 %} 11758 11759 // Manifest a CmpU result in an integer register. Very painful. 11760 // This is the test to avoid. 11761 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 11762 %{ 11763 match(Set dst (CmpU3 src1 src2)); 11764 effect(KILL flags); 11765 11766 ins_cost(275); // XXX 11767 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 11768 "movl $dst, -1\n\t" 11769 "jb,u done\n\t" 11770 "setne $dst\n\t" 11771 "movzbl $dst, $dst\n\t" 11772 "done:" %} 11773 ins_encode %{ 11774 Label done; 11775 __ cmpl($src1$$Register, $src2$$Register); 11776 __ movl($dst$$Register, -1); 11777 __ jccb(Assembler::below, done); 11778 __ setb(Assembler::notZero, $dst$$Register); 11779 __ movzbl($dst$$Register, $dst$$Register); 11780 __ bind(done); 11781 %} 11782 ins_pipe(pipe_slow); 11783 %} 11784 11785 // Manifest a CmpL result in an integer register. Very painful. 11786 // This is the test to avoid. 11787 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11788 %{ 11789 match(Set dst (CmpL3 src1 src2)); 11790 effect(KILL flags); 11791 11792 ins_cost(275); // XXX 11793 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11794 "movl $dst, -1\n\t" 11795 "jl,s done\n\t" 11796 "setne $dst\n\t" 11797 "movzbl $dst, $dst\n\t" 11798 "done:" %} 11799 ins_encode %{ 11800 Label done; 11801 __ cmpq($src1$$Register, $src2$$Register); 11802 __ movl($dst$$Register, -1); 11803 __ jccb(Assembler::less, done); 11804 __ setb(Assembler::notZero, $dst$$Register); 11805 __ movzbl($dst$$Register, $dst$$Register); 11806 __ bind(done); 11807 %} 11808 ins_pipe(pipe_slow); 11809 %} 11810 11811 // Manifest a CmpUL result in an integer register. Very painful. 11812 // This is the test to avoid. 11813 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11814 %{ 11815 match(Set dst (CmpUL3 src1 src2)); 11816 effect(KILL flags); 11817 11818 ins_cost(275); // XXX 11819 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11820 "movl $dst, -1\n\t" 11821 "jb,u done\n\t" 11822 "setne $dst\n\t" 11823 "movzbl $dst, $dst\n\t" 11824 "done:" %} 11825 ins_encode %{ 11826 Label done; 11827 __ cmpq($src1$$Register, $src2$$Register); 11828 __ movl($dst$$Register, -1); 11829 __ jccb(Assembler::below, done); 11830 __ setb(Assembler::notZero, $dst$$Register); 11831 __ movzbl($dst$$Register, $dst$$Register); 11832 __ bind(done); 11833 %} 11834 ins_pipe(pipe_slow); 11835 %} 11836 11837 // Unsigned long compare Instructions; really, same as signed long except they 11838 // produce an rFlagsRegU instead of rFlagsReg. 11839 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11840 %{ 11841 match(Set cr (CmpUL op1 op2)); 11842 11843 format %{ "cmpq $op1, $op2\t# unsigned" %} 11844 ins_encode %{ 11845 __ cmpq($op1$$Register, $op2$$Register); 11846 %} 11847 ins_pipe(ialu_cr_reg_reg); 11848 %} 11849 11850 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11851 %{ 11852 match(Set cr (CmpUL op1 op2)); 11853 11854 format %{ "cmpq $op1, $op2\t# unsigned" %} 11855 ins_encode %{ 11856 __ cmpq($op1$$Register, $op2$$constant); 11857 %} 11858 ins_pipe(ialu_cr_reg_imm); 11859 %} 11860 11861 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11862 %{ 11863 match(Set cr (CmpUL op1 (LoadL op2))); 11864 11865 format %{ "cmpq $op1, $op2\t# unsigned" %} 11866 ins_encode %{ 11867 __ cmpq($op1$$Register, $op2$$Address); 11868 %} 11869 ins_pipe(ialu_cr_reg_mem); 11870 %} 11871 11872 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11873 %{ 11874 match(Set cr (CmpUL src zero)); 11875 11876 format %{ "testq $src, $src\t# unsigned" %} 11877 ins_encode %{ 11878 __ testq($src$$Register, $src$$Register); 11879 %} 11880 ins_pipe(ialu_cr_reg_imm); 11881 %} 11882 11883 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11884 %{ 11885 match(Set cr (CmpI (LoadB mem) imm)); 11886 11887 ins_cost(125); 11888 format %{ "cmpb $mem, $imm" %} 11889 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11890 ins_pipe(ialu_cr_reg_mem); 11891 %} 11892 11893 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 11894 %{ 11895 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11896 11897 ins_cost(125); 11898 format %{ "testb $mem, $imm\t# ubyte" %} 11899 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11900 ins_pipe(ialu_cr_reg_mem); 11901 %} 11902 11903 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 11904 %{ 11905 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11906 11907 ins_cost(125); 11908 format %{ "testb $mem, $imm\t# byte" %} 11909 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11910 ins_pipe(ialu_cr_reg_mem); 11911 %} 11912 11913 //----------Max and Min-------------------------------------------------------- 11914 // Min Instructions 11915 11916 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11917 %{ 11918 effect(USE_DEF dst, USE src, USE cr); 11919 11920 format %{ "cmovlgt $dst, $src\t# min" %} 11921 ins_encode %{ 11922 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 11923 %} 11924 ins_pipe(pipe_cmov_reg); 11925 %} 11926 11927 11928 instruct minI_rReg(rRegI dst, rRegI src) 11929 %{ 11930 match(Set dst (MinI dst src)); 11931 11932 ins_cost(200); 11933 expand %{ 11934 rFlagsReg cr; 11935 compI_rReg(cr, dst, src); 11936 cmovI_reg_g(dst, src, cr); 11937 %} 11938 %} 11939 11940 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11941 %{ 11942 effect(USE_DEF dst, USE src, USE cr); 11943 11944 format %{ "cmovllt $dst, $src\t# max" %} 11945 ins_encode %{ 11946 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 11947 %} 11948 ins_pipe(pipe_cmov_reg); 11949 %} 11950 11951 11952 instruct maxI_rReg(rRegI dst, rRegI src) 11953 %{ 11954 match(Set dst (MaxI dst src)); 11955 11956 ins_cost(200); 11957 expand %{ 11958 rFlagsReg cr; 11959 compI_rReg(cr, dst, src); 11960 cmovI_reg_l(dst, src, cr); 11961 %} 11962 %} 11963 11964 // ============================================================================ 11965 // Branch Instructions 11966 11967 // Jump Direct - Label defines a relative address from JMP+1 11968 instruct jmpDir(label labl) 11969 %{ 11970 match(Goto); 11971 effect(USE labl); 11972 11973 ins_cost(300); 11974 format %{ "jmp $labl" %} 11975 size(5); 11976 ins_encode %{ 11977 Label* L = $labl$$label; 11978 __ jmp(*L, false); // Always long jump 11979 %} 11980 ins_pipe(pipe_jmp); 11981 %} 11982 11983 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11984 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11985 %{ 11986 match(If cop cr); 11987 effect(USE labl); 11988 11989 ins_cost(300); 11990 format %{ "j$cop $labl" %} 11991 size(6); 11992 ins_encode %{ 11993 Label* L = $labl$$label; 11994 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11995 %} 11996 ins_pipe(pipe_jcc); 11997 %} 11998 11999 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12000 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12001 %{ 12002 match(CountedLoopEnd cop cr); 12003 effect(USE labl); 12004 12005 ins_cost(300); 12006 format %{ "j$cop $labl\t# loop end" %} 12007 size(6); 12008 ins_encode %{ 12009 Label* L = $labl$$label; 12010 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12011 %} 12012 ins_pipe(pipe_jcc); 12013 %} 12014 12015 // Jump Direct Conditional - using unsigned comparison 12016 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12017 match(If cop cmp); 12018 effect(USE labl); 12019 12020 ins_cost(300); 12021 format %{ "j$cop,u $labl" %} 12022 size(6); 12023 ins_encode %{ 12024 Label* L = $labl$$label; 12025 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12026 %} 12027 ins_pipe(pipe_jcc); 12028 %} 12029 12030 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12031 match(If cop cmp); 12032 effect(USE labl); 12033 12034 ins_cost(200); 12035 format %{ "j$cop,u $labl" %} 12036 size(6); 12037 ins_encode %{ 12038 Label* L = $labl$$label; 12039 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12040 %} 12041 ins_pipe(pipe_jcc); 12042 %} 12043 12044 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12045 match(If cop cmp); 12046 effect(USE labl); 12047 12048 ins_cost(200); 12049 format %{ $$template 12050 if ($cop$$cmpcode == Assembler::notEqual) { 12051 $$emit$$"jp,u $labl\n\t" 12052 $$emit$$"j$cop,u $labl" 12053 } else { 12054 $$emit$$"jp,u done\n\t" 12055 $$emit$$"j$cop,u $labl\n\t" 12056 $$emit$$"done:" 12057 } 12058 %} 12059 ins_encode %{ 12060 Label* l = $labl$$label; 12061 if ($cop$$cmpcode == Assembler::notEqual) { 12062 __ jcc(Assembler::parity, *l, false); 12063 __ jcc(Assembler::notEqual, *l, false); 12064 } else if ($cop$$cmpcode == Assembler::equal) { 12065 Label done; 12066 __ jccb(Assembler::parity, done); 12067 __ jcc(Assembler::equal, *l, false); 12068 __ bind(done); 12069 } else { 12070 ShouldNotReachHere(); 12071 } 12072 %} 12073 ins_pipe(pipe_jcc); 12074 %} 12075 12076 // ============================================================================ 12077 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12078 // superklass array for an instance of the superklass. Set a hidden 12079 // internal cache on a hit (cache is checked with exposed code in 12080 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12081 // encoding ALSO sets flags. 12082 12083 instruct partialSubtypeCheck(rdi_RegP result, 12084 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12085 rFlagsReg cr) 12086 %{ 12087 match(Set result (PartialSubtypeCheck sub super)); 12088 effect(KILL rcx, KILL cr); 12089 12090 ins_cost(1100); // slightly larger than the next version 12091 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12092 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12093 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12094 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12095 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12096 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12097 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12098 "miss:\t" %} 12099 12100 opcode(0x1); // Force a XOR of RDI 12101 ins_encode(enc_PartialSubtypeCheck()); 12102 ins_pipe(pipe_slow); 12103 %} 12104 12105 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12106 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12107 rFlagsReg cr) 12108 %{ 12109 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12110 predicate(UseSecondarySupersTable); 12111 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12112 12113 ins_cost(700); // smaller than the next version 12114 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12115 12116 ins_encode %{ 12117 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12118 if (InlineSecondarySupersTest) { 12119 __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12120 $temp3$$Register, $temp4$$Register, $result$$Register, 12121 super_klass_slot); 12122 } else { 12123 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12124 } 12125 %} 12126 12127 ins_pipe(pipe_slow); 12128 %} 12129 12130 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12131 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12132 immP0 zero, 12133 rdi_RegP result) 12134 %{ 12135 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12136 effect(KILL rcx, KILL result); 12137 12138 ins_cost(1000); 12139 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12140 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12141 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12142 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12143 "jne,s miss\t\t# Missed: flags nz\n\t" 12144 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12145 "miss:\t" %} 12146 12147 opcode(0x0); // No need to XOR RDI 12148 ins_encode(enc_PartialSubtypeCheck()); 12149 ins_pipe(pipe_slow); 12150 %} 12151 12152 // ============================================================================ 12153 // Branch Instructions -- short offset versions 12154 // 12155 // These instructions are used to replace jumps of a long offset (the default 12156 // match) with jumps of a shorter offset. These instructions are all tagged 12157 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12158 // match rules in general matching. Instead, the ADLC generates a conversion 12159 // method in the MachNode which can be used to do in-place replacement of the 12160 // long variant with the shorter variant. The compiler will determine if a 12161 // branch can be taken by the is_short_branch_offset() predicate in the machine 12162 // specific code section of the file. 12163 12164 // Jump Direct - Label defines a relative address from JMP+1 12165 instruct jmpDir_short(label labl) %{ 12166 match(Goto); 12167 effect(USE labl); 12168 12169 ins_cost(300); 12170 format %{ "jmp,s $labl" %} 12171 size(2); 12172 ins_encode %{ 12173 Label* L = $labl$$label; 12174 __ jmpb(*L); 12175 %} 12176 ins_pipe(pipe_jmp); 12177 ins_short_branch(1); 12178 %} 12179 12180 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12181 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12182 match(If cop cr); 12183 effect(USE labl); 12184 12185 ins_cost(300); 12186 format %{ "j$cop,s $labl" %} 12187 size(2); 12188 ins_encode %{ 12189 Label* L = $labl$$label; 12190 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12191 %} 12192 ins_pipe(pipe_jcc); 12193 ins_short_branch(1); 12194 %} 12195 12196 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12197 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12198 match(CountedLoopEnd cop cr); 12199 effect(USE labl); 12200 12201 ins_cost(300); 12202 format %{ "j$cop,s $labl\t# loop end" %} 12203 size(2); 12204 ins_encode %{ 12205 Label* L = $labl$$label; 12206 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12207 %} 12208 ins_pipe(pipe_jcc); 12209 ins_short_branch(1); 12210 %} 12211 12212 // Jump Direct Conditional - using unsigned comparison 12213 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12214 match(If cop cmp); 12215 effect(USE labl); 12216 12217 ins_cost(300); 12218 format %{ "j$cop,us $labl" %} 12219 size(2); 12220 ins_encode %{ 12221 Label* L = $labl$$label; 12222 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12223 %} 12224 ins_pipe(pipe_jcc); 12225 ins_short_branch(1); 12226 %} 12227 12228 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12229 match(If cop cmp); 12230 effect(USE labl); 12231 12232 ins_cost(300); 12233 format %{ "j$cop,us $labl" %} 12234 size(2); 12235 ins_encode %{ 12236 Label* L = $labl$$label; 12237 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12238 %} 12239 ins_pipe(pipe_jcc); 12240 ins_short_branch(1); 12241 %} 12242 12243 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12244 match(If cop cmp); 12245 effect(USE labl); 12246 12247 ins_cost(300); 12248 format %{ $$template 12249 if ($cop$$cmpcode == Assembler::notEqual) { 12250 $$emit$$"jp,u,s $labl\n\t" 12251 $$emit$$"j$cop,u,s $labl" 12252 } else { 12253 $$emit$$"jp,u,s done\n\t" 12254 $$emit$$"j$cop,u,s $labl\n\t" 12255 $$emit$$"done:" 12256 } 12257 %} 12258 size(4); 12259 ins_encode %{ 12260 Label* l = $labl$$label; 12261 if ($cop$$cmpcode == Assembler::notEqual) { 12262 __ jccb(Assembler::parity, *l); 12263 __ jccb(Assembler::notEqual, *l); 12264 } else if ($cop$$cmpcode == Assembler::equal) { 12265 Label done; 12266 __ jccb(Assembler::parity, done); 12267 __ jccb(Assembler::equal, *l); 12268 __ bind(done); 12269 } else { 12270 ShouldNotReachHere(); 12271 } 12272 %} 12273 ins_pipe(pipe_jcc); 12274 ins_short_branch(1); 12275 %} 12276 12277 // ============================================================================ 12278 // inlined locking and unlocking 12279 12280 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12281 predicate(LockingMode != LM_LIGHTWEIGHT); 12282 match(Set cr (FastLock object box)); 12283 effect(TEMP tmp, TEMP scr, USE_KILL box); 12284 ins_cost(300); 12285 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12286 ins_encode %{ 12287 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12288 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12289 %} 12290 ins_pipe(pipe_slow); 12291 %} 12292 12293 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12294 predicate(LockingMode != LM_LIGHTWEIGHT); 12295 match(Set cr (FastUnlock object box)); 12296 effect(TEMP tmp, USE_KILL box); 12297 ins_cost(300); 12298 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12299 ins_encode %{ 12300 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12301 %} 12302 ins_pipe(pipe_slow); 12303 %} 12304 12305 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12306 predicate(LockingMode == LM_LIGHTWEIGHT); 12307 match(Set cr (FastLock object box)); 12308 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12309 ins_cost(300); 12310 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12311 ins_encode %{ 12312 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12313 %} 12314 ins_pipe(pipe_slow); 12315 %} 12316 12317 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12318 predicate(LockingMode == LM_LIGHTWEIGHT); 12319 match(Set cr (FastUnlock object rax_reg)); 12320 effect(TEMP tmp, USE_KILL rax_reg); 12321 ins_cost(300); 12322 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12323 ins_encode %{ 12324 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12325 %} 12326 ins_pipe(pipe_slow); 12327 %} 12328 12329 12330 // ============================================================================ 12331 // Safepoint Instructions 12332 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12333 %{ 12334 match(SafePoint poll); 12335 effect(KILL cr, USE poll); 12336 12337 format %{ "testl rax, [$poll]\t" 12338 "# Safepoint: poll for GC" %} 12339 ins_cost(125); 12340 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12341 ins_encode %{ 12342 __ relocate(relocInfo::poll_type); 12343 address pre_pc = __ pc(); 12344 __ testl(rax, Address($poll$$Register, 0)); 12345 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12346 %} 12347 ins_pipe(ialu_reg_mem); 12348 %} 12349 12350 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12351 match(Set dst (MaskAll src)); 12352 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12353 ins_encode %{ 12354 int mask_len = Matcher::vector_length(this); 12355 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12356 %} 12357 ins_pipe( pipe_slow ); 12358 %} 12359 12360 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12361 predicate(Matcher::vector_length(n) > 32); 12362 match(Set dst (MaskAll src)); 12363 effect(TEMP tmp); 12364 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12365 ins_encode %{ 12366 int mask_len = Matcher::vector_length(this); 12367 __ movslq($tmp$$Register, $src$$Register); 12368 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12369 %} 12370 ins_pipe( pipe_slow ); 12371 %} 12372 12373 // ============================================================================ 12374 // Procedure Call/Return Instructions 12375 // Call Java Static Instruction 12376 // Note: If this code changes, the corresponding ret_addr_offset() and 12377 // compute_padding() functions will have to be adjusted. 12378 instruct CallStaticJavaDirect(method meth) %{ 12379 match(CallStaticJava); 12380 effect(USE meth); 12381 12382 ins_cost(300); 12383 format %{ "call,static " %} 12384 opcode(0xE8); /* E8 cd */ 12385 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12386 ins_pipe(pipe_slow); 12387 ins_alignment(4); 12388 %} 12389 12390 // Call Java Dynamic Instruction 12391 // Note: If this code changes, the corresponding ret_addr_offset() and 12392 // compute_padding() functions will have to be adjusted. 12393 instruct CallDynamicJavaDirect(method meth) 12394 %{ 12395 match(CallDynamicJava); 12396 effect(USE meth); 12397 12398 ins_cost(300); 12399 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12400 "call,dynamic " %} 12401 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12402 ins_pipe(pipe_slow); 12403 ins_alignment(4); 12404 %} 12405 12406 // Call Runtime Instruction 12407 instruct CallRuntimeDirect(method meth) 12408 %{ 12409 match(CallRuntime); 12410 effect(USE meth); 12411 12412 ins_cost(300); 12413 format %{ "call,runtime " %} 12414 ins_encode(clear_avx, Java_To_Runtime(meth)); 12415 ins_pipe(pipe_slow); 12416 %} 12417 12418 // Call runtime without safepoint 12419 instruct CallLeafDirect(method meth) 12420 %{ 12421 match(CallLeaf); 12422 effect(USE meth); 12423 12424 ins_cost(300); 12425 format %{ "call_leaf,runtime " %} 12426 ins_encode(clear_avx, Java_To_Runtime(meth)); 12427 ins_pipe(pipe_slow); 12428 %} 12429 12430 // Call runtime without safepoint and with vector arguments 12431 instruct CallLeafDirectVector(method meth) 12432 %{ 12433 match(CallLeafVector); 12434 effect(USE meth); 12435 12436 ins_cost(300); 12437 format %{ "call_leaf,vector " %} 12438 ins_encode(Java_To_Runtime(meth)); 12439 ins_pipe(pipe_slow); 12440 %} 12441 12442 // Call runtime without safepoint 12443 instruct CallLeafNoFPDirect(method meth) 12444 %{ 12445 match(CallLeafNoFP); 12446 effect(USE meth); 12447 12448 ins_cost(300); 12449 format %{ "call_leaf_nofp,runtime " %} 12450 ins_encode(clear_avx, Java_To_Runtime(meth)); 12451 ins_pipe(pipe_slow); 12452 %} 12453 12454 // Return Instruction 12455 // Remove the return address & jump to it. 12456 // Notice: We always emit a nop after a ret to make sure there is room 12457 // for safepoint patching 12458 instruct Ret() 12459 %{ 12460 match(Return); 12461 12462 format %{ "ret" %} 12463 ins_encode %{ 12464 __ ret(0); 12465 %} 12466 ins_pipe(pipe_jmp); 12467 %} 12468 12469 // Tail Call; Jump from runtime stub to Java code. 12470 // Also known as an 'interprocedural jump'. 12471 // Target of jump will eventually return to caller. 12472 // TailJump below removes the return address. 12473 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12474 // emitted just above the TailCall which has reset rbp to the caller state. 12475 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12476 %{ 12477 match(TailCall jump_target method_ptr); 12478 12479 ins_cost(300); 12480 format %{ "jmp $jump_target\t# rbx holds method" %} 12481 ins_encode %{ 12482 __ jmp($jump_target$$Register); 12483 %} 12484 ins_pipe(pipe_jmp); 12485 %} 12486 12487 // Tail Jump; remove the return address; jump to target. 12488 // TailCall above leaves the return address around. 12489 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12490 %{ 12491 match(TailJump jump_target ex_oop); 12492 12493 ins_cost(300); 12494 format %{ "popq rdx\t# pop return address\n\t" 12495 "jmp $jump_target" %} 12496 ins_encode %{ 12497 __ popq(as_Register(RDX_enc)); 12498 __ jmp($jump_target$$Register); 12499 %} 12500 ins_pipe(pipe_jmp); 12501 %} 12502 12503 // Create exception oop: created by stack-crawling runtime code. 12504 // Created exception is now available to this handler, and is setup 12505 // just prior to jumping to this handler. No code emitted. 12506 instruct CreateException(rax_RegP ex_oop) 12507 %{ 12508 match(Set ex_oop (CreateEx)); 12509 12510 size(0); 12511 // use the following format syntax 12512 format %{ "# exception oop is in rax; no code emitted" %} 12513 ins_encode(); 12514 ins_pipe(empty); 12515 %} 12516 12517 // Rethrow exception: 12518 // The exception oop will come in the first argument position. 12519 // Then JUMP (not call) to the rethrow stub code. 12520 instruct RethrowException() 12521 %{ 12522 match(Rethrow); 12523 12524 // use the following format syntax 12525 format %{ "jmp rethrow_stub" %} 12526 ins_encode %{ 12527 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12528 %} 12529 ins_pipe(pipe_jmp); 12530 %} 12531 12532 // ============================================================================ 12533 // This name is KNOWN by the ADLC and cannot be changed. 12534 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12535 // for this guy. 12536 instruct tlsLoadP(r15_RegP dst) %{ 12537 match(Set dst (ThreadLocal)); 12538 effect(DEF dst); 12539 12540 size(0); 12541 format %{ "# TLS is in R15" %} 12542 ins_encode( /*empty encoding*/ ); 12543 ins_pipe(ialu_reg_reg); 12544 %} 12545 12546 12547 //----------PEEPHOLE RULES----------------------------------------------------- 12548 // These must follow all instruction definitions as they use the names 12549 // defined in the instructions definitions. 12550 // 12551 // peeppredicate ( rule_predicate ); 12552 // // the predicate unless which the peephole rule will be ignored 12553 // 12554 // peepmatch ( root_instr_name [preceding_instruction]* ); 12555 // 12556 // peepprocedure ( procedure_name ); 12557 // // provide a procedure name to perform the optimization, the procedure should 12558 // // reside in the architecture dependent peephole file, the method has the 12559 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12560 // // with the arguments being the basic block, the current node index inside the 12561 // // block, the register allocator, the functions upon invoked return a new node 12562 // // defined in peepreplace, and the rules of the nodes appearing in the 12563 // // corresponding peepmatch, the function return true if successful, else 12564 // // return false 12565 // 12566 // peepconstraint %{ 12567 // (instruction_number.operand_name relational_op instruction_number.operand_name 12568 // [, ...] ); 12569 // // instruction numbers are zero-based using left to right order in peepmatch 12570 // 12571 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12572 // // provide an instruction_number.operand_name for each operand that appears 12573 // // in the replacement instruction's match rule 12574 // 12575 // ---------VM FLAGS--------------------------------------------------------- 12576 // 12577 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12578 // 12579 // Each peephole rule is given an identifying number starting with zero and 12580 // increasing by one in the order seen by the parser. An individual peephole 12581 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12582 // on the command-line. 12583 // 12584 // ---------CURRENT LIMITATIONS---------------------------------------------- 12585 // 12586 // Only transformations inside a basic block (do we need more for peephole) 12587 // 12588 // ---------EXAMPLE---------------------------------------------------------- 12589 // 12590 // // pertinent parts of existing instructions in architecture description 12591 // instruct movI(rRegI dst, rRegI src) 12592 // %{ 12593 // match(Set dst (CopyI src)); 12594 // %} 12595 // 12596 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12597 // %{ 12598 // match(Set dst (AddI dst src)); 12599 // effect(KILL cr); 12600 // %} 12601 // 12602 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12603 // %{ 12604 // match(Set dst (AddI dst src)); 12605 // %} 12606 // 12607 // 1. Simple replacement 12608 // - Only match adjacent instructions in same basic block 12609 // - Only equality constraints 12610 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12611 // - Only one replacement instruction 12612 // 12613 // // Change (inc mov) to lea 12614 // peephole %{ 12615 // // lea should only be emitted when beneficial 12616 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12617 // // increment preceded by register-register move 12618 // peepmatch ( incI_rReg movI ); 12619 // // require that the destination register of the increment 12620 // // match the destination register of the move 12621 // peepconstraint ( 0.dst == 1.dst ); 12622 // // construct a replacement instruction that sets 12623 // // the destination to ( move's source register + one ) 12624 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12625 // %} 12626 // 12627 // 2. Procedural replacement 12628 // - More flexible finding relevent nodes 12629 // - More flexible constraints 12630 // - More flexible transformations 12631 // - May utilise architecture-dependent API more effectively 12632 // - Currently only one replacement instruction due to adlc parsing capabilities 12633 // 12634 // // Change (inc mov) to lea 12635 // peephole %{ 12636 // // lea should only be emitted when beneficial 12637 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12638 // // the rule numbers of these nodes inside are passed into the function below 12639 // peepmatch ( incI_rReg movI ); 12640 // // the method that takes the responsibility of transformation 12641 // peepprocedure ( inc_mov_to_lea ); 12642 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12643 // // node is passed into the function above 12644 // peepreplace ( leaI_rReg_immI() ); 12645 // %} 12646 12647 // These instructions is not matched by the matcher but used by the peephole 12648 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12649 %{ 12650 predicate(false); 12651 match(Set dst (AddI src1 src2)); 12652 format %{ "leal $dst, [$src1 + $src2]" %} 12653 ins_encode %{ 12654 Register dst = $dst$$Register; 12655 Register src1 = $src1$$Register; 12656 Register src2 = $src2$$Register; 12657 if (src1 != rbp && src1 != r13) { 12658 __ leal(dst, Address(src1, src2, Address::times_1)); 12659 } else { 12660 assert(src2 != rbp && src2 != r13, ""); 12661 __ leal(dst, Address(src2, src1, Address::times_1)); 12662 } 12663 %} 12664 ins_pipe(ialu_reg_reg); 12665 %} 12666 12667 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 12668 %{ 12669 predicate(false); 12670 match(Set dst (AddI src1 src2)); 12671 format %{ "leal $dst, [$src1 + $src2]" %} 12672 ins_encode %{ 12673 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 12674 %} 12675 ins_pipe(ialu_reg_reg); 12676 %} 12677 12678 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 12679 %{ 12680 predicate(false); 12681 match(Set dst (LShiftI src shift)); 12682 format %{ "leal $dst, [$src << $shift]" %} 12683 ins_encode %{ 12684 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12685 Register src = $src$$Register; 12686 if (scale == Address::times_2 && src != rbp && src != r13) { 12687 __ leal($dst$$Register, Address(src, src, Address::times_1)); 12688 } else { 12689 __ leal($dst$$Register, Address(noreg, src, scale)); 12690 } 12691 %} 12692 ins_pipe(ialu_reg_reg); 12693 %} 12694 12695 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 12696 %{ 12697 predicate(false); 12698 match(Set dst (AddL src1 src2)); 12699 format %{ "leaq $dst, [$src1 + $src2]" %} 12700 ins_encode %{ 12701 Register dst = $dst$$Register; 12702 Register src1 = $src1$$Register; 12703 Register src2 = $src2$$Register; 12704 if (src1 != rbp && src1 != r13) { 12705 __ leaq(dst, Address(src1, src2, Address::times_1)); 12706 } else { 12707 assert(src2 != rbp && src2 != r13, ""); 12708 __ leaq(dst, Address(src2, src1, Address::times_1)); 12709 } 12710 %} 12711 ins_pipe(ialu_reg_reg); 12712 %} 12713 12714 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 12715 %{ 12716 predicate(false); 12717 match(Set dst (AddL src1 src2)); 12718 format %{ "leaq $dst, [$src1 + $src2]" %} 12719 ins_encode %{ 12720 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 12721 %} 12722 ins_pipe(ialu_reg_reg); 12723 %} 12724 12725 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 12726 %{ 12727 predicate(false); 12728 match(Set dst (LShiftL src shift)); 12729 format %{ "leaq $dst, [$src << $shift]" %} 12730 ins_encode %{ 12731 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12732 Register src = $src$$Register; 12733 if (scale == Address::times_2 && src != rbp && src != r13) { 12734 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 12735 } else { 12736 __ leaq($dst$$Register, Address(noreg, src, scale)); 12737 } 12738 %} 12739 ins_pipe(ialu_reg_reg); 12740 %} 12741 12742 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 12743 // sal}) with lea instructions. The {add, sal} rules are beneficial in 12744 // processors with at least partial ALU support for lea 12745 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 12746 // beneficial for processors with full ALU support 12747 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 12748 12749 peephole 12750 %{ 12751 peeppredicate(VM_Version::supports_fast_2op_lea()); 12752 peepmatch (addI_rReg); 12753 peepprocedure (lea_coalesce_reg); 12754 peepreplace (leaI_rReg_rReg_peep()); 12755 %} 12756 12757 peephole 12758 %{ 12759 peeppredicate(VM_Version::supports_fast_2op_lea()); 12760 peepmatch (addI_rReg_imm); 12761 peepprocedure (lea_coalesce_imm); 12762 peepreplace (leaI_rReg_immI_peep()); 12763 %} 12764 12765 peephole 12766 %{ 12767 peeppredicate(VM_Version::supports_fast_3op_lea() || 12768 VM_Version::is_intel_cascade_lake()); 12769 peepmatch (incI_rReg); 12770 peepprocedure (lea_coalesce_imm); 12771 peepreplace (leaI_rReg_immI_peep()); 12772 %} 12773 12774 peephole 12775 %{ 12776 peeppredicate(VM_Version::supports_fast_3op_lea() || 12777 VM_Version::is_intel_cascade_lake()); 12778 peepmatch (decI_rReg); 12779 peepprocedure (lea_coalesce_imm); 12780 peepreplace (leaI_rReg_immI_peep()); 12781 %} 12782 12783 peephole 12784 %{ 12785 peeppredicate(VM_Version::supports_fast_2op_lea()); 12786 peepmatch (salI_rReg_immI2); 12787 peepprocedure (lea_coalesce_imm); 12788 peepreplace (leaI_rReg_immI2_peep()); 12789 %} 12790 12791 peephole 12792 %{ 12793 peeppredicate(VM_Version::supports_fast_2op_lea()); 12794 peepmatch (addL_rReg); 12795 peepprocedure (lea_coalesce_reg); 12796 peepreplace (leaL_rReg_rReg_peep()); 12797 %} 12798 12799 peephole 12800 %{ 12801 peeppredicate(VM_Version::supports_fast_2op_lea()); 12802 peepmatch (addL_rReg_imm); 12803 peepprocedure (lea_coalesce_imm); 12804 peepreplace (leaL_rReg_immL32_peep()); 12805 %} 12806 12807 peephole 12808 %{ 12809 peeppredicate(VM_Version::supports_fast_3op_lea() || 12810 VM_Version::is_intel_cascade_lake()); 12811 peepmatch (incL_rReg); 12812 peepprocedure (lea_coalesce_imm); 12813 peepreplace (leaL_rReg_immL32_peep()); 12814 %} 12815 12816 peephole 12817 %{ 12818 peeppredicate(VM_Version::supports_fast_3op_lea() || 12819 VM_Version::is_intel_cascade_lake()); 12820 peepmatch (decL_rReg); 12821 peepprocedure (lea_coalesce_imm); 12822 peepreplace (leaL_rReg_immL32_peep()); 12823 %} 12824 12825 peephole 12826 %{ 12827 peeppredicate(VM_Version::supports_fast_2op_lea()); 12828 peepmatch (salL_rReg_immI2); 12829 peepprocedure (lea_coalesce_imm); 12830 peepreplace (leaL_rReg_immI2_peep()); 12831 %} 12832 12833 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 12834 // 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 12835 12836 //int variant 12837 peephole 12838 %{ 12839 peepmatch (testI_reg); 12840 peepprocedure (test_may_remove); 12841 %} 12842 12843 //long variant 12844 peephole 12845 %{ 12846 peepmatch (testL_reg); 12847 peepprocedure (test_may_remove); 12848 %} 12849 12850 12851 //----------SMARTSPILL RULES--------------------------------------------------- 12852 // These must follow all instruction definitions as they use the names 12853 // defined in the instructions definitions.