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 reg_def R16 (SOC, SOC, Op_RegI, 16, r16->as_VMReg()); 132 reg_def R16_H(SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 133 134 reg_def R17 (SOC, SOC, Op_RegI, 17, r17->as_VMReg()); 135 reg_def R17_H(SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 136 137 reg_def R18 (SOC, SOC, Op_RegI, 18, r18->as_VMReg()); 138 reg_def R18_H(SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 139 140 reg_def R19 (SOC, SOC, Op_RegI, 19, r19->as_VMReg()); 141 reg_def R19_H(SOC, SOC, Op_RegI, 19, r19->as_VMReg()->next()); 142 143 reg_def R20 (SOC, SOC, Op_RegI, 20, r20->as_VMReg()); 144 reg_def R20_H(SOC, SOC, Op_RegI, 20, r20->as_VMReg()->next()); 145 146 reg_def R21 (SOC, SOC, Op_RegI, 21, r21->as_VMReg()); 147 reg_def R21_H(SOC, SOC, Op_RegI, 21, r21->as_VMReg()->next()); 148 149 reg_def R22 (SOC, SOC, Op_RegI, 22, r22->as_VMReg()); 150 reg_def R22_H(SOC, SOC, Op_RegI, 22, r22->as_VMReg()->next()); 151 152 reg_def R23 (SOC, SOC, Op_RegI, 23, r23->as_VMReg()); 153 reg_def R23_H(SOC, SOC, Op_RegI, 23, r23->as_VMReg()->next()); 154 155 reg_def R24 (SOC, SOC, Op_RegI, 24, r24->as_VMReg()); 156 reg_def R24_H(SOC, SOC, Op_RegI, 24, r24->as_VMReg()->next()); 157 158 reg_def R25 (SOC, SOC, Op_RegI, 25, r25->as_VMReg()); 159 reg_def R25_H(SOC, SOC, Op_RegI, 25, r25->as_VMReg()->next()); 160 161 reg_def R26 (SOC, SOC, Op_RegI, 26, r26->as_VMReg()); 162 reg_def R26_H(SOC, SOC, Op_RegI, 26, r26->as_VMReg()->next()); 163 164 reg_def R27 (SOC, SOC, Op_RegI, 27, r27->as_VMReg()); 165 reg_def R27_H(SOC, SOC, Op_RegI, 27, r27->as_VMReg()->next()); 166 167 reg_def R28 (SOC, SOC, Op_RegI, 28, r28->as_VMReg()); 168 reg_def R28_H(SOC, SOC, Op_RegI, 28, r28->as_VMReg()->next()); 169 170 reg_def R29 (SOC, SOC, Op_RegI, 29, r29->as_VMReg()); 171 reg_def R29_H(SOC, SOC, Op_RegI, 29, r29->as_VMReg()->next()); 172 173 reg_def R30 (SOC, SOC, Op_RegI, 30, r30->as_VMReg()); 174 reg_def R30_H(SOC, SOC, Op_RegI, 30, r30->as_VMReg()->next()); 175 176 reg_def R31 (SOC, SOC, Op_RegI, 31, r31->as_VMReg()); 177 reg_def R31_H(SOC, SOC, Op_RegI, 31, r31->as_VMReg()->next()); 178 179 // Floating Point Registers 180 181 // Specify priority of register selection within phases of register 182 // allocation. Highest priority is first. A useful heuristic is to 183 // give registers a low priority when they are required by machine 184 // instructions, like EAX and EDX on I486, and choose no-save registers 185 // before save-on-call, & save-on-call before save-on-entry. Registers 186 // which participate in fixed calling sequences should come last. 187 // Registers which are used as pairs must fall on an even boundary. 188 189 alloc_class chunk0(R10, R10_H, 190 R11, R11_H, 191 R8, R8_H, 192 R9, R9_H, 193 R12, R12_H, 194 RCX, RCX_H, 195 RBX, RBX_H, 196 RDI, RDI_H, 197 RDX, RDX_H, 198 RSI, RSI_H, 199 RAX, RAX_H, 200 RBP, RBP_H, 201 R13, R13_H, 202 R14, R14_H, 203 R15, R15_H, 204 R16, R16_H, 205 R17, R17_H, 206 R18, R18_H, 207 R19, R19_H, 208 R20, R20_H, 209 R21, R21_H, 210 R22, R22_H, 211 R23, R23_H, 212 R24, R24_H, 213 R25, R25_H, 214 R26, R26_H, 215 R27, R27_H, 216 R28, R28_H, 217 R29, R29_H, 218 R30, R30_H, 219 R31, R31_H, 220 RSP, RSP_H); 221 222 223 //----------Architecture Description Register Classes-------------------------- 224 // Several register classes are automatically defined based upon information in 225 // this architecture description. 226 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 227 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 228 // 229 230 // Empty register class. 231 reg_class no_reg(); 232 233 // Class for all pointer/long registers including APX extended GPRs. 234 reg_class all_reg(RAX, RAX_H, 235 RDX, RDX_H, 236 RBP, RBP_H, 237 RDI, RDI_H, 238 RSI, RSI_H, 239 RCX, RCX_H, 240 RBX, RBX_H, 241 RSP, RSP_H, 242 R8, R8_H, 243 R9, R9_H, 244 R10, R10_H, 245 R11, R11_H, 246 R12, R12_H, 247 R13, R13_H, 248 R14, R14_H, 249 R15, R15_H, 250 R16, R16_H, 251 R17, R17_H, 252 R18, R18_H, 253 R19, R19_H, 254 R20, R20_H, 255 R21, R21_H, 256 R22, R22_H, 257 R23, R23_H, 258 R24, R24_H, 259 R25, R25_H, 260 R26, R26_H, 261 R27, R27_H, 262 R28, R28_H, 263 R29, R29_H, 264 R30, R30_H, 265 R31, R31_H); 266 267 // Class for all int registers including APX extended GPRs. 268 reg_class all_int_reg(RAX 269 RDX, 270 RBP, 271 RDI, 272 RSI, 273 RCX, 274 RBX, 275 R8, 276 R9, 277 R10, 278 R11, 279 R12, 280 R13, 281 R14, 282 R16, 283 R17, 284 R18, 285 R19, 286 R20, 287 R21, 288 R22, 289 R23, 290 R24, 291 R25, 292 R26, 293 R27, 294 R28, 295 R29, 296 R30, 297 R31); 298 299 // Class for all pointer registers 300 reg_class any_reg %{ 301 return _ANY_REG_mask; 302 %} 303 304 // Class for all pointer registers (excluding RSP) 305 reg_class ptr_reg %{ 306 return _PTR_REG_mask; 307 %} 308 309 // Class for all pointer registers (excluding RSP and RBP) 310 reg_class ptr_reg_no_rbp %{ 311 return _PTR_REG_NO_RBP_mask; 312 %} 313 314 // Class for all pointer registers (excluding RAX and RSP) 315 reg_class ptr_no_rax_reg %{ 316 return _PTR_NO_RAX_REG_mask; 317 %} 318 319 // Class for all pointer registers (excluding RAX, RBX, and RSP) 320 reg_class ptr_no_rax_rbx_reg %{ 321 return _PTR_NO_RAX_RBX_REG_mask; 322 %} 323 324 // Class for all long registers (excluding RSP) 325 reg_class long_reg %{ 326 return _LONG_REG_mask; 327 %} 328 329 // Class for all long registers (excluding RAX, RDX and RSP) 330 reg_class long_no_rax_rdx_reg %{ 331 return _LONG_NO_RAX_RDX_REG_mask; 332 %} 333 334 // Class for all long registers (excluding RCX and RSP) 335 reg_class long_no_rcx_reg %{ 336 return _LONG_NO_RCX_REG_mask; 337 %} 338 339 // Class for all long registers (excluding RBP and R13) 340 reg_class long_no_rbp_r13_reg %{ 341 return _LONG_NO_RBP_R13_REG_mask; 342 %} 343 344 // Class for all int registers (excluding RSP) 345 reg_class int_reg %{ 346 return _INT_REG_mask; 347 %} 348 349 // Class for all int registers (excluding RAX, RDX, and RSP) 350 reg_class int_no_rax_rdx_reg %{ 351 return _INT_NO_RAX_RDX_REG_mask; 352 %} 353 354 // Class for all int registers (excluding RCX and RSP) 355 reg_class int_no_rcx_reg %{ 356 return _INT_NO_RCX_REG_mask; 357 %} 358 359 // Class for all int registers (excluding RBP and R13) 360 reg_class int_no_rbp_r13_reg %{ 361 return _INT_NO_RBP_R13_REG_mask; 362 %} 363 364 // Singleton class for RAX pointer register 365 reg_class ptr_rax_reg(RAX, RAX_H); 366 367 // Singleton class for RBX pointer register 368 reg_class ptr_rbx_reg(RBX, RBX_H); 369 370 // Singleton class for RSI pointer register 371 reg_class ptr_rsi_reg(RSI, RSI_H); 372 373 // Singleton class for RBP pointer register 374 reg_class ptr_rbp_reg(RBP, RBP_H); 375 376 // Singleton class for RDI pointer register 377 reg_class ptr_rdi_reg(RDI, RDI_H); 378 379 // Singleton class for stack pointer 380 reg_class ptr_rsp_reg(RSP, RSP_H); 381 382 // Singleton class for TLS pointer 383 reg_class ptr_r15_reg(R15, R15_H); 384 385 // Singleton class for RAX long register 386 reg_class long_rax_reg(RAX, RAX_H); 387 388 // Singleton class for RCX long register 389 reg_class long_rcx_reg(RCX, RCX_H); 390 391 // Singleton class for RDX long register 392 reg_class long_rdx_reg(RDX, RDX_H); 393 394 // Singleton class for R11 long register 395 reg_class long_r11_reg(R11, R11_H); 396 397 // Singleton class for RAX int register 398 reg_class int_rax_reg(RAX); 399 400 // Singleton class for RBX int register 401 reg_class int_rbx_reg(RBX); 402 403 // Singleton class for RCX int register 404 reg_class int_rcx_reg(RCX); 405 406 // Singleton class for RDX int register 407 reg_class int_rdx_reg(RDX); 408 409 // Singleton class for RDI int register 410 reg_class int_rdi_reg(RDI); 411 412 // Singleton class for instruction pointer 413 // reg_class ip_reg(RIP); 414 415 %} 416 417 //----------SOURCE BLOCK------------------------------------------------------- 418 // This is a block of C++ code which provides values, functions, and 419 // definitions necessary in the rest of the architecture description 420 421 source_hpp %{ 422 423 #include "peephole_x86_64.hpp" 424 425 %} 426 427 // Register masks 428 source_hpp %{ 429 430 extern RegMask _ANY_REG_mask; 431 extern RegMask _PTR_REG_mask; 432 extern RegMask _PTR_REG_NO_RBP_mask; 433 extern RegMask _PTR_NO_RAX_REG_mask; 434 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 435 extern RegMask _LONG_REG_mask; 436 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 437 extern RegMask _LONG_NO_RCX_REG_mask; 438 extern RegMask _LONG_NO_RBP_R13_REG_mask; 439 extern RegMask _INT_REG_mask; 440 extern RegMask _INT_NO_RAX_RDX_REG_mask; 441 extern RegMask _INT_NO_RCX_REG_mask; 442 extern RegMask _INT_NO_RBP_R13_REG_mask; 443 extern RegMask _FLOAT_REG_mask; 444 445 extern RegMask _STACK_OR_PTR_REG_mask; 446 extern RegMask _STACK_OR_LONG_REG_mask; 447 extern RegMask _STACK_OR_INT_REG_mask; 448 449 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 450 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 451 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 452 453 %} 454 455 source %{ 456 #define RELOC_IMM64 Assembler::imm_operand 457 #define RELOC_DISP32 Assembler::disp32_operand 458 459 #define __ masm-> 460 461 RegMask _ANY_REG_mask; 462 RegMask _PTR_REG_mask; 463 RegMask _PTR_REG_NO_RBP_mask; 464 RegMask _PTR_NO_RAX_REG_mask; 465 RegMask _PTR_NO_RAX_RBX_REG_mask; 466 RegMask _LONG_REG_mask; 467 RegMask _LONG_NO_RAX_RDX_REG_mask; 468 RegMask _LONG_NO_RCX_REG_mask; 469 RegMask _LONG_NO_RBP_R13_REG_mask; 470 RegMask _INT_REG_mask; 471 RegMask _INT_NO_RAX_RDX_REG_mask; 472 RegMask _INT_NO_RCX_REG_mask; 473 RegMask _INT_NO_RBP_R13_REG_mask; 474 RegMask _FLOAT_REG_mask; 475 RegMask _STACK_OR_PTR_REG_mask; 476 RegMask _STACK_OR_LONG_REG_mask; 477 RegMask _STACK_OR_INT_REG_mask; 478 479 static bool need_r12_heapbase() { 480 return UseCompressedOops; 481 } 482 483 void reg_mask_init() { 484 constexpr Register egprs[] = {r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31}; 485 486 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 487 // We derive a number of subsets from it. 488 _ANY_REG_mask = _ALL_REG_mask; 489 490 if (PreserveFramePointer) { 491 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 492 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 493 } 494 if (need_r12_heapbase()) { 495 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 496 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 497 } 498 499 _PTR_REG_mask = _ANY_REG_mask; 500 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 501 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 502 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 503 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 504 if (!UseAPX) { 505 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 506 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 507 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg()->next())); 508 } 509 } 510 511 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 512 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 513 514 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 515 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 516 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 517 518 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 519 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 520 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 521 522 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 523 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 524 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 525 526 527 _LONG_REG_mask = _PTR_REG_mask; 528 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 529 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 530 531 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 532 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 533 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 534 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 535 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 536 537 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 538 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 539 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 540 541 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 542 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 543 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 544 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 545 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 546 547 _INT_REG_mask = _ALL_INT_REG_mask; 548 if (!UseAPX) { 549 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 550 _INT_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 551 } 552 } 553 554 if (PreserveFramePointer) { 555 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 556 } 557 if (need_r12_heapbase()) { 558 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 559 } 560 561 _STACK_OR_INT_REG_mask = _INT_REG_mask; 562 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 563 564 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 565 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 566 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 567 568 _INT_NO_RCX_REG_mask = _INT_REG_mask; 569 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 570 571 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 572 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 573 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 574 575 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 576 // from the float_reg_legacy/float_reg_evex register class. 577 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 578 } 579 580 static bool generate_vzeroupper(Compile* C) { 581 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 582 } 583 584 static int clear_avx_size() { 585 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 586 } 587 588 // !!!!! Special hack to get all types of calls to specify the byte offset 589 // from the start of the call to the point where the return address 590 // will point. 591 int MachCallStaticJavaNode::ret_addr_offset() 592 { 593 int offset = 5; // 5 bytes from start of call to where return address points 594 offset += clear_avx_size(); 595 return offset; 596 } 597 598 int MachCallDynamicJavaNode::ret_addr_offset() 599 { 600 int offset = 15; // 15 bytes from start of call to where return address points 601 offset += clear_avx_size(); 602 return offset; 603 } 604 605 int MachCallRuntimeNode::ret_addr_offset() { 606 int offset = 13; // movq r10,#addr; callq (r10) 607 if (this->ideal_Opcode() != Op_CallLeafVector) { 608 offset += clear_avx_size(); 609 } 610 return offset; 611 } 612 // 613 // Compute padding required for nodes which need alignment 614 // 615 616 // The address of the call instruction needs to be 4-byte aligned to 617 // ensure that it does not span a cache line so that it can be patched. 618 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 619 { 620 current_offset += clear_avx_size(); // skip vzeroupper 621 current_offset += 1; // skip call opcode byte 622 return align_up(current_offset, alignment_required()) - current_offset; 623 } 624 625 // The address of the call instruction needs to be 4-byte aligned to 626 // ensure that it does not span a cache line so that it can be patched. 627 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 628 { 629 current_offset += clear_avx_size(); // skip vzeroupper 630 current_offset += 11; // skip movq instruction + call opcode byte 631 return align_up(current_offset, alignment_required()) - current_offset; 632 } 633 634 // This could be in MacroAssembler but it's fairly C2 specific 635 static void emit_cmpfp_fixup(MacroAssembler* masm) { 636 Label exit; 637 __ jccb(Assembler::noParity, exit); 638 __ pushf(); 639 // 640 // comiss/ucomiss instructions set ZF,PF,CF flags and 641 // zero OF,AF,SF for NaN values. 642 // Fixup flags by zeroing ZF,PF so that compare of NaN 643 // values returns 'less than' result (CF is set). 644 // Leave the rest of flags unchanged. 645 // 646 // 7 6 5 4 3 2 1 0 647 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 648 // 0 0 1 0 1 0 1 1 (0x2B) 649 // 650 __ andq(Address(rsp, 0), 0xffffff2b); 651 __ popf(); 652 __ bind(exit); 653 } 654 655 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 656 Label done; 657 __ movl(dst, -1); 658 __ jcc(Assembler::parity, done); 659 __ jcc(Assembler::below, done); 660 __ setcc(Assembler::notEqual, dst); 661 __ bind(done); 662 } 663 664 // Math.min() # Math.max() 665 // -------------------------- 666 // ucomis[s/d] # 667 // ja -> b # a 668 // jp -> NaN # NaN 669 // jb -> a # b 670 // je # 671 // |-jz -> a | b # a & b 672 // | -> a # 673 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 674 XMMRegister a, XMMRegister b, 675 XMMRegister xmmt, Register rt, 676 bool min, bool single) { 677 678 Label nan, zero, below, above, done; 679 680 if (single) 681 __ ucomiss(a, b); 682 else 683 __ ucomisd(a, b); 684 685 if (dst->encoding() != (min ? b : a)->encoding()) 686 __ jccb(Assembler::above, above); // CF=0 & ZF=0 687 else 688 __ jccb(Assembler::above, done); 689 690 __ jccb(Assembler::parity, nan); // PF=1 691 __ jccb(Assembler::below, below); // CF=1 692 693 // equal 694 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 695 if (single) { 696 __ ucomiss(a, xmmt); 697 __ jccb(Assembler::equal, zero); 698 699 __ movflt(dst, a); 700 __ jmp(done); 701 } 702 else { 703 __ ucomisd(a, xmmt); 704 __ jccb(Assembler::equal, zero); 705 706 __ movdbl(dst, a); 707 __ jmp(done); 708 } 709 710 __ bind(zero); 711 if (min) 712 __ vpor(dst, a, b, Assembler::AVX_128bit); 713 else 714 __ vpand(dst, a, b, Assembler::AVX_128bit); 715 716 __ jmp(done); 717 718 __ bind(above); 719 if (single) 720 __ movflt(dst, min ? b : a); 721 else 722 __ movdbl(dst, min ? b : a); 723 724 __ jmp(done); 725 726 __ bind(nan); 727 if (single) { 728 __ movl(rt, 0x7fc00000); // Float.NaN 729 __ movdl(dst, rt); 730 } 731 else { 732 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 733 __ movdq(dst, rt); 734 } 735 __ jmp(done); 736 737 __ bind(below); 738 if (single) 739 __ movflt(dst, min ? a : b); 740 else 741 __ movdbl(dst, min ? a : b); 742 743 __ bind(done); 744 } 745 746 //============================================================================= 747 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 748 749 int ConstantTable::calculate_table_base_offset() const { 750 return 0; // absolute addressing, no offset 751 } 752 753 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 754 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 755 ShouldNotReachHere(); 756 } 757 758 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 759 // Empty encoding 760 } 761 762 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 763 return 0; 764 } 765 766 #ifndef PRODUCT 767 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 768 st->print("# MachConstantBaseNode (empty encoding)"); 769 } 770 #endif 771 772 773 //============================================================================= 774 #ifndef PRODUCT 775 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 776 Compile* C = ra_->C; 777 778 int framesize = C->output()->frame_size_in_bytes(); 779 int bangsize = C->output()->bang_size_in_bytes(); 780 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 781 // Remove wordSize for return addr which is already pushed. 782 framesize -= wordSize; 783 784 if (C->output()->need_stack_bang(bangsize)) { 785 framesize -= wordSize; 786 st->print("# stack bang (%d bytes)", bangsize); 787 st->print("\n\t"); 788 st->print("pushq rbp\t# Save rbp"); 789 if (PreserveFramePointer) { 790 st->print("\n\t"); 791 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 792 } 793 if (framesize) { 794 st->print("\n\t"); 795 st->print("subq rsp, #%d\t# Create frame",framesize); 796 } 797 } else { 798 st->print("subq rsp, #%d\t# Create frame",framesize); 799 st->print("\n\t"); 800 framesize -= wordSize; 801 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 802 if (PreserveFramePointer) { 803 st->print("\n\t"); 804 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 805 if (framesize > 0) { 806 st->print("\n\t"); 807 st->print("addq rbp, #%d", framesize); 808 } 809 } 810 } 811 812 if (VerifyStackAtCalls) { 813 st->print("\n\t"); 814 framesize -= wordSize; 815 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 816 #ifdef ASSERT 817 st->print("\n\t"); 818 st->print("# stack alignment check"); 819 #endif 820 } 821 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 822 st->print("\n\t"); 823 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 824 st->print("\n\t"); 825 st->print("je fast_entry\t"); 826 st->print("\n\t"); 827 st->print("call #nmethod_entry_barrier_stub\t"); 828 st->print("\n\tfast_entry:"); 829 } 830 st->cr(); 831 } 832 #endif 833 834 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 835 Compile* C = ra_->C; 836 837 int framesize = C->output()->frame_size_in_bytes(); 838 int bangsize = C->output()->bang_size_in_bytes(); 839 840 if (C->clinit_barrier_on_entry()) { 841 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 842 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 843 844 Label L_skip_barrier; 845 Register klass = rscratch1; 846 847 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 848 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 849 850 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 851 852 __ bind(L_skip_barrier); 853 } 854 855 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 856 857 C->output()->set_frame_complete(__ offset()); 858 859 if (C->has_mach_constant_base_node()) { 860 // NOTE: We set the table base offset here because users might be 861 // emitted before MachConstantBaseNode. 862 ConstantTable& constant_table = C->output()->constant_table(); 863 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 864 } 865 } 866 867 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 868 { 869 return MachNode::size(ra_); // too many variables; just compute it 870 // the hard way 871 } 872 873 int MachPrologNode::reloc() const 874 { 875 return 0; // a large enough number 876 } 877 878 //============================================================================= 879 #ifndef PRODUCT 880 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 881 { 882 Compile* C = ra_->C; 883 if (generate_vzeroupper(C)) { 884 st->print("vzeroupper"); 885 st->cr(); st->print("\t"); 886 } 887 888 int framesize = C->output()->frame_size_in_bytes(); 889 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 890 // Remove word for return adr already pushed 891 // and RBP 892 framesize -= 2*wordSize; 893 894 if (framesize) { 895 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 896 st->print("\t"); 897 } 898 899 st->print_cr("popq rbp"); 900 if (do_polling() && C->is_method_compilation()) { 901 st->print("\t"); 902 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 903 "ja #safepoint_stub\t" 904 "# Safepoint: poll for GC"); 905 } 906 } 907 #endif 908 909 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 910 { 911 Compile* C = ra_->C; 912 913 if (generate_vzeroupper(C)) { 914 // Clear upper bits of YMM registers when current compiled code uses 915 // wide vectors to avoid AVX <-> SSE transition penalty during call. 916 __ vzeroupper(); 917 } 918 919 int framesize = C->output()->frame_size_in_bytes(); 920 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 921 // Remove word for return adr already pushed 922 // and RBP 923 framesize -= 2*wordSize; 924 925 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 926 927 if (framesize) { 928 __ addq(rsp, framesize); 929 } 930 931 __ popq(rbp); 932 933 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 934 __ reserved_stack_check(); 935 } 936 937 if (do_polling() && C->is_method_compilation()) { 938 Label dummy_label; 939 Label* code_stub = &dummy_label; 940 if (!C->output()->in_scratch_emit_size()) { 941 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 942 C->output()->add_stub(stub); 943 code_stub = &stub->entry(); 944 } 945 __ relocate(relocInfo::poll_return_type); 946 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 947 } 948 } 949 950 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 951 { 952 return MachNode::size(ra_); // too many variables; just compute it 953 // the hard way 954 } 955 956 int MachEpilogNode::reloc() const 957 { 958 return 2; // a large enough number 959 } 960 961 const Pipeline* MachEpilogNode::pipeline() const 962 { 963 return MachNode::pipeline_class(); 964 } 965 966 //============================================================================= 967 968 enum RC { 969 rc_bad, 970 rc_int, 971 rc_kreg, 972 rc_float, 973 rc_stack 974 }; 975 976 static enum RC rc_class(OptoReg::Name reg) 977 { 978 if( !OptoReg::is_valid(reg) ) return rc_bad; 979 980 if (OptoReg::is_stack(reg)) return rc_stack; 981 982 VMReg r = OptoReg::as_VMReg(reg); 983 984 if (r->is_Register()) return rc_int; 985 986 if (r->is_KRegister()) return rc_kreg; 987 988 assert(r->is_XMMRegister(), "must be"); 989 return rc_float; 990 } 991 992 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 993 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 994 int src_hi, int dst_hi, uint ireg, outputStream* st); 995 996 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 997 int stack_offset, int reg, uint ireg, outputStream* st); 998 999 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 1000 int dst_offset, uint ireg, outputStream* st) { 1001 if (masm) { 1002 switch (ireg) { 1003 case Op_VecS: 1004 __ movq(Address(rsp, -8), rax); 1005 __ movl(rax, Address(rsp, src_offset)); 1006 __ movl(Address(rsp, dst_offset), rax); 1007 __ movq(rax, Address(rsp, -8)); 1008 break; 1009 case Op_VecD: 1010 __ pushq(Address(rsp, src_offset)); 1011 __ popq (Address(rsp, dst_offset)); 1012 break; 1013 case Op_VecX: 1014 __ pushq(Address(rsp, src_offset)); 1015 __ popq (Address(rsp, dst_offset)); 1016 __ pushq(Address(rsp, src_offset+8)); 1017 __ popq (Address(rsp, dst_offset+8)); 1018 break; 1019 case Op_VecY: 1020 __ vmovdqu(Address(rsp, -32), xmm0); 1021 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1022 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1023 __ vmovdqu(xmm0, Address(rsp, -32)); 1024 break; 1025 case Op_VecZ: 1026 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1027 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1028 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1029 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1030 break; 1031 default: 1032 ShouldNotReachHere(); 1033 } 1034 #ifndef PRODUCT 1035 } else { 1036 switch (ireg) { 1037 case Op_VecS: 1038 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1039 "movl rax, [rsp + #%d]\n\t" 1040 "movl [rsp + #%d], rax\n\t" 1041 "movq rax, [rsp - #8]", 1042 src_offset, dst_offset); 1043 break; 1044 case Op_VecD: 1045 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1046 "popq [rsp + #%d]", 1047 src_offset, dst_offset); 1048 break; 1049 case Op_VecX: 1050 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1051 "popq [rsp + #%d]\n\t" 1052 "pushq [rsp + #%d]\n\t" 1053 "popq [rsp + #%d]", 1054 src_offset, dst_offset, src_offset+8, dst_offset+8); 1055 break; 1056 case Op_VecY: 1057 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1058 "vmovdqu xmm0, [rsp + #%d]\n\t" 1059 "vmovdqu [rsp + #%d], xmm0\n\t" 1060 "vmovdqu xmm0, [rsp - #32]", 1061 src_offset, dst_offset); 1062 break; 1063 case Op_VecZ: 1064 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1065 "vmovdqu xmm0, [rsp + #%d]\n\t" 1066 "vmovdqu [rsp + #%d], xmm0\n\t" 1067 "vmovdqu xmm0, [rsp - #64]", 1068 src_offset, dst_offset); 1069 break; 1070 default: 1071 ShouldNotReachHere(); 1072 } 1073 #endif 1074 } 1075 } 1076 1077 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1078 PhaseRegAlloc* ra_, 1079 bool do_size, 1080 outputStream* st) const { 1081 assert(masm != nullptr || st != nullptr, "sanity"); 1082 // Get registers to move 1083 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1084 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1085 OptoReg::Name dst_second = ra_->get_reg_second(this); 1086 OptoReg::Name dst_first = ra_->get_reg_first(this); 1087 1088 enum RC src_second_rc = rc_class(src_second); 1089 enum RC src_first_rc = rc_class(src_first); 1090 enum RC dst_second_rc = rc_class(dst_second); 1091 enum RC dst_first_rc = rc_class(dst_first); 1092 1093 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1094 "must move at least 1 register" ); 1095 1096 if (src_first == dst_first && src_second == dst_second) { 1097 // Self copy, no move 1098 return 0; 1099 } 1100 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1101 uint ireg = ideal_reg(); 1102 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1103 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1104 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1105 // mem -> mem 1106 int src_offset = ra_->reg2offset(src_first); 1107 int dst_offset = ra_->reg2offset(dst_first); 1108 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1109 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1110 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1111 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1112 int stack_offset = ra_->reg2offset(dst_first); 1113 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1114 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1115 int stack_offset = ra_->reg2offset(src_first); 1116 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1117 } else { 1118 ShouldNotReachHere(); 1119 } 1120 return 0; 1121 } 1122 if (src_first_rc == rc_stack) { 1123 // mem -> 1124 if (dst_first_rc == rc_stack) { 1125 // mem -> mem 1126 assert(src_second != dst_first, "overlap"); 1127 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1128 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1129 // 64-bit 1130 int src_offset = ra_->reg2offset(src_first); 1131 int dst_offset = ra_->reg2offset(dst_first); 1132 if (masm) { 1133 __ pushq(Address(rsp, src_offset)); 1134 __ popq (Address(rsp, dst_offset)); 1135 #ifndef PRODUCT 1136 } else { 1137 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1138 "popq [rsp + #%d]", 1139 src_offset, dst_offset); 1140 #endif 1141 } 1142 } else { 1143 // 32-bit 1144 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1145 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1146 // No pushl/popl, so: 1147 int src_offset = ra_->reg2offset(src_first); 1148 int dst_offset = ra_->reg2offset(dst_first); 1149 if (masm) { 1150 __ movq(Address(rsp, -8), rax); 1151 __ movl(rax, Address(rsp, src_offset)); 1152 __ movl(Address(rsp, dst_offset), rax); 1153 __ movq(rax, Address(rsp, -8)); 1154 #ifndef PRODUCT 1155 } else { 1156 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1157 "movl rax, [rsp + #%d]\n\t" 1158 "movl [rsp + #%d], rax\n\t" 1159 "movq rax, [rsp - #8]", 1160 src_offset, dst_offset); 1161 #endif 1162 } 1163 } 1164 return 0; 1165 } else if (dst_first_rc == rc_int) { 1166 // mem -> gpr 1167 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1168 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1169 // 64-bit 1170 int offset = ra_->reg2offset(src_first); 1171 if (masm) { 1172 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1173 #ifndef PRODUCT 1174 } else { 1175 st->print("movq %s, [rsp + #%d]\t# spill", 1176 Matcher::regName[dst_first], 1177 offset); 1178 #endif 1179 } 1180 } else { 1181 // 32-bit 1182 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1183 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1184 int offset = ra_->reg2offset(src_first); 1185 if (masm) { 1186 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1187 #ifndef PRODUCT 1188 } else { 1189 st->print("movl %s, [rsp + #%d]\t# spill", 1190 Matcher::regName[dst_first], 1191 offset); 1192 #endif 1193 } 1194 } 1195 return 0; 1196 } else if (dst_first_rc == rc_float) { 1197 // mem-> xmm 1198 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1199 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1200 // 64-bit 1201 int offset = ra_->reg2offset(src_first); 1202 if (masm) { 1203 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1204 #ifndef PRODUCT 1205 } else { 1206 st->print("%s %s, [rsp + #%d]\t# spill", 1207 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1208 Matcher::regName[dst_first], 1209 offset); 1210 #endif 1211 } 1212 } else { 1213 // 32-bit 1214 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1215 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1216 int offset = ra_->reg2offset(src_first); 1217 if (masm) { 1218 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1219 #ifndef PRODUCT 1220 } else { 1221 st->print("movss %s, [rsp + #%d]\t# spill", 1222 Matcher::regName[dst_first], 1223 offset); 1224 #endif 1225 } 1226 } 1227 return 0; 1228 } else if (dst_first_rc == rc_kreg) { 1229 // mem -> kreg 1230 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1231 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1232 // 64-bit 1233 int offset = ra_->reg2offset(src_first); 1234 if (masm) { 1235 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1236 #ifndef PRODUCT 1237 } else { 1238 st->print("kmovq %s, [rsp + #%d]\t# spill", 1239 Matcher::regName[dst_first], 1240 offset); 1241 #endif 1242 } 1243 } 1244 return 0; 1245 } 1246 } else if (src_first_rc == rc_int) { 1247 // gpr -> 1248 if (dst_first_rc == rc_stack) { 1249 // gpr -> mem 1250 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1251 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1252 // 64-bit 1253 int offset = ra_->reg2offset(dst_first); 1254 if (masm) { 1255 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1256 #ifndef PRODUCT 1257 } else { 1258 st->print("movq [rsp + #%d], %s\t# spill", 1259 offset, 1260 Matcher::regName[src_first]); 1261 #endif 1262 } 1263 } else { 1264 // 32-bit 1265 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1266 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1267 int offset = ra_->reg2offset(dst_first); 1268 if (masm) { 1269 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1270 #ifndef PRODUCT 1271 } else { 1272 st->print("movl [rsp + #%d], %s\t# spill", 1273 offset, 1274 Matcher::regName[src_first]); 1275 #endif 1276 } 1277 } 1278 return 0; 1279 } else if (dst_first_rc == rc_int) { 1280 // gpr -> gpr 1281 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1282 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1283 // 64-bit 1284 if (masm) { 1285 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1286 as_Register(Matcher::_regEncode[src_first])); 1287 #ifndef PRODUCT 1288 } else { 1289 st->print("movq %s, %s\t# spill", 1290 Matcher::regName[dst_first], 1291 Matcher::regName[src_first]); 1292 #endif 1293 } 1294 return 0; 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 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1301 as_Register(Matcher::_regEncode[src_first])); 1302 #ifndef PRODUCT 1303 } else { 1304 st->print("movl %s, %s\t# spill", 1305 Matcher::regName[dst_first], 1306 Matcher::regName[src_first]); 1307 #endif 1308 } 1309 return 0; 1310 } 1311 } else if (dst_first_rc == rc_float) { 1312 // gpr -> xmm 1313 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1314 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1315 // 64-bit 1316 if (masm) { 1317 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1318 #ifndef PRODUCT 1319 } else { 1320 st->print("movdq %s, %s\t# spill", 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 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1331 #ifndef PRODUCT 1332 } else { 1333 st->print("movdl %s, %s\t# spill", 1334 Matcher::regName[dst_first], 1335 Matcher::regName[src_first]); 1336 #endif 1337 } 1338 } 1339 return 0; 1340 } else if (dst_first_rc == rc_kreg) { 1341 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1342 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1343 // 64-bit 1344 if (masm) { 1345 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1346 #ifndef PRODUCT 1347 } else { 1348 st->print("kmovq %s, %s\t# spill", 1349 Matcher::regName[dst_first], 1350 Matcher::regName[src_first]); 1351 #endif 1352 } 1353 } 1354 Unimplemented(); 1355 return 0; 1356 } 1357 } else if (src_first_rc == rc_float) { 1358 // xmm -> 1359 if (dst_first_rc == rc_stack) { 1360 // xmm -> mem 1361 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1362 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1363 // 64-bit 1364 int offset = ra_->reg2offset(dst_first); 1365 if (masm) { 1366 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1367 #ifndef PRODUCT 1368 } else { 1369 st->print("movsd [rsp + #%d], %s\t# spill", 1370 offset, 1371 Matcher::regName[src_first]); 1372 #endif 1373 } 1374 } else { 1375 // 32-bit 1376 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1377 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1378 int offset = ra_->reg2offset(dst_first); 1379 if (masm) { 1380 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1381 #ifndef PRODUCT 1382 } else { 1383 st->print("movss [rsp + #%d], %s\t# spill", 1384 offset, 1385 Matcher::regName[src_first]); 1386 #endif 1387 } 1388 } 1389 return 0; 1390 } else if (dst_first_rc == rc_int) { 1391 // xmm -> gpr 1392 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1393 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1394 // 64-bit 1395 if (masm) { 1396 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1397 #ifndef PRODUCT 1398 } else { 1399 st->print("movdq %s, %s\t# spill", 1400 Matcher::regName[dst_first], 1401 Matcher::regName[src_first]); 1402 #endif 1403 } 1404 } else { 1405 // 32-bit 1406 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1407 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1408 if (masm) { 1409 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1410 #ifndef PRODUCT 1411 } else { 1412 st->print("movdl %s, %s\t# spill", 1413 Matcher::regName[dst_first], 1414 Matcher::regName[src_first]); 1415 #endif 1416 } 1417 } 1418 return 0; 1419 } else if (dst_first_rc == rc_float) { 1420 // xmm -> xmm 1421 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1422 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1423 // 64-bit 1424 if (masm) { 1425 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1426 #ifndef PRODUCT 1427 } else { 1428 st->print("%s %s, %s\t# spill", 1429 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1430 Matcher::regName[dst_first], 1431 Matcher::regName[src_first]); 1432 #endif 1433 } 1434 } else { 1435 // 32-bit 1436 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1437 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1438 if (masm) { 1439 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1440 #ifndef PRODUCT 1441 } else { 1442 st->print("%s %s, %s\t# spill", 1443 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1444 Matcher::regName[dst_first], 1445 Matcher::regName[src_first]); 1446 #endif 1447 } 1448 } 1449 return 0; 1450 } else if (dst_first_rc == rc_kreg) { 1451 assert(false, "Illegal spilling"); 1452 return 0; 1453 } 1454 } else if (src_first_rc == rc_kreg) { 1455 if (dst_first_rc == rc_stack) { 1456 // mem -> kreg 1457 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1458 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1459 // 64-bit 1460 int offset = ra_->reg2offset(dst_first); 1461 if (masm) { 1462 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1463 #ifndef PRODUCT 1464 } else { 1465 st->print("kmovq [rsp + #%d] , %s\t# spill", 1466 offset, 1467 Matcher::regName[src_first]); 1468 #endif 1469 } 1470 } 1471 return 0; 1472 } else if (dst_first_rc == rc_int) { 1473 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1474 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1475 // 64-bit 1476 if (masm) { 1477 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1478 #ifndef PRODUCT 1479 } else { 1480 st->print("kmovq %s, %s\t# spill", 1481 Matcher::regName[dst_first], 1482 Matcher::regName[src_first]); 1483 #endif 1484 } 1485 } 1486 Unimplemented(); 1487 return 0; 1488 } else if (dst_first_rc == rc_kreg) { 1489 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1490 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1491 // 64-bit 1492 if (masm) { 1493 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1494 #ifndef PRODUCT 1495 } else { 1496 st->print("kmovq %s, %s\t# spill", 1497 Matcher::regName[dst_first], 1498 Matcher::regName[src_first]); 1499 #endif 1500 } 1501 } 1502 return 0; 1503 } else if (dst_first_rc == rc_float) { 1504 assert(false, "Illegal spill"); 1505 return 0; 1506 } 1507 } 1508 1509 assert(0," foo "); 1510 Unimplemented(); 1511 return 0; 1512 } 1513 1514 #ifndef PRODUCT 1515 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1516 implementation(nullptr, ra_, false, st); 1517 } 1518 #endif 1519 1520 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1521 implementation(masm, ra_, false, nullptr); 1522 } 1523 1524 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1525 return MachNode::size(ra_); 1526 } 1527 1528 //============================================================================= 1529 #ifndef PRODUCT 1530 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1531 { 1532 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1533 int reg = ra_->get_reg_first(this); 1534 st->print("leaq %s, [rsp + #%d]\t# box lock", 1535 Matcher::regName[reg], offset); 1536 } 1537 #endif 1538 1539 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1540 { 1541 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1542 int reg = ra_->get_encode(this); 1543 1544 __ lea(as_Register(reg), Address(rsp, offset)); 1545 } 1546 1547 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1548 { 1549 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1550 return (offset < 0x80) ? 5 : 8; // REX 1551 } 1552 1553 //============================================================================= 1554 #ifndef PRODUCT 1555 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1556 { 1557 if (UseCompressedClassPointers) { 1558 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1559 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1560 } else { 1561 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1562 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1563 } 1564 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1565 } 1566 #endif 1567 1568 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1569 { 1570 __ ic_check(InteriorEntryAlignment); 1571 } 1572 1573 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1574 { 1575 return MachNode::size(ra_); // too many variables; just compute it 1576 // the hard way 1577 } 1578 1579 1580 //============================================================================= 1581 1582 bool Matcher::supports_vector_calling_convention(void) { 1583 if (EnableVectorSupport && UseVectorStubs) { 1584 return true; 1585 } 1586 return false; 1587 } 1588 1589 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1590 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1591 int lo = XMM0_num; 1592 int hi = XMM0b_num; 1593 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1594 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1595 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1596 return OptoRegPair(hi, lo); 1597 } 1598 1599 // Is this branch offset short enough that a short branch can be used? 1600 // 1601 // NOTE: If the platform does not provide any short branch variants, then 1602 // this method should return false for offset 0. 1603 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1604 // The passed offset is relative to address of the branch. 1605 // On 86 a branch displacement is calculated relative to address 1606 // of a next instruction. 1607 offset -= br_size; 1608 1609 // the short version of jmpConUCF2 contains multiple branches, 1610 // making the reach slightly less 1611 if (rule == jmpConUCF2_rule) 1612 return (-126 <= offset && offset <= 125); 1613 return (-128 <= offset && offset <= 127); 1614 } 1615 1616 // Return whether or not this register is ever used as an argument. 1617 // This function is used on startup to build the trampoline stubs in 1618 // generateOptoStub. Registers not mentioned will be killed by the VM 1619 // call in the trampoline, and arguments in those registers not be 1620 // available to the callee. 1621 bool Matcher::can_be_java_arg(int reg) 1622 { 1623 return 1624 reg == RDI_num || reg == RDI_H_num || 1625 reg == RSI_num || reg == RSI_H_num || 1626 reg == RDX_num || reg == RDX_H_num || 1627 reg == RCX_num || reg == RCX_H_num || 1628 reg == R8_num || reg == R8_H_num || 1629 reg == R9_num || reg == R9_H_num || 1630 reg == R12_num || reg == R12_H_num || 1631 reg == XMM0_num || reg == XMM0b_num || 1632 reg == XMM1_num || reg == XMM1b_num || 1633 reg == XMM2_num || reg == XMM2b_num || 1634 reg == XMM3_num || reg == XMM3b_num || 1635 reg == XMM4_num || reg == XMM4b_num || 1636 reg == XMM5_num || reg == XMM5b_num || 1637 reg == XMM6_num || reg == XMM6b_num || 1638 reg == XMM7_num || reg == XMM7b_num; 1639 } 1640 1641 bool Matcher::is_spillable_arg(int reg) 1642 { 1643 return can_be_java_arg(reg); 1644 } 1645 1646 uint Matcher::int_pressure_limit() 1647 { 1648 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1649 } 1650 1651 uint Matcher::float_pressure_limit() 1652 { 1653 // After experiment around with different values, the following default threshold 1654 // works best for LCM's register pressure scheduling on x64. 1655 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1656 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1657 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1658 } 1659 1660 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1661 // In 64 bit mode a code which use multiply when 1662 // devisor is constant is faster than hardware 1663 // DIV instruction (it uses MulHiL). 1664 return false; 1665 } 1666 1667 // Register for DIVI projection of divmodI 1668 RegMask Matcher::divI_proj_mask() { 1669 return INT_RAX_REG_mask(); 1670 } 1671 1672 // Register for MODI projection of divmodI 1673 RegMask Matcher::modI_proj_mask() { 1674 return INT_RDX_REG_mask(); 1675 } 1676 1677 // Register for DIVL projection of divmodL 1678 RegMask Matcher::divL_proj_mask() { 1679 return LONG_RAX_REG_mask(); 1680 } 1681 1682 // Register for MODL projection of divmodL 1683 RegMask Matcher::modL_proj_mask() { 1684 return LONG_RDX_REG_mask(); 1685 } 1686 1687 // Register for saving SP into on method handle invokes. Not used on x86_64. 1688 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1689 return NO_REG_mask(); 1690 } 1691 1692 %} 1693 1694 //----------ENCODING BLOCK----------------------------------------------------- 1695 // This block specifies the encoding classes used by the compiler to 1696 // output byte streams. Encoding classes are parameterized macros 1697 // used by Machine Instruction Nodes in order to generate the bit 1698 // encoding of the instruction. Operands specify their base encoding 1699 // interface with the interface keyword. There are currently 1700 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1701 // COND_INTER. REG_INTER causes an operand to generate a function 1702 // which returns its register number when queried. CONST_INTER causes 1703 // an operand to generate a function which returns the value of the 1704 // constant when queried. MEMORY_INTER causes an operand to generate 1705 // four functions which return the Base Register, the Index Register, 1706 // the Scale Value, and the Offset Value of the operand when queried. 1707 // COND_INTER causes an operand to generate six functions which return 1708 // the encoding code (ie - encoding bits for the instruction) 1709 // associated with each basic boolean condition for a conditional 1710 // instruction. 1711 // 1712 // Instructions specify two basic values for encoding. Again, a 1713 // function is available to check if the constant displacement is an 1714 // oop. They use the ins_encode keyword to specify their encoding 1715 // classes (which must be a sequence of enc_class names, and their 1716 // parameters, specified in the encoding block), and they use the 1717 // opcode keyword to specify, in order, their primary, secondary, and 1718 // tertiary opcode. Only the opcode sections which a particular 1719 // instruction needs for encoding need to be specified. 1720 encode %{ 1721 enc_class cdql_enc(no_rax_rdx_RegI div) 1722 %{ 1723 // Full implementation of Java idiv and irem; checks for 1724 // special case as described in JVM spec., p.243 & p.271. 1725 // 1726 // normal case special case 1727 // 1728 // input : rax: dividend min_int 1729 // reg: divisor -1 1730 // 1731 // output: rax: quotient (= rax idiv reg) min_int 1732 // rdx: remainder (= rax irem reg) 0 1733 // 1734 // Code sequnce: 1735 // 1736 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1737 // 5: 75 07/08 jne e <normal> 1738 // 7: 33 d2 xor %edx,%edx 1739 // [div >= 8 -> offset + 1] 1740 // [REX_B] 1741 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1742 // c: 74 03/04 je 11 <done> 1743 // 000000000000000e <normal>: 1744 // e: 99 cltd 1745 // [div >= 8 -> offset + 1] 1746 // [REX_B] 1747 // f: f7 f9 idiv $div 1748 // 0000000000000011 <done>: 1749 Label normal; 1750 Label done; 1751 1752 // cmp $0x80000000,%eax 1753 __ cmpl(as_Register(RAX_enc), 0x80000000); 1754 1755 // jne e <normal> 1756 __ jccb(Assembler::notEqual, normal); 1757 1758 // xor %edx,%edx 1759 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1760 1761 // cmp $0xffffffffffffffff,%ecx 1762 __ cmpl($div$$Register, -1); 1763 1764 // je 11 <done> 1765 __ jccb(Assembler::equal, done); 1766 1767 // <normal> 1768 // cltd 1769 __ bind(normal); 1770 __ cdql(); 1771 1772 // idivl 1773 // <done> 1774 __ idivl($div$$Register); 1775 __ bind(done); 1776 %} 1777 1778 enc_class cdqq_enc(no_rax_rdx_RegL div) 1779 %{ 1780 // Full implementation of Java ldiv and lrem; checks for 1781 // special case as described in JVM spec., p.243 & p.271. 1782 // 1783 // normal case special case 1784 // 1785 // input : rax: dividend min_long 1786 // reg: divisor -1 1787 // 1788 // output: rax: quotient (= rax idiv reg) min_long 1789 // rdx: remainder (= rax irem reg) 0 1790 // 1791 // Code sequnce: 1792 // 1793 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1794 // 7: 00 00 80 1795 // a: 48 39 d0 cmp %rdx,%rax 1796 // d: 75 08 jne 17 <normal> 1797 // f: 33 d2 xor %edx,%edx 1798 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1799 // 15: 74 05 je 1c <done> 1800 // 0000000000000017 <normal>: 1801 // 17: 48 99 cqto 1802 // 19: 48 f7 f9 idiv $div 1803 // 000000000000001c <done>: 1804 Label normal; 1805 Label done; 1806 1807 // mov $0x8000000000000000,%rdx 1808 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1809 1810 // cmp %rdx,%rax 1811 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1812 1813 // jne 17 <normal> 1814 __ jccb(Assembler::notEqual, normal); 1815 1816 // xor %edx,%edx 1817 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1818 1819 // cmp $0xffffffffffffffff,$div 1820 __ cmpq($div$$Register, -1); 1821 1822 // je 1e <done> 1823 __ jccb(Assembler::equal, done); 1824 1825 // <normal> 1826 // cqto 1827 __ bind(normal); 1828 __ cdqq(); 1829 1830 // idivq (note: must be emitted by the user of this rule) 1831 // <done> 1832 __ idivq($div$$Register); 1833 __ bind(done); 1834 %} 1835 1836 enc_class clear_avx %{ 1837 debug_only(int off0 = __ offset()); 1838 if (generate_vzeroupper(Compile::current())) { 1839 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1840 // Clear upper bits of YMM registers when current compiled code uses 1841 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1842 __ vzeroupper(); 1843 } 1844 debug_only(int off1 = __ offset()); 1845 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1846 %} 1847 1848 enc_class Java_To_Runtime(method meth) %{ 1849 // No relocation needed 1850 __ mov64(r10, (int64_t) $meth$$method); 1851 __ call(r10); 1852 __ post_call_nop(); 1853 %} 1854 1855 enc_class Java_Static_Call(method meth) 1856 %{ 1857 // JAVA STATIC CALL 1858 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1859 // determine who we intended to call. 1860 if (!_method) { 1861 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1862 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1863 // The NOP here is purely to ensure that eliding a call to 1864 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1865 __ addr_nop_5(); 1866 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1867 } else { 1868 int method_index = resolved_method_index(masm); 1869 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1870 : static_call_Relocation::spec(method_index); 1871 address mark = __ pc(); 1872 int call_offset = __ offset(); 1873 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1874 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1875 // Calls of the same statically bound method can share 1876 // a stub to the interpreter. 1877 __ code()->shared_stub_to_interp_for(_method, call_offset); 1878 } else { 1879 // Emit stubs for static call. 1880 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1881 __ clear_inst_mark(); 1882 if (stub == nullptr) { 1883 ciEnv::current()->record_failure("CodeCache is full"); 1884 return; 1885 } 1886 } 1887 } 1888 __ post_call_nop(); 1889 %} 1890 1891 enc_class Java_Dynamic_Call(method meth) %{ 1892 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1893 __ post_call_nop(); 1894 %} 1895 1896 %} 1897 1898 1899 1900 //----------FRAME-------------------------------------------------------------- 1901 // Definition of frame structure and management information. 1902 // 1903 // S T A C K L A Y O U T Allocators stack-slot number 1904 // | (to get allocators register number 1905 // G Owned by | | v add OptoReg::stack0()) 1906 // r CALLER | | 1907 // o | +--------+ pad to even-align allocators stack-slot 1908 // w V | pad0 | numbers; owned by CALLER 1909 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1910 // h ^ | in | 5 1911 // | | args | 4 Holes in incoming args owned by SELF 1912 // | | | | 3 1913 // | | +--------+ 1914 // V | | old out| Empty on Intel, window on Sparc 1915 // | old |preserve| Must be even aligned. 1916 // | SP-+--------+----> Matcher::_old_SP, even aligned 1917 // | | in | 3 area for Intel ret address 1918 // Owned by |preserve| Empty on Sparc. 1919 // SELF +--------+ 1920 // | | pad2 | 2 pad to align old SP 1921 // | +--------+ 1 1922 // | | locks | 0 1923 // | +--------+----> OptoReg::stack0(), even aligned 1924 // | | pad1 | 11 pad to align new SP 1925 // | +--------+ 1926 // | | | 10 1927 // | | spills | 9 spills 1928 // V | | 8 (pad0 slot for callee) 1929 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1930 // ^ | out | 7 1931 // | | args | 6 Holes in outgoing args owned by CALLEE 1932 // Owned by +--------+ 1933 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1934 // | new |preserve| Must be even-aligned. 1935 // | SP-+--------+----> Matcher::_new_SP, even aligned 1936 // | | | 1937 // 1938 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1939 // known from SELF's arguments and the Java calling convention. 1940 // Region 6-7 is determined per call site. 1941 // Note 2: If the calling convention leaves holes in the incoming argument 1942 // area, those holes are owned by SELF. Holes in the outgoing area 1943 // are owned by the CALLEE. Holes should not be necessary in the 1944 // incoming area, as the Java calling convention is completely under 1945 // the control of the AD file. Doubles can be sorted and packed to 1946 // avoid holes. Holes in the outgoing arguments may be necessary for 1947 // varargs C calling conventions. 1948 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1949 // even aligned with pad0 as needed. 1950 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1951 // region 6-11 is even aligned; it may be padded out more so that 1952 // the region from SP to FP meets the minimum stack alignment. 1953 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1954 // alignment. Region 11, pad1, may be dynamically extended so that 1955 // SP meets the minimum alignment. 1956 1957 frame 1958 %{ 1959 // These three registers define part of the calling convention 1960 // between compiled code and the interpreter. 1961 inline_cache_reg(RAX); // Inline Cache Register 1962 1963 // Optional: name the operand used by cisc-spilling to access 1964 // [stack_pointer + offset] 1965 cisc_spilling_operand_name(indOffset32); 1966 1967 // Number of stack slots consumed by locking an object 1968 sync_stack_slots(2); 1969 1970 // Compiled code's Frame Pointer 1971 frame_pointer(RSP); 1972 1973 // Interpreter stores its frame pointer in a register which is 1974 // stored to the stack by I2CAdaptors. 1975 // I2CAdaptors convert from interpreted java to compiled java. 1976 interpreter_frame_pointer(RBP); 1977 1978 // Stack alignment requirement 1979 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1980 1981 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1982 // for calls to C. Supports the var-args backing area for register parms. 1983 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1984 1985 // The after-PROLOG location of the return address. Location of 1986 // return address specifies a type (REG or STACK) and a number 1987 // representing the register number (i.e. - use a register name) or 1988 // stack slot. 1989 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 1990 // Otherwise, it is above the locks and verification slot and alignment word 1991 return_addr(STACK - 2 + 1992 align_up((Compile::current()->in_preserve_stack_slots() + 1993 Compile::current()->fixed_slots()), 1994 stack_alignment_in_slots())); 1995 1996 // Location of compiled Java return values. Same as C for now. 1997 return_value 1998 %{ 1999 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2000 "only return normal values"); 2001 2002 static const int lo[Op_RegL + 1] = { 2003 0, 2004 0, 2005 RAX_num, // Op_RegN 2006 RAX_num, // Op_RegI 2007 RAX_num, // Op_RegP 2008 XMM0_num, // Op_RegF 2009 XMM0_num, // Op_RegD 2010 RAX_num // Op_RegL 2011 }; 2012 static const int hi[Op_RegL + 1] = { 2013 0, 2014 0, 2015 OptoReg::Bad, // Op_RegN 2016 OptoReg::Bad, // Op_RegI 2017 RAX_H_num, // Op_RegP 2018 OptoReg::Bad, // Op_RegF 2019 XMM0b_num, // Op_RegD 2020 RAX_H_num // Op_RegL 2021 }; 2022 // Excluded flags and vector registers. 2023 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2024 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2025 %} 2026 %} 2027 2028 //----------ATTRIBUTES--------------------------------------------------------- 2029 //----------Operand Attributes------------------------------------------------- 2030 op_attrib op_cost(0); // Required cost attribute 2031 2032 //----------Instruction Attributes--------------------------------------------- 2033 ins_attrib ins_cost(100); // Required cost attribute 2034 ins_attrib ins_size(8); // Required size attribute (in bits) 2035 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2036 // a non-matching short branch variant 2037 // of some long branch? 2038 ins_attrib ins_alignment(1); // Required alignment attribute (must 2039 // be a power of 2) specifies the 2040 // alignment that some part of the 2041 // instruction (not necessarily the 2042 // start) requires. If > 1, a 2043 // compute_padding() function must be 2044 // provided for the instruction 2045 2046 //----------OPERANDS----------------------------------------------------------- 2047 // Operand definitions must precede instruction definitions for correct parsing 2048 // in the ADLC because operands constitute user defined types which are used in 2049 // instruction definitions. 2050 2051 //----------Simple Operands---------------------------------------------------- 2052 // Immediate Operands 2053 // Integer Immediate 2054 operand immI() 2055 %{ 2056 match(ConI); 2057 2058 op_cost(10); 2059 format %{ %} 2060 interface(CONST_INTER); 2061 %} 2062 2063 // Constant for test vs zero 2064 operand immI_0() 2065 %{ 2066 predicate(n->get_int() == 0); 2067 match(ConI); 2068 2069 op_cost(0); 2070 format %{ %} 2071 interface(CONST_INTER); 2072 %} 2073 2074 // Constant for increment 2075 operand immI_1() 2076 %{ 2077 predicate(n->get_int() == 1); 2078 match(ConI); 2079 2080 op_cost(0); 2081 format %{ %} 2082 interface(CONST_INTER); 2083 %} 2084 2085 // Constant for decrement 2086 operand immI_M1() 2087 %{ 2088 predicate(n->get_int() == -1); 2089 match(ConI); 2090 2091 op_cost(0); 2092 format %{ %} 2093 interface(CONST_INTER); 2094 %} 2095 2096 operand immI_2() 2097 %{ 2098 predicate(n->get_int() == 2); 2099 match(ConI); 2100 2101 op_cost(0); 2102 format %{ %} 2103 interface(CONST_INTER); 2104 %} 2105 2106 operand immI_4() 2107 %{ 2108 predicate(n->get_int() == 4); 2109 match(ConI); 2110 2111 op_cost(0); 2112 format %{ %} 2113 interface(CONST_INTER); 2114 %} 2115 2116 operand immI_8() 2117 %{ 2118 predicate(n->get_int() == 8); 2119 match(ConI); 2120 2121 op_cost(0); 2122 format %{ %} 2123 interface(CONST_INTER); 2124 %} 2125 2126 // Valid scale values for addressing modes 2127 operand immI2() 2128 %{ 2129 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2130 match(ConI); 2131 2132 format %{ %} 2133 interface(CONST_INTER); 2134 %} 2135 2136 operand immU7() 2137 %{ 2138 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2139 match(ConI); 2140 2141 op_cost(5); 2142 format %{ %} 2143 interface(CONST_INTER); 2144 %} 2145 2146 operand immI8() 2147 %{ 2148 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2149 match(ConI); 2150 2151 op_cost(5); 2152 format %{ %} 2153 interface(CONST_INTER); 2154 %} 2155 2156 operand immU8() 2157 %{ 2158 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2159 match(ConI); 2160 2161 op_cost(5); 2162 format %{ %} 2163 interface(CONST_INTER); 2164 %} 2165 2166 operand immI16() 2167 %{ 2168 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2169 match(ConI); 2170 2171 op_cost(10); 2172 format %{ %} 2173 interface(CONST_INTER); 2174 %} 2175 2176 // Int Immediate non-negative 2177 operand immU31() 2178 %{ 2179 predicate(n->get_int() >= 0); 2180 match(ConI); 2181 2182 op_cost(0); 2183 format %{ %} 2184 interface(CONST_INTER); 2185 %} 2186 2187 // Pointer Immediate 2188 operand immP() 2189 %{ 2190 match(ConP); 2191 2192 op_cost(10); 2193 format %{ %} 2194 interface(CONST_INTER); 2195 %} 2196 2197 // Null Pointer Immediate 2198 operand immP0() 2199 %{ 2200 predicate(n->get_ptr() == 0); 2201 match(ConP); 2202 2203 op_cost(5); 2204 format %{ %} 2205 interface(CONST_INTER); 2206 %} 2207 2208 // Pointer Immediate 2209 operand immN() %{ 2210 match(ConN); 2211 2212 op_cost(10); 2213 format %{ %} 2214 interface(CONST_INTER); 2215 %} 2216 2217 operand immNKlass() %{ 2218 match(ConNKlass); 2219 2220 op_cost(10); 2221 format %{ %} 2222 interface(CONST_INTER); 2223 %} 2224 2225 // Null Pointer Immediate 2226 operand immN0() %{ 2227 predicate(n->get_narrowcon() == 0); 2228 match(ConN); 2229 2230 op_cost(5); 2231 format %{ %} 2232 interface(CONST_INTER); 2233 %} 2234 2235 operand immP31() 2236 %{ 2237 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2238 && (n->get_ptr() >> 31) == 0); 2239 match(ConP); 2240 2241 op_cost(5); 2242 format %{ %} 2243 interface(CONST_INTER); 2244 %} 2245 2246 2247 // Long Immediate 2248 operand immL() 2249 %{ 2250 match(ConL); 2251 2252 op_cost(20); 2253 format %{ %} 2254 interface(CONST_INTER); 2255 %} 2256 2257 // Long Immediate 8-bit 2258 operand immL8() 2259 %{ 2260 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2261 match(ConL); 2262 2263 op_cost(5); 2264 format %{ %} 2265 interface(CONST_INTER); 2266 %} 2267 2268 // Long Immediate 32-bit unsigned 2269 operand immUL32() 2270 %{ 2271 predicate(n->get_long() == (unsigned int) (n->get_long())); 2272 match(ConL); 2273 2274 op_cost(10); 2275 format %{ %} 2276 interface(CONST_INTER); 2277 %} 2278 2279 // Long Immediate 32-bit signed 2280 operand immL32() 2281 %{ 2282 predicate(n->get_long() == (int) (n->get_long())); 2283 match(ConL); 2284 2285 op_cost(15); 2286 format %{ %} 2287 interface(CONST_INTER); 2288 %} 2289 2290 operand immL_Pow2() 2291 %{ 2292 predicate(is_power_of_2((julong)n->get_long())); 2293 match(ConL); 2294 2295 op_cost(15); 2296 format %{ %} 2297 interface(CONST_INTER); 2298 %} 2299 2300 operand immL_NotPow2() 2301 %{ 2302 predicate(is_power_of_2((julong)~n->get_long())); 2303 match(ConL); 2304 2305 op_cost(15); 2306 format %{ %} 2307 interface(CONST_INTER); 2308 %} 2309 2310 // Long Immediate zero 2311 operand immL0() 2312 %{ 2313 predicate(n->get_long() == 0L); 2314 match(ConL); 2315 2316 op_cost(10); 2317 format %{ %} 2318 interface(CONST_INTER); 2319 %} 2320 2321 // Constant for increment 2322 operand immL1() 2323 %{ 2324 predicate(n->get_long() == 1); 2325 match(ConL); 2326 2327 format %{ %} 2328 interface(CONST_INTER); 2329 %} 2330 2331 // Constant for decrement 2332 operand immL_M1() 2333 %{ 2334 predicate(n->get_long() == -1); 2335 match(ConL); 2336 2337 format %{ %} 2338 interface(CONST_INTER); 2339 %} 2340 2341 // Long Immediate: low 32-bit mask 2342 operand immL_32bits() 2343 %{ 2344 predicate(n->get_long() == 0xFFFFFFFFL); 2345 match(ConL); 2346 op_cost(20); 2347 2348 format %{ %} 2349 interface(CONST_INTER); 2350 %} 2351 2352 // Int Immediate: 2^n-1, positive 2353 operand immI_Pow2M1() 2354 %{ 2355 predicate((n->get_int() > 0) 2356 && is_power_of_2((juint)n->get_int() + 1)); 2357 match(ConI); 2358 2359 op_cost(20); 2360 format %{ %} 2361 interface(CONST_INTER); 2362 %} 2363 2364 // Float Immediate zero 2365 operand immF0() 2366 %{ 2367 predicate(jint_cast(n->getf()) == 0); 2368 match(ConF); 2369 2370 op_cost(5); 2371 format %{ %} 2372 interface(CONST_INTER); 2373 %} 2374 2375 // Float Immediate 2376 operand immF() 2377 %{ 2378 match(ConF); 2379 2380 op_cost(15); 2381 format %{ %} 2382 interface(CONST_INTER); 2383 %} 2384 2385 // Double Immediate zero 2386 operand immD0() 2387 %{ 2388 predicate(jlong_cast(n->getd()) == 0); 2389 match(ConD); 2390 2391 op_cost(5); 2392 format %{ %} 2393 interface(CONST_INTER); 2394 %} 2395 2396 // Double Immediate 2397 operand immD() 2398 %{ 2399 match(ConD); 2400 2401 op_cost(15); 2402 format %{ %} 2403 interface(CONST_INTER); 2404 %} 2405 2406 // Immediates for special shifts (sign extend) 2407 2408 // Constants for increment 2409 operand immI_16() 2410 %{ 2411 predicate(n->get_int() == 16); 2412 match(ConI); 2413 2414 format %{ %} 2415 interface(CONST_INTER); 2416 %} 2417 2418 operand immI_24() 2419 %{ 2420 predicate(n->get_int() == 24); 2421 match(ConI); 2422 2423 format %{ %} 2424 interface(CONST_INTER); 2425 %} 2426 2427 // Constant for byte-wide masking 2428 operand immI_255() 2429 %{ 2430 predicate(n->get_int() == 255); 2431 match(ConI); 2432 2433 format %{ %} 2434 interface(CONST_INTER); 2435 %} 2436 2437 // Constant for short-wide masking 2438 operand immI_65535() 2439 %{ 2440 predicate(n->get_int() == 65535); 2441 match(ConI); 2442 2443 format %{ %} 2444 interface(CONST_INTER); 2445 %} 2446 2447 // Constant for byte-wide masking 2448 operand immL_255() 2449 %{ 2450 predicate(n->get_long() == 255); 2451 match(ConL); 2452 2453 format %{ %} 2454 interface(CONST_INTER); 2455 %} 2456 2457 // Constant for short-wide masking 2458 operand immL_65535() 2459 %{ 2460 predicate(n->get_long() == 65535); 2461 match(ConL); 2462 2463 format %{ %} 2464 interface(CONST_INTER); 2465 %} 2466 2467 operand kReg() 2468 %{ 2469 constraint(ALLOC_IN_RC(vectmask_reg)); 2470 match(RegVectMask); 2471 format %{%} 2472 interface(REG_INTER); 2473 %} 2474 2475 // Register Operands 2476 // Integer Register 2477 operand rRegI() 2478 %{ 2479 constraint(ALLOC_IN_RC(int_reg)); 2480 match(RegI); 2481 2482 match(rax_RegI); 2483 match(rbx_RegI); 2484 match(rcx_RegI); 2485 match(rdx_RegI); 2486 match(rdi_RegI); 2487 2488 format %{ %} 2489 interface(REG_INTER); 2490 %} 2491 2492 // Special Registers 2493 operand rax_RegI() 2494 %{ 2495 constraint(ALLOC_IN_RC(int_rax_reg)); 2496 match(RegI); 2497 match(rRegI); 2498 2499 format %{ "RAX" %} 2500 interface(REG_INTER); 2501 %} 2502 2503 // Special Registers 2504 operand rbx_RegI() 2505 %{ 2506 constraint(ALLOC_IN_RC(int_rbx_reg)); 2507 match(RegI); 2508 match(rRegI); 2509 2510 format %{ "RBX" %} 2511 interface(REG_INTER); 2512 %} 2513 2514 operand rcx_RegI() 2515 %{ 2516 constraint(ALLOC_IN_RC(int_rcx_reg)); 2517 match(RegI); 2518 match(rRegI); 2519 2520 format %{ "RCX" %} 2521 interface(REG_INTER); 2522 %} 2523 2524 operand rdx_RegI() 2525 %{ 2526 constraint(ALLOC_IN_RC(int_rdx_reg)); 2527 match(RegI); 2528 match(rRegI); 2529 2530 format %{ "RDX" %} 2531 interface(REG_INTER); 2532 %} 2533 2534 operand rdi_RegI() 2535 %{ 2536 constraint(ALLOC_IN_RC(int_rdi_reg)); 2537 match(RegI); 2538 match(rRegI); 2539 2540 format %{ "RDI" %} 2541 interface(REG_INTER); 2542 %} 2543 2544 operand no_rax_rdx_RegI() 2545 %{ 2546 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2547 match(RegI); 2548 match(rbx_RegI); 2549 match(rcx_RegI); 2550 match(rdi_RegI); 2551 2552 format %{ %} 2553 interface(REG_INTER); 2554 %} 2555 2556 operand no_rbp_r13_RegI() 2557 %{ 2558 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2559 match(RegI); 2560 match(rRegI); 2561 match(rax_RegI); 2562 match(rbx_RegI); 2563 match(rcx_RegI); 2564 match(rdx_RegI); 2565 match(rdi_RegI); 2566 2567 format %{ %} 2568 interface(REG_INTER); 2569 %} 2570 2571 // Pointer Register 2572 operand any_RegP() 2573 %{ 2574 constraint(ALLOC_IN_RC(any_reg)); 2575 match(RegP); 2576 match(rax_RegP); 2577 match(rbx_RegP); 2578 match(rdi_RegP); 2579 match(rsi_RegP); 2580 match(rbp_RegP); 2581 match(r15_RegP); 2582 match(rRegP); 2583 2584 format %{ %} 2585 interface(REG_INTER); 2586 %} 2587 2588 operand rRegP() 2589 %{ 2590 constraint(ALLOC_IN_RC(ptr_reg)); 2591 match(RegP); 2592 match(rax_RegP); 2593 match(rbx_RegP); 2594 match(rdi_RegP); 2595 match(rsi_RegP); 2596 match(rbp_RegP); // See Q&A below about 2597 match(r15_RegP); // r15_RegP and rbp_RegP. 2598 2599 format %{ %} 2600 interface(REG_INTER); 2601 %} 2602 2603 operand rRegN() %{ 2604 constraint(ALLOC_IN_RC(int_reg)); 2605 match(RegN); 2606 2607 format %{ %} 2608 interface(REG_INTER); 2609 %} 2610 2611 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2612 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2613 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2614 // The output of an instruction is controlled by the allocator, which respects 2615 // register class masks, not match rules. Unless an instruction mentions 2616 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2617 // by the allocator as an input. 2618 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2619 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2620 // result, RBP is not included in the output of the instruction either. 2621 2622 // This operand is not allowed to use RBP even if 2623 // RBP is not used to hold the frame pointer. 2624 operand no_rbp_RegP() 2625 %{ 2626 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2627 match(RegP); 2628 match(rbx_RegP); 2629 match(rsi_RegP); 2630 match(rdi_RegP); 2631 2632 format %{ %} 2633 interface(REG_INTER); 2634 %} 2635 2636 // Special Registers 2637 // Return a pointer value 2638 operand rax_RegP() 2639 %{ 2640 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2641 match(RegP); 2642 match(rRegP); 2643 2644 format %{ %} 2645 interface(REG_INTER); 2646 %} 2647 2648 // Special Registers 2649 // Return a compressed pointer value 2650 operand rax_RegN() 2651 %{ 2652 constraint(ALLOC_IN_RC(int_rax_reg)); 2653 match(RegN); 2654 match(rRegN); 2655 2656 format %{ %} 2657 interface(REG_INTER); 2658 %} 2659 2660 // Used in AtomicAdd 2661 operand rbx_RegP() 2662 %{ 2663 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2664 match(RegP); 2665 match(rRegP); 2666 2667 format %{ %} 2668 interface(REG_INTER); 2669 %} 2670 2671 operand rsi_RegP() 2672 %{ 2673 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2674 match(RegP); 2675 match(rRegP); 2676 2677 format %{ %} 2678 interface(REG_INTER); 2679 %} 2680 2681 operand rbp_RegP() 2682 %{ 2683 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2684 match(RegP); 2685 match(rRegP); 2686 2687 format %{ %} 2688 interface(REG_INTER); 2689 %} 2690 2691 // Used in rep stosq 2692 operand rdi_RegP() 2693 %{ 2694 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2695 match(RegP); 2696 match(rRegP); 2697 2698 format %{ %} 2699 interface(REG_INTER); 2700 %} 2701 2702 operand r15_RegP() 2703 %{ 2704 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2705 match(RegP); 2706 match(rRegP); 2707 2708 format %{ %} 2709 interface(REG_INTER); 2710 %} 2711 2712 operand rRegL() 2713 %{ 2714 constraint(ALLOC_IN_RC(long_reg)); 2715 match(RegL); 2716 match(rax_RegL); 2717 match(rdx_RegL); 2718 2719 format %{ %} 2720 interface(REG_INTER); 2721 %} 2722 2723 // Special Registers 2724 operand no_rax_rdx_RegL() 2725 %{ 2726 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2727 match(RegL); 2728 match(rRegL); 2729 2730 format %{ %} 2731 interface(REG_INTER); 2732 %} 2733 2734 operand rax_RegL() 2735 %{ 2736 constraint(ALLOC_IN_RC(long_rax_reg)); 2737 match(RegL); 2738 match(rRegL); 2739 2740 format %{ "RAX" %} 2741 interface(REG_INTER); 2742 %} 2743 2744 operand rcx_RegL() 2745 %{ 2746 constraint(ALLOC_IN_RC(long_rcx_reg)); 2747 match(RegL); 2748 match(rRegL); 2749 2750 format %{ %} 2751 interface(REG_INTER); 2752 %} 2753 2754 operand rdx_RegL() 2755 %{ 2756 constraint(ALLOC_IN_RC(long_rdx_reg)); 2757 match(RegL); 2758 match(rRegL); 2759 2760 format %{ %} 2761 interface(REG_INTER); 2762 %} 2763 2764 operand r11_RegL() 2765 %{ 2766 constraint(ALLOC_IN_RC(long_r11_reg)); 2767 match(RegL); 2768 match(rRegL); 2769 2770 format %{ %} 2771 interface(REG_INTER); 2772 %} 2773 2774 operand no_rbp_r13_RegL() 2775 %{ 2776 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2777 match(RegL); 2778 match(rRegL); 2779 match(rax_RegL); 2780 match(rcx_RegL); 2781 match(rdx_RegL); 2782 2783 format %{ %} 2784 interface(REG_INTER); 2785 %} 2786 2787 // Flags register, used as output of compare instructions 2788 operand rFlagsReg() 2789 %{ 2790 constraint(ALLOC_IN_RC(int_flags)); 2791 match(RegFlags); 2792 2793 format %{ "RFLAGS" %} 2794 interface(REG_INTER); 2795 %} 2796 2797 // Flags register, used as output of FLOATING POINT compare instructions 2798 operand rFlagsRegU() 2799 %{ 2800 constraint(ALLOC_IN_RC(int_flags)); 2801 match(RegFlags); 2802 2803 format %{ "RFLAGS_U" %} 2804 interface(REG_INTER); 2805 %} 2806 2807 operand rFlagsRegUCF() %{ 2808 constraint(ALLOC_IN_RC(int_flags)); 2809 match(RegFlags); 2810 predicate(false); 2811 2812 format %{ "RFLAGS_U_CF" %} 2813 interface(REG_INTER); 2814 %} 2815 2816 // Float register operands 2817 operand regF() %{ 2818 constraint(ALLOC_IN_RC(float_reg)); 2819 match(RegF); 2820 2821 format %{ %} 2822 interface(REG_INTER); 2823 %} 2824 2825 // Float register operands 2826 operand legRegF() %{ 2827 constraint(ALLOC_IN_RC(float_reg_legacy)); 2828 match(RegF); 2829 2830 format %{ %} 2831 interface(REG_INTER); 2832 %} 2833 2834 // Float register operands 2835 operand vlRegF() %{ 2836 constraint(ALLOC_IN_RC(float_reg_vl)); 2837 match(RegF); 2838 2839 format %{ %} 2840 interface(REG_INTER); 2841 %} 2842 2843 // Double register operands 2844 operand regD() %{ 2845 constraint(ALLOC_IN_RC(double_reg)); 2846 match(RegD); 2847 2848 format %{ %} 2849 interface(REG_INTER); 2850 %} 2851 2852 // Double register operands 2853 operand legRegD() %{ 2854 constraint(ALLOC_IN_RC(double_reg_legacy)); 2855 match(RegD); 2856 2857 format %{ %} 2858 interface(REG_INTER); 2859 %} 2860 2861 // Double register operands 2862 operand vlRegD() %{ 2863 constraint(ALLOC_IN_RC(double_reg_vl)); 2864 match(RegD); 2865 2866 format %{ %} 2867 interface(REG_INTER); 2868 %} 2869 2870 //----------Memory Operands---------------------------------------------------- 2871 // Direct Memory Operand 2872 // operand direct(immP addr) 2873 // %{ 2874 // match(addr); 2875 2876 // format %{ "[$addr]" %} 2877 // interface(MEMORY_INTER) %{ 2878 // base(0xFFFFFFFF); 2879 // index(0x4); 2880 // scale(0x0); 2881 // disp($addr); 2882 // %} 2883 // %} 2884 2885 // Indirect Memory Operand 2886 operand indirect(any_RegP reg) 2887 %{ 2888 constraint(ALLOC_IN_RC(ptr_reg)); 2889 match(reg); 2890 2891 format %{ "[$reg]" %} 2892 interface(MEMORY_INTER) %{ 2893 base($reg); 2894 index(0x4); 2895 scale(0x0); 2896 disp(0x0); 2897 %} 2898 %} 2899 2900 // Indirect Memory Plus Short Offset Operand 2901 operand indOffset8(any_RegP reg, immL8 off) 2902 %{ 2903 constraint(ALLOC_IN_RC(ptr_reg)); 2904 match(AddP reg off); 2905 2906 format %{ "[$reg + $off (8-bit)]" %} 2907 interface(MEMORY_INTER) %{ 2908 base($reg); 2909 index(0x4); 2910 scale(0x0); 2911 disp($off); 2912 %} 2913 %} 2914 2915 // Indirect Memory Plus Long Offset Operand 2916 operand indOffset32(any_RegP reg, immL32 off) 2917 %{ 2918 constraint(ALLOC_IN_RC(ptr_reg)); 2919 match(AddP reg off); 2920 2921 format %{ "[$reg + $off (32-bit)]" %} 2922 interface(MEMORY_INTER) %{ 2923 base($reg); 2924 index(0x4); 2925 scale(0x0); 2926 disp($off); 2927 %} 2928 %} 2929 2930 // Indirect Memory Plus Index Register Plus Offset Operand 2931 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2932 %{ 2933 constraint(ALLOC_IN_RC(ptr_reg)); 2934 match(AddP (AddP reg lreg) off); 2935 2936 op_cost(10); 2937 format %{"[$reg + $off + $lreg]" %} 2938 interface(MEMORY_INTER) %{ 2939 base($reg); 2940 index($lreg); 2941 scale(0x0); 2942 disp($off); 2943 %} 2944 %} 2945 2946 // Indirect Memory Plus Index Register Plus Offset Operand 2947 operand indIndex(any_RegP reg, rRegL lreg) 2948 %{ 2949 constraint(ALLOC_IN_RC(ptr_reg)); 2950 match(AddP reg lreg); 2951 2952 op_cost(10); 2953 format %{"[$reg + $lreg]" %} 2954 interface(MEMORY_INTER) %{ 2955 base($reg); 2956 index($lreg); 2957 scale(0x0); 2958 disp(0x0); 2959 %} 2960 %} 2961 2962 // Indirect Memory Times Scale Plus Index Register 2963 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2964 %{ 2965 constraint(ALLOC_IN_RC(ptr_reg)); 2966 match(AddP reg (LShiftL lreg scale)); 2967 2968 op_cost(10); 2969 format %{"[$reg + $lreg << $scale]" %} 2970 interface(MEMORY_INTER) %{ 2971 base($reg); 2972 index($lreg); 2973 scale($scale); 2974 disp(0x0); 2975 %} 2976 %} 2977 2978 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 2979 %{ 2980 constraint(ALLOC_IN_RC(ptr_reg)); 2981 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 2982 match(AddP reg (LShiftL (ConvI2L idx) scale)); 2983 2984 op_cost(10); 2985 format %{"[$reg + pos $idx << $scale]" %} 2986 interface(MEMORY_INTER) %{ 2987 base($reg); 2988 index($idx); 2989 scale($scale); 2990 disp(0x0); 2991 %} 2992 %} 2993 2994 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 2995 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 2996 %{ 2997 constraint(ALLOC_IN_RC(ptr_reg)); 2998 match(AddP (AddP reg (LShiftL lreg scale)) off); 2999 3000 op_cost(10); 3001 format %{"[$reg + $off + $lreg << $scale]" %} 3002 interface(MEMORY_INTER) %{ 3003 base($reg); 3004 index($lreg); 3005 scale($scale); 3006 disp($off); 3007 %} 3008 %} 3009 3010 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3011 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3012 %{ 3013 constraint(ALLOC_IN_RC(ptr_reg)); 3014 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3015 match(AddP (AddP reg (ConvI2L idx)) off); 3016 3017 op_cost(10); 3018 format %{"[$reg + $off + $idx]" %} 3019 interface(MEMORY_INTER) %{ 3020 base($reg); 3021 index($idx); 3022 scale(0x0); 3023 disp($off); 3024 %} 3025 %} 3026 3027 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3028 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3029 %{ 3030 constraint(ALLOC_IN_RC(ptr_reg)); 3031 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3032 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3033 3034 op_cost(10); 3035 format %{"[$reg + $off + $idx << $scale]" %} 3036 interface(MEMORY_INTER) %{ 3037 base($reg); 3038 index($idx); 3039 scale($scale); 3040 disp($off); 3041 %} 3042 %} 3043 3044 // Indirect Narrow Oop Plus Offset Operand 3045 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3046 // we can't free r12 even with CompressedOops::base() == nullptr. 3047 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3048 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3049 constraint(ALLOC_IN_RC(ptr_reg)); 3050 match(AddP (DecodeN reg) off); 3051 3052 op_cost(10); 3053 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3054 interface(MEMORY_INTER) %{ 3055 base(0xc); // R12 3056 index($reg); 3057 scale(0x3); 3058 disp($off); 3059 %} 3060 %} 3061 3062 // Indirect Memory Operand 3063 operand indirectNarrow(rRegN reg) 3064 %{ 3065 predicate(CompressedOops::shift() == 0); 3066 constraint(ALLOC_IN_RC(ptr_reg)); 3067 match(DecodeN reg); 3068 3069 format %{ "[$reg]" %} 3070 interface(MEMORY_INTER) %{ 3071 base($reg); 3072 index(0x4); 3073 scale(0x0); 3074 disp(0x0); 3075 %} 3076 %} 3077 3078 // Indirect Memory Plus Short Offset Operand 3079 operand indOffset8Narrow(rRegN reg, immL8 off) 3080 %{ 3081 predicate(CompressedOops::shift() == 0); 3082 constraint(ALLOC_IN_RC(ptr_reg)); 3083 match(AddP (DecodeN reg) off); 3084 3085 format %{ "[$reg + $off (8-bit)]" %} 3086 interface(MEMORY_INTER) %{ 3087 base($reg); 3088 index(0x4); 3089 scale(0x0); 3090 disp($off); 3091 %} 3092 %} 3093 3094 // Indirect Memory Plus Long Offset Operand 3095 operand indOffset32Narrow(rRegN reg, immL32 off) 3096 %{ 3097 predicate(CompressedOops::shift() == 0); 3098 constraint(ALLOC_IN_RC(ptr_reg)); 3099 match(AddP (DecodeN reg) off); 3100 3101 format %{ "[$reg + $off (32-bit)]" %} 3102 interface(MEMORY_INTER) %{ 3103 base($reg); 3104 index(0x4); 3105 scale(0x0); 3106 disp($off); 3107 %} 3108 %} 3109 3110 // Indirect Memory Plus Index Register Plus Offset Operand 3111 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3112 %{ 3113 predicate(CompressedOops::shift() == 0); 3114 constraint(ALLOC_IN_RC(ptr_reg)); 3115 match(AddP (AddP (DecodeN reg) lreg) off); 3116 3117 op_cost(10); 3118 format %{"[$reg + $off + $lreg]" %} 3119 interface(MEMORY_INTER) %{ 3120 base($reg); 3121 index($lreg); 3122 scale(0x0); 3123 disp($off); 3124 %} 3125 %} 3126 3127 // Indirect Memory Plus Index Register Plus Offset Operand 3128 operand indIndexNarrow(rRegN reg, rRegL lreg) 3129 %{ 3130 predicate(CompressedOops::shift() == 0); 3131 constraint(ALLOC_IN_RC(ptr_reg)); 3132 match(AddP (DecodeN reg) lreg); 3133 3134 op_cost(10); 3135 format %{"[$reg + $lreg]" %} 3136 interface(MEMORY_INTER) %{ 3137 base($reg); 3138 index($lreg); 3139 scale(0x0); 3140 disp(0x0); 3141 %} 3142 %} 3143 3144 // Indirect Memory Times Scale Plus Index Register 3145 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3146 %{ 3147 predicate(CompressedOops::shift() == 0); 3148 constraint(ALLOC_IN_RC(ptr_reg)); 3149 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3150 3151 op_cost(10); 3152 format %{"[$reg + $lreg << $scale]" %} 3153 interface(MEMORY_INTER) %{ 3154 base($reg); 3155 index($lreg); 3156 scale($scale); 3157 disp(0x0); 3158 %} 3159 %} 3160 3161 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3162 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3163 %{ 3164 predicate(CompressedOops::shift() == 0); 3165 constraint(ALLOC_IN_RC(ptr_reg)); 3166 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3167 3168 op_cost(10); 3169 format %{"[$reg + $off + $lreg << $scale]" %} 3170 interface(MEMORY_INTER) %{ 3171 base($reg); 3172 index($lreg); 3173 scale($scale); 3174 disp($off); 3175 %} 3176 %} 3177 3178 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3179 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3180 %{ 3181 constraint(ALLOC_IN_RC(ptr_reg)); 3182 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3183 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3184 3185 op_cost(10); 3186 format %{"[$reg + $off + $idx]" %} 3187 interface(MEMORY_INTER) %{ 3188 base($reg); 3189 index($idx); 3190 scale(0x0); 3191 disp($off); 3192 %} 3193 %} 3194 3195 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3196 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3197 %{ 3198 constraint(ALLOC_IN_RC(ptr_reg)); 3199 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3200 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3201 3202 op_cost(10); 3203 format %{"[$reg + $off + $idx << $scale]" %} 3204 interface(MEMORY_INTER) %{ 3205 base($reg); 3206 index($idx); 3207 scale($scale); 3208 disp($off); 3209 %} 3210 %} 3211 3212 //----------Special Memory Operands-------------------------------------------- 3213 // Stack Slot Operand - This operand is used for loading and storing temporary 3214 // values on the stack where a match requires a value to 3215 // flow through memory. 3216 operand stackSlotP(sRegP reg) 3217 %{ 3218 constraint(ALLOC_IN_RC(stack_slots)); 3219 // No match rule because this operand is only generated in matching 3220 3221 format %{ "[$reg]" %} 3222 interface(MEMORY_INTER) %{ 3223 base(0x4); // RSP 3224 index(0x4); // No Index 3225 scale(0x0); // No Scale 3226 disp($reg); // Stack Offset 3227 %} 3228 %} 3229 3230 operand stackSlotI(sRegI reg) 3231 %{ 3232 constraint(ALLOC_IN_RC(stack_slots)); 3233 // No match rule because this operand is only generated in matching 3234 3235 format %{ "[$reg]" %} 3236 interface(MEMORY_INTER) %{ 3237 base(0x4); // RSP 3238 index(0x4); // No Index 3239 scale(0x0); // No Scale 3240 disp($reg); // Stack Offset 3241 %} 3242 %} 3243 3244 operand stackSlotF(sRegF reg) 3245 %{ 3246 constraint(ALLOC_IN_RC(stack_slots)); 3247 // No match rule because this operand is only generated in matching 3248 3249 format %{ "[$reg]" %} 3250 interface(MEMORY_INTER) %{ 3251 base(0x4); // RSP 3252 index(0x4); // No Index 3253 scale(0x0); // No Scale 3254 disp($reg); // Stack Offset 3255 %} 3256 %} 3257 3258 operand stackSlotD(sRegD reg) 3259 %{ 3260 constraint(ALLOC_IN_RC(stack_slots)); 3261 // No match rule because this operand is only generated in matching 3262 3263 format %{ "[$reg]" %} 3264 interface(MEMORY_INTER) %{ 3265 base(0x4); // RSP 3266 index(0x4); // No Index 3267 scale(0x0); // No Scale 3268 disp($reg); // Stack Offset 3269 %} 3270 %} 3271 operand stackSlotL(sRegL reg) 3272 %{ 3273 constraint(ALLOC_IN_RC(stack_slots)); 3274 // No match rule because this operand is only generated in matching 3275 3276 format %{ "[$reg]" %} 3277 interface(MEMORY_INTER) %{ 3278 base(0x4); // RSP 3279 index(0x4); // No Index 3280 scale(0x0); // No Scale 3281 disp($reg); // Stack Offset 3282 %} 3283 %} 3284 3285 //----------Conditional Branch Operands---------------------------------------- 3286 // Comparison Op - This is the operation of the comparison, and is limited to 3287 // the following set of codes: 3288 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3289 // 3290 // Other attributes of the comparison, such as unsignedness, are specified 3291 // by the comparison instruction that sets a condition code flags register. 3292 // That result is represented by a flags operand whose subtype is appropriate 3293 // to the unsignedness (etc.) of the comparison. 3294 // 3295 // Later, the instruction which matches both the Comparison Op (a Bool) and 3296 // the flags (produced by the Cmp) specifies the coding of the comparison op 3297 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3298 3299 // Comparison Code 3300 operand cmpOp() 3301 %{ 3302 match(Bool); 3303 3304 format %{ "" %} 3305 interface(COND_INTER) %{ 3306 equal(0x4, "e"); 3307 not_equal(0x5, "ne"); 3308 less(0xC, "l"); 3309 greater_equal(0xD, "ge"); 3310 less_equal(0xE, "le"); 3311 greater(0xF, "g"); 3312 overflow(0x0, "o"); 3313 no_overflow(0x1, "no"); 3314 %} 3315 %} 3316 3317 // Comparison Code, unsigned compare. Used by FP also, with 3318 // C2 (unordered) turned into GT or LT already. The other bits 3319 // C0 and C3 are turned into Carry & Zero flags. 3320 operand cmpOpU() 3321 %{ 3322 match(Bool); 3323 3324 format %{ "" %} 3325 interface(COND_INTER) %{ 3326 equal(0x4, "e"); 3327 not_equal(0x5, "ne"); 3328 less(0x2, "b"); 3329 greater_equal(0x3, "ae"); 3330 less_equal(0x6, "be"); 3331 greater(0x7, "a"); 3332 overflow(0x0, "o"); 3333 no_overflow(0x1, "no"); 3334 %} 3335 %} 3336 3337 3338 // Floating comparisons that don't require any fixup for the unordered case, 3339 // If both inputs of the comparison are the same, ZF is always set so we 3340 // don't need to use cmpOpUCF2 for eq/ne 3341 operand cmpOpUCF() %{ 3342 match(Bool); 3343 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3344 n->as_Bool()->_test._test == BoolTest::ge || 3345 n->as_Bool()->_test._test == BoolTest::le || 3346 n->as_Bool()->_test._test == BoolTest::gt || 3347 n->in(1)->in(1) == n->in(1)->in(2)); 3348 format %{ "" %} 3349 interface(COND_INTER) %{ 3350 equal(0xb, "np"); 3351 not_equal(0xa, "p"); 3352 less(0x2, "b"); 3353 greater_equal(0x3, "ae"); 3354 less_equal(0x6, "be"); 3355 greater(0x7, "a"); 3356 overflow(0x0, "o"); 3357 no_overflow(0x1, "no"); 3358 %} 3359 %} 3360 3361 3362 // Floating comparisons that can be fixed up with extra conditional jumps 3363 operand cmpOpUCF2() %{ 3364 match(Bool); 3365 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3366 n->as_Bool()->_test._test == BoolTest::eq) && 3367 n->in(1)->in(1) != n->in(1)->in(2)); 3368 format %{ "" %} 3369 interface(COND_INTER) %{ 3370 equal(0x4, "e"); 3371 not_equal(0x5, "ne"); 3372 less(0x2, "b"); 3373 greater_equal(0x3, "ae"); 3374 less_equal(0x6, "be"); 3375 greater(0x7, "a"); 3376 overflow(0x0, "o"); 3377 no_overflow(0x1, "no"); 3378 %} 3379 %} 3380 3381 //----------OPERAND CLASSES---------------------------------------------------- 3382 // Operand Classes are groups of operands that are used as to simplify 3383 // instruction definitions by not requiring the AD writer to specify separate 3384 // instructions for every form of operand when the instruction accepts 3385 // multiple operand types with the same basic encoding and format. The classic 3386 // case of this is memory operands. 3387 3388 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3389 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3390 indCompressedOopOffset, 3391 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3392 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3393 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3394 3395 //----------PIPELINE----------------------------------------------------------- 3396 // Rules which define the behavior of the target architectures pipeline. 3397 pipeline %{ 3398 3399 //----------ATTRIBUTES--------------------------------------------------------- 3400 attributes %{ 3401 variable_size_instructions; // Fixed size instructions 3402 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3403 instruction_unit_size = 1; // An instruction is 1 bytes long 3404 instruction_fetch_unit_size = 16; // The processor fetches one line 3405 instruction_fetch_units = 1; // of 16 bytes 3406 3407 // List of nop instructions 3408 nops( MachNop ); 3409 %} 3410 3411 //----------RESOURCES---------------------------------------------------------- 3412 // Resources are the functional units available to the machine 3413 3414 // Generic P2/P3 pipeline 3415 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3416 // 3 instructions decoded per cycle. 3417 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3418 // 3 ALU op, only ALU0 handles mul instructions. 3419 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3420 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3421 BR, FPU, 3422 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3423 3424 //----------PIPELINE DESCRIPTION----------------------------------------------- 3425 // Pipeline Description specifies the stages in the machine's pipeline 3426 3427 // Generic P2/P3 pipeline 3428 pipe_desc(S0, S1, S2, S3, S4, S5); 3429 3430 //----------PIPELINE CLASSES--------------------------------------------------- 3431 // Pipeline Classes describe the stages in which input and output are 3432 // referenced by the hardware pipeline. 3433 3434 // Naming convention: ialu or fpu 3435 // Then: _reg 3436 // Then: _reg if there is a 2nd register 3437 // Then: _long if it's a pair of instructions implementing a long 3438 // Then: _fat if it requires the big decoder 3439 // Or: _mem if it requires the big decoder and a memory unit. 3440 3441 // Integer ALU reg operation 3442 pipe_class ialu_reg(rRegI dst) 3443 %{ 3444 single_instruction; 3445 dst : S4(write); 3446 dst : S3(read); 3447 DECODE : S0; // any decoder 3448 ALU : S3; // any alu 3449 %} 3450 3451 // Long ALU reg operation 3452 pipe_class ialu_reg_long(rRegL dst) 3453 %{ 3454 instruction_count(2); 3455 dst : S4(write); 3456 dst : S3(read); 3457 DECODE : S0(2); // any 2 decoders 3458 ALU : S3(2); // both alus 3459 %} 3460 3461 // Integer ALU reg operation using big decoder 3462 pipe_class ialu_reg_fat(rRegI dst) 3463 %{ 3464 single_instruction; 3465 dst : S4(write); 3466 dst : S3(read); 3467 D0 : S0; // big decoder only 3468 ALU : S3; // any alu 3469 %} 3470 3471 // Integer ALU reg-reg operation 3472 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3473 %{ 3474 single_instruction; 3475 dst : S4(write); 3476 src : S3(read); 3477 DECODE : S0; // any decoder 3478 ALU : S3; // any alu 3479 %} 3480 3481 // Integer ALU reg-reg operation 3482 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3483 %{ 3484 single_instruction; 3485 dst : S4(write); 3486 src : S3(read); 3487 D0 : S0; // big decoder only 3488 ALU : S3; // any alu 3489 %} 3490 3491 // Integer ALU reg-mem operation 3492 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3493 %{ 3494 single_instruction; 3495 dst : S5(write); 3496 mem : S3(read); 3497 D0 : S0; // big decoder only 3498 ALU : S4; // any alu 3499 MEM : S3; // any mem 3500 %} 3501 3502 // Integer mem operation (prefetch) 3503 pipe_class ialu_mem(memory mem) 3504 %{ 3505 single_instruction; 3506 mem : S3(read); 3507 D0 : S0; // big decoder only 3508 MEM : S3; // any mem 3509 %} 3510 3511 // Integer Store to Memory 3512 pipe_class ialu_mem_reg(memory mem, rRegI src) 3513 %{ 3514 single_instruction; 3515 mem : S3(read); 3516 src : S5(read); 3517 D0 : S0; // big decoder only 3518 ALU : S4; // any alu 3519 MEM : S3; 3520 %} 3521 3522 // // Long Store to Memory 3523 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3524 // %{ 3525 // instruction_count(2); 3526 // mem : S3(read); 3527 // src : S5(read); 3528 // D0 : S0(2); // big decoder only; twice 3529 // ALU : S4(2); // any 2 alus 3530 // MEM : S3(2); // Both mems 3531 // %} 3532 3533 // Integer Store to Memory 3534 pipe_class ialu_mem_imm(memory mem) 3535 %{ 3536 single_instruction; 3537 mem : S3(read); 3538 D0 : S0; // big decoder only 3539 ALU : S4; // any alu 3540 MEM : S3; 3541 %} 3542 3543 // Integer ALU0 reg-reg operation 3544 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3545 %{ 3546 single_instruction; 3547 dst : S4(write); 3548 src : S3(read); 3549 D0 : S0; // Big decoder only 3550 ALU0 : S3; // only alu0 3551 %} 3552 3553 // Integer ALU0 reg-mem operation 3554 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3555 %{ 3556 single_instruction; 3557 dst : S5(write); 3558 mem : S3(read); 3559 D0 : S0; // big decoder only 3560 ALU0 : S4; // ALU0 only 3561 MEM : S3; // any mem 3562 %} 3563 3564 // Integer ALU reg-reg operation 3565 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3566 %{ 3567 single_instruction; 3568 cr : S4(write); 3569 src1 : S3(read); 3570 src2 : S3(read); 3571 DECODE : S0; // any decoder 3572 ALU : S3; // any alu 3573 %} 3574 3575 // Integer ALU reg-imm operation 3576 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3577 %{ 3578 single_instruction; 3579 cr : S4(write); 3580 src1 : S3(read); 3581 DECODE : S0; // any decoder 3582 ALU : S3; // any alu 3583 %} 3584 3585 // Integer ALU reg-mem operation 3586 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3587 %{ 3588 single_instruction; 3589 cr : S4(write); 3590 src1 : S3(read); 3591 src2 : S3(read); 3592 D0 : S0; // big decoder only 3593 ALU : S4; // any alu 3594 MEM : S3; 3595 %} 3596 3597 // Conditional move reg-reg 3598 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3599 %{ 3600 instruction_count(4); 3601 y : S4(read); 3602 q : S3(read); 3603 p : S3(read); 3604 DECODE : S0(4); // any decoder 3605 %} 3606 3607 // Conditional move reg-reg 3608 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3609 %{ 3610 single_instruction; 3611 dst : S4(write); 3612 src : S3(read); 3613 cr : S3(read); 3614 DECODE : S0; // any decoder 3615 %} 3616 3617 // Conditional move reg-mem 3618 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3619 %{ 3620 single_instruction; 3621 dst : S4(write); 3622 src : S3(read); 3623 cr : S3(read); 3624 DECODE : S0; // any decoder 3625 MEM : S3; 3626 %} 3627 3628 // Conditional move reg-reg long 3629 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3630 %{ 3631 single_instruction; 3632 dst : S4(write); 3633 src : S3(read); 3634 cr : S3(read); 3635 DECODE : S0(2); // any 2 decoders 3636 %} 3637 3638 // Float reg-reg operation 3639 pipe_class fpu_reg(regD dst) 3640 %{ 3641 instruction_count(2); 3642 dst : S3(read); 3643 DECODE : S0(2); // any 2 decoders 3644 FPU : S3; 3645 %} 3646 3647 // Float reg-reg operation 3648 pipe_class fpu_reg_reg(regD dst, regD src) 3649 %{ 3650 instruction_count(2); 3651 dst : S4(write); 3652 src : S3(read); 3653 DECODE : S0(2); // any 2 decoders 3654 FPU : S3; 3655 %} 3656 3657 // Float reg-reg operation 3658 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3659 %{ 3660 instruction_count(3); 3661 dst : S4(write); 3662 src1 : S3(read); 3663 src2 : S3(read); 3664 DECODE : S0(3); // any 3 decoders 3665 FPU : S3(2); 3666 %} 3667 3668 // Float reg-reg operation 3669 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3670 %{ 3671 instruction_count(4); 3672 dst : S4(write); 3673 src1 : S3(read); 3674 src2 : S3(read); 3675 src3 : S3(read); 3676 DECODE : S0(4); // any 3 decoders 3677 FPU : S3(2); 3678 %} 3679 3680 // Float reg-reg operation 3681 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3682 %{ 3683 instruction_count(4); 3684 dst : S4(write); 3685 src1 : S3(read); 3686 src2 : S3(read); 3687 src3 : S3(read); 3688 DECODE : S1(3); // any 3 decoders 3689 D0 : S0; // Big decoder only 3690 FPU : S3(2); 3691 MEM : S3; 3692 %} 3693 3694 // Float reg-mem operation 3695 pipe_class fpu_reg_mem(regD dst, memory mem) 3696 %{ 3697 instruction_count(2); 3698 dst : S5(write); 3699 mem : S3(read); 3700 D0 : S0; // big decoder only 3701 DECODE : S1; // any decoder for FPU POP 3702 FPU : S4; 3703 MEM : S3; // any mem 3704 %} 3705 3706 // Float reg-mem operation 3707 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3708 %{ 3709 instruction_count(3); 3710 dst : S5(write); 3711 src1 : S3(read); 3712 mem : S3(read); 3713 D0 : S0; // big decoder only 3714 DECODE : S1(2); // any decoder for FPU POP 3715 FPU : S4; 3716 MEM : S3; // any mem 3717 %} 3718 3719 // Float mem-reg operation 3720 pipe_class fpu_mem_reg(memory mem, regD src) 3721 %{ 3722 instruction_count(2); 3723 src : S5(read); 3724 mem : S3(read); 3725 DECODE : S0; // any decoder for FPU PUSH 3726 D0 : S1; // big decoder only 3727 FPU : S4; 3728 MEM : S3; // any mem 3729 %} 3730 3731 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3732 %{ 3733 instruction_count(3); 3734 src1 : S3(read); 3735 src2 : S3(read); 3736 mem : S3(read); 3737 DECODE : S0(2); // any decoder for FPU PUSH 3738 D0 : S1; // big decoder only 3739 FPU : S4; 3740 MEM : S3; // any mem 3741 %} 3742 3743 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3744 %{ 3745 instruction_count(3); 3746 src1 : S3(read); 3747 src2 : S3(read); 3748 mem : S4(read); 3749 DECODE : S0; // any decoder for FPU PUSH 3750 D0 : S0(2); // big decoder only 3751 FPU : S4; 3752 MEM : S3(2); // any mem 3753 %} 3754 3755 pipe_class fpu_mem_mem(memory dst, memory src1) 3756 %{ 3757 instruction_count(2); 3758 src1 : S3(read); 3759 dst : S4(read); 3760 D0 : S0(2); // big decoder only 3761 MEM : S3(2); // any mem 3762 %} 3763 3764 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3765 %{ 3766 instruction_count(3); 3767 src1 : S3(read); 3768 src2 : S3(read); 3769 dst : S4(read); 3770 D0 : S0(3); // big decoder only 3771 FPU : S4; 3772 MEM : S3(3); // any mem 3773 %} 3774 3775 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3776 %{ 3777 instruction_count(3); 3778 src1 : S4(read); 3779 mem : S4(read); 3780 DECODE : S0; // any decoder for FPU PUSH 3781 D0 : S0(2); // big decoder only 3782 FPU : S4; 3783 MEM : S3(2); // any mem 3784 %} 3785 3786 // Float load constant 3787 pipe_class fpu_reg_con(regD dst) 3788 %{ 3789 instruction_count(2); 3790 dst : S5(write); 3791 D0 : S0; // big decoder only for the load 3792 DECODE : S1; // any decoder for FPU POP 3793 FPU : S4; 3794 MEM : S3; // any mem 3795 %} 3796 3797 // Float load constant 3798 pipe_class fpu_reg_reg_con(regD dst, regD src) 3799 %{ 3800 instruction_count(3); 3801 dst : S5(write); 3802 src : S3(read); 3803 D0 : S0; // big decoder only for the load 3804 DECODE : S1(2); // any decoder for FPU POP 3805 FPU : S4; 3806 MEM : S3; // any mem 3807 %} 3808 3809 // UnConditional branch 3810 pipe_class pipe_jmp(label labl) 3811 %{ 3812 single_instruction; 3813 BR : S3; 3814 %} 3815 3816 // Conditional branch 3817 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3818 %{ 3819 single_instruction; 3820 cr : S1(read); 3821 BR : S3; 3822 %} 3823 3824 // Allocation idiom 3825 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3826 %{ 3827 instruction_count(1); force_serialization; 3828 fixed_latency(6); 3829 heap_ptr : S3(read); 3830 DECODE : S0(3); 3831 D0 : S2; 3832 MEM : S3; 3833 ALU : S3(2); 3834 dst : S5(write); 3835 BR : S5; 3836 %} 3837 3838 // Generic big/slow expanded idiom 3839 pipe_class pipe_slow() 3840 %{ 3841 instruction_count(10); multiple_bundles; force_serialization; 3842 fixed_latency(100); 3843 D0 : S0(2); 3844 MEM : S3(2); 3845 %} 3846 3847 // The real do-nothing guy 3848 pipe_class empty() 3849 %{ 3850 instruction_count(0); 3851 %} 3852 3853 // Define the class for the Nop node 3854 define 3855 %{ 3856 MachNop = empty; 3857 %} 3858 3859 %} 3860 3861 //----------INSTRUCTIONS------------------------------------------------------- 3862 // 3863 // match -- States which machine-independent subtree may be replaced 3864 // by this instruction. 3865 // ins_cost -- The estimated cost of this instruction is used by instruction 3866 // selection to identify a minimum cost tree of machine 3867 // instructions that matches a tree of machine-independent 3868 // instructions. 3869 // format -- A string providing the disassembly for this instruction. 3870 // The value of an instruction's operand may be inserted 3871 // by referring to it with a '$' prefix. 3872 // opcode -- Three instruction opcodes may be provided. These are referred 3873 // to within an encode class as $primary, $secondary, and $tertiary 3874 // rrspectively. The primary opcode is commonly used to 3875 // indicate the type of machine instruction, while secondary 3876 // and tertiary are often used for prefix options or addressing 3877 // modes. 3878 // ins_encode -- A list of encode classes with parameters. The encode class 3879 // name must have been defined in an 'enc_class' specification 3880 // in the encode section of the architecture description. 3881 3882 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3883 // Load Float 3884 instruct MoveF2VL(vlRegF dst, regF src) %{ 3885 match(Set dst src); 3886 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3887 ins_encode %{ 3888 ShouldNotReachHere(); 3889 %} 3890 ins_pipe( fpu_reg_reg ); 3891 %} 3892 3893 // Load Float 3894 instruct MoveF2LEG(legRegF dst, regF src) %{ 3895 match(Set dst src); 3896 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3897 ins_encode %{ 3898 ShouldNotReachHere(); 3899 %} 3900 ins_pipe( fpu_reg_reg ); 3901 %} 3902 3903 // Load Float 3904 instruct MoveVL2F(regF dst, vlRegF src) %{ 3905 match(Set dst src); 3906 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3907 ins_encode %{ 3908 ShouldNotReachHere(); 3909 %} 3910 ins_pipe( fpu_reg_reg ); 3911 %} 3912 3913 // Load Float 3914 instruct MoveLEG2F(regF dst, legRegF src) %{ 3915 match(Set dst src); 3916 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3917 ins_encode %{ 3918 ShouldNotReachHere(); 3919 %} 3920 ins_pipe( fpu_reg_reg ); 3921 %} 3922 3923 // Load Double 3924 instruct MoveD2VL(vlRegD dst, regD src) %{ 3925 match(Set dst src); 3926 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3927 ins_encode %{ 3928 ShouldNotReachHere(); 3929 %} 3930 ins_pipe( fpu_reg_reg ); 3931 %} 3932 3933 // Load Double 3934 instruct MoveD2LEG(legRegD dst, regD src) %{ 3935 match(Set dst src); 3936 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3937 ins_encode %{ 3938 ShouldNotReachHere(); 3939 %} 3940 ins_pipe( fpu_reg_reg ); 3941 %} 3942 3943 // Load Double 3944 instruct MoveVL2D(regD dst, vlRegD src) %{ 3945 match(Set dst src); 3946 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3947 ins_encode %{ 3948 ShouldNotReachHere(); 3949 %} 3950 ins_pipe( fpu_reg_reg ); 3951 %} 3952 3953 // Load Double 3954 instruct MoveLEG2D(regD dst, legRegD src) %{ 3955 match(Set dst src); 3956 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3957 ins_encode %{ 3958 ShouldNotReachHere(); 3959 %} 3960 ins_pipe( fpu_reg_reg ); 3961 %} 3962 3963 //----------Load/Store/Move Instructions--------------------------------------- 3964 //----------Load Instructions-------------------------------------------------- 3965 3966 // Load Byte (8 bit signed) 3967 instruct loadB(rRegI dst, memory mem) 3968 %{ 3969 match(Set dst (LoadB mem)); 3970 3971 ins_cost(125); 3972 format %{ "movsbl $dst, $mem\t# byte" %} 3973 3974 ins_encode %{ 3975 __ movsbl($dst$$Register, $mem$$Address); 3976 %} 3977 3978 ins_pipe(ialu_reg_mem); 3979 %} 3980 3981 // Load Byte (8 bit signed) into Long Register 3982 instruct loadB2L(rRegL dst, memory mem) 3983 %{ 3984 match(Set dst (ConvI2L (LoadB mem))); 3985 3986 ins_cost(125); 3987 format %{ "movsbq $dst, $mem\t# byte -> long" %} 3988 3989 ins_encode %{ 3990 __ movsbq($dst$$Register, $mem$$Address); 3991 %} 3992 3993 ins_pipe(ialu_reg_mem); 3994 %} 3995 3996 // Load Unsigned Byte (8 bit UNsigned) 3997 instruct loadUB(rRegI dst, memory mem) 3998 %{ 3999 match(Set dst (LoadUB mem)); 4000 4001 ins_cost(125); 4002 format %{ "movzbl $dst, $mem\t# ubyte" %} 4003 4004 ins_encode %{ 4005 __ movzbl($dst$$Register, $mem$$Address); 4006 %} 4007 4008 ins_pipe(ialu_reg_mem); 4009 %} 4010 4011 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4012 instruct loadUB2L(rRegL dst, memory mem) 4013 %{ 4014 match(Set dst (ConvI2L (LoadUB mem))); 4015 4016 ins_cost(125); 4017 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4018 4019 ins_encode %{ 4020 __ movzbq($dst$$Register, $mem$$Address); 4021 %} 4022 4023 ins_pipe(ialu_reg_mem); 4024 %} 4025 4026 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4027 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4028 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4029 effect(KILL cr); 4030 4031 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4032 "andl $dst, right_n_bits($mask, 8)" %} 4033 ins_encode %{ 4034 Register Rdst = $dst$$Register; 4035 __ movzbq(Rdst, $mem$$Address); 4036 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4037 %} 4038 ins_pipe(ialu_reg_mem); 4039 %} 4040 4041 // Load Short (16 bit signed) 4042 instruct loadS(rRegI dst, memory mem) 4043 %{ 4044 match(Set dst (LoadS mem)); 4045 4046 ins_cost(125); 4047 format %{ "movswl $dst, $mem\t# short" %} 4048 4049 ins_encode %{ 4050 __ movswl($dst$$Register, $mem$$Address); 4051 %} 4052 4053 ins_pipe(ialu_reg_mem); 4054 %} 4055 4056 // Load Short (16 bit signed) to Byte (8 bit signed) 4057 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4058 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4059 4060 ins_cost(125); 4061 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4062 ins_encode %{ 4063 __ movsbl($dst$$Register, $mem$$Address); 4064 %} 4065 ins_pipe(ialu_reg_mem); 4066 %} 4067 4068 // Load Short (16 bit signed) into Long Register 4069 instruct loadS2L(rRegL dst, memory mem) 4070 %{ 4071 match(Set dst (ConvI2L (LoadS mem))); 4072 4073 ins_cost(125); 4074 format %{ "movswq $dst, $mem\t# short -> long" %} 4075 4076 ins_encode %{ 4077 __ movswq($dst$$Register, $mem$$Address); 4078 %} 4079 4080 ins_pipe(ialu_reg_mem); 4081 %} 4082 4083 // Load Unsigned Short/Char (16 bit UNsigned) 4084 instruct loadUS(rRegI dst, memory mem) 4085 %{ 4086 match(Set dst (LoadUS mem)); 4087 4088 ins_cost(125); 4089 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4090 4091 ins_encode %{ 4092 __ movzwl($dst$$Register, $mem$$Address); 4093 %} 4094 4095 ins_pipe(ialu_reg_mem); 4096 %} 4097 4098 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4099 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4100 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4101 4102 ins_cost(125); 4103 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4104 ins_encode %{ 4105 __ movsbl($dst$$Register, $mem$$Address); 4106 %} 4107 ins_pipe(ialu_reg_mem); 4108 %} 4109 4110 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4111 instruct loadUS2L(rRegL dst, memory mem) 4112 %{ 4113 match(Set dst (ConvI2L (LoadUS mem))); 4114 4115 ins_cost(125); 4116 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4117 4118 ins_encode %{ 4119 __ movzwq($dst$$Register, $mem$$Address); 4120 %} 4121 4122 ins_pipe(ialu_reg_mem); 4123 %} 4124 4125 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4126 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4127 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4128 4129 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4130 ins_encode %{ 4131 __ movzbq($dst$$Register, $mem$$Address); 4132 %} 4133 ins_pipe(ialu_reg_mem); 4134 %} 4135 4136 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4137 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4138 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4139 effect(KILL cr); 4140 4141 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4142 "andl $dst, right_n_bits($mask, 16)" %} 4143 ins_encode %{ 4144 Register Rdst = $dst$$Register; 4145 __ movzwq(Rdst, $mem$$Address); 4146 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4147 %} 4148 ins_pipe(ialu_reg_mem); 4149 %} 4150 4151 // Load Integer 4152 instruct loadI(rRegI dst, memory mem) 4153 %{ 4154 match(Set dst (LoadI mem)); 4155 4156 ins_cost(125); 4157 format %{ "movl $dst, $mem\t# int" %} 4158 4159 ins_encode %{ 4160 __ movl($dst$$Register, $mem$$Address); 4161 %} 4162 4163 ins_pipe(ialu_reg_mem); 4164 %} 4165 4166 // Load Integer (32 bit signed) to Byte (8 bit signed) 4167 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4168 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4169 4170 ins_cost(125); 4171 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4172 ins_encode %{ 4173 __ movsbl($dst$$Register, $mem$$Address); 4174 %} 4175 ins_pipe(ialu_reg_mem); 4176 %} 4177 4178 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4179 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4180 match(Set dst (AndI (LoadI mem) mask)); 4181 4182 ins_cost(125); 4183 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4184 ins_encode %{ 4185 __ movzbl($dst$$Register, $mem$$Address); 4186 %} 4187 ins_pipe(ialu_reg_mem); 4188 %} 4189 4190 // Load Integer (32 bit signed) to Short (16 bit signed) 4191 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4192 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4193 4194 ins_cost(125); 4195 format %{ "movswl $dst, $mem\t# int -> short" %} 4196 ins_encode %{ 4197 __ movswl($dst$$Register, $mem$$Address); 4198 %} 4199 ins_pipe(ialu_reg_mem); 4200 %} 4201 4202 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4203 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4204 match(Set dst (AndI (LoadI mem) mask)); 4205 4206 ins_cost(125); 4207 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4208 ins_encode %{ 4209 __ movzwl($dst$$Register, $mem$$Address); 4210 %} 4211 ins_pipe(ialu_reg_mem); 4212 %} 4213 4214 // Load Integer into Long Register 4215 instruct loadI2L(rRegL dst, memory mem) 4216 %{ 4217 match(Set dst (ConvI2L (LoadI mem))); 4218 4219 ins_cost(125); 4220 format %{ "movslq $dst, $mem\t# int -> long" %} 4221 4222 ins_encode %{ 4223 __ movslq($dst$$Register, $mem$$Address); 4224 %} 4225 4226 ins_pipe(ialu_reg_mem); 4227 %} 4228 4229 // Load Integer with mask 0xFF into Long Register 4230 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4231 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4232 4233 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4234 ins_encode %{ 4235 __ movzbq($dst$$Register, $mem$$Address); 4236 %} 4237 ins_pipe(ialu_reg_mem); 4238 %} 4239 4240 // Load Integer with mask 0xFFFF into Long Register 4241 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4242 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4243 4244 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4245 ins_encode %{ 4246 __ movzwq($dst$$Register, $mem$$Address); 4247 %} 4248 ins_pipe(ialu_reg_mem); 4249 %} 4250 4251 // Load Integer with a 31-bit mask into Long Register 4252 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4253 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4254 effect(KILL cr); 4255 4256 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4257 "andl $dst, $mask" %} 4258 ins_encode %{ 4259 Register Rdst = $dst$$Register; 4260 __ movl(Rdst, $mem$$Address); 4261 __ andl(Rdst, $mask$$constant); 4262 %} 4263 ins_pipe(ialu_reg_mem); 4264 %} 4265 4266 // Load Unsigned Integer into Long Register 4267 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4268 %{ 4269 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4270 4271 ins_cost(125); 4272 format %{ "movl $dst, $mem\t# uint -> long" %} 4273 4274 ins_encode %{ 4275 __ movl($dst$$Register, $mem$$Address); 4276 %} 4277 4278 ins_pipe(ialu_reg_mem); 4279 %} 4280 4281 // Load Long 4282 instruct loadL(rRegL dst, memory mem) 4283 %{ 4284 match(Set dst (LoadL mem)); 4285 4286 ins_cost(125); 4287 format %{ "movq $dst, $mem\t# long" %} 4288 4289 ins_encode %{ 4290 __ movq($dst$$Register, $mem$$Address); 4291 %} 4292 4293 ins_pipe(ialu_reg_mem); // XXX 4294 %} 4295 4296 // Load Range 4297 instruct loadRange(rRegI dst, memory mem) 4298 %{ 4299 match(Set dst (LoadRange mem)); 4300 4301 ins_cost(125); // XXX 4302 format %{ "movl $dst, $mem\t# range" %} 4303 ins_encode %{ 4304 __ movl($dst$$Register, $mem$$Address); 4305 %} 4306 ins_pipe(ialu_reg_mem); 4307 %} 4308 4309 // Load Pointer 4310 instruct loadP(rRegP dst, memory mem) 4311 %{ 4312 match(Set dst (LoadP mem)); 4313 predicate(n->as_Load()->barrier_data() == 0); 4314 4315 ins_cost(125); // XXX 4316 format %{ "movq $dst, $mem\t# ptr" %} 4317 ins_encode %{ 4318 __ movq($dst$$Register, $mem$$Address); 4319 %} 4320 ins_pipe(ialu_reg_mem); // XXX 4321 %} 4322 4323 // Load Compressed Pointer 4324 instruct loadN(rRegN dst, memory mem) 4325 %{ 4326 predicate(n->as_Load()->barrier_data() == 0); 4327 match(Set dst (LoadN mem)); 4328 4329 ins_cost(125); // XXX 4330 format %{ "movl $dst, $mem\t# compressed ptr" %} 4331 ins_encode %{ 4332 __ movl($dst$$Register, $mem$$Address); 4333 %} 4334 ins_pipe(ialu_reg_mem); // XXX 4335 %} 4336 4337 4338 // Load Klass Pointer 4339 instruct loadKlass(rRegP dst, memory mem) 4340 %{ 4341 match(Set dst (LoadKlass mem)); 4342 4343 ins_cost(125); // XXX 4344 format %{ "movq $dst, $mem\t# class" %} 4345 ins_encode %{ 4346 __ movq($dst$$Register, $mem$$Address); 4347 %} 4348 ins_pipe(ialu_reg_mem); // XXX 4349 %} 4350 4351 // Load narrow Klass Pointer 4352 instruct loadNKlass(rRegN dst, memory mem) 4353 %{ 4354 predicate(!UseCompactObjectHeaders); 4355 match(Set dst (LoadNKlass mem)); 4356 4357 ins_cost(125); // XXX 4358 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4359 ins_encode %{ 4360 __ movl($dst$$Register, $mem$$Address); 4361 %} 4362 ins_pipe(ialu_reg_mem); // XXX 4363 %} 4364 4365 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4366 %{ 4367 predicate(UseCompactObjectHeaders); 4368 match(Set dst (LoadNKlass mem)); 4369 effect(KILL cr); 4370 ins_cost(125); // XXX 4371 format %{ 4372 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4373 "shrl $dst, markWord::klass_shift_at_offset" 4374 %} 4375 ins_encode %{ 4376 __ movl($dst$$Register, $mem$$Address); 4377 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4378 %} 4379 ins_pipe(ialu_reg_mem); // XXX 4380 %} 4381 4382 // Load Float 4383 instruct loadF(regF dst, memory mem) 4384 %{ 4385 match(Set dst (LoadF mem)); 4386 4387 ins_cost(145); // XXX 4388 format %{ "movss $dst, $mem\t# float" %} 4389 ins_encode %{ 4390 __ movflt($dst$$XMMRegister, $mem$$Address); 4391 %} 4392 ins_pipe(pipe_slow); // XXX 4393 %} 4394 4395 // Load Double 4396 instruct loadD_partial(regD dst, memory mem) 4397 %{ 4398 predicate(!UseXmmLoadAndClearUpper); 4399 match(Set dst (LoadD mem)); 4400 4401 ins_cost(145); // XXX 4402 format %{ "movlpd $dst, $mem\t# double" %} 4403 ins_encode %{ 4404 __ movdbl($dst$$XMMRegister, $mem$$Address); 4405 %} 4406 ins_pipe(pipe_slow); // XXX 4407 %} 4408 4409 instruct loadD(regD dst, memory mem) 4410 %{ 4411 predicate(UseXmmLoadAndClearUpper); 4412 match(Set dst (LoadD mem)); 4413 4414 ins_cost(145); // XXX 4415 format %{ "movsd $dst, $mem\t# double" %} 4416 ins_encode %{ 4417 __ movdbl($dst$$XMMRegister, $mem$$Address); 4418 %} 4419 ins_pipe(pipe_slow); // XXX 4420 %} 4421 4422 // max = java.lang.Math.max(float a, float b) 4423 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4424 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4425 match(Set dst (MaxF a b)); 4426 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4427 format %{ "maxF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4428 ins_encode %{ 4429 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4430 %} 4431 ins_pipe( pipe_slow ); 4432 %} 4433 4434 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4435 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4436 match(Set dst (MaxF a b)); 4437 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4438 4439 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 4440 ins_encode %{ 4441 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4442 false /*min*/, true /*single*/); 4443 %} 4444 ins_pipe( pipe_slow ); 4445 %} 4446 4447 // max = java.lang.Math.max(double a, double b) 4448 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4449 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4450 match(Set dst (MaxD a b)); 4451 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4452 format %{ "maxD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4453 ins_encode %{ 4454 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4455 %} 4456 ins_pipe( pipe_slow ); 4457 %} 4458 4459 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4460 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4461 match(Set dst (MaxD a b)); 4462 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4463 4464 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 4465 ins_encode %{ 4466 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4467 false /*min*/, false /*single*/); 4468 %} 4469 ins_pipe( pipe_slow ); 4470 %} 4471 4472 // min = java.lang.Math.min(float a, float b) 4473 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4474 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4475 match(Set dst (MinF a b)); 4476 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4477 format %{ "minF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4478 ins_encode %{ 4479 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4480 %} 4481 ins_pipe( pipe_slow ); 4482 %} 4483 4484 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4485 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4486 match(Set dst (MinF a b)); 4487 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4488 4489 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 4490 ins_encode %{ 4491 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4492 true /*min*/, true /*single*/); 4493 %} 4494 ins_pipe( pipe_slow ); 4495 %} 4496 4497 // min = java.lang.Math.min(double a, double b) 4498 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4499 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4500 match(Set dst (MinD a b)); 4501 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4502 format %{ "minD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4503 ins_encode %{ 4504 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4505 %} 4506 ins_pipe( pipe_slow ); 4507 %} 4508 4509 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4510 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4511 match(Set dst (MinD a b)); 4512 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4513 4514 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 4515 ins_encode %{ 4516 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4517 true /*min*/, false /*single*/); 4518 %} 4519 ins_pipe( pipe_slow ); 4520 %} 4521 4522 // Load Effective Address 4523 instruct leaP8(rRegP dst, indOffset8 mem) 4524 %{ 4525 match(Set dst mem); 4526 4527 ins_cost(110); // XXX 4528 format %{ "leaq $dst, $mem\t# ptr 8" %} 4529 ins_encode %{ 4530 __ leaq($dst$$Register, $mem$$Address); 4531 %} 4532 ins_pipe(ialu_reg_reg_fat); 4533 %} 4534 4535 instruct leaP32(rRegP dst, indOffset32 mem) 4536 %{ 4537 match(Set dst mem); 4538 4539 ins_cost(110); 4540 format %{ "leaq $dst, $mem\t# ptr 32" %} 4541 ins_encode %{ 4542 __ leaq($dst$$Register, $mem$$Address); 4543 %} 4544 ins_pipe(ialu_reg_reg_fat); 4545 %} 4546 4547 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4548 %{ 4549 match(Set dst mem); 4550 4551 ins_cost(110); 4552 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4553 ins_encode %{ 4554 __ leaq($dst$$Register, $mem$$Address); 4555 %} 4556 ins_pipe(ialu_reg_reg_fat); 4557 %} 4558 4559 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4560 %{ 4561 match(Set dst mem); 4562 4563 ins_cost(110); 4564 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4565 ins_encode %{ 4566 __ leaq($dst$$Register, $mem$$Address); 4567 %} 4568 ins_pipe(ialu_reg_reg_fat); 4569 %} 4570 4571 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4572 %{ 4573 match(Set dst mem); 4574 4575 ins_cost(110); 4576 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4577 ins_encode %{ 4578 __ leaq($dst$$Register, $mem$$Address); 4579 %} 4580 ins_pipe(ialu_reg_reg_fat); 4581 %} 4582 4583 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4584 %{ 4585 match(Set dst mem); 4586 4587 ins_cost(110); 4588 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4589 ins_encode %{ 4590 __ leaq($dst$$Register, $mem$$Address); 4591 %} 4592 ins_pipe(ialu_reg_reg_fat); 4593 %} 4594 4595 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4596 %{ 4597 match(Set dst mem); 4598 4599 ins_cost(110); 4600 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4601 ins_encode %{ 4602 __ leaq($dst$$Register, $mem$$Address); 4603 %} 4604 ins_pipe(ialu_reg_reg_fat); 4605 %} 4606 4607 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4608 %{ 4609 match(Set dst mem); 4610 4611 ins_cost(110); 4612 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4613 ins_encode %{ 4614 __ leaq($dst$$Register, $mem$$Address); 4615 %} 4616 ins_pipe(ialu_reg_reg_fat); 4617 %} 4618 4619 // Load Effective Address which uses Narrow (32-bits) oop 4620 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4621 %{ 4622 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4623 match(Set dst mem); 4624 4625 ins_cost(110); 4626 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4627 ins_encode %{ 4628 __ leaq($dst$$Register, $mem$$Address); 4629 %} 4630 ins_pipe(ialu_reg_reg_fat); 4631 %} 4632 4633 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4634 %{ 4635 predicate(CompressedOops::shift() == 0); 4636 match(Set dst mem); 4637 4638 ins_cost(110); // XXX 4639 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4640 ins_encode %{ 4641 __ leaq($dst$$Register, $mem$$Address); 4642 %} 4643 ins_pipe(ialu_reg_reg_fat); 4644 %} 4645 4646 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4647 %{ 4648 predicate(CompressedOops::shift() == 0); 4649 match(Set dst mem); 4650 4651 ins_cost(110); 4652 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4653 ins_encode %{ 4654 __ leaq($dst$$Register, $mem$$Address); 4655 %} 4656 ins_pipe(ialu_reg_reg_fat); 4657 %} 4658 4659 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4660 %{ 4661 predicate(CompressedOops::shift() == 0); 4662 match(Set dst mem); 4663 4664 ins_cost(110); 4665 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4666 ins_encode %{ 4667 __ leaq($dst$$Register, $mem$$Address); 4668 %} 4669 ins_pipe(ialu_reg_reg_fat); 4670 %} 4671 4672 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4673 %{ 4674 predicate(CompressedOops::shift() == 0); 4675 match(Set dst mem); 4676 4677 ins_cost(110); 4678 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4679 ins_encode %{ 4680 __ leaq($dst$$Register, $mem$$Address); 4681 %} 4682 ins_pipe(ialu_reg_reg_fat); 4683 %} 4684 4685 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4686 %{ 4687 predicate(CompressedOops::shift() == 0); 4688 match(Set dst mem); 4689 4690 ins_cost(110); 4691 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4692 ins_encode %{ 4693 __ leaq($dst$$Register, $mem$$Address); 4694 %} 4695 ins_pipe(ialu_reg_reg_fat); 4696 %} 4697 4698 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4699 %{ 4700 predicate(CompressedOops::shift() == 0); 4701 match(Set dst mem); 4702 4703 ins_cost(110); 4704 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4705 ins_encode %{ 4706 __ leaq($dst$$Register, $mem$$Address); 4707 %} 4708 ins_pipe(ialu_reg_reg_fat); 4709 %} 4710 4711 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4712 %{ 4713 predicate(CompressedOops::shift() == 0); 4714 match(Set dst mem); 4715 4716 ins_cost(110); 4717 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4718 ins_encode %{ 4719 __ leaq($dst$$Register, $mem$$Address); 4720 %} 4721 ins_pipe(ialu_reg_reg_fat); 4722 %} 4723 4724 instruct loadConI(rRegI dst, immI src) 4725 %{ 4726 match(Set dst src); 4727 4728 format %{ "movl $dst, $src\t# int" %} 4729 ins_encode %{ 4730 __ movl($dst$$Register, $src$$constant); 4731 %} 4732 ins_pipe(ialu_reg_fat); // XXX 4733 %} 4734 4735 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4736 %{ 4737 match(Set dst src); 4738 effect(KILL cr); 4739 4740 ins_cost(50); 4741 format %{ "xorl $dst, $dst\t# int" %} 4742 ins_encode %{ 4743 __ xorl($dst$$Register, $dst$$Register); 4744 %} 4745 ins_pipe(ialu_reg); 4746 %} 4747 4748 instruct loadConL(rRegL dst, immL src) 4749 %{ 4750 match(Set dst src); 4751 4752 ins_cost(150); 4753 format %{ "movq $dst, $src\t# long" %} 4754 ins_encode %{ 4755 __ mov64($dst$$Register, $src$$constant); 4756 %} 4757 ins_pipe(ialu_reg); 4758 %} 4759 4760 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4761 %{ 4762 match(Set dst src); 4763 effect(KILL cr); 4764 4765 ins_cost(50); 4766 format %{ "xorl $dst, $dst\t# long" %} 4767 ins_encode %{ 4768 __ xorl($dst$$Register, $dst$$Register); 4769 %} 4770 ins_pipe(ialu_reg); // XXX 4771 %} 4772 4773 instruct loadConUL32(rRegL dst, immUL32 src) 4774 %{ 4775 match(Set dst src); 4776 4777 ins_cost(60); 4778 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4779 ins_encode %{ 4780 __ movl($dst$$Register, $src$$constant); 4781 %} 4782 ins_pipe(ialu_reg); 4783 %} 4784 4785 instruct loadConL32(rRegL dst, immL32 src) 4786 %{ 4787 match(Set dst src); 4788 4789 ins_cost(70); 4790 format %{ "movq $dst, $src\t# long (32-bit)" %} 4791 ins_encode %{ 4792 __ movq($dst$$Register, $src$$constant); 4793 %} 4794 ins_pipe(ialu_reg); 4795 %} 4796 4797 instruct loadConP(rRegP dst, immP con) %{ 4798 match(Set dst con); 4799 4800 format %{ "movq $dst, $con\t# ptr" %} 4801 ins_encode %{ 4802 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4803 %} 4804 ins_pipe(ialu_reg_fat); // XXX 4805 %} 4806 4807 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4808 %{ 4809 match(Set dst src); 4810 effect(KILL cr); 4811 4812 ins_cost(50); 4813 format %{ "xorl $dst, $dst\t# ptr" %} 4814 ins_encode %{ 4815 __ xorl($dst$$Register, $dst$$Register); 4816 %} 4817 ins_pipe(ialu_reg); 4818 %} 4819 4820 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4821 %{ 4822 match(Set dst src); 4823 effect(KILL cr); 4824 4825 ins_cost(60); 4826 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4827 ins_encode %{ 4828 __ movl($dst$$Register, $src$$constant); 4829 %} 4830 ins_pipe(ialu_reg); 4831 %} 4832 4833 instruct loadConF(regF dst, immF con) %{ 4834 match(Set dst con); 4835 ins_cost(125); 4836 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4837 ins_encode %{ 4838 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4839 %} 4840 ins_pipe(pipe_slow); 4841 %} 4842 4843 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4844 match(Set dst src); 4845 effect(KILL cr); 4846 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4847 ins_encode %{ 4848 __ xorq($dst$$Register, $dst$$Register); 4849 %} 4850 ins_pipe(ialu_reg); 4851 %} 4852 4853 instruct loadConN(rRegN dst, immN src) %{ 4854 match(Set dst src); 4855 4856 ins_cost(125); 4857 format %{ "movl $dst, $src\t# compressed ptr" %} 4858 ins_encode %{ 4859 address con = (address)$src$$constant; 4860 if (con == nullptr) { 4861 ShouldNotReachHere(); 4862 } else { 4863 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4864 } 4865 %} 4866 ins_pipe(ialu_reg_fat); // XXX 4867 %} 4868 4869 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4870 match(Set dst src); 4871 4872 ins_cost(125); 4873 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4874 ins_encode %{ 4875 address con = (address)$src$$constant; 4876 if (con == nullptr) { 4877 ShouldNotReachHere(); 4878 } else { 4879 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4880 } 4881 %} 4882 ins_pipe(ialu_reg_fat); // XXX 4883 %} 4884 4885 instruct loadConF0(regF dst, immF0 src) 4886 %{ 4887 match(Set dst src); 4888 ins_cost(100); 4889 4890 format %{ "xorps $dst, $dst\t# float 0.0" %} 4891 ins_encode %{ 4892 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4893 %} 4894 ins_pipe(pipe_slow); 4895 %} 4896 4897 // Use the same format since predicate() can not be used here. 4898 instruct loadConD(regD dst, immD con) %{ 4899 match(Set dst con); 4900 ins_cost(125); 4901 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4902 ins_encode %{ 4903 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4904 %} 4905 ins_pipe(pipe_slow); 4906 %} 4907 4908 instruct loadConD0(regD dst, immD0 src) 4909 %{ 4910 match(Set dst src); 4911 ins_cost(100); 4912 4913 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4914 ins_encode %{ 4915 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4916 %} 4917 ins_pipe(pipe_slow); 4918 %} 4919 4920 instruct loadSSI(rRegI dst, stackSlotI src) 4921 %{ 4922 match(Set dst src); 4923 4924 ins_cost(125); 4925 format %{ "movl $dst, $src\t# int stk" %} 4926 ins_encode %{ 4927 __ movl($dst$$Register, $src$$Address); 4928 %} 4929 ins_pipe(ialu_reg_mem); 4930 %} 4931 4932 instruct loadSSL(rRegL dst, stackSlotL src) 4933 %{ 4934 match(Set dst src); 4935 4936 ins_cost(125); 4937 format %{ "movq $dst, $src\t# long stk" %} 4938 ins_encode %{ 4939 __ movq($dst$$Register, $src$$Address); 4940 %} 4941 ins_pipe(ialu_reg_mem); 4942 %} 4943 4944 instruct loadSSP(rRegP dst, stackSlotP src) 4945 %{ 4946 match(Set dst src); 4947 4948 ins_cost(125); 4949 format %{ "movq $dst, $src\t# ptr stk" %} 4950 ins_encode %{ 4951 __ movq($dst$$Register, $src$$Address); 4952 %} 4953 ins_pipe(ialu_reg_mem); 4954 %} 4955 4956 instruct loadSSF(regF dst, stackSlotF src) 4957 %{ 4958 match(Set dst src); 4959 4960 ins_cost(125); 4961 format %{ "movss $dst, $src\t# float stk" %} 4962 ins_encode %{ 4963 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 4964 %} 4965 ins_pipe(pipe_slow); // XXX 4966 %} 4967 4968 // Use the same format since predicate() can not be used here. 4969 instruct loadSSD(regD dst, stackSlotD src) 4970 %{ 4971 match(Set dst src); 4972 4973 ins_cost(125); 4974 format %{ "movsd $dst, $src\t# double stk" %} 4975 ins_encode %{ 4976 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 4977 %} 4978 ins_pipe(pipe_slow); // XXX 4979 %} 4980 4981 // Prefetch instructions for allocation. 4982 // Must be safe to execute with invalid address (cannot fault). 4983 4984 instruct prefetchAlloc( memory mem ) %{ 4985 predicate(AllocatePrefetchInstr==3); 4986 match(PrefetchAllocation mem); 4987 ins_cost(125); 4988 4989 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 4990 ins_encode %{ 4991 __ prefetchw($mem$$Address); 4992 %} 4993 ins_pipe(ialu_mem); 4994 %} 4995 4996 instruct prefetchAllocNTA( memory mem ) %{ 4997 predicate(AllocatePrefetchInstr==0); 4998 match(PrefetchAllocation mem); 4999 ins_cost(125); 5000 5001 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5002 ins_encode %{ 5003 __ prefetchnta($mem$$Address); 5004 %} 5005 ins_pipe(ialu_mem); 5006 %} 5007 5008 instruct prefetchAllocT0( memory mem ) %{ 5009 predicate(AllocatePrefetchInstr==1); 5010 match(PrefetchAllocation mem); 5011 ins_cost(125); 5012 5013 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5014 ins_encode %{ 5015 __ prefetcht0($mem$$Address); 5016 %} 5017 ins_pipe(ialu_mem); 5018 %} 5019 5020 instruct prefetchAllocT2( memory mem ) %{ 5021 predicate(AllocatePrefetchInstr==2); 5022 match(PrefetchAllocation mem); 5023 ins_cost(125); 5024 5025 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5026 ins_encode %{ 5027 __ prefetcht2($mem$$Address); 5028 %} 5029 ins_pipe(ialu_mem); 5030 %} 5031 5032 //----------Store Instructions------------------------------------------------- 5033 5034 // Store Byte 5035 instruct storeB(memory mem, rRegI src) 5036 %{ 5037 match(Set mem (StoreB mem src)); 5038 5039 ins_cost(125); // XXX 5040 format %{ "movb $mem, $src\t# byte" %} 5041 ins_encode %{ 5042 __ movb($mem$$Address, $src$$Register); 5043 %} 5044 ins_pipe(ialu_mem_reg); 5045 %} 5046 5047 // Store Char/Short 5048 instruct storeC(memory mem, rRegI src) 5049 %{ 5050 match(Set mem (StoreC mem src)); 5051 5052 ins_cost(125); // XXX 5053 format %{ "movw $mem, $src\t# char/short" %} 5054 ins_encode %{ 5055 __ movw($mem$$Address, $src$$Register); 5056 %} 5057 ins_pipe(ialu_mem_reg); 5058 %} 5059 5060 // Store Integer 5061 instruct storeI(memory mem, rRegI src) 5062 %{ 5063 match(Set mem (StoreI mem src)); 5064 5065 ins_cost(125); // XXX 5066 format %{ "movl $mem, $src\t# int" %} 5067 ins_encode %{ 5068 __ movl($mem$$Address, $src$$Register); 5069 %} 5070 ins_pipe(ialu_mem_reg); 5071 %} 5072 5073 // Store Long 5074 instruct storeL(memory mem, rRegL src) 5075 %{ 5076 match(Set mem (StoreL mem src)); 5077 5078 ins_cost(125); // XXX 5079 format %{ "movq $mem, $src\t# long" %} 5080 ins_encode %{ 5081 __ movq($mem$$Address, $src$$Register); 5082 %} 5083 ins_pipe(ialu_mem_reg); // XXX 5084 %} 5085 5086 // Store Pointer 5087 instruct storeP(memory mem, any_RegP src) 5088 %{ 5089 predicate(n->as_Store()->barrier_data() == 0); 5090 match(Set mem (StoreP mem src)); 5091 5092 ins_cost(125); // XXX 5093 format %{ "movq $mem, $src\t# ptr" %} 5094 ins_encode %{ 5095 __ movq($mem$$Address, $src$$Register); 5096 %} 5097 ins_pipe(ialu_mem_reg); 5098 %} 5099 5100 instruct storeImmP0(memory mem, immP0 zero) 5101 %{ 5102 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5103 match(Set mem (StoreP mem zero)); 5104 5105 ins_cost(125); // XXX 5106 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5107 ins_encode %{ 5108 __ movq($mem$$Address, r12); 5109 %} 5110 ins_pipe(ialu_mem_reg); 5111 %} 5112 5113 // Store Null Pointer, mark word, or other simple pointer constant. 5114 instruct storeImmP(memory mem, immP31 src) 5115 %{ 5116 predicate(n->as_Store()->barrier_data() == 0); 5117 match(Set mem (StoreP mem src)); 5118 5119 ins_cost(150); // XXX 5120 format %{ "movq $mem, $src\t# ptr" %} 5121 ins_encode %{ 5122 __ movq($mem$$Address, $src$$constant); 5123 %} 5124 ins_pipe(ialu_mem_imm); 5125 %} 5126 5127 // Store Compressed Pointer 5128 instruct storeN(memory mem, rRegN src) 5129 %{ 5130 predicate(n->as_Store()->barrier_data() == 0); 5131 match(Set mem (StoreN mem src)); 5132 5133 ins_cost(125); // XXX 5134 format %{ "movl $mem, $src\t# compressed ptr" %} 5135 ins_encode %{ 5136 __ movl($mem$$Address, $src$$Register); 5137 %} 5138 ins_pipe(ialu_mem_reg); 5139 %} 5140 5141 instruct storeNKlass(memory mem, rRegN src) 5142 %{ 5143 match(Set mem (StoreNKlass mem src)); 5144 5145 ins_cost(125); // XXX 5146 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5147 ins_encode %{ 5148 __ movl($mem$$Address, $src$$Register); 5149 %} 5150 ins_pipe(ialu_mem_reg); 5151 %} 5152 5153 instruct storeImmN0(memory mem, immN0 zero) 5154 %{ 5155 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5156 match(Set mem (StoreN mem zero)); 5157 5158 ins_cost(125); // XXX 5159 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5160 ins_encode %{ 5161 __ movl($mem$$Address, r12); 5162 %} 5163 ins_pipe(ialu_mem_reg); 5164 %} 5165 5166 instruct storeImmN(memory mem, immN src) 5167 %{ 5168 predicate(n->as_Store()->barrier_data() == 0); 5169 match(Set mem (StoreN mem src)); 5170 5171 ins_cost(150); // XXX 5172 format %{ "movl $mem, $src\t# compressed ptr" %} 5173 ins_encode %{ 5174 address con = (address)$src$$constant; 5175 if (con == nullptr) { 5176 __ movl($mem$$Address, 0); 5177 } else { 5178 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5179 } 5180 %} 5181 ins_pipe(ialu_mem_imm); 5182 %} 5183 5184 instruct storeImmNKlass(memory mem, immNKlass src) 5185 %{ 5186 match(Set mem (StoreNKlass mem src)); 5187 5188 ins_cost(150); // XXX 5189 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5190 ins_encode %{ 5191 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5192 %} 5193 ins_pipe(ialu_mem_imm); 5194 %} 5195 5196 // Store Integer Immediate 5197 instruct storeImmI0(memory mem, immI_0 zero) 5198 %{ 5199 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5200 match(Set mem (StoreI mem zero)); 5201 5202 ins_cost(125); // XXX 5203 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5204 ins_encode %{ 5205 __ movl($mem$$Address, r12); 5206 %} 5207 ins_pipe(ialu_mem_reg); 5208 %} 5209 5210 instruct storeImmI(memory mem, immI src) 5211 %{ 5212 match(Set mem (StoreI mem src)); 5213 5214 ins_cost(150); 5215 format %{ "movl $mem, $src\t# int" %} 5216 ins_encode %{ 5217 __ movl($mem$$Address, $src$$constant); 5218 %} 5219 ins_pipe(ialu_mem_imm); 5220 %} 5221 5222 // Store Long Immediate 5223 instruct storeImmL0(memory mem, immL0 zero) 5224 %{ 5225 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5226 match(Set mem (StoreL mem zero)); 5227 5228 ins_cost(125); // XXX 5229 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5230 ins_encode %{ 5231 __ movq($mem$$Address, r12); 5232 %} 5233 ins_pipe(ialu_mem_reg); 5234 %} 5235 5236 instruct storeImmL(memory mem, immL32 src) 5237 %{ 5238 match(Set mem (StoreL mem src)); 5239 5240 ins_cost(150); 5241 format %{ "movq $mem, $src\t# long" %} 5242 ins_encode %{ 5243 __ movq($mem$$Address, $src$$constant); 5244 %} 5245 ins_pipe(ialu_mem_imm); 5246 %} 5247 5248 // Store Short/Char Immediate 5249 instruct storeImmC0(memory mem, immI_0 zero) 5250 %{ 5251 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5252 match(Set mem (StoreC mem zero)); 5253 5254 ins_cost(125); // XXX 5255 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5256 ins_encode %{ 5257 __ movw($mem$$Address, r12); 5258 %} 5259 ins_pipe(ialu_mem_reg); 5260 %} 5261 5262 instruct storeImmI16(memory mem, immI16 src) 5263 %{ 5264 predicate(UseStoreImmI16); 5265 match(Set mem (StoreC mem src)); 5266 5267 ins_cost(150); 5268 format %{ "movw $mem, $src\t# short/char" %} 5269 ins_encode %{ 5270 __ movw($mem$$Address, $src$$constant); 5271 %} 5272 ins_pipe(ialu_mem_imm); 5273 %} 5274 5275 // Store Byte Immediate 5276 instruct storeImmB0(memory mem, immI_0 zero) 5277 %{ 5278 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5279 match(Set mem (StoreB mem zero)); 5280 5281 ins_cost(125); // XXX 5282 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5283 ins_encode %{ 5284 __ movb($mem$$Address, r12); 5285 %} 5286 ins_pipe(ialu_mem_reg); 5287 %} 5288 5289 instruct storeImmB(memory mem, immI8 src) 5290 %{ 5291 match(Set mem (StoreB mem src)); 5292 5293 ins_cost(150); // XXX 5294 format %{ "movb $mem, $src\t# byte" %} 5295 ins_encode %{ 5296 __ movb($mem$$Address, $src$$constant); 5297 %} 5298 ins_pipe(ialu_mem_imm); 5299 %} 5300 5301 // Store Float 5302 instruct storeF(memory mem, regF src) 5303 %{ 5304 match(Set mem (StoreF mem src)); 5305 5306 ins_cost(95); // XXX 5307 format %{ "movss $mem, $src\t# float" %} 5308 ins_encode %{ 5309 __ movflt($mem$$Address, $src$$XMMRegister); 5310 %} 5311 ins_pipe(pipe_slow); // XXX 5312 %} 5313 5314 // Store immediate Float value (it is faster than store from XMM register) 5315 instruct storeF0(memory mem, immF0 zero) 5316 %{ 5317 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5318 match(Set mem (StoreF mem zero)); 5319 5320 ins_cost(25); // XXX 5321 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5322 ins_encode %{ 5323 __ movl($mem$$Address, r12); 5324 %} 5325 ins_pipe(ialu_mem_reg); 5326 %} 5327 5328 instruct storeF_imm(memory mem, immF src) 5329 %{ 5330 match(Set mem (StoreF mem src)); 5331 5332 ins_cost(50); 5333 format %{ "movl $mem, $src\t# float" %} 5334 ins_encode %{ 5335 __ movl($mem$$Address, jint_cast($src$$constant)); 5336 %} 5337 ins_pipe(ialu_mem_imm); 5338 %} 5339 5340 // Store Double 5341 instruct storeD(memory mem, regD src) 5342 %{ 5343 match(Set mem (StoreD mem src)); 5344 5345 ins_cost(95); // XXX 5346 format %{ "movsd $mem, $src\t# double" %} 5347 ins_encode %{ 5348 __ movdbl($mem$$Address, $src$$XMMRegister); 5349 %} 5350 ins_pipe(pipe_slow); // XXX 5351 %} 5352 5353 // Store immediate double 0.0 (it is faster than store from XMM register) 5354 instruct storeD0_imm(memory mem, immD0 src) 5355 %{ 5356 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5357 match(Set mem (StoreD mem src)); 5358 5359 ins_cost(50); 5360 format %{ "movq $mem, $src\t# double 0." %} 5361 ins_encode %{ 5362 __ movq($mem$$Address, $src$$constant); 5363 %} 5364 ins_pipe(ialu_mem_imm); 5365 %} 5366 5367 instruct storeD0(memory mem, immD0 zero) 5368 %{ 5369 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5370 match(Set mem (StoreD mem zero)); 5371 5372 ins_cost(25); // XXX 5373 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5374 ins_encode %{ 5375 __ movq($mem$$Address, r12); 5376 %} 5377 ins_pipe(ialu_mem_reg); 5378 %} 5379 5380 instruct storeSSI(stackSlotI dst, rRegI src) 5381 %{ 5382 match(Set dst src); 5383 5384 ins_cost(100); 5385 format %{ "movl $dst, $src\t# int stk" %} 5386 ins_encode %{ 5387 __ movl($dst$$Address, $src$$Register); 5388 %} 5389 ins_pipe( ialu_mem_reg ); 5390 %} 5391 5392 instruct storeSSL(stackSlotL dst, rRegL src) 5393 %{ 5394 match(Set dst src); 5395 5396 ins_cost(100); 5397 format %{ "movq $dst, $src\t# long stk" %} 5398 ins_encode %{ 5399 __ movq($dst$$Address, $src$$Register); 5400 %} 5401 ins_pipe(ialu_mem_reg); 5402 %} 5403 5404 instruct storeSSP(stackSlotP dst, rRegP src) 5405 %{ 5406 match(Set dst src); 5407 5408 ins_cost(100); 5409 format %{ "movq $dst, $src\t# ptr stk" %} 5410 ins_encode %{ 5411 __ movq($dst$$Address, $src$$Register); 5412 %} 5413 ins_pipe(ialu_mem_reg); 5414 %} 5415 5416 instruct storeSSF(stackSlotF dst, regF src) 5417 %{ 5418 match(Set dst src); 5419 5420 ins_cost(95); // XXX 5421 format %{ "movss $dst, $src\t# float stk" %} 5422 ins_encode %{ 5423 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5424 %} 5425 ins_pipe(pipe_slow); // XXX 5426 %} 5427 5428 instruct storeSSD(stackSlotD dst, regD src) 5429 %{ 5430 match(Set dst src); 5431 5432 ins_cost(95); // XXX 5433 format %{ "movsd $dst, $src\t# double stk" %} 5434 ins_encode %{ 5435 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5436 %} 5437 ins_pipe(pipe_slow); // XXX 5438 %} 5439 5440 instruct cacheWB(indirect addr) 5441 %{ 5442 predicate(VM_Version::supports_data_cache_line_flush()); 5443 match(CacheWB addr); 5444 5445 ins_cost(100); 5446 format %{"cache wb $addr" %} 5447 ins_encode %{ 5448 assert($addr->index_position() < 0, "should be"); 5449 assert($addr$$disp == 0, "should be"); 5450 __ cache_wb(Address($addr$$base$$Register, 0)); 5451 %} 5452 ins_pipe(pipe_slow); // XXX 5453 %} 5454 5455 instruct cacheWBPreSync() 5456 %{ 5457 predicate(VM_Version::supports_data_cache_line_flush()); 5458 match(CacheWBPreSync); 5459 5460 ins_cost(100); 5461 format %{"cache wb presync" %} 5462 ins_encode %{ 5463 __ cache_wbsync(true); 5464 %} 5465 ins_pipe(pipe_slow); // XXX 5466 %} 5467 5468 instruct cacheWBPostSync() 5469 %{ 5470 predicate(VM_Version::supports_data_cache_line_flush()); 5471 match(CacheWBPostSync); 5472 5473 ins_cost(100); 5474 format %{"cache wb postsync" %} 5475 ins_encode %{ 5476 __ cache_wbsync(false); 5477 %} 5478 ins_pipe(pipe_slow); // XXX 5479 %} 5480 5481 //----------BSWAP Instructions------------------------------------------------- 5482 instruct bytes_reverse_int(rRegI dst) %{ 5483 match(Set dst (ReverseBytesI dst)); 5484 5485 format %{ "bswapl $dst" %} 5486 ins_encode %{ 5487 __ bswapl($dst$$Register); 5488 %} 5489 ins_pipe( ialu_reg ); 5490 %} 5491 5492 instruct bytes_reverse_long(rRegL dst) %{ 5493 match(Set dst (ReverseBytesL dst)); 5494 5495 format %{ "bswapq $dst" %} 5496 ins_encode %{ 5497 __ bswapq($dst$$Register); 5498 %} 5499 ins_pipe( ialu_reg); 5500 %} 5501 5502 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5503 match(Set dst (ReverseBytesUS dst)); 5504 effect(KILL cr); 5505 5506 format %{ "bswapl $dst\n\t" 5507 "shrl $dst,16\n\t" %} 5508 ins_encode %{ 5509 __ bswapl($dst$$Register); 5510 __ shrl($dst$$Register, 16); 5511 %} 5512 ins_pipe( ialu_reg ); 5513 %} 5514 5515 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5516 match(Set dst (ReverseBytesS dst)); 5517 effect(KILL cr); 5518 5519 format %{ "bswapl $dst\n\t" 5520 "sar $dst,16\n\t" %} 5521 ins_encode %{ 5522 __ bswapl($dst$$Register); 5523 __ sarl($dst$$Register, 16); 5524 %} 5525 ins_pipe( ialu_reg ); 5526 %} 5527 5528 //---------- Zeros Count Instructions ------------------------------------------ 5529 5530 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5531 predicate(UseCountLeadingZerosInstruction); 5532 match(Set dst (CountLeadingZerosI src)); 5533 effect(KILL cr); 5534 5535 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5536 ins_encode %{ 5537 __ lzcntl($dst$$Register, $src$$Register); 5538 %} 5539 ins_pipe(ialu_reg); 5540 %} 5541 5542 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5543 predicate(UseCountLeadingZerosInstruction); 5544 match(Set dst (CountLeadingZerosI (LoadI src))); 5545 effect(KILL cr); 5546 ins_cost(175); 5547 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5548 ins_encode %{ 5549 __ lzcntl($dst$$Register, $src$$Address); 5550 %} 5551 ins_pipe(ialu_reg_mem); 5552 %} 5553 5554 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5555 predicate(!UseCountLeadingZerosInstruction); 5556 match(Set dst (CountLeadingZerosI src)); 5557 effect(KILL cr); 5558 5559 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5560 "jnz skip\n\t" 5561 "movl $dst, -1\n" 5562 "skip:\n\t" 5563 "negl $dst\n\t" 5564 "addl $dst, 31" %} 5565 ins_encode %{ 5566 Register Rdst = $dst$$Register; 5567 Register Rsrc = $src$$Register; 5568 Label skip; 5569 __ bsrl(Rdst, Rsrc); 5570 __ jccb(Assembler::notZero, skip); 5571 __ movl(Rdst, -1); 5572 __ bind(skip); 5573 __ negl(Rdst); 5574 __ addl(Rdst, BitsPerInt - 1); 5575 %} 5576 ins_pipe(ialu_reg); 5577 %} 5578 5579 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5580 predicate(UseCountLeadingZerosInstruction); 5581 match(Set dst (CountLeadingZerosL src)); 5582 effect(KILL cr); 5583 5584 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5585 ins_encode %{ 5586 __ lzcntq($dst$$Register, $src$$Register); 5587 %} 5588 ins_pipe(ialu_reg); 5589 %} 5590 5591 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5592 predicate(UseCountLeadingZerosInstruction); 5593 match(Set dst (CountLeadingZerosL (LoadL src))); 5594 effect(KILL cr); 5595 ins_cost(175); 5596 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5597 ins_encode %{ 5598 __ lzcntq($dst$$Register, $src$$Address); 5599 %} 5600 ins_pipe(ialu_reg_mem); 5601 %} 5602 5603 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5604 predicate(!UseCountLeadingZerosInstruction); 5605 match(Set dst (CountLeadingZerosL src)); 5606 effect(KILL cr); 5607 5608 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5609 "jnz skip\n\t" 5610 "movl $dst, -1\n" 5611 "skip:\n\t" 5612 "negl $dst\n\t" 5613 "addl $dst, 63" %} 5614 ins_encode %{ 5615 Register Rdst = $dst$$Register; 5616 Register Rsrc = $src$$Register; 5617 Label skip; 5618 __ bsrq(Rdst, Rsrc); 5619 __ jccb(Assembler::notZero, skip); 5620 __ movl(Rdst, -1); 5621 __ bind(skip); 5622 __ negl(Rdst); 5623 __ addl(Rdst, BitsPerLong - 1); 5624 %} 5625 ins_pipe(ialu_reg); 5626 %} 5627 5628 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5629 predicate(UseCountTrailingZerosInstruction); 5630 match(Set dst (CountTrailingZerosI src)); 5631 effect(KILL cr); 5632 5633 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5634 ins_encode %{ 5635 __ tzcntl($dst$$Register, $src$$Register); 5636 %} 5637 ins_pipe(ialu_reg); 5638 %} 5639 5640 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5641 predicate(UseCountTrailingZerosInstruction); 5642 match(Set dst (CountTrailingZerosI (LoadI src))); 5643 effect(KILL cr); 5644 ins_cost(175); 5645 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5646 ins_encode %{ 5647 __ tzcntl($dst$$Register, $src$$Address); 5648 %} 5649 ins_pipe(ialu_reg_mem); 5650 %} 5651 5652 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5653 predicate(!UseCountTrailingZerosInstruction); 5654 match(Set dst (CountTrailingZerosI src)); 5655 effect(KILL cr); 5656 5657 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5658 "jnz done\n\t" 5659 "movl $dst, 32\n" 5660 "done:" %} 5661 ins_encode %{ 5662 Register Rdst = $dst$$Register; 5663 Label done; 5664 __ bsfl(Rdst, $src$$Register); 5665 __ jccb(Assembler::notZero, done); 5666 __ movl(Rdst, BitsPerInt); 5667 __ bind(done); 5668 %} 5669 ins_pipe(ialu_reg); 5670 %} 5671 5672 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5673 predicate(UseCountTrailingZerosInstruction); 5674 match(Set dst (CountTrailingZerosL src)); 5675 effect(KILL cr); 5676 5677 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5678 ins_encode %{ 5679 __ tzcntq($dst$$Register, $src$$Register); 5680 %} 5681 ins_pipe(ialu_reg); 5682 %} 5683 5684 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5685 predicate(UseCountTrailingZerosInstruction); 5686 match(Set dst (CountTrailingZerosL (LoadL src))); 5687 effect(KILL cr); 5688 ins_cost(175); 5689 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5690 ins_encode %{ 5691 __ tzcntq($dst$$Register, $src$$Address); 5692 %} 5693 ins_pipe(ialu_reg_mem); 5694 %} 5695 5696 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5697 predicate(!UseCountTrailingZerosInstruction); 5698 match(Set dst (CountTrailingZerosL src)); 5699 effect(KILL cr); 5700 5701 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5702 "jnz done\n\t" 5703 "movl $dst, 64\n" 5704 "done:" %} 5705 ins_encode %{ 5706 Register Rdst = $dst$$Register; 5707 Label done; 5708 __ bsfq(Rdst, $src$$Register); 5709 __ jccb(Assembler::notZero, done); 5710 __ movl(Rdst, BitsPerLong); 5711 __ bind(done); 5712 %} 5713 ins_pipe(ialu_reg); 5714 %} 5715 5716 //--------------- Reverse Operation Instructions ---------------- 5717 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5718 predicate(!VM_Version::supports_gfni()); 5719 match(Set dst (ReverseI src)); 5720 effect(TEMP dst, TEMP rtmp, KILL cr); 5721 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5722 ins_encode %{ 5723 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5724 %} 5725 ins_pipe( ialu_reg ); 5726 %} 5727 5728 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5729 predicate(VM_Version::supports_gfni()); 5730 match(Set dst (ReverseI src)); 5731 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5732 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5733 ins_encode %{ 5734 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5735 %} 5736 ins_pipe( ialu_reg ); 5737 %} 5738 5739 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5740 predicate(!VM_Version::supports_gfni()); 5741 match(Set dst (ReverseL src)); 5742 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5743 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5744 ins_encode %{ 5745 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5746 %} 5747 ins_pipe( ialu_reg ); 5748 %} 5749 5750 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5751 predicate(VM_Version::supports_gfni()); 5752 match(Set dst (ReverseL src)); 5753 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5754 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5755 ins_encode %{ 5756 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5757 %} 5758 ins_pipe( ialu_reg ); 5759 %} 5760 5761 //---------- Population Count Instructions ------------------------------------- 5762 5763 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5764 predicate(UsePopCountInstruction); 5765 match(Set dst (PopCountI src)); 5766 effect(KILL cr); 5767 5768 format %{ "popcnt $dst, $src" %} 5769 ins_encode %{ 5770 __ popcntl($dst$$Register, $src$$Register); 5771 %} 5772 ins_pipe(ialu_reg); 5773 %} 5774 5775 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5776 predicate(UsePopCountInstruction); 5777 match(Set dst (PopCountI (LoadI mem))); 5778 effect(KILL cr); 5779 5780 format %{ "popcnt $dst, $mem" %} 5781 ins_encode %{ 5782 __ popcntl($dst$$Register, $mem$$Address); 5783 %} 5784 ins_pipe(ialu_reg); 5785 %} 5786 5787 // Note: Long.bitCount(long) returns an int. 5788 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5789 predicate(UsePopCountInstruction); 5790 match(Set dst (PopCountL src)); 5791 effect(KILL cr); 5792 5793 format %{ "popcnt $dst, $src" %} 5794 ins_encode %{ 5795 __ popcntq($dst$$Register, $src$$Register); 5796 %} 5797 ins_pipe(ialu_reg); 5798 %} 5799 5800 // Note: Long.bitCount(long) returns an int. 5801 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5802 predicate(UsePopCountInstruction); 5803 match(Set dst (PopCountL (LoadL mem))); 5804 effect(KILL cr); 5805 5806 format %{ "popcnt $dst, $mem" %} 5807 ins_encode %{ 5808 __ popcntq($dst$$Register, $mem$$Address); 5809 %} 5810 ins_pipe(ialu_reg); 5811 %} 5812 5813 5814 //----------MemBar Instructions----------------------------------------------- 5815 // Memory barrier flavors 5816 5817 instruct membar_acquire() 5818 %{ 5819 match(MemBarAcquire); 5820 match(LoadFence); 5821 ins_cost(0); 5822 5823 size(0); 5824 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5825 ins_encode(); 5826 ins_pipe(empty); 5827 %} 5828 5829 instruct membar_acquire_lock() 5830 %{ 5831 match(MemBarAcquireLock); 5832 ins_cost(0); 5833 5834 size(0); 5835 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5836 ins_encode(); 5837 ins_pipe(empty); 5838 %} 5839 5840 instruct membar_release() 5841 %{ 5842 match(MemBarRelease); 5843 match(StoreFence); 5844 ins_cost(0); 5845 5846 size(0); 5847 format %{ "MEMBAR-release ! (empty encoding)" %} 5848 ins_encode(); 5849 ins_pipe(empty); 5850 %} 5851 5852 instruct membar_release_lock() 5853 %{ 5854 match(MemBarReleaseLock); 5855 ins_cost(0); 5856 5857 size(0); 5858 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5859 ins_encode(); 5860 ins_pipe(empty); 5861 %} 5862 5863 instruct membar_volatile(rFlagsReg cr) %{ 5864 match(MemBarVolatile); 5865 effect(KILL cr); 5866 ins_cost(400); 5867 5868 format %{ 5869 $$template 5870 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5871 %} 5872 ins_encode %{ 5873 __ membar(Assembler::StoreLoad); 5874 %} 5875 ins_pipe(pipe_slow); 5876 %} 5877 5878 instruct unnecessary_membar_volatile() 5879 %{ 5880 match(MemBarVolatile); 5881 predicate(Matcher::post_store_load_barrier(n)); 5882 ins_cost(0); 5883 5884 size(0); 5885 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5886 ins_encode(); 5887 ins_pipe(empty); 5888 %} 5889 5890 instruct membar_storestore() %{ 5891 match(MemBarStoreStore); 5892 match(StoreStoreFence); 5893 ins_cost(0); 5894 5895 size(0); 5896 format %{ "MEMBAR-storestore (empty encoding)" %} 5897 ins_encode( ); 5898 ins_pipe(empty); 5899 %} 5900 5901 //----------Move Instructions-------------------------------------------------- 5902 5903 instruct castX2P(rRegP dst, rRegL src) 5904 %{ 5905 match(Set dst (CastX2P src)); 5906 5907 format %{ "movq $dst, $src\t# long->ptr" %} 5908 ins_encode %{ 5909 if ($dst$$reg != $src$$reg) { 5910 __ movptr($dst$$Register, $src$$Register); 5911 } 5912 %} 5913 ins_pipe(ialu_reg_reg); // XXX 5914 %} 5915 5916 instruct castP2X(rRegL dst, rRegP src) 5917 %{ 5918 match(Set dst (CastP2X src)); 5919 5920 format %{ "movq $dst, $src\t# ptr -> long" %} 5921 ins_encode %{ 5922 if ($dst$$reg != $src$$reg) { 5923 __ movptr($dst$$Register, $src$$Register); 5924 } 5925 %} 5926 ins_pipe(ialu_reg_reg); // XXX 5927 %} 5928 5929 // Convert oop into int for vectors alignment masking 5930 instruct convP2I(rRegI dst, rRegP src) 5931 %{ 5932 match(Set dst (ConvL2I (CastP2X src))); 5933 5934 format %{ "movl $dst, $src\t# ptr -> int" %} 5935 ins_encode %{ 5936 __ movl($dst$$Register, $src$$Register); 5937 %} 5938 ins_pipe(ialu_reg_reg); // XXX 5939 %} 5940 5941 // Convert compressed oop into int for vectors alignment masking 5942 // in case of 32bit oops (heap < 4Gb). 5943 instruct convN2I(rRegI dst, rRegN src) 5944 %{ 5945 predicate(CompressedOops::shift() == 0); 5946 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5947 5948 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5949 ins_encode %{ 5950 __ movl($dst$$Register, $src$$Register); 5951 %} 5952 ins_pipe(ialu_reg_reg); // XXX 5953 %} 5954 5955 // Convert oop pointer into compressed form 5956 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5957 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5958 match(Set dst (EncodeP src)); 5959 effect(KILL cr); 5960 format %{ "encode_heap_oop $dst,$src" %} 5961 ins_encode %{ 5962 Register s = $src$$Register; 5963 Register d = $dst$$Register; 5964 if (s != d) { 5965 __ movq(d, s); 5966 } 5967 __ encode_heap_oop(d); 5968 %} 5969 ins_pipe(ialu_reg_long); 5970 %} 5971 5972 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5973 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 5974 match(Set dst (EncodeP src)); 5975 effect(KILL cr); 5976 format %{ "encode_heap_oop_not_null $dst,$src" %} 5977 ins_encode %{ 5978 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 5979 %} 5980 ins_pipe(ialu_reg_long); 5981 %} 5982 5983 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 5984 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 5985 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 5986 match(Set dst (DecodeN src)); 5987 effect(KILL cr); 5988 format %{ "decode_heap_oop $dst,$src" %} 5989 ins_encode %{ 5990 Register s = $src$$Register; 5991 Register d = $dst$$Register; 5992 if (s != d) { 5993 __ movq(d, s); 5994 } 5995 __ decode_heap_oop(d); 5996 %} 5997 ins_pipe(ialu_reg_long); 5998 %} 5999 6000 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6001 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6002 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6003 match(Set dst (DecodeN src)); 6004 effect(KILL cr); 6005 format %{ "decode_heap_oop_not_null $dst,$src" %} 6006 ins_encode %{ 6007 Register s = $src$$Register; 6008 Register d = $dst$$Register; 6009 if (s != d) { 6010 __ decode_heap_oop_not_null(d, s); 6011 } else { 6012 __ decode_heap_oop_not_null(d); 6013 } 6014 %} 6015 ins_pipe(ialu_reg_long); 6016 %} 6017 6018 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6019 match(Set dst (EncodePKlass src)); 6020 effect(TEMP dst, KILL cr); 6021 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6022 ins_encode %{ 6023 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6024 %} 6025 ins_pipe(ialu_reg_long); 6026 %} 6027 6028 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6029 match(Set dst (DecodeNKlass src)); 6030 effect(TEMP dst, KILL cr); 6031 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6032 ins_encode %{ 6033 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6034 %} 6035 ins_pipe(ialu_reg_long); 6036 %} 6037 6038 //----------Conditional Move--------------------------------------------------- 6039 // Jump 6040 // dummy instruction for generating temp registers 6041 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6042 match(Jump (LShiftL switch_val shift)); 6043 ins_cost(350); 6044 predicate(false); 6045 effect(TEMP dest); 6046 6047 format %{ "leaq $dest, [$constantaddress]\n\t" 6048 "jmp [$dest + $switch_val << $shift]\n\t" %} 6049 ins_encode %{ 6050 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6051 // to do that and the compiler is using that register as one it can allocate. 6052 // So we build it all by hand. 6053 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6054 // ArrayAddress dispatch(table, index); 6055 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6056 __ lea($dest$$Register, $constantaddress); 6057 __ jmp(dispatch); 6058 %} 6059 ins_pipe(pipe_jmp); 6060 %} 6061 6062 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6063 match(Jump (AddL (LShiftL switch_val shift) offset)); 6064 ins_cost(350); 6065 effect(TEMP dest); 6066 6067 format %{ "leaq $dest, [$constantaddress]\n\t" 6068 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6069 ins_encode %{ 6070 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6071 // to do that and the compiler is using that register as one it can allocate. 6072 // So we build it all by hand. 6073 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6074 // ArrayAddress dispatch(table, index); 6075 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6076 __ lea($dest$$Register, $constantaddress); 6077 __ jmp(dispatch); 6078 %} 6079 ins_pipe(pipe_jmp); 6080 %} 6081 6082 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6083 match(Jump switch_val); 6084 ins_cost(350); 6085 effect(TEMP dest); 6086 6087 format %{ "leaq $dest, [$constantaddress]\n\t" 6088 "jmp [$dest + $switch_val]\n\t" %} 6089 ins_encode %{ 6090 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6091 // to do that and the compiler is using that register as one it can allocate. 6092 // So we build it all by hand. 6093 // Address index(noreg, switch_reg, Address::times_1); 6094 // ArrayAddress dispatch(table, index); 6095 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6096 __ lea($dest$$Register, $constantaddress); 6097 __ jmp(dispatch); 6098 %} 6099 ins_pipe(pipe_jmp); 6100 %} 6101 6102 // Conditional move 6103 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6104 %{ 6105 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6106 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6107 6108 ins_cost(100); // XXX 6109 format %{ "setbn$cop $dst\t# signed, int" %} 6110 ins_encode %{ 6111 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6112 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6113 %} 6114 ins_pipe(ialu_reg); 6115 %} 6116 6117 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6118 %{ 6119 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6120 6121 ins_cost(200); // XXX 6122 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6123 ins_encode %{ 6124 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6125 %} 6126 ins_pipe(pipe_cmov_reg); 6127 %} 6128 6129 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6130 %{ 6131 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6132 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6133 6134 ins_cost(100); // XXX 6135 format %{ "setbn$cop $dst\t# unsigned, int" %} 6136 ins_encode %{ 6137 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6138 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6139 %} 6140 ins_pipe(ialu_reg); 6141 %} 6142 6143 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6144 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6145 6146 ins_cost(200); // XXX 6147 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6148 ins_encode %{ 6149 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6150 %} 6151 ins_pipe(pipe_cmov_reg); 6152 %} 6153 6154 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6155 %{ 6156 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6157 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6158 6159 ins_cost(100); // XXX 6160 format %{ "setbn$cop $dst\t# unsigned, int" %} 6161 ins_encode %{ 6162 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6163 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6164 %} 6165 ins_pipe(ialu_reg); 6166 %} 6167 6168 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6169 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6170 ins_cost(200); 6171 expand %{ 6172 cmovI_regU(cop, cr, dst, src); 6173 %} 6174 %} 6175 6176 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6177 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6178 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6179 6180 ins_cost(200); // XXX 6181 format %{ "cmovpl $dst, $src\n\t" 6182 "cmovnel $dst, $src" %} 6183 ins_encode %{ 6184 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6185 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6186 %} 6187 ins_pipe(pipe_cmov_reg); 6188 %} 6189 6190 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6191 // inputs of the CMove 6192 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6193 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6194 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6195 6196 ins_cost(200); // XXX 6197 format %{ "cmovpl $dst, $src\n\t" 6198 "cmovnel $dst, $src" %} 6199 ins_encode %{ 6200 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6201 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6202 %} 6203 ins_pipe(pipe_cmov_reg); 6204 %} 6205 6206 // Conditional move 6207 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6208 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6209 6210 ins_cost(250); // XXX 6211 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6212 ins_encode %{ 6213 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6214 %} 6215 ins_pipe(pipe_cmov_mem); 6216 %} 6217 6218 // Conditional move 6219 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6220 %{ 6221 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6222 6223 ins_cost(250); // XXX 6224 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6225 ins_encode %{ 6226 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6227 %} 6228 ins_pipe(pipe_cmov_mem); 6229 %} 6230 6231 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6232 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6233 ins_cost(250); 6234 expand %{ 6235 cmovI_memU(cop, cr, dst, src); 6236 %} 6237 %} 6238 6239 // Conditional move 6240 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6241 %{ 6242 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6243 6244 ins_cost(200); // XXX 6245 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6246 ins_encode %{ 6247 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6248 %} 6249 ins_pipe(pipe_cmov_reg); 6250 %} 6251 6252 // Conditional move 6253 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6254 %{ 6255 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6256 6257 ins_cost(200); // XXX 6258 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6259 ins_encode %{ 6260 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6261 %} 6262 ins_pipe(pipe_cmov_reg); 6263 %} 6264 6265 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6266 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6267 ins_cost(200); 6268 expand %{ 6269 cmovN_regU(cop, cr, dst, src); 6270 %} 6271 %} 6272 6273 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6274 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6275 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6276 6277 ins_cost(200); // XXX 6278 format %{ "cmovpl $dst, $src\n\t" 6279 "cmovnel $dst, $src" %} 6280 ins_encode %{ 6281 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6282 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6283 %} 6284 ins_pipe(pipe_cmov_reg); 6285 %} 6286 6287 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6288 // inputs of the CMove 6289 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6290 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6291 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6292 6293 ins_cost(200); // XXX 6294 format %{ "cmovpl $dst, $src\n\t" 6295 "cmovnel $dst, $src" %} 6296 ins_encode %{ 6297 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6298 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6299 %} 6300 ins_pipe(pipe_cmov_reg); 6301 %} 6302 6303 // Conditional move 6304 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6305 %{ 6306 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6307 6308 ins_cost(200); // XXX 6309 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6310 ins_encode %{ 6311 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6312 %} 6313 ins_pipe(pipe_cmov_reg); // XXX 6314 %} 6315 6316 // Conditional move 6317 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6318 %{ 6319 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6320 6321 ins_cost(200); // XXX 6322 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6323 ins_encode %{ 6324 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6325 %} 6326 ins_pipe(pipe_cmov_reg); // XXX 6327 %} 6328 6329 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6330 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6331 ins_cost(200); 6332 expand %{ 6333 cmovP_regU(cop, cr, dst, src); 6334 %} 6335 %} 6336 6337 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6338 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6339 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6340 6341 ins_cost(200); // XXX 6342 format %{ "cmovpq $dst, $src\n\t" 6343 "cmovneq $dst, $src" %} 6344 ins_encode %{ 6345 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6346 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6347 %} 6348 ins_pipe(pipe_cmov_reg); 6349 %} 6350 6351 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6352 // inputs of the CMove 6353 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6354 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6355 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6356 6357 ins_cost(200); // XXX 6358 format %{ "cmovpq $dst, $src\n\t" 6359 "cmovneq $dst, $src" %} 6360 ins_encode %{ 6361 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6362 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6363 %} 6364 ins_pipe(pipe_cmov_reg); 6365 %} 6366 6367 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6368 %{ 6369 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6370 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6371 6372 ins_cost(100); // XXX 6373 format %{ "setbn$cop $dst\t# signed, long" %} 6374 ins_encode %{ 6375 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6376 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6377 %} 6378 ins_pipe(ialu_reg); 6379 %} 6380 6381 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6382 %{ 6383 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6384 6385 ins_cost(200); // XXX 6386 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6387 ins_encode %{ 6388 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6389 %} 6390 ins_pipe(pipe_cmov_reg); // XXX 6391 %} 6392 6393 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6394 %{ 6395 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6396 6397 ins_cost(200); // XXX 6398 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6399 ins_encode %{ 6400 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6401 %} 6402 ins_pipe(pipe_cmov_mem); // XXX 6403 %} 6404 6405 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6406 %{ 6407 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6408 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6409 6410 ins_cost(100); // XXX 6411 format %{ "setbn$cop $dst\t# unsigned, long" %} 6412 ins_encode %{ 6413 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6414 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6415 %} 6416 ins_pipe(ialu_reg); 6417 %} 6418 6419 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6420 %{ 6421 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6422 6423 ins_cost(200); // XXX 6424 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6425 ins_encode %{ 6426 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6427 %} 6428 ins_pipe(pipe_cmov_reg); // XXX 6429 %} 6430 6431 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6432 %{ 6433 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6434 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6435 6436 ins_cost(100); // XXX 6437 format %{ "setbn$cop $dst\t# unsigned, long" %} 6438 ins_encode %{ 6439 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6440 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6441 %} 6442 ins_pipe(ialu_reg); 6443 %} 6444 6445 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6446 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6447 ins_cost(200); 6448 expand %{ 6449 cmovL_regU(cop, cr, dst, src); 6450 %} 6451 %} 6452 6453 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6454 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6455 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6456 6457 ins_cost(200); // XXX 6458 format %{ "cmovpq $dst, $src\n\t" 6459 "cmovneq $dst, $src" %} 6460 ins_encode %{ 6461 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6462 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6463 %} 6464 ins_pipe(pipe_cmov_reg); 6465 %} 6466 6467 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6468 // inputs of the CMove 6469 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6470 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6471 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6472 6473 ins_cost(200); // XXX 6474 format %{ "cmovpq $dst, $src\n\t" 6475 "cmovneq $dst, $src" %} 6476 ins_encode %{ 6477 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6478 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6479 %} 6480 ins_pipe(pipe_cmov_reg); 6481 %} 6482 6483 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6484 %{ 6485 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6486 6487 ins_cost(200); // XXX 6488 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6489 ins_encode %{ 6490 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6491 %} 6492 ins_pipe(pipe_cmov_mem); // XXX 6493 %} 6494 6495 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6496 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6497 ins_cost(200); 6498 expand %{ 6499 cmovL_memU(cop, cr, dst, src); 6500 %} 6501 %} 6502 6503 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6504 %{ 6505 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6506 6507 ins_cost(200); // XXX 6508 format %{ "jn$cop skip\t# signed cmove float\n\t" 6509 "movss $dst, $src\n" 6510 "skip:" %} 6511 ins_encode %{ 6512 Label Lskip; 6513 // Invert sense of branch from sense of CMOV 6514 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6515 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6516 __ bind(Lskip); 6517 %} 6518 ins_pipe(pipe_slow); 6519 %} 6520 6521 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6522 %{ 6523 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6524 6525 ins_cost(200); // XXX 6526 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6527 "movss $dst, $src\n" 6528 "skip:" %} 6529 ins_encode %{ 6530 Label Lskip; 6531 // Invert sense of branch from sense of CMOV 6532 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6533 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6534 __ bind(Lskip); 6535 %} 6536 ins_pipe(pipe_slow); 6537 %} 6538 6539 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6540 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6541 ins_cost(200); 6542 expand %{ 6543 cmovF_regU(cop, cr, dst, src); 6544 %} 6545 %} 6546 6547 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6548 %{ 6549 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6550 6551 ins_cost(200); // XXX 6552 format %{ "jn$cop skip\t# signed cmove double\n\t" 6553 "movsd $dst, $src\n" 6554 "skip:" %} 6555 ins_encode %{ 6556 Label Lskip; 6557 // Invert sense of branch from sense of CMOV 6558 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6559 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6560 __ bind(Lskip); 6561 %} 6562 ins_pipe(pipe_slow); 6563 %} 6564 6565 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6566 %{ 6567 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6568 6569 ins_cost(200); // XXX 6570 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6571 "movsd $dst, $src\n" 6572 "skip:" %} 6573 ins_encode %{ 6574 Label Lskip; 6575 // Invert sense of branch from sense of CMOV 6576 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6577 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6578 __ bind(Lskip); 6579 %} 6580 ins_pipe(pipe_slow); 6581 %} 6582 6583 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6584 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6585 ins_cost(200); 6586 expand %{ 6587 cmovD_regU(cop, cr, dst, src); 6588 %} 6589 %} 6590 6591 //----------Arithmetic Instructions-------------------------------------------- 6592 //----------Addition Instructions---------------------------------------------- 6593 6594 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6595 %{ 6596 match(Set dst (AddI dst src)); 6597 effect(KILL cr); 6598 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); 6599 format %{ "addl $dst, $src\t# int" %} 6600 ins_encode %{ 6601 __ addl($dst$$Register, $src$$Register); 6602 %} 6603 ins_pipe(ialu_reg_reg); 6604 %} 6605 6606 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6607 %{ 6608 match(Set dst (AddI dst src)); 6609 effect(KILL cr); 6610 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); 6611 6612 format %{ "addl $dst, $src\t# int" %} 6613 ins_encode %{ 6614 __ addl($dst$$Register, $src$$constant); 6615 %} 6616 ins_pipe( ialu_reg ); 6617 %} 6618 6619 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6620 %{ 6621 match(Set dst (AddI dst (LoadI src))); 6622 effect(KILL cr); 6623 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); 6624 6625 ins_cost(150); // XXX 6626 format %{ "addl $dst, $src\t# int" %} 6627 ins_encode %{ 6628 __ addl($dst$$Register, $src$$Address); 6629 %} 6630 ins_pipe(ialu_reg_mem); 6631 %} 6632 6633 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6634 %{ 6635 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6636 effect(KILL cr); 6637 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); 6638 6639 ins_cost(150); // XXX 6640 format %{ "addl $dst, $src\t# int" %} 6641 ins_encode %{ 6642 __ addl($dst$$Address, $src$$Register); 6643 %} 6644 ins_pipe(ialu_mem_reg); 6645 %} 6646 6647 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6648 %{ 6649 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6650 effect(KILL cr); 6651 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); 6652 6653 6654 ins_cost(125); // XXX 6655 format %{ "addl $dst, $src\t# int" %} 6656 ins_encode %{ 6657 __ addl($dst$$Address, $src$$constant); 6658 %} 6659 ins_pipe(ialu_mem_imm); 6660 %} 6661 6662 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6663 %{ 6664 predicate(UseIncDec); 6665 match(Set dst (AddI dst src)); 6666 effect(KILL cr); 6667 6668 format %{ "incl $dst\t# int" %} 6669 ins_encode %{ 6670 __ incrementl($dst$$Register); 6671 %} 6672 ins_pipe(ialu_reg); 6673 %} 6674 6675 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6676 %{ 6677 predicate(UseIncDec); 6678 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6679 effect(KILL cr); 6680 6681 ins_cost(125); // XXX 6682 format %{ "incl $dst\t# int" %} 6683 ins_encode %{ 6684 __ incrementl($dst$$Address); 6685 %} 6686 ins_pipe(ialu_mem_imm); 6687 %} 6688 6689 // XXX why does that use AddI 6690 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6691 %{ 6692 predicate(UseIncDec); 6693 match(Set dst (AddI dst src)); 6694 effect(KILL cr); 6695 6696 format %{ "decl $dst\t# int" %} 6697 ins_encode %{ 6698 __ decrementl($dst$$Register); 6699 %} 6700 ins_pipe(ialu_reg); 6701 %} 6702 6703 // XXX why does that use AddI 6704 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6705 %{ 6706 predicate(UseIncDec); 6707 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6708 effect(KILL cr); 6709 6710 ins_cost(125); // XXX 6711 format %{ "decl $dst\t# int" %} 6712 ins_encode %{ 6713 __ decrementl($dst$$Address); 6714 %} 6715 ins_pipe(ialu_mem_imm); 6716 %} 6717 6718 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6719 %{ 6720 predicate(VM_Version::supports_fast_2op_lea()); 6721 match(Set dst (AddI (LShiftI index scale) disp)); 6722 6723 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6724 ins_encode %{ 6725 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6726 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6727 %} 6728 ins_pipe(ialu_reg_reg); 6729 %} 6730 6731 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6732 %{ 6733 predicate(VM_Version::supports_fast_3op_lea()); 6734 match(Set dst (AddI (AddI base index) disp)); 6735 6736 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6737 ins_encode %{ 6738 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6739 %} 6740 ins_pipe(ialu_reg_reg); 6741 %} 6742 6743 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6744 %{ 6745 predicate(VM_Version::supports_fast_2op_lea()); 6746 match(Set dst (AddI base (LShiftI index scale))); 6747 6748 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6749 ins_encode %{ 6750 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6751 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6752 %} 6753 ins_pipe(ialu_reg_reg); 6754 %} 6755 6756 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6757 %{ 6758 predicate(VM_Version::supports_fast_3op_lea()); 6759 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6760 6761 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6762 ins_encode %{ 6763 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6764 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6765 %} 6766 ins_pipe(ialu_reg_reg); 6767 %} 6768 6769 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6770 %{ 6771 match(Set dst (AddL dst src)); 6772 effect(KILL cr); 6773 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); 6774 6775 format %{ "addq $dst, $src\t# long" %} 6776 ins_encode %{ 6777 __ addq($dst$$Register, $src$$Register); 6778 %} 6779 ins_pipe(ialu_reg_reg); 6780 %} 6781 6782 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6783 %{ 6784 match(Set dst (AddL dst src)); 6785 effect(KILL cr); 6786 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); 6787 6788 format %{ "addq $dst, $src\t# long" %} 6789 ins_encode %{ 6790 __ addq($dst$$Register, $src$$constant); 6791 %} 6792 ins_pipe( ialu_reg ); 6793 %} 6794 6795 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6796 %{ 6797 match(Set dst (AddL dst (LoadL src))); 6798 effect(KILL cr); 6799 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); 6800 6801 ins_cost(150); // XXX 6802 format %{ "addq $dst, $src\t# long" %} 6803 ins_encode %{ 6804 __ addq($dst$$Register, $src$$Address); 6805 %} 6806 ins_pipe(ialu_reg_mem); 6807 %} 6808 6809 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6810 %{ 6811 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6812 effect(KILL cr); 6813 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); 6814 6815 ins_cost(150); // XXX 6816 format %{ "addq $dst, $src\t# long" %} 6817 ins_encode %{ 6818 __ addq($dst$$Address, $src$$Register); 6819 %} 6820 ins_pipe(ialu_mem_reg); 6821 %} 6822 6823 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6824 %{ 6825 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6826 effect(KILL cr); 6827 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); 6828 6829 ins_cost(125); // XXX 6830 format %{ "addq $dst, $src\t# long" %} 6831 ins_encode %{ 6832 __ addq($dst$$Address, $src$$constant); 6833 %} 6834 ins_pipe(ialu_mem_imm); 6835 %} 6836 6837 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6838 %{ 6839 predicate(UseIncDec); 6840 match(Set dst (AddL dst src)); 6841 effect(KILL cr); 6842 6843 format %{ "incq $dst\t# long" %} 6844 ins_encode %{ 6845 __ incrementq($dst$$Register); 6846 %} 6847 ins_pipe(ialu_reg); 6848 %} 6849 6850 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6851 %{ 6852 predicate(UseIncDec); 6853 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6854 effect(KILL cr); 6855 6856 ins_cost(125); // XXX 6857 format %{ "incq $dst\t# long" %} 6858 ins_encode %{ 6859 __ incrementq($dst$$Address); 6860 %} 6861 ins_pipe(ialu_mem_imm); 6862 %} 6863 6864 // XXX why does that use AddL 6865 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6866 %{ 6867 predicate(UseIncDec); 6868 match(Set dst (AddL dst src)); 6869 effect(KILL cr); 6870 6871 format %{ "decq $dst\t# long" %} 6872 ins_encode %{ 6873 __ decrementq($dst$$Register); 6874 %} 6875 ins_pipe(ialu_reg); 6876 %} 6877 6878 // XXX why does that use AddL 6879 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6880 %{ 6881 predicate(UseIncDec); 6882 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6883 effect(KILL cr); 6884 6885 ins_cost(125); // XXX 6886 format %{ "decq $dst\t# long" %} 6887 ins_encode %{ 6888 __ decrementq($dst$$Address); 6889 %} 6890 ins_pipe(ialu_mem_imm); 6891 %} 6892 6893 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6894 %{ 6895 predicate(VM_Version::supports_fast_2op_lea()); 6896 match(Set dst (AddL (LShiftL index scale) disp)); 6897 6898 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6899 ins_encode %{ 6900 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6901 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6902 %} 6903 ins_pipe(ialu_reg_reg); 6904 %} 6905 6906 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6907 %{ 6908 predicate(VM_Version::supports_fast_3op_lea()); 6909 match(Set dst (AddL (AddL base index) disp)); 6910 6911 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6912 ins_encode %{ 6913 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6914 %} 6915 ins_pipe(ialu_reg_reg); 6916 %} 6917 6918 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6919 %{ 6920 predicate(VM_Version::supports_fast_2op_lea()); 6921 match(Set dst (AddL base (LShiftL index scale))); 6922 6923 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6924 ins_encode %{ 6925 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6926 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6927 %} 6928 ins_pipe(ialu_reg_reg); 6929 %} 6930 6931 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6932 %{ 6933 predicate(VM_Version::supports_fast_3op_lea()); 6934 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6935 6936 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6937 ins_encode %{ 6938 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6939 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6940 %} 6941 ins_pipe(ialu_reg_reg); 6942 %} 6943 6944 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6945 %{ 6946 match(Set dst (AddP dst src)); 6947 effect(KILL cr); 6948 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); 6949 6950 format %{ "addq $dst, $src\t# ptr" %} 6951 ins_encode %{ 6952 __ addq($dst$$Register, $src$$Register); 6953 %} 6954 ins_pipe(ialu_reg_reg); 6955 %} 6956 6957 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6958 %{ 6959 match(Set dst (AddP dst src)); 6960 effect(KILL cr); 6961 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); 6962 6963 format %{ "addq $dst, $src\t# ptr" %} 6964 ins_encode %{ 6965 __ addq($dst$$Register, $src$$constant); 6966 %} 6967 ins_pipe( ialu_reg ); 6968 %} 6969 6970 // XXX addP mem ops ???? 6971 6972 instruct checkCastPP(rRegP dst) 6973 %{ 6974 match(Set dst (CheckCastPP dst)); 6975 6976 size(0); 6977 format %{ "# checkcastPP of $dst" %} 6978 ins_encode(/* empty encoding */); 6979 ins_pipe(empty); 6980 %} 6981 6982 instruct castPP(rRegP dst) 6983 %{ 6984 match(Set dst (CastPP dst)); 6985 6986 size(0); 6987 format %{ "# castPP of $dst" %} 6988 ins_encode(/* empty encoding */); 6989 ins_pipe(empty); 6990 %} 6991 6992 instruct castII(rRegI dst) 6993 %{ 6994 match(Set dst (CastII dst)); 6995 6996 size(0); 6997 format %{ "# castII of $dst" %} 6998 ins_encode(/* empty encoding */); 6999 ins_cost(0); 7000 ins_pipe(empty); 7001 %} 7002 7003 instruct castLL(rRegL dst) 7004 %{ 7005 match(Set dst (CastLL dst)); 7006 7007 size(0); 7008 format %{ "# castLL of $dst" %} 7009 ins_encode(/* empty encoding */); 7010 ins_cost(0); 7011 ins_pipe(empty); 7012 %} 7013 7014 instruct castFF(regF dst) 7015 %{ 7016 match(Set dst (CastFF dst)); 7017 7018 size(0); 7019 format %{ "# castFF of $dst" %} 7020 ins_encode(/* empty encoding */); 7021 ins_cost(0); 7022 ins_pipe(empty); 7023 %} 7024 7025 instruct castDD(regD dst) 7026 %{ 7027 match(Set dst (CastDD dst)); 7028 7029 size(0); 7030 format %{ "# castDD of $dst" %} 7031 ins_encode(/* empty encoding */); 7032 ins_cost(0); 7033 ins_pipe(empty); 7034 %} 7035 7036 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7037 instruct compareAndSwapP(rRegI res, 7038 memory mem_ptr, 7039 rax_RegP oldval, rRegP newval, 7040 rFlagsReg cr) 7041 %{ 7042 predicate(n->as_LoadStore()->barrier_data() == 0); 7043 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7044 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7045 effect(KILL cr, KILL oldval); 7046 7047 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7048 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7049 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7050 ins_encode %{ 7051 __ lock(); 7052 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7053 __ setcc(Assembler::equal, $res$$Register); 7054 %} 7055 ins_pipe( pipe_cmpxchg ); 7056 %} 7057 7058 instruct compareAndSwapL(rRegI res, 7059 memory mem_ptr, 7060 rax_RegL oldval, rRegL newval, 7061 rFlagsReg cr) 7062 %{ 7063 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7064 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7065 effect(KILL cr, KILL oldval); 7066 7067 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7068 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7069 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7070 ins_encode %{ 7071 __ lock(); 7072 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7073 __ setcc(Assembler::equal, $res$$Register); 7074 %} 7075 ins_pipe( pipe_cmpxchg ); 7076 %} 7077 7078 instruct compareAndSwapI(rRegI res, 7079 memory mem_ptr, 7080 rax_RegI oldval, rRegI newval, 7081 rFlagsReg cr) 7082 %{ 7083 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7084 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7085 effect(KILL cr, KILL oldval); 7086 7087 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7088 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7089 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7090 ins_encode %{ 7091 __ lock(); 7092 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7093 __ setcc(Assembler::equal, $res$$Register); 7094 %} 7095 ins_pipe( pipe_cmpxchg ); 7096 %} 7097 7098 instruct compareAndSwapB(rRegI res, 7099 memory mem_ptr, 7100 rax_RegI oldval, rRegI newval, 7101 rFlagsReg cr) 7102 %{ 7103 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7104 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7105 effect(KILL cr, KILL oldval); 7106 7107 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7108 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7109 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7110 ins_encode %{ 7111 __ lock(); 7112 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7113 __ setcc(Assembler::equal, $res$$Register); 7114 %} 7115 ins_pipe( pipe_cmpxchg ); 7116 %} 7117 7118 instruct compareAndSwapS(rRegI res, 7119 memory mem_ptr, 7120 rax_RegI oldval, rRegI newval, 7121 rFlagsReg cr) 7122 %{ 7123 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7124 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7125 effect(KILL cr, KILL oldval); 7126 7127 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7128 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7129 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7130 ins_encode %{ 7131 __ lock(); 7132 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7133 __ setcc(Assembler::equal, $res$$Register); 7134 %} 7135 ins_pipe( pipe_cmpxchg ); 7136 %} 7137 7138 instruct compareAndSwapN(rRegI res, 7139 memory mem_ptr, 7140 rax_RegN oldval, rRegN newval, 7141 rFlagsReg cr) %{ 7142 predicate(n->as_LoadStore()->barrier_data() == 0); 7143 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7144 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7145 effect(KILL cr, KILL oldval); 7146 7147 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7148 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7149 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7150 ins_encode %{ 7151 __ lock(); 7152 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7153 __ setcc(Assembler::equal, $res$$Register); 7154 %} 7155 ins_pipe( pipe_cmpxchg ); 7156 %} 7157 7158 instruct compareAndExchangeB( 7159 memory mem_ptr, 7160 rax_RegI oldval, rRegI newval, 7161 rFlagsReg cr) 7162 %{ 7163 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7164 effect(KILL cr); 7165 7166 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7167 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7168 ins_encode %{ 7169 __ lock(); 7170 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7171 %} 7172 ins_pipe( pipe_cmpxchg ); 7173 %} 7174 7175 instruct compareAndExchangeS( 7176 memory mem_ptr, 7177 rax_RegI oldval, rRegI newval, 7178 rFlagsReg cr) 7179 %{ 7180 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7181 effect(KILL cr); 7182 7183 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7184 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7185 ins_encode %{ 7186 __ lock(); 7187 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7188 %} 7189 ins_pipe( pipe_cmpxchg ); 7190 %} 7191 7192 instruct compareAndExchangeI( 7193 memory mem_ptr, 7194 rax_RegI oldval, rRegI newval, 7195 rFlagsReg cr) 7196 %{ 7197 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7198 effect(KILL cr); 7199 7200 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7201 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7202 ins_encode %{ 7203 __ lock(); 7204 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7205 %} 7206 ins_pipe( pipe_cmpxchg ); 7207 %} 7208 7209 instruct compareAndExchangeL( 7210 memory mem_ptr, 7211 rax_RegL oldval, rRegL newval, 7212 rFlagsReg cr) 7213 %{ 7214 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7215 effect(KILL cr); 7216 7217 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7218 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7219 ins_encode %{ 7220 __ lock(); 7221 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7222 %} 7223 ins_pipe( pipe_cmpxchg ); 7224 %} 7225 7226 instruct compareAndExchangeN( 7227 memory mem_ptr, 7228 rax_RegN oldval, rRegN newval, 7229 rFlagsReg cr) %{ 7230 predicate(n->as_LoadStore()->barrier_data() == 0); 7231 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7232 effect(KILL cr); 7233 7234 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7235 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7236 ins_encode %{ 7237 __ lock(); 7238 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7239 %} 7240 ins_pipe( pipe_cmpxchg ); 7241 %} 7242 7243 instruct compareAndExchangeP( 7244 memory mem_ptr, 7245 rax_RegP oldval, rRegP newval, 7246 rFlagsReg cr) 7247 %{ 7248 predicate(n->as_LoadStore()->barrier_data() == 0); 7249 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7250 effect(KILL cr); 7251 7252 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7253 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7254 ins_encode %{ 7255 __ lock(); 7256 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7257 %} 7258 ins_pipe( pipe_cmpxchg ); 7259 %} 7260 7261 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7262 predicate(n->as_LoadStore()->result_not_used()); 7263 match(Set dummy (GetAndAddB mem add)); 7264 effect(KILL cr); 7265 format %{ "addb_lock $mem, $add" %} 7266 ins_encode %{ 7267 __ lock(); 7268 __ addb($mem$$Address, $add$$Register); 7269 %} 7270 ins_pipe(pipe_cmpxchg); 7271 %} 7272 7273 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7274 predicate(n->as_LoadStore()->result_not_used()); 7275 match(Set dummy (GetAndAddB mem add)); 7276 effect(KILL cr); 7277 format %{ "addb_lock $mem, $add" %} 7278 ins_encode %{ 7279 __ lock(); 7280 __ addb($mem$$Address, $add$$constant); 7281 %} 7282 ins_pipe(pipe_cmpxchg); 7283 %} 7284 7285 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7286 predicate(!n->as_LoadStore()->result_not_used()); 7287 match(Set newval (GetAndAddB mem newval)); 7288 effect(KILL cr); 7289 format %{ "xaddb_lock $mem, $newval" %} 7290 ins_encode %{ 7291 __ lock(); 7292 __ xaddb($mem$$Address, $newval$$Register); 7293 %} 7294 ins_pipe(pipe_cmpxchg); 7295 %} 7296 7297 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7298 predicate(n->as_LoadStore()->result_not_used()); 7299 match(Set dummy (GetAndAddS mem add)); 7300 effect(KILL cr); 7301 format %{ "addw_lock $mem, $add" %} 7302 ins_encode %{ 7303 __ lock(); 7304 __ addw($mem$$Address, $add$$Register); 7305 %} 7306 ins_pipe(pipe_cmpxchg); 7307 %} 7308 7309 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7310 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7311 match(Set dummy (GetAndAddS mem add)); 7312 effect(KILL cr); 7313 format %{ "addw_lock $mem, $add" %} 7314 ins_encode %{ 7315 __ lock(); 7316 __ addw($mem$$Address, $add$$constant); 7317 %} 7318 ins_pipe(pipe_cmpxchg); 7319 %} 7320 7321 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7322 predicate(!n->as_LoadStore()->result_not_used()); 7323 match(Set newval (GetAndAddS mem newval)); 7324 effect(KILL cr); 7325 format %{ "xaddw_lock $mem, $newval" %} 7326 ins_encode %{ 7327 __ lock(); 7328 __ xaddw($mem$$Address, $newval$$Register); 7329 %} 7330 ins_pipe(pipe_cmpxchg); 7331 %} 7332 7333 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7334 predicate(n->as_LoadStore()->result_not_used()); 7335 match(Set dummy (GetAndAddI mem add)); 7336 effect(KILL cr); 7337 format %{ "addl_lock $mem, $add" %} 7338 ins_encode %{ 7339 __ lock(); 7340 __ addl($mem$$Address, $add$$Register); 7341 %} 7342 ins_pipe(pipe_cmpxchg); 7343 %} 7344 7345 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7346 predicate(n->as_LoadStore()->result_not_used()); 7347 match(Set dummy (GetAndAddI mem add)); 7348 effect(KILL cr); 7349 format %{ "addl_lock $mem, $add" %} 7350 ins_encode %{ 7351 __ lock(); 7352 __ addl($mem$$Address, $add$$constant); 7353 %} 7354 ins_pipe(pipe_cmpxchg); 7355 %} 7356 7357 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7358 predicate(!n->as_LoadStore()->result_not_used()); 7359 match(Set newval (GetAndAddI mem newval)); 7360 effect(KILL cr); 7361 format %{ "xaddl_lock $mem, $newval" %} 7362 ins_encode %{ 7363 __ lock(); 7364 __ xaddl($mem$$Address, $newval$$Register); 7365 %} 7366 ins_pipe(pipe_cmpxchg); 7367 %} 7368 7369 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7370 predicate(n->as_LoadStore()->result_not_used()); 7371 match(Set dummy (GetAndAddL mem add)); 7372 effect(KILL cr); 7373 format %{ "addq_lock $mem, $add" %} 7374 ins_encode %{ 7375 __ lock(); 7376 __ addq($mem$$Address, $add$$Register); 7377 %} 7378 ins_pipe(pipe_cmpxchg); 7379 %} 7380 7381 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7382 predicate(n->as_LoadStore()->result_not_used()); 7383 match(Set dummy (GetAndAddL mem add)); 7384 effect(KILL cr); 7385 format %{ "addq_lock $mem, $add" %} 7386 ins_encode %{ 7387 __ lock(); 7388 __ addq($mem$$Address, $add$$constant); 7389 %} 7390 ins_pipe(pipe_cmpxchg); 7391 %} 7392 7393 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7394 predicate(!n->as_LoadStore()->result_not_used()); 7395 match(Set newval (GetAndAddL mem newval)); 7396 effect(KILL cr); 7397 format %{ "xaddq_lock $mem, $newval" %} 7398 ins_encode %{ 7399 __ lock(); 7400 __ xaddq($mem$$Address, $newval$$Register); 7401 %} 7402 ins_pipe(pipe_cmpxchg); 7403 %} 7404 7405 instruct xchgB( memory mem, rRegI newval) %{ 7406 match(Set newval (GetAndSetB mem newval)); 7407 format %{ "XCHGB $newval,[$mem]" %} 7408 ins_encode %{ 7409 __ xchgb($newval$$Register, $mem$$Address); 7410 %} 7411 ins_pipe( pipe_cmpxchg ); 7412 %} 7413 7414 instruct xchgS( memory mem, rRegI newval) %{ 7415 match(Set newval (GetAndSetS mem newval)); 7416 format %{ "XCHGW $newval,[$mem]" %} 7417 ins_encode %{ 7418 __ xchgw($newval$$Register, $mem$$Address); 7419 %} 7420 ins_pipe( pipe_cmpxchg ); 7421 %} 7422 7423 instruct xchgI( memory mem, rRegI newval) %{ 7424 match(Set newval (GetAndSetI mem newval)); 7425 format %{ "XCHGL $newval,[$mem]" %} 7426 ins_encode %{ 7427 __ xchgl($newval$$Register, $mem$$Address); 7428 %} 7429 ins_pipe( pipe_cmpxchg ); 7430 %} 7431 7432 instruct xchgL( memory mem, rRegL newval) %{ 7433 match(Set newval (GetAndSetL mem newval)); 7434 format %{ "XCHGL $newval,[$mem]" %} 7435 ins_encode %{ 7436 __ xchgq($newval$$Register, $mem$$Address); 7437 %} 7438 ins_pipe( pipe_cmpxchg ); 7439 %} 7440 7441 instruct xchgP( memory mem, rRegP newval) %{ 7442 match(Set newval (GetAndSetP mem newval)); 7443 predicate(n->as_LoadStore()->barrier_data() == 0); 7444 format %{ "XCHGQ $newval,[$mem]" %} 7445 ins_encode %{ 7446 __ xchgq($newval$$Register, $mem$$Address); 7447 %} 7448 ins_pipe( pipe_cmpxchg ); 7449 %} 7450 7451 instruct xchgN( memory mem, rRegN newval) %{ 7452 predicate(n->as_LoadStore()->barrier_data() == 0); 7453 match(Set newval (GetAndSetN mem newval)); 7454 format %{ "XCHGL $newval,$mem]" %} 7455 ins_encode %{ 7456 __ xchgl($newval$$Register, $mem$$Address); 7457 %} 7458 ins_pipe( pipe_cmpxchg ); 7459 %} 7460 7461 //----------Abs Instructions------------------------------------------- 7462 7463 // Integer Absolute Instructions 7464 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7465 %{ 7466 match(Set dst (AbsI src)); 7467 effect(TEMP dst, KILL cr); 7468 format %{ "xorl $dst, $dst\t# abs int\n\t" 7469 "subl $dst, $src\n\t" 7470 "cmovll $dst, $src" %} 7471 ins_encode %{ 7472 __ xorl($dst$$Register, $dst$$Register); 7473 __ subl($dst$$Register, $src$$Register); 7474 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7475 %} 7476 7477 ins_pipe(ialu_reg_reg); 7478 %} 7479 7480 // Long Absolute Instructions 7481 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7482 %{ 7483 match(Set dst (AbsL src)); 7484 effect(TEMP dst, KILL cr); 7485 format %{ "xorl $dst, $dst\t# abs long\n\t" 7486 "subq $dst, $src\n\t" 7487 "cmovlq $dst, $src" %} 7488 ins_encode %{ 7489 __ xorl($dst$$Register, $dst$$Register); 7490 __ subq($dst$$Register, $src$$Register); 7491 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7492 %} 7493 7494 ins_pipe(ialu_reg_reg); 7495 %} 7496 7497 //----------Subtraction Instructions------------------------------------------- 7498 7499 // Integer Subtraction Instructions 7500 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7501 %{ 7502 match(Set dst (SubI dst src)); 7503 effect(KILL cr); 7504 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); 7505 7506 format %{ "subl $dst, $src\t# int" %} 7507 ins_encode %{ 7508 __ subl($dst$$Register, $src$$Register); 7509 %} 7510 ins_pipe(ialu_reg_reg); 7511 %} 7512 7513 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7514 %{ 7515 match(Set dst (SubI dst (LoadI src))); 7516 effect(KILL cr); 7517 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); 7518 7519 ins_cost(150); 7520 format %{ "subl $dst, $src\t# int" %} 7521 ins_encode %{ 7522 __ subl($dst$$Register, $src$$Address); 7523 %} 7524 ins_pipe(ialu_reg_mem); 7525 %} 7526 7527 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7528 %{ 7529 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7530 effect(KILL cr); 7531 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); 7532 7533 ins_cost(150); 7534 format %{ "subl $dst, $src\t# int" %} 7535 ins_encode %{ 7536 __ subl($dst$$Address, $src$$Register); 7537 %} 7538 ins_pipe(ialu_mem_reg); 7539 %} 7540 7541 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7542 %{ 7543 match(Set dst (SubL dst src)); 7544 effect(KILL cr); 7545 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); 7546 7547 format %{ "subq $dst, $src\t# long" %} 7548 ins_encode %{ 7549 __ subq($dst$$Register, $src$$Register); 7550 %} 7551 ins_pipe(ialu_reg_reg); 7552 %} 7553 7554 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7555 %{ 7556 match(Set dst (SubL dst (LoadL src))); 7557 effect(KILL cr); 7558 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); 7559 7560 ins_cost(150); 7561 format %{ "subq $dst, $src\t# long" %} 7562 ins_encode %{ 7563 __ subq($dst$$Register, $src$$Address); 7564 %} 7565 ins_pipe(ialu_reg_mem); 7566 %} 7567 7568 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7569 %{ 7570 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7571 effect(KILL cr); 7572 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); 7573 7574 ins_cost(150); 7575 format %{ "subq $dst, $src\t# long" %} 7576 ins_encode %{ 7577 __ subq($dst$$Address, $src$$Register); 7578 %} 7579 ins_pipe(ialu_mem_reg); 7580 %} 7581 7582 // Subtract from a pointer 7583 // XXX hmpf??? 7584 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7585 %{ 7586 match(Set dst (AddP dst (SubI zero src))); 7587 effect(KILL cr); 7588 7589 format %{ "subq $dst, $src\t# ptr - int" %} 7590 ins_encode %{ 7591 __ subq($dst$$Register, $src$$Register); 7592 %} 7593 ins_pipe(ialu_reg_reg); 7594 %} 7595 7596 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7597 %{ 7598 match(Set dst (SubI zero dst)); 7599 effect(KILL cr); 7600 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7601 7602 format %{ "negl $dst\t# int" %} 7603 ins_encode %{ 7604 __ negl($dst$$Register); 7605 %} 7606 ins_pipe(ialu_reg); 7607 %} 7608 7609 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7610 %{ 7611 match(Set dst (NegI dst)); 7612 effect(KILL cr); 7613 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7614 7615 format %{ "negl $dst\t# int" %} 7616 ins_encode %{ 7617 __ negl($dst$$Register); 7618 %} 7619 ins_pipe(ialu_reg); 7620 %} 7621 7622 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7623 %{ 7624 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7625 effect(KILL cr); 7626 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7627 7628 format %{ "negl $dst\t# int" %} 7629 ins_encode %{ 7630 __ negl($dst$$Address); 7631 %} 7632 ins_pipe(ialu_reg); 7633 %} 7634 7635 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7636 %{ 7637 match(Set dst (SubL zero dst)); 7638 effect(KILL cr); 7639 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7640 7641 format %{ "negq $dst\t# long" %} 7642 ins_encode %{ 7643 __ negq($dst$$Register); 7644 %} 7645 ins_pipe(ialu_reg); 7646 %} 7647 7648 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7649 %{ 7650 match(Set dst (NegL dst)); 7651 effect(KILL cr); 7652 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7653 7654 format %{ "negq $dst\t# int" %} 7655 ins_encode %{ 7656 __ negq($dst$$Register); 7657 %} 7658 ins_pipe(ialu_reg); 7659 %} 7660 7661 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7662 %{ 7663 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7664 effect(KILL cr); 7665 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7666 7667 format %{ "negq $dst\t# long" %} 7668 ins_encode %{ 7669 __ negq($dst$$Address); 7670 %} 7671 ins_pipe(ialu_reg); 7672 %} 7673 7674 //----------Multiplication/Division Instructions------------------------------- 7675 // Integer Multiplication Instructions 7676 // Multiply Register 7677 7678 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7679 %{ 7680 match(Set dst (MulI dst src)); 7681 effect(KILL cr); 7682 7683 ins_cost(300); 7684 format %{ "imull $dst, $src\t# int" %} 7685 ins_encode %{ 7686 __ imull($dst$$Register, $src$$Register); 7687 %} 7688 ins_pipe(ialu_reg_reg_alu0); 7689 %} 7690 7691 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7692 %{ 7693 match(Set dst (MulI src imm)); 7694 effect(KILL cr); 7695 7696 ins_cost(300); 7697 format %{ "imull $dst, $src, $imm\t# int" %} 7698 ins_encode %{ 7699 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7700 %} 7701 ins_pipe(ialu_reg_reg_alu0); 7702 %} 7703 7704 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7705 %{ 7706 match(Set dst (MulI dst (LoadI src))); 7707 effect(KILL cr); 7708 7709 ins_cost(350); 7710 format %{ "imull $dst, $src\t# int" %} 7711 ins_encode %{ 7712 __ imull($dst$$Register, $src$$Address); 7713 %} 7714 ins_pipe(ialu_reg_mem_alu0); 7715 %} 7716 7717 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7718 %{ 7719 match(Set dst (MulI (LoadI src) imm)); 7720 effect(KILL cr); 7721 7722 ins_cost(300); 7723 format %{ "imull $dst, $src, $imm\t# int" %} 7724 ins_encode %{ 7725 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7726 %} 7727 ins_pipe(ialu_reg_mem_alu0); 7728 %} 7729 7730 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7731 %{ 7732 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7733 effect(KILL cr, KILL src2); 7734 7735 expand %{ mulI_rReg(dst, src1, cr); 7736 mulI_rReg(src2, src3, cr); 7737 addI_rReg(dst, src2, cr); %} 7738 %} 7739 7740 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7741 %{ 7742 match(Set dst (MulL dst src)); 7743 effect(KILL cr); 7744 7745 ins_cost(300); 7746 format %{ "imulq $dst, $src\t# long" %} 7747 ins_encode %{ 7748 __ imulq($dst$$Register, $src$$Register); 7749 %} 7750 ins_pipe(ialu_reg_reg_alu0); 7751 %} 7752 7753 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7754 %{ 7755 match(Set dst (MulL src imm)); 7756 effect(KILL cr); 7757 7758 ins_cost(300); 7759 format %{ "imulq $dst, $src, $imm\t# long" %} 7760 ins_encode %{ 7761 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7762 %} 7763 ins_pipe(ialu_reg_reg_alu0); 7764 %} 7765 7766 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7767 %{ 7768 match(Set dst (MulL dst (LoadL src))); 7769 effect(KILL cr); 7770 7771 ins_cost(350); 7772 format %{ "imulq $dst, $src\t# long" %} 7773 ins_encode %{ 7774 __ imulq($dst$$Register, $src$$Address); 7775 %} 7776 ins_pipe(ialu_reg_mem_alu0); 7777 %} 7778 7779 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7780 %{ 7781 match(Set dst (MulL (LoadL src) imm)); 7782 effect(KILL cr); 7783 7784 ins_cost(300); 7785 format %{ "imulq $dst, $src, $imm\t# long" %} 7786 ins_encode %{ 7787 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7788 %} 7789 ins_pipe(ialu_reg_mem_alu0); 7790 %} 7791 7792 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7793 %{ 7794 match(Set dst (MulHiL src rax)); 7795 effect(USE_KILL rax, KILL cr); 7796 7797 ins_cost(300); 7798 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7799 ins_encode %{ 7800 __ imulq($src$$Register); 7801 %} 7802 ins_pipe(ialu_reg_reg_alu0); 7803 %} 7804 7805 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7806 %{ 7807 match(Set dst (UMulHiL src rax)); 7808 effect(USE_KILL rax, KILL cr); 7809 7810 ins_cost(300); 7811 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7812 ins_encode %{ 7813 __ mulq($src$$Register); 7814 %} 7815 ins_pipe(ialu_reg_reg_alu0); 7816 %} 7817 7818 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7819 rFlagsReg cr) 7820 %{ 7821 match(Set rax (DivI rax div)); 7822 effect(KILL rdx, KILL cr); 7823 7824 ins_cost(30*100+10*100); // XXX 7825 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7826 "jne,s normal\n\t" 7827 "xorl rdx, rdx\n\t" 7828 "cmpl $div, -1\n\t" 7829 "je,s done\n" 7830 "normal: cdql\n\t" 7831 "idivl $div\n" 7832 "done:" %} 7833 ins_encode(cdql_enc(div)); 7834 ins_pipe(ialu_reg_reg_alu0); 7835 %} 7836 7837 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7838 rFlagsReg cr) 7839 %{ 7840 match(Set rax (DivL rax div)); 7841 effect(KILL rdx, KILL cr); 7842 7843 ins_cost(30*100+10*100); // XXX 7844 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7845 "cmpq rax, rdx\n\t" 7846 "jne,s normal\n\t" 7847 "xorl rdx, rdx\n\t" 7848 "cmpq $div, -1\n\t" 7849 "je,s done\n" 7850 "normal: cdqq\n\t" 7851 "idivq $div\n" 7852 "done:" %} 7853 ins_encode(cdqq_enc(div)); 7854 ins_pipe(ialu_reg_reg_alu0); 7855 %} 7856 7857 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7858 %{ 7859 match(Set rax (UDivI rax div)); 7860 effect(KILL rdx, KILL cr); 7861 7862 ins_cost(300); 7863 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7864 ins_encode %{ 7865 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7866 %} 7867 ins_pipe(ialu_reg_reg_alu0); 7868 %} 7869 7870 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7871 %{ 7872 match(Set rax (UDivL rax div)); 7873 effect(KILL rdx, KILL cr); 7874 7875 ins_cost(300); 7876 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7877 ins_encode %{ 7878 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7879 %} 7880 ins_pipe(ialu_reg_reg_alu0); 7881 %} 7882 7883 // Integer DIVMOD with Register, both quotient and mod results 7884 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7885 rFlagsReg cr) 7886 %{ 7887 match(DivModI rax div); 7888 effect(KILL cr); 7889 7890 ins_cost(30*100+10*100); // XXX 7891 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7892 "jne,s normal\n\t" 7893 "xorl rdx, rdx\n\t" 7894 "cmpl $div, -1\n\t" 7895 "je,s done\n" 7896 "normal: cdql\n\t" 7897 "idivl $div\n" 7898 "done:" %} 7899 ins_encode(cdql_enc(div)); 7900 ins_pipe(pipe_slow); 7901 %} 7902 7903 // Long DIVMOD with Register, both quotient and mod results 7904 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7905 rFlagsReg cr) 7906 %{ 7907 match(DivModL rax div); 7908 effect(KILL cr); 7909 7910 ins_cost(30*100+10*100); // XXX 7911 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7912 "cmpq rax, rdx\n\t" 7913 "jne,s normal\n\t" 7914 "xorl rdx, rdx\n\t" 7915 "cmpq $div, -1\n\t" 7916 "je,s done\n" 7917 "normal: cdqq\n\t" 7918 "idivq $div\n" 7919 "done:" %} 7920 ins_encode(cdqq_enc(div)); 7921 ins_pipe(pipe_slow); 7922 %} 7923 7924 // Unsigned integer DIVMOD with Register, both quotient and mod results 7925 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7926 no_rax_rdx_RegI div, rFlagsReg cr) 7927 %{ 7928 match(UDivModI rax div); 7929 effect(TEMP tmp, KILL cr); 7930 7931 ins_cost(300); 7932 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7933 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7934 %} 7935 ins_encode %{ 7936 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7937 %} 7938 ins_pipe(pipe_slow); 7939 %} 7940 7941 // Unsigned long DIVMOD with Register, both quotient and mod results 7942 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7943 no_rax_rdx_RegL div, rFlagsReg cr) 7944 %{ 7945 match(UDivModL rax div); 7946 effect(TEMP tmp, KILL cr); 7947 7948 ins_cost(300); 7949 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7950 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7951 %} 7952 ins_encode %{ 7953 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7954 %} 7955 ins_pipe(pipe_slow); 7956 %} 7957 7958 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7959 rFlagsReg cr) 7960 %{ 7961 match(Set rdx (ModI rax div)); 7962 effect(KILL rax, KILL cr); 7963 7964 ins_cost(300); // XXX 7965 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7966 "jne,s normal\n\t" 7967 "xorl rdx, rdx\n\t" 7968 "cmpl $div, -1\n\t" 7969 "je,s done\n" 7970 "normal: cdql\n\t" 7971 "idivl $div\n" 7972 "done:" %} 7973 ins_encode(cdql_enc(div)); 7974 ins_pipe(ialu_reg_reg_alu0); 7975 %} 7976 7977 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7978 rFlagsReg cr) 7979 %{ 7980 match(Set rdx (ModL rax div)); 7981 effect(KILL rax, KILL cr); 7982 7983 ins_cost(300); // XXX 7984 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7985 "cmpq rax, rdx\n\t" 7986 "jne,s normal\n\t" 7987 "xorl rdx, rdx\n\t" 7988 "cmpq $div, -1\n\t" 7989 "je,s done\n" 7990 "normal: cdqq\n\t" 7991 "idivq $div\n" 7992 "done:" %} 7993 ins_encode(cdqq_enc(div)); 7994 ins_pipe(ialu_reg_reg_alu0); 7995 %} 7996 7997 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 7998 %{ 7999 match(Set rdx (UModI rax div)); 8000 effect(KILL rax, KILL cr); 8001 8002 ins_cost(300); 8003 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8004 ins_encode %{ 8005 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8006 %} 8007 ins_pipe(ialu_reg_reg_alu0); 8008 %} 8009 8010 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8011 %{ 8012 match(Set rdx (UModL rax div)); 8013 effect(KILL rax, KILL cr); 8014 8015 ins_cost(300); 8016 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8017 ins_encode %{ 8018 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8019 %} 8020 ins_pipe(ialu_reg_reg_alu0); 8021 %} 8022 8023 // Integer Shift Instructions 8024 // Shift Left by one, two, three 8025 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8026 %{ 8027 match(Set dst (LShiftI dst shift)); 8028 effect(KILL cr); 8029 8030 format %{ "sall $dst, $shift" %} 8031 ins_encode %{ 8032 __ sall($dst$$Register, $shift$$constant); 8033 %} 8034 ins_pipe(ialu_reg); 8035 %} 8036 8037 // Shift Left by 8-bit immediate 8038 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8039 %{ 8040 match(Set dst (LShiftI dst shift)); 8041 effect(KILL cr); 8042 8043 format %{ "sall $dst, $shift" %} 8044 ins_encode %{ 8045 __ sall($dst$$Register, $shift$$constant); 8046 %} 8047 ins_pipe(ialu_reg); 8048 %} 8049 8050 // Shift Left by 8-bit immediate 8051 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8052 %{ 8053 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8054 effect(KILL cr); 8055 8056 format %{ "sall $dst, $shift" %} 8057 ins_encode %{ 8058 __ sall($dst$$Address, $shift$$constant); 8059 %} 8060 ins_pipe(ialu_mem_imm); 8061 %} 8062 8063 // Shift Left by variable 8064 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8065 %{ 8066 predicate(!VM_Version::supports_bmi2()); 8067 match(Set dst (LShiftI dst shift)); 8068 effect(KILL cr); 8069 8070 format %{ "sall $dst, $shift" %} 8071 ins_encode %{ 8072 __ sall($dst$$Register); 8073 %} 8074 ins_pipe(ialu_reg_reg); 8075 %} 8076 8077 // Shift Left by variable 8078 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8079 %{ 8080 predicate(!VM_Version::supports_bmi2()); 8081 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8082 effect(KILL cr); 8083 8084 format %{ "sall $dst, $shift" %} 8085 ins_encode %{ 8086 __ sall($dst$$Address); 8087 %} 8088 ins_pipe(ialu_mem_reg); 8089 %} 8090 8091 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8092 %{ 8093 predicate(VM_Version::supports_bmi2()); 8094 match(Set dst (LShiftI src shift)); 8095 8096 format %{ "shlxl $dst, $src, $shift" %} 8097 ins_encode %{ 8098 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8099 %} 8100 ins_pipe(ialu_reg_reg); 8101 %} 8102 8103 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8104 %{ 8105 predicate(VM_Version::supports_bmi2()); 8106 match(Set dst (LShiftI (LoadI src) shift)); 8107 ins_cost(175); 8108 format %{ "shlxl $dst, $src, $shift" %} 8109 ins_encode %{ 8110 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8111 %} 8112 ins_pipe(ialu_reg_mem); 8113 %} 8114 8115 // Arithmetic Shift Right by 8-bit immediate 8116 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8117 %{ 8118 match(Set dst (RShiftI dst shift)); 8119 effect(KILL cr); 8120 8121 format %{ "sarl $dst, $shift" %} 8122 ins_encode %{ 8123 __ sarl($dst$$Register, $shift$$constant); 8124 %} 8125 ins_pipe(ialu_mem_imm); 8126 %} 8127 8128 // Arithmetic Shift Right by 8-bit immediate 8129 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8130 %{ 8131 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8132 effect(KILL cr); 8133 8134 format %{ "sarl $dst, $shift" %} 8135 ins_encode %{ 8136 __ sarl($dst$$Address, $shift$$constant); 8137 %} 8138 ins_pipe(ialu_mem_imm); 8139 %} 8140 8141 // Arithmetic Shift Right by variable 8142 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8143 %{ 8144 predicate(!VM_Version::supports_bmi2()); 8145 match(Set dst (RShiftI dst shift)); 8146 effect(KILL cr); 8147 8148 format %{ "sarl $dst, $shift" %} 8149 ins_encode %{ 8150 __ sarl($dst$$Register); 8151 %} 8152 ins_pipe(ialu_reg_reg); 8153 %} 8154 8155 // Arithmetic Shift Right by variable 8156 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8157 %{ 8158 predicate(!VM_Version::supports_bmi2()); 8159 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8160 effect(KILL cr); 8161 8162 format %{ "sarl $dst, $shift" %} 8163 ins_encode %{ 8164 __ sarl($dst$$Address); 8165 %} 8166 ins_pipe(ialu_mem_reg); 8167 %} 8168 8169 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8170 %{ 8171 predicate(VM_Version::supports_bmi2()); 8172 match(Set dst (RShiftI src shift)); 8173 8174 format %{ "sarxl $dst, $src, $shift" %} 8175 ins_encode %{ 8176 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8177 %} 8178 ins_pipe(ialu_reg_reg); 8179 %} 8180 8181 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8182 %{ 8183 predicate(VM_Version::supports_bmi2()); 8184 match(Set dst (RShiftI (LoadI src) shift)); 8185 ins_cost(175); 8186 format %{ "sarxl $dst, $src, $shift" %} 8187 ins_encode %{ 8188 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8189 %} 8190 ins_pipe(ialu_reg_mem); 8191 %} 8192 8193 // Logical Shift Right by 8-bit immediate 8194 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8195 %{ 8196 match(Set dst (URShiftI dst shift)); 8197 effect(KILL cr); 8198 8199 format %{ "shrl $dst, $shift" %} 8200 ins_encode %{ 8201 __ shrl($dst$$Register, $shift$$constant); 8202 %} 8203 ins_pipe(ialu_reg); 8204 %} 8205 8206 // Logical Shift Right by 8-bit immediate 8207 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8208 %{ 8209 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8210 effect(KILL cr); 8211 8212 format %{ "shrl $dst, $shift" %} 8213 ins_encode %{ 8214 __ shrl($dst$$Address, $shift$$constant); 8215 %} 8216 ins_pipe(ialu_mem_imm); 8217 %} 8218 8219 // Logical Shift Right by variable 8220 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8221 %{ 8222 predicate(!VM_Version::supports_bmi2()); 8223 match(Set dst (URShiftI dst shift)); 8224 effect(KILL cr); 8225 8226 format %{ "shrl $dst, $shift" %} 8227 ins_encode %{ 8228 __ shrl($dst$$Register); 8229 %} 8230 ins_pipe(ialu_reg_reg); 8231 %} 8232 8233 // Logical Shift Right by variable 8234 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8235 %{ 8236 predicate(!VM_Version::supports_bmi2()); 8237 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8238 effect(KILL cr); 8239 8240 format %{ "shrl $dst, $shift" %} 8241 ins_encode %{ 8242 __ shrl($dst$$Address); 8243 %} 8244 ins_pipe(ialu_mem_reg); 8245 %} 8246 8247 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8248 %{ 8249 predicate(VM_Version::supports_bmi2()); 8250 match(Set dst (URShiftI src shift)); 8251 8252 format %{ "shrxl $dst, $src, $shift" %} 8253 ins_encode %{ 8254 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8255 %} 8256 ins_pipe(ialu_reg_reg); 8257 %} 8258 8259 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8260 %{ 8261 predicate(VM_Version::supports_bmi2()); 8262 match(Set dst (URShiftI (LoadI src) shift)); 8263 ins_cost(175); 8264 format %{ "shrxl $dst, $src, $shift" %} 8265 ins_encode %{ 8266 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8267 %} 8268 ins_pipe(ialu_reg_mem); 8269 %} 8270 8271 // Long Shift Instructions 8272 // Shift Left by one, two, three 8273 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8274 %{ 8275 match(Set dst (LShiftL dst shift)); 8276 effect(KILL cr); 8277 8278 format %{ "salq $dst, $shift" %} 8279 ins_encode %{ 8280 __ salq($dst$$Register, $shift$$constant); 8281 %} 8282 ins_pipe(ialu_reg); 8283 %} 8284 8285 // Shift Left by 8-bit immediate 8286 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8287 %{ 8288 match(Set dst (LShiftL dst shift)); 8289 effect(KILL cr); 8290 8291 format %{ "salq $dst, $shift" %} 8292 ins_encode %{ 8293 __ salq($dst$$Register, $shift$$constant); 8294 %} 8295 ins_pipe(ialu_reg); 8296 %} 8297 8298 // Shift Left by 8-bit immediate 8299 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8300 %{ 8301 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8302 effect(KILL cr); 8303 8304 format %{ "salq $dst, $shift" %} 8305 ins_encode %{ 8306 __ salq($dst$$Address, $shift$$constant); 8307 %} 8308 ins_pipe(ialu_mem_imm); 8309 %} 8310 8311 // Shift Left by variable 8312 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8313 %{ 8314 predicate(!VM_Version::supports_bmi2()); 8315 match(Set dst (LShiftL dst shift)); 8316 effect(KILL cr); 8317 8318 format %{ "salq $dst, $shift" %} 8319 ins_encode %{ 8320 __ salq($dst$$Register); 8321 %} 8322 ins_pipe(ialu_reg_reg); 8323 %} 8324 8325 // Shift Left by variable 8326 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8327 %{ 8328 predicate(!VM_Version::supports_bmi2()); 8329 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8330 effect(KILL cr); 8331 8332 format %{ "salq $dst, $shift" %} 8333 ins_encode %{ 8334 __ salq($dst$$Address); 8335 %} 8336 ins_pipe(ialu_mem_reg); 8337 %} 8338 8339 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8340 %{ 8341 predicate(VM_Version::supports_bmi2()); 8342 match(Set dst (LShiftL src shift)); 8343 8344 format %{ "shlxq $dst, $src, $shift" %} 8345 ins_encode %{ 8346 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8347 %} 8348 ins_pipe(ialu_reg_reg); 8349 %} 8350 8351 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8352 %{ 8353 predicate(VM_Version::supports_bmi2()); 8354 match(Set dst (LShiftL (LoadL src) shift)); 8355 ins_cost(175); 8356 format %{ "shlxq $dst, $src, $shift" %} 8357 ins_encode %{ 8358 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8359 %} 8360 ins_pipe(ialu_reg_mem); 8361 %} 8362 8363 // Arithmetic Shift Right by 8-bit immediate 8364 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8365 %{ 8366 match(Set dst (RShiftL dst shift)); 8367 effect(KILL cr); 8368 8369 format %{ "sarq $dst, $shift" %} 8370 ins_encode %{ 8371 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8372 %} 8373 ins_pipe(ialu_mem_imm); 8374 %} 8375 8376 // Arithmetic Shift Right by 8-bit immediate 8377 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8378 %{ 8379 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8380 effect(KILL cr); 8381 8382 format %{ "sarq $dst, $shift" %} 8383 ins_encode %{ 8384 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8385 %} 8386 ins_pipe(ialu_mem_imm); 8387 %} 8388 8389 // Arithmetic Shift Right by variable 8390 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8391 %{ 8392 predicate(!VM_Version::supports_bmi2()); 8393 match(Set dst (RShiftL dst shift)); 8394 effect(KILL cr); 8395 8396 format %{ "sarq $dst, $shift" %} 8397 ins_encode %{ 8398 __ sarq($dst$$Register); 8399 %} 8400 ins_pipe(ialu_reg_reg); 8401 %} 8402 8403 // Arithmetic Shift Right by variable 8404 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8405 %{ 8406 predicate(!VM_Version::supports_bmi2()); 8407 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8408 effect(KILL cr); 8409 8410 format %{ "sarq $dst, $shift" %} 8411 ins_encode %{ 8412 __ sarq($dst$$Address); 8413 %} 8414 ins_pipe(ialu_mem_reg); 8415 %} 8416 8417 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8418 %{ 8419 predicate(VM_Version::supports_bmi2()); 8420 match(Set dst (RShiftL src shift)); 8421 8422 format %{ "sarxq $dst, $src, $shift" %} 8423 ins_encode %{ 8424 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8425 %} 8426 ins_pipe(ialu_reg_reg); 8427 %} 8428 8429 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8430 %{ 8431 predicate(VM_Version::supports_bmi2()); 8432 match(Set dst (RShiftL (LoadL src) shift)); 8433 ins_cost(175); 8434 format %{ "sarxq $dst, $src, $shift" %} 8435 ins_encode %{ 8436 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8437 %} 8438 ins_pipe(ialu_reg_mem); 8439 %} 8440 8441 // Logical Shift Right by 8-bit immediate 8442 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8443 %{ 8444 match(Set dst (URShiftL dst shift)); 8445 effect(KILL cr); 8446 8447 format %{ "shrq $dst, $shift" %} 8448 ins_encode %{ 8449 __ shrq($dst$$Register, $shift$$constant); 8450 %} 8451 ins_pipe(ialu_reg); 8452 %} 8453 8454 // Logical Shift Right by 8-bit immediate 8455 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8456 %{ 8457 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8458 effect(KILL cr); 8459 8460 format %{ "shrq $dst, $shift" %} 8461 ins_encode %{ 8462 __ shrq($dst$$Address, $shift$$constant); 8463 %} 8464 ins_pipe(ialu_mem_imm); 8465 %} 8466 8467 // Logical Shift Right by variable 8468 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8469 %{ 8470 predicate(!VM_Version::supports_bmi2()); 8471 match(Set dst (URShiftL dst shift)); 8472 effect(KILL cr); 8473 8474 format %{ "shrq $dst, $shift" %} 8475 ins_encode %{ 8476 __ shrq($dst$$Register); 8477 %} 8478 ins_pipe(ialu_reg_reg); 8479 %} 8480 8481 // Logical Shift Right by variable 8482 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8483 %{ 8484 predicate(!VM_Version::supports_bmi2()); 8485 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8486 effect(KILL cr); 8487 8488 format %{ "shrq $dst, $shift" %} 8489 ins_encode %{ 8490 __ shrq($dst$$Address); 8491 %} 8492 ins_pipe(ialu_mem_reg); 8493 %} 8494 8495 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8496 %{ 8497 predicate(VM_Version::supports_bmi2()); 8498 match(Set dst (URShiftL src shift)); 8499 8500 format %{ "shrxq $dst, $src, $shift" %} 8501 ins_encode %{ 8502 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8503 %} 8504 ins_pipe(ialu_reg_reg); 8505 %} 8506 8507 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8508 %{ 8509 predicate(VM_Version::supports_bmi2()); 8510 match(Set dst (URShiftL (LoadL src) shift)); 8511 ins_cost(175); 8512 format %{ "shrxq $dst, $src, $shift" %} 8513 ins_encode %{ 8514 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8515 %} 8516 ins_pipe(ialu_reg_mem); 8517 %} 8518 8519 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8520 // This idiom is used by the compiler for the i2b bytecode. 8521 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8522 %{ 8523 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8524 8525 format %{ "movsbl $dst, $src\t# i2b" %} 8526 ins_encode %{ 8527 __ movsbl($dst$$Register, $src$$Register); 8528 %} 8529 ins_pipe(ialu_reg_reg); 8530 %} 8531 8532 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8533 // This idiom is used by the compiler the i2s bytecode. 8534 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8535 %{ 8536 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8537 8538 format %{ "movswl $dst, $src\t# i2s" %} 8539 ins_encode %{ 8540 __ movswl($dst$$Register, $src$$Register); 8541 %} 8542 ins_pipe(ialu_reg_reg); 8543 %} 8544 8545 // ROL/ROR instructions 8546 8547 // Rotate left by constant. 8548 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8549 %{ 8550 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8551 match(Set dst (RotateLeft dst shift)); 8552 effect(KILL cr); 8553 format %{ "roll $dst, $shift" %} 8554 ins_encode %{ 8555 __ roll($dst$$Register, $shift$$constant); 8556 %} 8557 ins_pipe(ialu_reg); 8558 %} 8559 8560 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8561 %{ 8562 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8563 match(Set dst (RotateLeft src shift)); 8564 format %{ "rolxl $dst, $src, $shift" %} 8565 ins_encode %{ 8566 int shift = 32 - ($shift$$constant & 31); 8567 __ rorxl($dst$$Register, $src$$Register, shift); 8568 %} 8569 ins_pipe(ialu_reg_reg); 8570 %} 8571 8572 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8573 %{ 8574 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8575 match(Set dst (RotateLeft (LoadI src) shift)); 8576 ins_cost(175); 8577 format %{ "rolxl $dst, $src, $shift" %} 8578 ins_encode %{ 8579 int shift = 32 - ($shift$$constant & 31); 8580 __ rorxl($dst$$Register, $src$$Address, shift); 8581 %} 8582 ins_pipe(ialu_reg_mem); 8583 %} 8584 8585 // Rotate Left by variable 8586 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8587 %{ 8588 predicate(n->bottom_type()->basic_type() == T_INT); 8589 match(Set dst (RotateLeft dst shift)); 8590 effect(KILL cr); 8591 format %{ "roll $dst, $shift" %} 8592 ins_encode %{ 8593 __ roll($dst$$Register); 8594 %} 8595 ins_pipe(ialu_reg_reg); 8596 %} 8597 8598 // Rotate Right by constant. 8599 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8600 %{ 8601 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8602 match(Set dst (RotateRight dst shift)); 8603 effect(KILL cr); 8604 format %{ "rorl $dst, $shift" %} 8605 ins_encode %{ 8606 __ rorl($dst$$Register, $shift$$constant); 8607 %} 8608 ins_pipe(ialu_reg); 8609 %} 8610 8611 // Rotate Right by constant. 8612 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8613 %{ 8614 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8615 match(Set dst (RotateRight src shift)); 8616 format %{ "rorxl $dst, $src, $shift" %} 8617 ins_encode %{ 8618 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8619 %} 8620 ins_pipe(ialu_reg_reg); 8621 %} 8622 8623 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8624 %{ 8625 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8626 match(Set dst (RotateRight (LoadI src) shift)); 8627 ins_cost(175); 8628 format %{ "rorxl $dst, $src, $shift" %} 8629 ins_encode %{ 8630 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8631 %} 8632 ins_pipe(ialu_reg_mem); 8633 %} 8634 8635 // Rotate Right by variable 8636 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8637 %{ 8638 predicate(n->bottom_type()->basic_type() == T_INT); 8639 match(Set dst (RotateRight dst shift)); 8640 effect(KILL cr); 8641 format %{ "rorl $dst, $shift" %} 8642 ins_encode %{ 8643 __ rorl($dst$$Register); 8644 %} 8645 ins_pipe(ialu_reg_reg); 8646 %} 8647 8648 // Rotate Left by constant. 8649 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8650 %{ 8651 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8652 match(Set dst (RotateLeft dst shift)); 8653 effect(KILL cr); 8654 format %{ "rolq $dst, $shift" %} 8655 ins_encode %{ 8656 __ rolq($dst$$Register, $shift$$constant); 8657 %} 8658 ins_pipe(ialu_reg); 8659 %} 8660 8661 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8662 %{ 8663 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8664 match(Set dst (RotateLeft src shift)); 8665 format %{ "rolxq $dst, $src, $shift" %} 8666 ins_encode %{ 8667 int shift = 64 - ($shift$$constant & 63); 8668 __ rorxq($dst$$Register, $src$$Register, shift); 8669 %} 8670 ins_pipe(ialu_reg_reg); 8671 %} 8672 8673 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8674 %{ 8675 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8676 match(Set dst (RotateLeft (LoadL src) shift)); 8677 ins_cost(175); 8678 format %{ "rolxq $dst, $src, $shift" %} 8679 ins_encode %{ 8680 int shift = 64 - ($shift$$constant & 63); 8681 __ rorxq($dst$$Register, $src$$Address, shift); 8682 %} 8683 ins_pipe(ialu_reg_mem); 8684 %} 8685 8686 // Rotate Left by variable 8687 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8688 %{ 8689 predicate(n->bottom_type()->basic_type() == T_LONG); 8690 match(Set dst (RotateLeft dst shift)); 8691 effect(KILL cr); 8692 format %{ "rolq $dst, $shift" %} 8693 ins_encode %{ 8694 __ rolq($dst$$Register); 8695 %} 8696 ins_pipe(ialu_reg_reg); 8697 %} 8698 8699 // Rotate Right by constant. 8700 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8701 %{ 8702 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8703 match(Set dst (RotateRight dst shift)); 8704 effect(KILL cr); 8705 format %{ "rorq $dst, $shift" %} 8706 ins_encode %{ 8707 __ rorq($dst$$Register, $shift$$constant); 8708 %} 8709 ins_pipe(ialu_reg); 8710 %} 8711 8712 // Rotate Right by constant 8713 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8714 %{ 8715 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8716 match(Set dst (RotateRight src shift)); 8717 format %{ "rorxq $dst, $src, $shift" %} 8718 ins_encode %{ 8719 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8720 %} 8721 ins_pipe(ialu_reg_reg); 8722 %} 8723 8724 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8725 %{ 8726 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8727 match(Set dst (RotateRight (LoadL src) shift)); 8728 ins_cost(175); 8729 format %{ "rorxq $dst, $src, $shift" %} 8730 ins_encode %{ 8731 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8732 %} 8733 ins_pipe(ialu_reg_mem); 8734 %} 8735 8736 // Rotate Right by variable 8737 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8738 %{ 8739 predicate(n->bottom_type()->basic_type() == T_LONG); 8740 match(Set dst (RotateRight dst shift)); 8741 effect(KILL cr); 8742 format %{ "rorq $dst, $shift" %} 8743 ins_encode %{ 8744 __ rorq($dst$$Register); 8745 %} 8746 ins_pipe(ialu_reg_reg); 8747 %} 8748 8749 //----------------------------- CompressBits/ExpandBits ------------------------ 8750 8751 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8752 predicate(n->bottom_type()->isa_long()); 8753 match(Set dst (CompressBits src mask)); 8754 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8755 ins_encode %{ 8756 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8757 %} 8758 ins_pipe( pipe_slow ); 8759 %} 8760 8761 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8762 predicate(n->bottom_type()->isa_long()); 8763 match(Set dst (ExpandBits src mask)); 8764 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8765 ins_encode %{ 8766 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8767 %} 8768 ins_pipe( pipe_slow ); 8769 %} 8770 8771 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8772 predicate(n->bottom_type()->isa_long()); 8773 match(Set dst (CompressBits src (LoadL mask))); 8774 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8775 ins_encode %{ 8776 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8777 %} 8778 ins_pipe( pipe_slow ); 8779 %} 8780 8781 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8782 predicate(n->bottom_type()->isa_long()); 8783 match(Set dst (ExpandBits src (LoadL mask))); 8784 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8785 ins_encode %{ 8786 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8787 %} 8788 ins_pipe( pipe_slow ); 8789 %} 8790 8791 8792 // Logical Instructions 8793 8794 // Integer Logical Instructions 8795 8796 // And Instructions 8797 // And Register with Register 8798 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8799 %{ 8800 match(Set dst (AndI dst src)); 8801 effect(KILL cr); 8802 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); 8803 8804 format %{ "andl $dst, $src\t# int" %} 8805 ins_encode %{ 8806 __ andl($dst$$Register, $src$$Register); 8807 %} 8808 ins_pipe(ialu_reg_reg); 8809 %} 8810 8811 // And Register with Immediate 255 8812 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8813 %{ 8814 match(Set dst (AndI src mask)); 8815 8816 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8817 ins_encode %{ 8818 __ movzbl($dst$$Register, $src$$Register); 8819 %} 8820 ins_pipe(ialu_reg); 8821 %} 8822 8823 // And Register with Immediate 255 and promote to long 8824 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8825 %{ 8826 match(Set dst (ConvI2L (AndI src mask))); 8827 8828 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8829 ins_encode %{ 8830 __ movzbl($dst$$Register, $src$$Register); 8831 %} 8832 ins_pipe(ialu_reg); 8833 %} 8834 8835 // And Register with Immediate 65535 8836 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8837 %{ 8838 match(Set dst (AndI src mask)); 8839 8840 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8841 ins_encode %{ 8842 __ movzwl($dst$$Register, $src$$Register); 8843 %} 8844 ins_pipe(ialu_reg); 8845 %} 8846 8847 // And Register with Immediate 65535 and promote to long 8848 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8849 %{ 8850 match(Set dst (ConvI2L (AndI src mask))); 8851 8852 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8853 ins_encode %{ 8854 __ movzwl($dst$$Register, $src$$Register); 8855 %} 8856 ins_pipe(ialu_reg); 8857 %} 8858 8859 // Can skip int2long conversions after AND with small bitmask 8860 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8861 %{ 8862 predicate(VM_Version::supports_bmi2()); 8863 ins_cost(125); 8864 effect(TEMP tmp, KILL cr); 8865 match(Set dst (ConvI2L (AndI src mask))); 8866 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8867 ins_encode %{ 8868 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8869 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8870 %} 8871 ins_pipe(ialu_reg_reg); 8872 %} 8873 8874 // And Register with Immediate 8875 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8876 %{ 8877 match(Set dst (AndI dst src)); 8878 effect(KILL cr); 8879 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); 8880 8881 format %{ "andl $dst, $src\t# int" %} 8882 ins_encode %{ 8883 __ andl($dst$$Register, $src$$constant); 8884 %} 8885 ins_pipe(ialu_reg); 8886 %} 8887 8888 // And Register with Memory 8889 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8890 %{ 8891 match(Set dst (AndI dst (LoadI src))); 8892 effect(KILL cr); 8893 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); 8894 8895 ins_cost(150); 8896 format %{ "andl $dst, $src\t# int" %} 8897 ins_encode %{ 8898 __ andl($dst$$Register, $src$$Address); 8899 %} 8900 ins_pipe(ialu_reg_mem); 8901 %} 8902 8903 // And Memory with Register 8904 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8905 %{ 8906 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8907 effect(KILL cr); 8908 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); 8909 8910 ins_cost(150); 8911 format %{ "andb $dst, $src\t# byte" %} 8912 ins_encode %{ 8913 __ andb($dst$$Address, $src$$Register); 8914 %} 8915 ins_pipe(ialu_mem_reg); 8916 %} 8917 8918 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8919 %{ 8920 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8921 effect(KILL cr); 8922 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); 8923 8924 ins_cost(150); 8925 format %{ "andl $dst, $src\t# int" %} 8926 ins_encode %{ 8927 __ andl($dst$$Address, $src$$Register); 8928 %} 8929 ins_pipe(ialu_mem_reg); 8930 %} 8931 8932 // And Memory with Immediate 8933 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8934 %{ 8935 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8936 effect(KILL cr); 8937 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); 8938 8939 ins_cost(125); 8940 format %{ "andl $dst, $src\t# int" %} 8941 ins_encode %{ 8942 __ andl($dst$$Address, $src$$constant); 8943 %} 8944 ins_pipe(ialu_mem_imm); 8945 %} 8946 8947 // BMI1 instructions 8948 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8949 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8950 predicate(UseBMI1Instructions); 8951 effect(KILL cr); 8952 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8953 8954 ins_cost(125); 8955 format %{ "andnl $dst, $src1, $src2" %} 8956 8957 ins_encode %{ 8958 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8959 %} 8960 ins_pipe(ialu_reg_mem); 8961 %} 8962 8963 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8964 match(Set dst (AndI (XorI src1 minus_1) src2)); 8965 predicate(UseBMI1Instructions); 8966 effect(KILL cr); 8967 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8968 8969 format %{ "andnl $dst, $src1, $src2" %} 8970 8971 ins_encode %{ 8972 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8973 %} 8974 ins_pipe(ialu_reg); 8975 %} 8976 8977 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 8978 match(Set dst (AndI (SubI imm_zero src) src)); 8979 predicate(UseBMI1Instructions); 8980 effect(KILL cr); 8981 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8982 8983 format %{ "blsil $dst, $src" %} 8984 8985 ins_encode %{ 8986 __ blsil($dst$$Register, $src$$Register); 8987 %} 8988 ins_pipe(ialu_reg); 8989 %} 8990 8991 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 8992 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8993 predicate(UseBMI1Instructions); 8994 effect(KILL cr); 8995 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8996 8997 ins_cost(125); 8998 format %{ "blsil $dst, $src" %} 8999 9000 ins_encode %{ 9001 __ blsil($dst$$Register, $src$$Address); 9002 %} 9003 ins_pipe(ialu_reg_mem); 9004 %} 9005 9006 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9007 %{ 9008 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9009 predicate(UseBMI1Instructions); 9010 effect(KILL cr); 9011 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9012 9013 ins_cost(125); 9014 format %{ "blsmskl $dst, $src" %} 9015 9016 ins_encode %{ 9017 __ blsmskl($dst$$Register, $src$$Address); 9018 %} 9019 ins_pipe(ialu_reg_mem); 9020 %} 9021 9022 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9023 %{ 9024 match(Set dst (XorI (AddI src minus_1) src)); 9025 predicate(UseBMI1Instructions); 9026 effect(KILL cr); 9027 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9028 9029 format %{ "blsmskl $dst, $src" %} 9030 9031 ins_encode %{ 9032 __ blsmskl($dst$$Register, $src$$Register); 9033 %} 9034 9035 ins_pipe(ialu_reg); 9036 %} 9037 9038 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9039 %{ 9040 match(Set dst (AndI (AddI src minus_1) src) ); 9041 predicate(UseBMI1Instructions); 9042 effect(KILL cr); 9043 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9044 9045 format %{ "blsrl $dst, $src" %} 9046 9047 ins_encode %{ 9048 __ blsrl($dst$$Register, $src$$Register); 9049 %} 9050 9051 ins_pipe(ialu_reg_mem); 9052 %} 9053 9054 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9055 %{ 9056 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9057 predicate(UseBMI1Instructions); 9058 effect(KILL cr); 9059 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9060 9061 ins_cost(125); 9062 format %{ "blsrl $dst, $src" %} 9063 9064 ins_encode %{ 9065 __ blsrl($dst$$Register, $src$$Address); 9066 %} 9067 9068 ins_pipe(ialu_reg); 9069 %} 9070 9071 // Or Instructions 9072 // Or Register with Register 9073 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9074 %{ 9075 match(Set dst (OrI dst src)); 9076 effect(KILL cr); 9077 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9078 9079 format %{ "orl $dst, $src\t# int" %} 9080 ins_encode %{ 9081 __ orl($dst$$Register, $src$$Register); 9082 %} 9083 ins_pipe(ialu_reg_reg); 9084 %} 9085 9086 // Or Register with Immediate 9087 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9088 %{ 9089 match(Set dst (OrI dst src)); 9090 effect(KILL cr); 9091 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); 9092 9093 format %{ "orl $dst, $src\t# int" %} 9094 ins_encode %{ 9095 __ orl($dst$$Register, $src$$constant); 9096 %} 9097 ins_pipe(ialu_reg); 9098 %} 9099 9100 // Or Register with Memory 9101 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9102 %{ 9103 match(Set dst (OrI dst (LoadI src))); 9104 effect(KILL cr); 9105 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); 9106 9107 ins_cost(150); 9108 format %{ "orl $dst, $src\t# int" %} 9109 ins_encode %{ 9110 __ orl($dst$$Register, $src$$Address); 9111 %} 9112 ins_pipe(ialu_reg_mem); 9113 %} 9114 9115 // Or Memory with Register 9116 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9117 %{ 9118 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9119 effect(KILL cr); 9120 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); 9121 9122 ins_cost(150); 9123 format %{ "orb $dst, $src\t# byte" %} 9124 ins_encode %{ 9125 __ orb($dst$$Address, $src$$Register); 9126 %} 9127 ins_pipe(ialu_mem_reg); 9128 %} 9129 9130 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9131 %{ 9132 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9133 effect(KILL cr); 9134 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); 9135 9136 ins_cost(150); 9137 format %{ "orl $dst, $src\t# int" %} 9138 ins_encode %{ 9139 __ orl($dst$$Address, $src$$Register); 9140 %} 9141 ins_pipe(ialu_mem_reg); 9142 %} 9143 9144 // Or Memory with Immediate 9145 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9146 %{ 9147 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9148 effect(KILL cr); 9149 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); 9150 9151 ins_cost(125); 9152 format %{ "orl $dst, $src\t# int" %} 9153 ins_encode %{ 9154 __ orl($dst$$Address, $src$$constant); 9155 %} 9156 ins_pipe(ialu_mem_imm); 9157 %} 9158 9159 // Xor Instructions 9160 // Xor Register with Register 9161 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9162 %{ 9163 match(Set dst (XorI dst src)); 9164 effect(KILL cr); 9165 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); 9166 9167 format %{ "xorl $dst, $src\t# int" %} 9168 ins_encode %{ 9169 __ xorl($dst$$Register, $src$$Register); 9170 %} 9171 ins_pipe(ialu_reg_reg); 9172 %} 9173 9174 // Xor Register with Immediate -1 9175 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9176 match(Set dst (XorI dst imm)); 9177 9178 format %{ "not $dst" %} 9179 ins_encode %{ 9180 __ notl($dst$$Register); 9181 %} 9182 ins_pipe(ialu_reg); 9183 %} 9184 9185 // Xor Register with Immediate 9186 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9187 %{ 9188 match(Set dst (XorI dst src)); 9189 effect(KILL cr); 9190 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); 9191 9192 format %{ "xorl $dst, $src\t# int" %} 9193 ins_encode %{ 9194 __ xorl($dst$$Register, $src$$constant); 9195 %} 9196 ins_pipe(ialu_reg); 9197 %} 9198 9199 // Xor Register with Memory 9200 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9201 %{ 9202 match(Set dst (XorI dst (LoadI src))); 9203 effect(KILL cr); 9204 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); 9205 9206 ins_cost(150); 9207 format %{ "xorl $dst, $src\t# int" %} 9208 ins_encode %{ 9209 __ xorl($dst$$Register, $src$$Address); 9210 %} 9211 ins_pipe(ialu_reg_mem); 9212 %} 9213 9214 // Xor Memory with Register 9215 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9216 %{ 9217 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9218 effect(KILL cr); 9219 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); 9220 9221 ins_cost(150); 9222 format %{ "xorb $dst, $src\t# byte" %} 9223 ins_encode %{ 9224 __ xorb($dst$$Address, $src$$Register); 9225 %} 9226 ins_pipe(ialu_mem_reg); 9227 %} 9228 9229 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9230 %{ 9231 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9232 effect(KILL cr); 9233 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); 9234 9235 ins_cost(150); 9236 format %{ "xorl $dst, $src\t# int" %} 9237 ins_encode %{ 9238 __ xorl($dst$$Address, $src$$Register); 9239 %} 9240 ins_pipe(ialu_mem_reg); 9241 %} 9242 9243 // Xor Memory with Immediate 9244 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9245 %{ 9246 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9247 effect(KILL cr); 9248 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); 9249 9250 ins_cost(125); 9251 format %{ "xorl $dst, $src\t# int" %} 9252 ins_encode %{ 9253 __ xorl($dst$$Address, $src$$constant); 9254 %} 9255 ins_pipe(ialu_mem_imm); 9256 %} 9257 9258 9259 // Long Logical Instructions 9260 9261 // And Instructions 9262 // And Register with Register 9263 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9264 %{ 9265 match(Set dst (AndL dst src)); 9266 effect(KILL cr); 9267 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); 9268 9269 format %{ "andq $dst, $src\t# long" %} 9270 ins_encode %{ 9271 __ andq($dst$$Register, $src$$Register); 9272 %} 9273 ins_pipe(ialu_reg_reg); 9274 %} 9275 9276 // And Register with Immediate 255 9277 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9278 %{ 9279 match(Set dst (AndL src mask)); 9280 9281 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9282 ins_encode %{ 9283 // movzbl zeroes out the upper 32-bit and does not need REX.W 9284 __ movzbl($dst$$Register, $src$$Register); 9285 %} 9286 ins_pipe(ialu_reg); 9287 %} 9288 9289 // And Register with Immediate 65535 9290 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9291 %{ 9292 match(Set dst (AndL src mask)); 9293 9294 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9295 ins_encode %{ 9296 // movzwl zeroes out the upper 32-bit and does not need REX.W 9297 __ movzwl($dst$$Register, $src$$Register); 9298 %} 9299 ins_pipe(ialu_reg); 9300 %} 9301 9302 // And Register with Immediate 9303 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9304 %{ 9305 match(Set dst (AndL dst src)); 9306 effect(KILL cr); 9307 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); 9308 9309 format %{ "andq $dst, $src\t# long" %} 9310 ins_encode %{ 9311 __ andq($dst$$Register, $src$$constant); 9312 %} 9313 ins_pipe(ialu_reg); 9314 %} 9315 9316 // And Register with Memory 9317 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9318 %{ 9319 match(Set dst (AndL dst (LoadL src))); 9320 effect(KILL cr); 9321 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); 9322 9323 ins_cost(150); 9324 format %{ "andq $dst, $src\t# long" %} 9325 ins_encode %{ 9326 __ andq($dst$$Register, $src$$Address); 9327 %} 9328 ins_pipe(ialu_reg_mem); 9329 %} 9330 9331 // And Memory with Register 9332 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9333 %{ 9334 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9335 effect(KILL cr); 9336 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); 9337 9338 ins_cost(150); 9339 format %{ "andq $dst, $src\t# long" %} 9340 ins_encode %{ 9341 __ andq($dst$$Address, $src$$Register); 9342 %} 9343 ins_pipe(ialu_mem_reg); 9344 %} 9345 9346 // And Memory with Immediate 9347 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9348 %{ 9349 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9350 effect(KILL cr); 9351 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); 9352 9353 ins_cost(125); 9354 format %{ "andq $dst, $src\t# long" %} 9355 ins_encode %{ 9356 __ andq($dst$$Address, $src$$constant); 9357 %} 9358 ins_pipe(ialu_mem_imm); 9359 %} 9360 9361 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9362 %{ 9363 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9364 // because AND/OR works well enough for 8/32-bit values. 9365 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9366 9367 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9368 effect(KILL cr); 9369 9370 ins_cost(125); 9371 format %{ "btrq $dst, log2(not($con))\t# long" %} 9372 ins_encode %{ 9373 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9374 %} 9375 ins_pipe(ialu_mem_imm); 9376 %} 9377 9378 // BMI1 instructions 9379 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9380 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9381 predicate(UseBMI1Instructions); 9382 effect(KILL cr); 9383 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9384 9385 ins_cost(125); 9386 format %{ "andnq $dst, $src1, $src2" %} 9387 9388 ins_encode %{ 9389 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9390 %} 9391 ins_pipe(ialu_reg_mem); 9392 %} 9393 9394 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9395 match(Set dst (AndL (XorL src1 minus_1) src2)); 9396 predicate(UseBMI1Instructions); 9397 effect(KILL cr); 9398 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9399 9400 format %{ "andnq $dst, $src1, $src2" %} 9401 9402 ins_encode %{ 9403 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9404 %} 9405 ins_pipe(ialu_reg_mem); 9406 %} 9407 9408 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9409 match(Set dst (AndL (SubL imm_zero src) src)); 9410 predicate(UseBMI1Instructions); 9411 effect(KILL cr); 9412 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9413 9414 format %{ "blsiq $dst, $src" %} 9415 9416 ins_encode %{ 9417 __ blsiq($dst$$Register, $src$$Register); 9418 %} 9419 ins_pipe(ialu_reg); 9420 %} 9421 9422 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9423 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9424 predicate(UseBMI1Instructions); 9425 effect(KILL cr); 9426 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9427 9428 ins_cost(125); 9429 format %{ "blsiq $dst, $src" %} 9430 9431 ins_encode %{ 9432 __ blsiq($dst$$Register, $src$$Address); 9433 %} 9434 ins_pipe(ialu_reg_mem); 9435 %} 9436 9437 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9438 %{ 9439 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9440 predicate(UseBMI1Instructions); 9441 effect(KILL cr); 9442 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9443 9444 ins_cost(125); 9445 format %{ "blsmskq $dst, $src" %} 9446 9447 ins_encode %{ 9448 __ blsmskq($dst$$Register, $src$$Address); 9449 %} 9450 ins_pipe(ialu_reg_mem); 9451 %} 9452 9453 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9454 %{ 9455 match(Set dst (XorL (AddL src minus_1) src)); 9456 predicate(UseBMI1Instructions); 9457 effect(KILL cr); 9458 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9459 9460 format %{ "blsmskq $dst, $src" %} 9461 9462 ins_encode %{ 9463 __ blsmskq($dst$$Register, $src$$Register); 9464 %} 9465 9466 ins_pipe(ialu_reg); 9467 %} 9468 9469 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9470 %{ 9471 match(Set dst (AndL (AddL src minus_1) src) ); 9472 predicate(UseBMI1Instructions); 9473 effect(KILL cr); 9474 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9475 9476 format %{ "blsrq $dst, $src" %} 9477 9478 ins_encode %{ 9479 __ blsrq($dst$$Register, $src$$Register); 9480 %} 9481 9482 ins_pipe(ialu_reg); 9483 %} 9484 9485 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9486 %{ 9487 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9488 predicate(UseBMI1Instructions); 9489 effect(KILL cr); 9490 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9491 9492 ins_cost(125); 9493 format %{ "blsrq $dst, $src" %} 9494 9495 ins_encode %{ 9496 __ blsrq($dst$$Register, $src$$Address); 9497 %} 9498 9499 ins_pipe(ialu_reg); 9500 %} 9501 9502 // Or Instructions 9503 // Or Register with Register 9504 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9505 %{ 9506 match(Set dst (OrL dst src)); 9507 effect(KILL cr); 9508 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9509 9510 format %{ "orq $dst, $src\t# long" %} 9511 ins_encode %{ 9512 __ orq($dst$$Register, $src$$Register); 9513 %} 9514 ins_pipe(ialu_reg_reg); 9515 %} 9516 9517 // Use any_RegP to match R15 (TLS register) without spilling. 9518 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9519 match(Set dst (OrL dst (CastP2X src))); 9520 effect(KILL cr); 9521 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); 9522 9523 format %{ "orq $dst, $src\t# long" %} 9524 ins_encode %{ 9525 __ orq($dst$$Register, $src$$Register); 9526 %} 9527 ins_pipe(ialu_reg_reg); 9528 %} 9529 9530 9531 // Or Register with Immediate 9532 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9533 %{ 9534 match(Set dst (OrL dst src)); 9535 effect(KILL cr); 9536 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); 9537 9538 format %{ "orq $dst, $src\t# long" %} 9539 ins_encode %{ 9540 __ orq($dst$$Register, $src$$constant); 9541 %} 9542 ins_pipe(ialu_reg); 9543 %} 9544 9545 // Or Register with Memory 9546 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9547 %{ 9548 match(Set dst (OrL dst (LoadL src))); 9549 effect(KILL cr); 9550 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); 9551 9552 ins_cost(150); 9553 format %{ "orq $dst, $src\t# long" %} 9554 ins_encode %{ 9555 __ orq($dst$$Register, $src$$Address); 9556 %} 9557 ins_pipe(ialu_reg_mem); 9558 %} 9559 9560 // Or Memory with Register 9561 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9562 %{ 9563 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9564 effect(KILL cr); 9565 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); 9566 9567 ins_cost(150); 9568 format %{ "orq $dst, $src\t# long" %} 9569 ins_encode %{ 9570 __ orq($dst$$Address, $src$$Register); 9571 %} 9572 ins_pipe(ialu_mem_reg); 9573 %} 9574 9575 // Or Memory with Immediate 9576 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9577 %{ 9578 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9579 effect(KILL cr); 9580 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9581 9582 ins_cost(125); 9583 format %{ "orq $dst, $src\t# long" %} 9584 ins_encode %{ 9585 __ orq($dst$$Address, $src$$constant); 9586 %} 9587 ins_pipe(ialu_mem_imm); 9588 %} 9589 9590 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9591 %{ 9592 // con should be a pure 64-bit power of 2 immediate 9593 // because AND/OR works well enough for 8/32-bit values. 9594 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9595 9596 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9597 effect(KILL cr); 9598 9599 ins_cost(125); 9600 format %{ "btsq $dst, log2($con)\t# long" %} 9601 ins_encode %{ 9602 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9603 %} 9604 ins_pipe(ialu_mem_imm); 9605 %} 9606 9607 // Xor Instructions 9608 // Xor Register with Register 9609 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9610 %{ 9611 match(Set dst (XorL dst src)); 9612 effect(KILL cr); 9613 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); 9614 9615 format %{ "xorq $dst, $src\t# long" %} 9616 ins_encode %{ 9617 __ xorq($dst$$Register, $src$$Register); 9618 %} 9619 ins_pipe(ialu_reg_reg); 9620 %} 9621 9622 // Xor Register with Immediate -1 9623 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9624 match(Set dst (XorL dst imm)); 9625 9626 format %{ "notq $dst" %} 9627 ins_encode %{ 9628 __ notq($dst$$Register); 9629 %} 9630 ins_pipe(ialu_reg); 9631 %} 9632 9633 // Xor Register with Immediate 9634 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9635 %{ 9636 match(Set dst (XorL dst src)); 9637 effect(KILL cr); 9638 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); 9639 9640 format %{ "xorq $dst, $src\t# long" %} 9641 ins_encode %{ 9642 __ xorq($dst$$Register, $src$$constant); 9643 %} 9644 ins_pipe(ialu_reg); 9645 %} 9646 9647 // Xor Register with Memory 9648 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9649 %{ 9650 match(Set dst (XorL dst (LoadL src))); 9651 effect(KILL cr); 9652 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); 9653 9654 ins_cost(150); 9655 format %{ "xorq $dst, $src\t# long" %} 9656 ins_encode %{ 9657 __ xorq($dst$$Register, $src$$Address); 9658 %} 9659 ins_pipe(ialu_reg_mem); 9660 %} 9661 9662 // Xor Memory with Register 9663 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9664 %{ 9665 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9666 effect(KILL cr); 9667 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); 9668 9669 ins_cost(150); 9670 format %{ "xorq $dst, $src\t# long" %} 9671 ins_encode %{ 9672 __ xorq($dst$$Address, $src$$Register); 9673 %} 9674 ins_pipe(ialu_mem_reg); 9675 %} 9676 9677 // Xor Memory with Immediate 9678 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9679 %{ 9680 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9681 effect(KILL cr); 9682 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); 9683 9684 ins_cost(125); 9685 format %{ "xorq $dst, $src\t# long" %} 9686 ins_encode %{ 9687 __ xorq($dst$$Address, $src$$constant); 9688 %} 9689 ins_pipe(ialu_mem_imm); 9690 %} 9691 9692 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9693 %{ 9694 match(Set dst (CmpLTMask p q)); 9695 effect(KILL cr); 9696 9697 ins_cost(400); 9698 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9699 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 9700 "negl $dst" %} 9701 ins_encode %{ 9702 __ cmpl($p$$Register, $q$$Register); 9703 __ setcc(Assembler::less, $dst$$Register); 9704 __ negl($dst$$Register); 9705 %} 9706 ins_pipe(pipe_slow); 9707 %} 9708 9709 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9710 %{ 9711 match(Set dst (CmpLTMask dst zero)); 9712 effect(KILL cr); 9713 9714 ins_cost(100); 9715 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9716 ins_encode %{ 9717 __ sarl($dst$$Register, 31); 9718 %} 9719 ins_pipe(ialu_reg); 9720 %} 9721 9722 /* Better to save a register than avoid a branch */ 9723 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9724 %{ 9725 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9726 effect(KILL cr); 9727 ins_cost(300); 9728 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9729 "jge done\n\t" 9730 "addl $p,$y\n" 9731 "done: " %} 9732 ins_encode %{ 9733 Register Rp = $p$$Register; 9734 Register Rq = $q$$Register; 9735 Register Ry = $y$$Register; 9736 Label done; 9737 __ subl(Rp, Rq); 9738 __ jccb(Assembler::greaterEqual, done); 9739 __ addl(Rp, Ry); 9740 __ bind(done); 9741 %} 9742 ins_pipe(pipe_cmplt); 9743 %} 9744 9745 /* Better to save a register than avoid a branch */ 9746 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9747 %{ 9748 match(Set y (AndI (CmpLTMask p q) y)); 9749 effect(KILL cr); 9750 9751 ins_cost(300); 9752 9753 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9754 "jlt done\n\t" 9755 "xorl $y, $y\n" 9756 "done: " %} 9757 ins_encode %{ 9758 Register Rp = $p$$Register; 9759 Register Rq = $q$$Register; 9760 Register Ry = $y$$Register; 9761 Label done; 9762 __ cmpl(Rp, Rq); 9763 __ jccb(Assembler::less, done); 9764 __ xorl(Ry, Ry); 9765 __ bind(done); 9766 %} 9767 ins_pipe(pipe_cmplt); 9768 %} 9769 9770 9771 //---------- FP Instructions------------------------------------------------ 9772 9773 // Really expensive, avoid 9774 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9775 %{ 9776 match(Set cr (CmpF src1 src2)); 9777 9778 ins_cost(500); 9779 format %{ "ucomiss $src1, $src2\n\t" 9780 "jnp,s exit\n\t" 9781 "pushfq\t# saw NaN, set CF\n\t" 9782 "andq [rsp], #0xffffff2b\n\t" 9783 "popfq\n" 9784 "exit:" %} 9785 ins_encode %{ 9786 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9787 emit_cmpfp_fixup(masm); 9788 %} 9789 ins_pipe(pipe_slow); 9790 %} 9791 9792 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9793 match(Set cr (CmpF src1 src2)); 9794 9795 ins_cost(100); 9796 format %{ "ucomiss $src1, $src2" %} 9797 ins_encode %{ 9798 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9799 %} 9800 ins_pipe(pipe_slow); 9801 %} 9802 9803 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9804 match(Set cr (CmpF src1 (LoadF src2))); 9805 9806 ins_cost(100); 9807 format %{ "ucomiss $src1, $src2" %} 9808 ins_encode %{ 9809 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9810 %} 9811 ins_pipe(pipe_slow); 9812 %} 9813 9814 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9815 match(Set cr (CmpF src con)); 9816 ins_cost(100); 9817 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9818 ins_encode %{ 9819 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9820 %} 9821 ins_pipe(pipe_slow); 9822 %} 9823 9824 // Really expensive, avoid 9825 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9826 %{ 9827 match(Set cr (CmpD src1 src2)); 9828 9829 ins_cost(500); 9830 format %{ "ucomisd $src1, $src2\n\t" 9831 "jnp,s exit\n\t" 9832 "pushfq\t# saw NaN, set CF\n\t" 9833 "andq [rsp], #0xffffff2b\n\t" 9834 "popfq\n" 9835 "exit:" %} 9836 ins_encode %{ 9837 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9838 emit_cmpfp_fixup(masm); 9839 %} 9840 ins_pipe(pipe_slow); 9841 %} 9842 9843 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9844 match(Set cr (CmpD src1 src2)); 9845 9846 ins_cost(100); 9847 format %{ "ucomisd $src1, $src2 test" %} 9848 ins_encode %{ 9849 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9850 %} 9851 ins_pipe(pipe_slow); 9852 %} 9853 9854 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9855 match(Set cr (CmpD src1 (LoadD src2))); 9856 9857 ins_cost(100); 9858 format %{ "ucomisd $src1, $src2" %} 9859 ins_encode %{ 9860 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9861 %} 9862 ins_pipe(pipe_slow); 9863 %} 9864 9865 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9866 match(Set cr (CmpD src con)); 9867 ins_cost(100); 9868 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9869 ins_encode %{ 9870 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9871 %} 9872 ins_pipe(pipe_slow); 9873 %} 9874 9875 // Compare into -1,0,1 9876 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9877 %{ 9878 match(Set dst (CmpF3 src1 src2)); 9879 effect(KILL cr); 9880 9881 ins_cost(275); 9882 format %{ "ucomiss $src1, $src2\n\t" 9883 "movl $dst, #-1\n\t" 9884 "jp,s done\n\t" 9885 "jb,s done\n\t" 9886 "setne $dst\n\t" 9887 "movzbl $dst, $dst\n" 9888 "done:" %} 9889 ins_encode %{ 9890 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9891 emit_cmpfp3(masm, $dst$$Register); 9892 %} 9893 ins_pipe(pipe_slow); 9894 %} 9895 9896 // Compare into -1,0,1 9897 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9898 %{ 9899 match(Set dst (CmpF3 src1 (LoadF src2))); 9900 effect(KILL cr); 9901 9902 ins_cost(275); 9903 format %{ "ucomiss $src1, $src2\n\t" 9904 "movl $dst, #-1\n\t" 9905 "jp,s done\n\t" 9906 "jb,s done\n\t" 9907 "setne $dst\n\t" 9908 "movzbl $dst, $dst\n" 9909 "done:" %} 9910 ins_encode %{ 9911 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9912 emit_cmpfp3(masm, $dst$$Register); 9913 %} 9914 ins_pipe(pipe_slow); 9915 %} 9916 9917 // Compare into -1,0,1 9918 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9919 match(Set dst (CmpF3 src con)); 9920 effect(KILL cr); 9921 9922 ins_cost(275); 9923 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9924 "movl $dst, #-1\n\t" 9925 "jp,s done\n\t" 9926 "jb,s done\n\t" 9927 "setne $dst\n\t" 9928 "movzbl $dst, $dst\n" 9929 "done:" %} 9930 ins_encode %{ 9931 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9932 emit_cmpfp3(masm, $dst$$Register); 9933 %} 9934 ins_pipe(pipe_slow); 9935 %} 9936 9937 // Compare into -1,0,1 9938 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9939 %{ 9940 match(Set dst (CmpD3 src1 src2)); 9941 effect(KILL cr); 9942 9943 ins_cost(275); 9944 format %{ "ucomisd $src1, $src2\n\t" 9945 "movl $dst, #-1\n\t" 9946 "jp,s done\n\t" 9947 "jb,s done\n\t" 9948 "setne $dst\n\t" 9949 "movzbl $dst, $dst\n" 9950 "done:" %} 9951 ins_encode %{ 9952 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9953 emit_cmpfp3(masm, $dst$$Register); 9954 %} 9955 ins_pipe(pipe_slow); 9956 %} 9957 9958 // Compare into -1,0,1 9959 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9960 %{ 9961 match(Set dst (CmpD3 src1 (LoadD src2))); 9962 effect(KILL cr); 9963 9964 ins_cost(275); 9965 format %{ "ucomisd $src1, $src2\n\t" 9966 "movl $dst, #-1\n\t" 9967 "jp,s done\n\t" 9968 "jb,s done\n\t" 9969 "setne $dst\n\t" 9970 "movzbl $dst, $dst\n" 9971 "done:" %} 9972 ins_encode %{ 9973 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9974 emit_cmpfp3(masm, $dst$$Register); 9975 %} 9976 ins_pipe(pipe_slow); 9977 %} 9978 9979 // Compare into -1,0,1 9980 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9981 match(Set dst (CmpD3 src con)); 9982 effect(KILL cr); 9983 9984 ins_cost(275); 9985 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9986 "movl $dst, #-1\n\t" 9987 "jp,s done\n\t" 9988 "jb,s done\n\t" 9989 "setne $dst\n\t" 9990 "movzbl $dst, $dst\n" 9991 "done:" %} 9992 ins_encode %{ 9993 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9994 emit_cmpfp3(masm, $dst$$Register); 9995 %} 9996 ins_pipe(pipe_slow); 9997 %} 9998 9999 //----------Arithmetic Conversion Instructions--------------------------------- 10000 10001 instruct convF2D_reg_reg(regD dst, regF src) 10002 %{ 10003 match(Set dst (ConvF2D src)); 10004 10005 format %{ "cvtss2sd $dst, $src" %} 10006 ins_encode %{ 10007 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10008 %} 10009 ins_pipe(pipe_slow); // XXX 10010 %} 10011 10012 instruct convF2D_reg_mem(regD dst, memory src) 10013 %{ 10014 predicate(UseAVX == 0); 10015 match(Set dst (ConvF2D (LoadF src))); 10016 10017 format %{ "cvtss2sd $dst, $src" %} 10018 ins_encode %{ 10019 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10020 %} 10021 ins_pipe(pipe_slow); // XXX 10022 %} 10023 10024 instruct convD2F_reg_reg(regF dst, regD src) 10025 %{ 10026 match(Set dst (ConvD2F src)); 10027 10028 format %{ "cvtsd2ss $dst, $src" %} 10029 ins_encode %{ 10030 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10031 %} 10032 ins_pipe(pipe_slow); // XXX 10033 %} 10034 10035 instruct convD2F_reg_mem(regF dst, memory src) 10036 %{ 10037 predicate(UseAVX == 0); 10038 match(Set dst (ConvD2F (LoadD src))); 10039 10040 format %{ "cvtsd2ss $dst, $src" %} 10041 ins_encode %{ 10042 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10043 %} 10044 ins_pipe(pipe_slow); // XXX 10045 %} 10046 10047 // XXX do mem variants 10048 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10049 %{ 10050 match(Set dst (ConvF2I src)); 10051 effect(KILL cr); 10052 format %{ "convert_f2i $dst, $src" %} 10053 ins_encode %{ 10054 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10055 %} 10056 ins_pipe(pipe_slow); 10057 %} 10058 10059 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10060 %{ 10061 match(Set dst (ConvF2L src)); 10062 effect(KILL cr); 10063 format %{ "convert_f2l $dst, $src"%} 10064 ins_encode %{ 10065 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10066 %} 10067 ins_pipe(pipe_slow); 10068 %} 10069 10070 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10071 %{ 10072 match(Set dst (ConvD2I src)); 10073 effect(KILL cr); 10074 format %{ "convert_d2i $dst, $src"%} 10075 ins_encode %{ 10076 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10077 %} 10078 ins_pipe(pipe_slow); 10079 %} 10080 10081 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10082 %{ 10083 match(Set dst (ConvD2L src)); 10084 effect(KILL cr); 10085 format %{ "convert_d2l $dst, $src"%} 10086 ins_encode %{ 10087 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10088 %} 10089 ins_pipe(pipe_slow); 10090 %} 10091 10092 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10093 %{ 10094 match(Set dst (RoundD src)); 10095 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10096 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10097 ins_encode %{ 10098 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10099 %} 10100 ins_pipe(pipe_slow); 10101 %} 10102 10103 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10104 %{ 10105 match(Set dst (RoundF src)); 10106 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10107 format %{ "round_float $dst,$src" %} 10108 ins_encode %{ 10109 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10110 %} 10111 ins_pipe(pipe_slow); 10112 %} 10113 10114 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10115 %{ 10116 predicate(!UseXmmI2F); 10117 match(Set dst (ConvI2F src)); 10118 10119 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10120 ins_encode %{ 10121 if (UseAVX > 0) { 10122 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10123 } 10124 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10125 %} 10126 ins_pipe(pipe_slow); // XXX 10127 %} 10128 10129 instruct convI2F_reg_mem(regF dst, memory src) 10130 %{ 10131 predicate(UseAVX == 0); 10132 match(Set dst (ConvI2F (LoadI src))); 10133 10134 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10135 ins_encode %{ 10136 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10137 %} 10138 ins_pipe(pipe_slow); // XXX 10139 %} 10140 10141 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10142 %{ 10143 predicate(!UseXmmI2D); 10144 match(Set dst (ConvI2D src)); 10145 10146 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10147 ins_encode %{ 10148 if (UseAVX > 0) { 10149 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10150 } 10151 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10152 %} 10153 ins_pipe(pipe_slow); // XXX 10154 %} 10155 10156 instruct convI2D_reg_mem(regD dst, memory src) 10157 %{ 10158 predicate(UseAVX == 0); 10159 match(Set dst (ConvI2D (LoadI src))); 10160 10161 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10162 ins_encode %{ 10163 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10164 %} 10165 ins_pipe(pipe_slow); // XXX 10166 %} 10167 10168 instruct convXI2F_reg(regF dst, rRegI src) 10169 %{ 10170 predicate(UseXmmI2F); 10171 match(Set dst (ConvI2F src)); 10172 10173 format %{ "movdl $dst, $src\n\t" 10174 "cvtdq2psl $dst, $dst\t# i2f" %} 10175 ins_encode %{ 10176 __ movdl($dst$$XMMRegister, $src$$Register); 10177 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10178 %} 10179 ins_pipe(pipe_slow); // XXX 10180 %} 10181 10182 instruct convXI2D_reg(regD dst, rRegI src) 10183 %{ 10184 predicate(UseXmmI2D); 10185 match(Set dst (ConvI2D src)); 10186 10187 format %{ "movdl $dst, $src\n\t" 10188 "cvtdq2pdl $dst, $dst\t# i2d" %} 10189 ins_encode %{ 10190 __ movdl($dst$$XMMRegister, $src$$Register); 10191 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10192 %} 10193 ins_pipe(pipe_slow); // XXX 10194 %} 10195 10196 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10197 %{ 10198 match(Set dst (ConvL2F src)); 10199 10200 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10201 ins_encode %{ 10202 if (UseAVX > 0) { 10203 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10204 } 10205 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10206 %} 10207 ins_pipe(pipe_slow); // XXX 10208 %} 10209 10210 instruct convL2F_reg_mem(regF dst, memory src) 10211 %{ 10212 predicate(UseAVX == 0); 10213 match(Set dst (ConvL2F (LoadL src))); 10214 10215 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10216 ins_encode %{ 10217 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10218 %} 10219 ins_pipe(pipe_slow); // XXX 10220 %} 10221 10222 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10223 %{ 10224 match(Set dst (ConvL2D src)); 10225 10226 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10227 ins_encode %{ 10228 if (UseAVX > 0) { 10229 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10230 } 10231 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10232 %} 10233 ins_pipe(pipe_slow); // XXX 10234 %} 10235 10236 instruct convL2D_reg_mem(regD dst, memory src) 10237 %{ 10238 predicate(UseAVX == 0); 10239 match(Set dst (ConvL2D (LoadL src))); 10240 10241 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10242 ins_encode %{ 10243 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10244 %} 10245 ins_pipe(pipe_slow); // XXX 10246 %} 10247 10248 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10249 %{ 10250 match(Set dst (ConvI2L src)); 10251 10252 ins_cost(125); 10253 format %{ "movslq $dst, $src\t# i2l" %} 10254 ins_encode %{ 10255 __ movslq($dst$$Register, $src$$Register); 10256 %} 10257 ins_pipe(ialu_reg_reg); 10258 %} 10259 10260 // Zero-extend convert int to long 10261 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10262 %{ 10263 match(Set dst (AndL (ConvI2L src) mask)); 10264 10265 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10266 ins_encode %{ 10267 if ($dst$$reg != $src$$reg) { 10268 __ movl($dst$$Register, $src$$Register); 10269 } 10270 %} 10271 ins_pipe(ialu_reg_reg); 10272 %} 10273 10274 // Zero-extend convert int to long 10275 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10276 %{ 10277 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10278 10279 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10280 ins_encode %{ 10281 __ movl($dst$$Register, $src$$Address); 10282 %} 10283 ins_pipe(ialu_reg_mem); 10284 %} 10285 10286 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10287 %{ 10288 match(Set dst (AndL src mask)); 10289 10290 format %{ "movl $dst, $src\t# zero-extend long" %} 10291 ins_encode %{ 10292 __ movl($dst$$Register, $src$$Register); 10293 %} 10294 ins_pipe(ialu_reg_reg); 10295 %} 10296 10297 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10298 %{ 10299 match(Set dst (ConvL2I src)); 10300 10301 format %{ "movl $dst, $src\t# l2i" %} 10302 ins_encode %{ 10303 __ movl($dst$$Register, $src$$Register); 10304 %} 10305 ins_pipe(ialu_reg_reg); 10306 %} 10307 10308 10309 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10310 match(Set dst (MoveF2I src)); 10311 effect(DEF dst, USE src); 10312 10313 ins_cost(125); 10314 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10315 ins_encode %{ 10316 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10317 %} 10318 ins_pipe(ialu_reg_mem); 10319 %} 10320 10321 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10322 match(Set dst (MoveI2F src)); 10323 effect(DEF dst, USE src); 10324 10325 ins_cost(125); 10326 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10327 ins_encode %{ 10328 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10329 %} 10330 ins_pipe(pipe_slow); 10331 %} 10332 10333 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10334 match(Set dst (MoveD2L src)); 10335 effect(DEF dst, USE src); 10336 10337 ins_cost(125); 10338 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10339 ins_encode %{ 10340 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10341 %} 10342 ins_pipe(ialu_reg_mem); 10343 %} 10344 10345 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10346 predicate(!UseXmmLoadAndClearUpper); 10347 match(Set dst (MoveL2D src)); 10348 effect(DEF dst, USE src); 10349 10350 ins_cost(125); 10351 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10352 ins_encode %{ 10353 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10354 %} 10355 ins_pipe(pipe_slow); 10356 %} 10357 10358 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10359 predicate(UseXmmLoadAndClearUpper); 10360 match(Set dst (MoveL2D src)); 10361 effect(DEF dst, USE src); 10362 10363 ins_cost(125); 10364 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10365 ins_encode %{ 10366 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10367 %} 10368 ins_pipe(pipe_slow); 10369 %} 10370 10371 10372 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10373 match(Set dst (MoveF2I src)); 10374 effect(DEF dst, USE src); 10375 10376 ins_cost(95); // XXX 10377 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10378 ins_encode %{ 10379 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10380 %} 10381 ins_pipe(pipe_slow); 10382 %} 10383 10384 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10385 match(Set dst (MoveI2F src)); 10386 effect(DEF dst, USE src); 10387 10388 ins_cost(100); 10389 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10390 ins_encode %{ 10391 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10392 %} 10393 ins_pipe( ialu_mem_reg ); 10394 %} 10395 10396 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10397 match(Set dst (MoveD2L src)); 10398 effect(DEF dst, USE src); 10399 10400 ins_cost(95); // XXX 10401 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10402 ins_encode %{ 10403 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10404 %} 10405 ins_pipe(pipe_slow); 10406 %} 10407 10408 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10409 match(Set dst (MoveL2D src)); 10410 effect(DEF dst, USE src); 10411 10412 ins_cost(100); 10413 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10414 ins_encode %{ 10415 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10416 %} 10417 ins_pipe(ialu_mem_reg); 10418 %} 10419 10420 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10421 match(Set dst (MoveF2I src)); 10422 effect(DEF dst, USE src); 10423 ins_cost(85); 10424 format %{ "movd $dst,$src\t# MoveF2I" %} 10425 ins_encode %{ 10426 __ movdl($dst$$Register, $src$$XMMRegister); 10427 %} 10428 ins_pipe( pipe_slow ); 10429 %} 10430 10431 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10432 match(Set dst (MoveD2L src)); 10433 effect(DEF dst, USE src); 10434 ins_cost(85); 10435 format %{ "movd $dst,$src\t# MoveD2L" %} 10436 ins_encode %{ 10437 __ movdq($dst$$Register, $src$$XMMRegister); 10438 %} 10439 ins_pipe( pipe_slow ); 10440 %} 10441 10442 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10443 match(Set dst (MoveI2F src)); 10444 effect(DEF dst, USE src); 10445 ins_cost(100); 10446 format %{ "movd $dst,$src\t# MoveI2F" %} 10447 ins_encode %{ 10448 __ movdl($dst$$XMMRegister, $src$$Register); 10449 %} 10450 ins_pipe( pipe_slow ); 10451 %} 10452 10453 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10454 match(Set dst (MoveL2D src)); 10455 effect(DEF dst, USE src); 10456 ins_cost(100); 10457 format %{ "movd $dst,$src\t# MoveL2D" %} 10458 ins_encode %{ 10459 __ movdq($dst$$XMMRegister, $src$$Register); 10460 %} 10461 ins_pipe( pipe_slow ); 10462 %} 10463 10464 // Fast clearing of an array 10465 // Small non-constant lenght ClearArray for non-AVX512 targets. 10466 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10467 Universe dummy, rFlagsReg cr) 10468 %{ 10469 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 10470 match(Set dummy (ClearArray cnt base)); 10471 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10472 10473 format %{ $$template 10474 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10475 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10476 $$emit$$"jg LARGE\n\t" 10477 $$emit$$"dec rcx\n\t" 10478 $$emit$$"js DONE\t# Zero length\n\t" 10479 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10480 $$emit$$"dec rcx\n\t" 10481 $$emit$$"jge LOOP\n\t" 10482 $$emit$$"jmp DONE\n\t" 10483 $$emit$$"# LARGE:\n\t" 10484 if (UseFastStosb) { 10485 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10486 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10487 } else if (UseXMMForObjInit) { 10488 $$emit$$"mov rdi,rax\n\t" 10489 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10490 $$emit$$"jmpq L_zero_64_bytes\n\t" 10491 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10492 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10493 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10494 $$emit$$"add 0x40,rax\n\t" 10495 $$emit$$"# L_zero_64_bytes:\n\t" 10496 $$emit$$"sub 0x8,rcx\n\t" 10497 $$emit$$"jge L_loop\n\t" 10498 $$emit$$"add 0x4,rcx\n\t" 10499 $$emit$$"jl L_tail\n\t" 10500 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10501 $$emit$$"add 0x20,rax\n\t" 10502 $$emit$$"sub 0x4,rcx\n\t" 10503 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10504 $$emit$$"add 0x4,rcx\n\t" 10505 $$emit$$"jle L_end\n\t" 10506 $$emit$$"dec rcx\n\t" 10507 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10508 $$emit$$"vmovq xmm0,(rax)\n\t" 10509 $$emit$$"add 0x8,rax\n\t" 10510 $$emit$$"dec rcx\n\t" 10511 $$emit$$"jge L_sloop\n\t" 10512 $$emit$$"# L_end:\n\t" 10513 } else { 10514 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10515 } 10516 $$emit$$"# DONE" 10517 %} 10518 ins_encode %{ 10519 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10520 $tmp$$XMMRegister, false, knoreg); 10521 %} 10522 ins_pipe(pipe_slow); 10523 %} 10524 10525 // Small non-constant length ClearArray for AVX512 targets. 10526 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10527 Universe dummy, rFlagsReg cr) 10528 %{ 10529 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 10530 match(Set dummy (ClearArray cnt base)); 10531 ins_cost(125); 10532 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10533 10534 format %{ $$template 10535 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10536 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10537 $$emit$$"jg LARGE\n\t" 10538 $$emit$$"dec rcx\n\t" 10539 $$emit$$"js DONE\t# Zero length\n\t" 10540 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10541 $$emit$$"dec rcx\n\t" 10542 $$emit$$"jge LOOP\n\t" 10543 $$emit$$"jmp DONE\n\t" 10544 $$emit$$"# LARGE:\n\t" 10545 if (UseFastStosb) { 10546 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10547 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10548 } else if (UseXMMForObjInit) { 10549 $$emit$$"mov rdi,rax\n\t" 10550 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10551 $$emit$$"jmpq L_zero_64_bytes\n\t" 10552 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10553 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10554 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10555 $$emit$$"add 0x40,rax\n\t" 10556 $$emit$$"# L_zero_64_bytes:\n\t" 10557 $$emit$$"sub 0x8,rcx\n\t" 10558 $$emit$$"jge L_loop\n\t" 10559 $$emit$$"add 0x4,rcx\n\t" 10560 $$emit$$"jl L_tail\n\t" 10561 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10562 $$emit$$"add 0x20,rax\n\t" 10563 $$emit$$"sub 0x4,rcx\n\t" 10564 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10565 $$emit$$"add 0x4,rcx\n\t" 10566 $$emit$$"jle L_end\n\t" 10567 $$emit$$"dec rcx\n\t" 10568 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10569 $$emit$$"vmovq xmm0,(rax)\n\t" 10570 $$emit$$"add 0x8,rax\n\t" 10571 $$emit$$"dec rcx\n\t" 10572 $$emit$$"jge L_sloop\n\t" 10573 $$emit$$"# L_end:\n\t" 10574 } else { 10575 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10576 } 10577 $$emit$$"# DONE" 10578 %} 10579 ins_encode %{ 10580 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10581 $tmp$$XMMRegister, false, $ktmp$$KRegister); 10582 %} 10583 ins_pipe(pipe_slow); 10584 %} 10585 10586 // Large non-constant length ClearArray for non-AVX512 targets. 10587 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10588 Universe dummy, rFlagsReg cr) 10589 %{ 10590 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 10591 match(Set dummy (ClearArray cnt base)); 10592 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10593 10594 format %{ $$template 10595 if (UseFastStosb) { 10596 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10597 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10598 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10599 } else if (UseXMMForObjInit) { 10600 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10601 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10602 $$emit$$"jmpq L_zero_64_bytes\n\t" 10603 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10604 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10605 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10606 $$emit$$"add 0x40,rax\n\t" 10607 $$emit$$"# L_zero_64_bytes:\n\t" 10608 $$emit$$"sub 0x8,rcx\n\t" 10609 $$emit$$"jge L_loop\n\t" 10610 $$emit$$"add 0x4,rcx\n\t" 10611 $$emit$$"jl L_tail\n\t" 10612 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10613 $$emit$$"add 0x20,rax\n\t" 10614 $$emit$$"sub 0x4,rcx\n\t" 10615 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10616 $$emit$$"add 0x4,rcx\n\t" 10617 $$emit$$"jle L_end\n\t" 10618 $$emit$$"dec rcx\n\t" 10619 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10620 $$emit$$"vmovq xmm0,(rax)\n\t" 10621 $$emit$$"add 0x8,rax\n\t" 10622 $$emit$$"dec rcx\n\t" 10623 $$emit$$"jge L_sloop\n\t" 10624 $$emit$$"# L_end:\n\t" 10625 } else { 10626 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10627 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10628 } 10629 %} 10630 ins_encode %{ 10631 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10632 $tmp$$XMMRegister, true, knoreg); 10633 %} 10634 ins_pipe(pipe_slow); 10635 %} 10636 10637 // Large non-constant length ClearArray for AVX512 targets. 10638 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10639 Universe dummy, rFlagsReg cr) 10640 %{ 10641 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 10642 match(Set dummy (ClearArray cnt base)); 10643 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10644 10645 format %{ $$template 10646 if (UseFastStosb) { 10647 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10648 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10649 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10650 } else if (UseXMMForObjInit) { 10651 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10652 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10653 $$emit$$"jmpq L_zero_64_bytes\n\t" 10654 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10655 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10656 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10657 $$emit$$"add 0x40,rax\n\t" 10658 $$emit$$"# L_zero_64_bytes:\n\t" 10659 $$emit$$"sub 0x8,rcx\n\t" 10660 $$emit$$"jge L_loop\n\t" 10661 $$emit$$"add 0x4,rcx\n\t" 10662 $$emit$$"jl L_tail\n\t" 10663 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10664 $$emit$$"add 0x20,rax\n\t" 10665 $$emit$$"sub 0x4,rcx\n\t" 10666 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10667 $$emit$$"add 0x4,rcx\n\t" 10668 $$emit$$"jle L_end\n\t" 10669 $$emit$$"dec rcx\n\t" 10670 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10671 $$emit$$"vmovq xmm0,(rax)\n\t" 10672 $$emit$$"add 0x8,rax\n\t" 10673 $$emit$$"dec rcx\n\t" 10674 $$emit$$"jge L_sloop\n\t" 10675 $$emit$$"# L_end:\n\t" 10676 } else { 10677 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10678 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10679 } 10680 %} 10681 ins_encode %{ 10682 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10683 $tmp$$XMMRegister, true, $ktmp$$KRegister); 10684 %} 10685 ins_pipe(pipe_slow); 10686 %} 10687 10688 // Small constant length ClearArray for AVX512 targets. 10689 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 10690 %{ 10691 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 10692 match(Set dummy (ClearArray cnt base)); 10693 ins_cost(100); 10694 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 10695 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10696 ins_encode %{ 10697 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10698 %} 10699 ins_pipe(pipe_slow); 10700 %} 10701 10702 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10703 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10704 %{ 10705 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10706 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10707 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10708 10709 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10710 ins_encode %{ 10711 __ string_compare($str1$$Register, $str2$$Register, 10712 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10713 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10714 %} 10715 ins_pipe( pipe_slow ); 10716 %} 10717 10718 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10719 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10720 %{ 10721 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10722 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10723 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10724 10725 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10726 ins_encode %{ 10727 __ string_compare($str1$$Register, $str2$$Register, 10728 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10729 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10730 %} 10731 ins_pipe( pipe_slow ); 10732 %} 10733 10734 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10735 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10736 %{ 10737 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10738 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10739 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10740 10741 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10742 ins_encode %{ 10743 __ string_compare($str1$$Register, $str2$$Register, 10744 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10745 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10746 %} 10747 ins_pipe( pipe_slow ); 10748 %} 10749 10750 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10751 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10752 %{ 10753 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10754 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10755 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10756 10757 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10758 ins_encode %{ 10759 __ string_compare($str1$$Register, $str2$$Register, 10760 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10761 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10762 %} 10763 ins_pipe( pipe_slow ); 10764 %} 10765 10766 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10767 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10768 %{ 10769 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10770 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10771 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10772 10773 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10774 ins_encode %{ 10775 __ string_compare($str1$$Register, $str2$$Register, 10776 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10777 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 10778 %} 10779 ins_pipe( pipe_slow ); 10780 %} 10781 10782 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10783 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10784 %{ 10785 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10786 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10787 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10788 10789 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10790 ins_encode %{ 10791 __ string_compare($str1$$Register, $str2$$Register, 10792 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10793 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 10794 %} 10795 ins_pipe( pipe_slow ); 10796 %} 10797 10798 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10799 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10800 %{ 10801 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10802 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10803 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10804 10805 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10806 ins_encode %{ 10807 __ string_compare($str2$$Register, $str1$$Register, 10808 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10809 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 10810 %} 10811 ins_pipe( pipe_slow ); 10812 %} 10813 10814 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10815 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10816 %{ 10817 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10818 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10819 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10820 10821 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10822 ins_encode %{ 10823 __ string_compare($str2$$Register, $str1$$Register, 10824 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10825 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 10826 %} 10827 ins_pipe( pipe_slow ); 10828 %} 10829 10830 // fast search of substring with known size. 10831 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10832 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10833 %{ 10834 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10835 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10836 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10837 10838 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10839 ins_encode %{ 10840 int icnt2 = (int)$int_cnt2$$constant; 10841 if (icnt2 >= 16) { 10842 // IndexOf for constant substrings with size >= 16 elements 10843 // which don't need to be loaded through stack. 10844 __ string_indexofC8($str1$$Register, $str2$$Register, 10845 $cnt1$$Register, $cnt2$$Register, 10846 icnt2, $result$$Register, 10847 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10848 } else { 10849 // Small strings are loaded through stack if they cross page boundary. 10850 __ string_indexof($str1$$Register, $str2$$Register, 10851 $cnt1$$Register, $cnt2$$Register, 10852 icnt2, $result$$Register, 10853 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10854 } 10855 %} 10856 ins_pipe( pipe_slow ); 10857 %} 10858 10859 // fast search of substring with known size. 10860 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10861 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10862 %{ 10863 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10864 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10865 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10866 10867 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10868 ins_encode %{ 10869 int icnt2 = (int)$int_cnt2$$constant; 10870 if (icnt2 >= 8) { 10871 // IndexOf for constant substrings with size >= 8 elements 10872 // which don't need to be loaded through stack. 10873 __ string_indexofC8($str1$$Register, $str2$$Register, 10874 $cnt1$$Register, $cnt2$$Register, 10875 icnt2, $result$$Register, 10876 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10877 } else { 10878 // Small strings are loaded through stack if they cross page boundary. 10879 __ string_indexof($str1$$Register, $str2$$Register, 10880 $cnt1$$Register, $cnt2$$Register, 10881 icnt2, $result$$Register, 10882 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10883 } 10884 %} 10885 ins_pipe( pipe_slow ); 10886 %} 10887 10888 // fast search of substring with known size. 10889 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10890 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10891 %{ 10892 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10893 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10894 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10895 10896 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10897 ins_encode %{ 10898 int icnt2 = (int)$int_cnt2$$constant; 10899 if (icnt2 >= 8) { 10900 // IndexOf for constant substrings with size >= 8 elements 10901 // which don't need to be loaded through stack. 10902 __ string_indexofC8($str1$$Register, $str2$$Register, 10903 $cnt1$$Register, $cnt2$$Register, 10904 icnt2, $result$$Register, 10905 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10906 } else { 10907 // Small strings are loaded through stack if they cross page boundary. 10908 __ string_indexof($str1$$Register, $str2$$Register, 10909 $cnt1$$Register, $cnt2$$Register, 10910 icnt2, $result$$Register, 10911 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10912 } 10913 %} 10914 ins_pipe( pipe_slow ); 10915 %} 10916 10917 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10918 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10919 %{ 10920 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10921 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10922 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10923 10924 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10925 ins_encode %{ 10926 __ string_indexof($str1$$Register, $str2$$Register, 10927 $cnt1$$Register, $cnt2$$Register, 10928 (-1), $result$$Register, 10929 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10930 %} 10931 ins_pipe( pipe_slow ); 10932 %} 10933 10934 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10935 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10936 %{ 10937 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10938 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10939 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10940 10941 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10942 ins_encode %{ 10943 __ string_indexof($str1$$Register, $str2$$Register, 10944 $cnt1$$Register, $cnt2$$Register, 10945 (-1), $result$$Register, 10946 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10947 %} 10948 ins_pipe( pipe_slow ); 10949 %} 10950 10951 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10952 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10953 %{ 10954 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10955 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10956 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10957 10958 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10959 ins_encode %{ 10960 __ string_indexof($str1$$Register, $str2$$Register, 10961 $cnt1$$Register, $cnt2$$Register, 10962 (-1), $result$$Register, 10963 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10964 %} 10965 ins_pipe( pipe_slow ); 10966 %} 10967 10968 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10969 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10970 %{ 10971 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 10972 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10973 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10974 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10975 ins_encode %{ 10976 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10977 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10978 %} 10979 ins_pipe( pipe_slow ); 10980 %} 10981 10982 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10983 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10984 %{ 10985 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 10986 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10987 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10988 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10989 ins_encode %{ 10990 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10991 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10992 %} 10993 ins_pipe( pipe_slow ); 10994 %} 10995 10996 // fast string equals 10997 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10998 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10999 %{ 11000 predicate(!VM_Version::supports_avx512vlbw()); 11001 match(Set result (StrEquals (Binary str1 str2) cnt)); 11002 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11003 11004 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11005 ins_encode %{ 11006 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11007 $cnt$$Register, $result$$Register, $tmp3$$Register, 11008 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11009 %} 11010 ins_pipe( pipe_slow ); 11011 %} 11012 11013 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11014 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11015 %{ 11016 predicate(VM_Version::supports_avx512vlbw()); 11017 match(Set result (StrEquals (Binary str1 str2) cnt)); 11018 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11019 11020 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11021 ins_encode %{ 11022 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11023 $cnt$$Register, $result$$Register, $tmp3$$Register, 11024 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11025 %} 11026 ins_pipe( pipe_slow ); 11027 %} 11028 11029 // fast array equals 11030 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11031 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11032 %{ 11033 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11034 match(Set result (AryEq ary1 ary2)); 11035 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11036 11037 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11038 ins_encode %{ 11039 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11040 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11041 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11042 %} 11043 ins_pipe( pipe_slow ); 11044 %} 11045 11046 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11047 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11048 %{ 11049 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11050 match(Set result (AryEq ary1 ary2)); 11051 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11052 11053 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11054 ins_encode %{ 11055 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11056 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11057 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11058 %} 11059 ins_pipe( pipe_slow ); 11060 %} 11061 11062 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11063 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11064 %{ 11065 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11066 match(Set result (AryEq ary1 ary2)); 11067 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11068 11069 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11070 ins_encode %{ 11071 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11072 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11073 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11074 %} 11075 ins_pipe( pipe_slow ); 11076 %} 11077 11078 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11079 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11080 %{ 11081 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11082 match(Set result (AryEq ary1 ary2)); 11083 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11084 11085 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11086 ins_encode %{ 11087 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11088 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11089 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11090 %} 11091 ins_pipe( pipe_slow ); 11092 %} 11093 11094 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11095 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11096 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11097 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11098 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11099 %{ 11100 predicate(UseAVX >= 2); 11101 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11102 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11103 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11104 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11105 USE basic_type, KILL cr); 11106 11107 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11108 ins_encode %{ 11109 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11110 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11111 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11112 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11113 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11114 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11115 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11116 %} 11117 ins_pipe( pipe_slow ); 11118 %} 11119 11120 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11121 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11122 %{ 11123 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11124 match(Set result (CountPositives ary1 len)); 11125 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11126 11127 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11128 ins_encode %{ 11129 __ count_positives($ary1$$Register, $len$$Register, 11130 $result$$Register, $tmp3$$Register, 11131 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11132 %} 11133 ins_pipe( pipe_slow ); 11134 %} 11135 11136 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11137 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11138 %{ 11139 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11140 match(Set result (CountPositives ary1 len)); 11141 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11142 11143 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11144 ins_encode %{ 11145 __ count_positives($ary1$$Register, $len$$Register, 11146 $result$$Register, $tmp3$$Register, 11147 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11148 %} 11149 ins_pipe( pipe_slow ); 11150 %} 11151 11152 // fast char[] to byte[] compression 11153 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11154 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11155 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11156 match(Set result (StrCompressedCopy src (Binary dst len))); 11157 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11158 USE_KILL len, KILL tmp5, KILL cr); 11159 11160 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11161 ins_encode %{ 11162 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11163 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11164 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11165 knoreg, knoreg); 11166 %} 11167 ins_pipe( pipe_slow ); 11168 %} 11169 11170 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11171 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11172 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11173 match(Set result (StrCompressedCopy src (Binary dst len))); 11174 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11175 USE_KILL len, KILL tmp5, KILL cr); 11176 11177 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11178 ins_encode %{ 11179 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11180 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11181 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11182 $ktmp1$$KRegister, $ktmp2$$KRegister); 11183 %} 11184 ins_pipe( pipe_slow ); 11185 %} 11186 // fast byte[] to char[] inflation 11187 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11188 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11189 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11190 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11191 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11192 11193 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11194 ins_encode %{ 11195 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11196 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11197 %} 11198 ins_pipe( pipe_slow ); 11199 %} 11200 11201 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11202 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11203 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11204 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11205 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11206 11207 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11208 ins_encode %{ 11209 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11210 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11211 %} 11212 ins_pipe( pipe_slow ); 11213 %} 11214 11215 // encode char[] to byte[] in ISO_8859_1 11216 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11217 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11218 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11219 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11220 match(Set result (EncodeISOArray src (Binary dst len))); 11221 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11222 11223 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11224 ins_encode %{ 11225 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11226 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11227 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11228 %} 11229 ins_pipe( pipe_slow ); 11230 %} 11231 11232 // encode char[] to byte[] in ASCII 11233 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11234 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11235 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11236 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11237 match(Set result (EncodeISOArray src (Binary dst len))); 11238 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11239 11240 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11241 ins_encode %{ 11242 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11243 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11244 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11245 %} 11246 ins_pipe( pipe_slow ); 11247 %} 11248 11249 //----------Overflow Math Instructions----------------------------------------- 11250 11251 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11252 %{ 11253 match(Set cr (OverflowAddI op1 op2)); 11254 effect(DEF cr, USE_KILL op1, USE op2); 11255 11256 format %{ "addl $op1, $op2\t# overflow check int" %} 11257 11258 ins_encode %{ 11259 __ addl($op1$$Register, $op2$$Register); 11260 %} 11261 ins_pipe(ialu_reg_reg); 11262 %} 11263 11264 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11265 %{ 11266 match(Set cr (OverflowAddI op1 op2)); 11267 effect(DEF cr, USE_KILL op1, USE op2); 11268 11269 format %{ "addl $op1, $op2\t# overflow check int" %} 11270 11271 ins_encode %{ 11272 __ addl($op1$$Register, $op2$$constant); 11273 %} 11274 ins_pipe(ialu_reg_reg); 11275 %} 11276 11277 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11278 %{ 11279 match(Set cr (OverflowAddL op1 op2)); 11280 effect(DEF cr, USE_KILL op1, USE op2); 11281 11282 format %{ "addq $op1, $op2\t# overflow check long" %} 11283 ins_encode %{ 11284 __ addq($op1$$Register, $op2$$Register); 11285 %} 11286 ins_pipe(ialu_reg_reg); 11287 %} 11288 11289 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11290 %{ 11291 match(Set cr (OverflowAddL op1 op2)); 11292 effect(DEF cr, USE_KILL op1, USE op2); 11293 11294 format %{ "addq $op1, $op2\t# overflow check long" %} 11295 ins_encode %{ 11296 __ addq($op1$$Register, $op2$$constant); 11297 %} 11298 ins_pipe(ialu_reg_reg); 11299 %} 11300 11301 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11302 %{ 11303 match(Set cr (OverflowSubI op1 op2)); 11304 11305 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11306 ins_encode %{ 11307 __ cmpl($op1$$Register, $op2$$Register); 11308 %} 11309 ins_pipe(ialu_reg_reg); 11310 %} 11311 11312 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11313 %{ 11314 match(Set cr (OverflowSubI op1 op2)); 11315 11316 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11317 ins_encode %{ 11318 __ cmpl($op1$$Register, $op2$$constant); 11319 %} 11320 ins_pipe(ialu_reg_reg); 11321 %} 11322 11323 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11324 %{ 11325 match(Set cr (OverflowSubL op1 op2)); 11326 11327 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11328 ins_encode %{ 11329 __ cmpq($op1$$Register, $op2$$Register); 11330 %} 11331 ins_pipe(ialu_reg_reg); 11332 %} 11333 11334 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11335 %{ 11336 match(Set cr (OverflowSubL op1 op2)); 11337 11338 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11339 ins_encode %{ 11340 __ cmpq($op1$$Register, $op2$$constant); 11341 %} 11342 ins_pipe(ialu_reg_reg); 11343 %} 11344 11345 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11346 %{ 11347 match(Set cr (OverflowSubI zero op2)); 11348 effect(DEF cr, USE_KILL op2); 11349 11350 format %{ "negl $op2\t# overflow check int" %} 11351 ins_encode %{ 11352 __ negl($op2$$Register); 11353 %} 11354 ins_pipe(ialu_reg_reg); 11355 %} 11356 11357 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11358 %{ 11359 match(Set cr (OverflowSubL zero op2)); 11360 effect(DEF cr, USE_KILL op2); 11361 11362 format %{ "negq $op2\t# overflow check long" %} 11363 ins_encode %{ 11364 __ negq($op2$$Register); 11365 %} 11366 ins_pipe(ialu_reg_reg); 11367 %} 11368 11369 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11370 %{ 11371 match(Set cr (OverflowMulI op1 op2)); 11372 effect(DEF cr, USE_KILL op1, USE op2); 11373 11374 format %{ "imull $op1, $op2\t# overflow check int" %} 11375 ins_encode %{ 11376 __ imull($op1$$Register, $op2$$Register); 11377 %} 11378 ins_pipe(ialu_reg_reg_alu0); 11379 %} 11380 11381 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11382 %{ 11383 match(Set cr (OverflowMulI op1 op2)); 11384 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11385 11386 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11387 ins_encode %{ 11388 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11389 %} 11390 ins_pipe(ialu_reg_reg_alu0); 11391 %} 11392 11393 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11394 %{ 11395 match(Set cr (OverflowMulL op1 op2)); 11396 effect(DEF cr, USE_KILL op1, USE op2); 11397 11398 format %{ "imulq $op1, $op2\t# overflow check long" %} 11399 ins_encode %{ 11400 __ imulq($op1$$Register, $op2$$Register); 11401 %} 11402 ins_pipe(ialu_reg_reg_alu0); 11403 %} 11404 11405 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11406 %{ 11407 match(Set cr (OverflowMulL op1 op2)); 11408 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11409 11410 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11411 ins_encode %{ 11412 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11413 %} 11414 ins_pipe(ialu_reg_reg_alu0); 11415 %} 11416 11417 11418 //----------Control Flow Instructions------------------------------------------ 11419 // Signed compare Instructions 11420 11421 // XXX more variants!! 11422 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11423 %{ 11424 match(Set cr (CmpI op1 op2)); 11425 effect(DEF cr, USE op1, USE op2); 11426 11427 format %{ "cmpl $op1, $op2" %} 11428 ins_encode %{ 11429 __ cmpl($op1$$Register, $op2$$Register); 11430 %} 11431 ins_pipe(ialu_cr_reg_reg); 11432 %} 11433 11434 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11435 %{ 11436 match(Set cr (CmpI op1 op2)); 11437 11438 format %{ "cmpl $op1, $op2" %} 11439 ins_encode %{ 11440 __ cmpl($op1$$Register, $op2$$constant); 11441 %} 11442 ins_pipe(ialu_cr_reg_imm); 11443 %} 11444 11445 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11446 %{ 11447 match(Set cr (CmpI op1 (LoadI op2))); 11448 11449 ins_cost(500); // XXX 11450 format %{ "cmpl $op1, $op2" %} 11451 ins_encode %{ 11452 __ cmpl($op1$$Register, $op2$$Address); 11453 %} 11454 ins_pipe(ialu_cr_reg_mem); 11455 %} 11456 11457 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11458 %{ 11459 match(Set cr (CmpI src zero)); 11460 11461 format %{ "testl $src, $src" %} 11462 ins_encode %{ 11463 __ testl($src$$Register, $src$$Register); 11464 %} 11465 ins_pipe(ialu_cr_reg_imm); 11466 %} 11467 11468 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11469 %{ 11470 match(Set cr (CmpI (AndI src con) zero)); 11471 11472 format %{ "testl $src, $con" %} 11473 ins_encode %{ 11474 __ testl($src$$Register, $con$$constant); 11475 %} 11476 ins_pipe(ialu_cr_reg_imm); 11477 %} 11478 11479 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11480 %{ 11481 match(Set cr (CmpI (AndI src1 src2) zero)); 11482 11483 format %{ "testl $src1, $src2" %} 11484 ins_encode %{ 11485 __ testl($src1$$Register, $src2$$Register); 11486 %} 11487 ins_pipe(ialu_cr_reg_imm); 11488 %} 11489 11490 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11491 %{ 11492 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11493 11494 format %{ "testl $src, $mem" %} 11495 ins_encode %{ 11496 __ testl($src$$Register, $mem$$Address); 11497 %} 11498 ins_pipe(ialu_cr_reg_mem); 11499 %} 11500 11501 // Unsigned compare Instructions; really, same as signed except they 11502 // produce an rFlagsRegU instead of rFlagsReg. 11503 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11504 %{ 11505 match(Set cr (CmpU op1 op2)); 11506 11507 format %{ "cmpl $op1, $op2\t# unsigned" %} 11508 ins_encode %{ 11509 __ cmpl($op1$$Register, $op2$$Register); 11510 %} 11511 ins_pipe(ialu_cr_reg_reg); 11512 %} 11513 11514 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11515 %{ 11516 match(Set cr (CmpU op1 op2)); 11517 11518 format %{ "cmpl $op1, $op2\t# unsigned" %} 11519 ins_encode %{ 11520 __ cmpl($op1$$Register, $op2$$constant); 11521 %} 11522 ins_pipe(ialu_cr_reg_imm); 11523 %} 11524 11525 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11526 %{ 11527 match(Set cr (CmpU op1 (LoadI op2))); 11528 11529 ins_cost(500); // XXX 11530 format %{ "cmpl $op1, $op2\t# unsigned" %} 11531 ins_encode %{ 11532 __ cmpl($op1$$Register, $op2$$Address); 11533 %} 11534 ins_pipe(ialu_cr_reg_mem); 11535 %} 11536 11537 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11538 %{ 11539 match(Set cr (CmpU src zero)); 11540 11541 format %{ "testl $src, $src\t# unsigned" %} 11542 ins_encode %{ 11543 __ testl($src$$Register, $src$$Register); 11544 %} 11545 ins_pipe(ialu_cr_reg_imm); 11546 %} 11547 11548 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11549 %{ 11550 match(Set cr (CmpP op1 op2)); 11551 11552 format %{ "cmpq $op1, $op2\t# ptr" %} 11553 ins_encode %{ 11554 __ cmpq($op1$$Register, $op2$$Register); 11555 %} 11556 ins_pipe(ialu_cr_reg_reg); 11557 %} 11558 11559 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11560 %{ 11561 match(Set cr (CmpP op1 (LoadP op2))); 11562 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11563 11564 ins_cost(500); // XXX 11565 format %{ "cmpq $op1, $op2\t# ptr" %} 11566 ins_encode %{ 11567 __ cmpq($op1$$Register, $op2$$Address); 11568 %} 11569 ins_pipe(ialu_cr_reg_mem); 11570 %} 11571 11572 // XXX this is generalized by compP_rReg_mem??? 11573 // Compare raw pointer (used in out-of-heap check). 11574 // Only works because non-oop pointers must be raw pointers 11575 // and raw pointers have no anti-dependencies. 11576 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11577 %{ 11578 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11579 n->in(2)->as_Load()->barrier_data() == 0); 11580 match(Set cr (CmpP op1 (LoadP op2))); 11581 11582 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11583 ins_encode %{ 11584 __ cmpq($op1$$Register, $op2$$Address); 11585 %} 11586 ins_pipe(ialu_cr_reg_mem); 11587 %} 11588 11589 // This will generate a signed flags result. This should be OK since 11590 // any compare to a zero should be eq/neq. 11591 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11592 %{ 11593 match(Set cr (CmpP src zero)); 11594 11595 format %{ "testq $src, $src\t# ptr" %} 11596 ins_encode %{ 11597 __ testq($src$$Register, $src$$Register); 11598 %} 11599 ins_pipe(ialu_cr_reg_imm); 11600 %} 11601 11602 // This will generate a signed flags result. This should be OK since 11603 // any compare to a zero should be eq/neq. 11604 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11605 %{ 11606 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11607 n->in(1)->as_Load()->barrier_data() == 0); 11608 match(Set cr (CmpP (LoadP op) zero)); 11609 11610 ins_cost(500); // XXX 11611 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11612 ins_encode %{ 11613 __ testq($op$$Address, 0xFFFFFFFF); 11614 %} 11615 ins_pipe(ialu_cr_reg_imm); 11616 %} 11617 11618 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11619 %{ 11620 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11621 n->in(1)->as_Load()->barrier_data() == 0); 11622 match(Set cr (CmpP (LoadP mem) zero)); 11623 11624 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11625 ins_encode %{ 11626 __ cmpq(r12, $mem$$Address); 11627 %} 11628 ins_pipe(ialu_cr_reg_mem); 11629 %} 11630 11631 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11632 %{ 11633 match(Set cr (CmpN op1 op2)); 11634 11635 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11636 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11637 ins_pipe(ialu_cr_reg_reg); 11638 %} 11639 11640 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11641 %{ 11642 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11643 match(Set cr (CmpN src (LoadN mem))); 11644 11645 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11646 ins_encode %{ 11647 __ cmpl($src$$Register, $mem$$Address); 11648 %} 11649 ins_pipe(ialu_cr_reg_mem); 11650 %} 11651 11652 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11653 match(Set cr (CmpN op1 op2)); 11654 11655 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11656 ins_encode %{ 11657 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11658 %} 11659 ins_pipe(ialu_cr_reg_imm); 11660 %} 11661 11662 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11663 %{ 11664 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11665 match(Set cr (CmpN src (LoadN mem))); 11666 11667 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11668 ins_encode %{ 11669 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11670 %} 11671 ins_pipe(ialu_cr_reg_mem); 11672 %} 11673 11674 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11675 match(Set cr (CmpN op1 op2)); 11676 11677 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11678 ins_encode %{ 11679 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11680 %} 11681 ins_pipe(ialu_cr_reg_imm); 11682 %} 11683 11684 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11685 %{ 11686 predicate(!UseCompactObjectHeaders); 11687 match(Set cr (CmpN src (LoadNKlass mem))); 11688 11689 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11690 ins_encode %{ 11691 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11692 %} 11693 ins_pipe(ialu_cr_reg_mem); 11694 %} 11695 11696 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11697 match(Set cr (CmpN src zero)); 11698 11699 format %{ "testl $src, $src\t# compressed ptr" %} 11700 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11701 ins_pipe(ialu_cr_reg_imm); 11702 %} 11703 11704 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11705 %{ 11706 predicate(CompressedOops::base() != nullptr && 11707 n->in(1)->as_Load()->barrier_data() == 0); 11708 match(Set cr (CmpN (LoadN mem) zero)); 11709 11710 ins_cost(500); // XXX 11711 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11712 ins_encode %{ 11713 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11714 %} 11715 ins_pipe(ialu_cr_reg_mem); 11716 %} 11717 11718 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11719 %{ 11720 predicate(CompressedOops::base() == nullptr && 11721 n->in(1)->as_Load()->barrier_data() == 0); 11722 match(Set cr (CmpN (LoadN mem) zero)); 11723 11724 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11725 ins_encode %{ 11726 __ cmpl(r12, $mem$$Address); 11727 %} 11728 ins_pipe(ialu_cr_reg_mem); 11729 %} 11730 11731 // Yanked all unsigned pointer compare operations. 11732 // Pointer compares are done with CmpP which is already unsigned. 11733 11734 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11735 %{ 11736 match(Set cr (CmpL op1 op2)); 11737 11738 format %{ "cmpq $op1, $op2" %} 11739 ins_encode %{ 11740 __ cmpq($op1$$Register, $op2$$Register); 11741 %} 11742 ins_pipe(ialu_cr_reg_reg); 11743 %} 11744 11745 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11746 %{ 11747 match(Set cr (CmpL op1 op2)); 11748 11749 format %{ "cmpq $op1, $op2" %} 11750 ins_encode %{ 11751 __ cmpq($op1$$Register, $op2$$constant); 11752 %} 11753 ins_pipe(ialu_cr_reg_imm); 11754 %} 11755 11756 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11757 %{ 11758 match(Set cr (CmpL op1 (LoadL op2))); 11759 11760 format %{ "cmpq $op1, $op2" %} 11761 ins_encode %{ 11762 __ cmpq($op1$$Register, $op2$$Address); 11763 %} 11764 ins_pipe(ialu_cr_reg_mem); 11765 %} 11766 11767 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11768 %{ 11769 match(Set cr (CmpL src zero)); 11770 11771 format %{ "testq $src, $src" %} 11772 ins_encode %{ 11773 __ testq($src$$Register, $src$$Register); 11774 %} 11775 ins_pipe(ialu_cr_reg_imm); 11776 %} 11777 11778 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11779 %{ 11780 match(Set cr (CmpL (AndL src con) zero)); 11781 11782 format %{ "testq $src, $con\t# long" %} 11783 ins_encode %{ 11784 __ testq($src$$Register, $con$$constant); 11785 %} 11786 ins_pipe(ialu_cr_reg_imm); 11787 %} 11788 11789 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 11790 %{ 11791 match(Set cr (CmpL (AndL src1 src2) zero)); 11792 11793 format %{ "testq $src1, $src2\t# long" %} 11794 ins_encode %{ 11795 __ testq($src1$$Register, $src2$$Register); 11796 %} 11797 ins_pipe(ialu_cr_reg_imm); 11798 %} 11799 11800 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11801 %{ 11802 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11803 11804 format %{ "testq $src, $mem" %} 11805 ins_encode %{ 11806 __ testq($src$$Register, $mem$$Address); 11807 %} 11808 ins_pipe(ialu_cr_reg_mem); 11809 %} 11810 11811 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11812 %{ 11813 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11814 11815 format %{ "testq $src, $mem" %} 11816 ins_encode %{ 11817 __ testq($src$$Register, $mem$$Address); 11818 %} 11819 ins_pipe(ialu_cr_reg_mem); 11820 %} 11821 11822 // Manifest a CmpU result in an integer register. Very painful. 11823 // This is the test to avoid. 11824 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 11825 %{ 11826 match(Set dst (CmpU3 src1 src2)); 11827 effect(KILL flags); 11828 11829 ins_cost(275); // XXX 11830 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 11831 "movl $dst, -1\n\t" 11832 "jb,u done\n\t" 11833 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11834 "done:" %} 11835 ins_encode %{ 11836 Label done; 11837 __ cmpl($src1$$Register, $src2$$Register); 11838 __ movl($dst$$Register, -1); 11839 __ jccb(Assembler::below, done); 11840 __ setcc(Assembler::notZero, $dst$$Register); 11841 __ bind(done); 11842 %} 11843 ins_pipe(pipe_slow); 11844 %} 11845 11846 // Manifest a CmpL result in an integer register. Very painful. 11847 // This is the test to avoid. 11848 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11849 %{ 11850 match(Set dst (CmpL3 src1 src2)); 11851 effect(KILL flags); 11852 11853 ins_cost(275); // XXX 11854 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11855 "movl $dst, -1\n\t" 11856 "jl,s done\n\t" 11857 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11858 "done:" %} 11859 ins_encode %{ 11860 Label done; 11861 __ cmpq($src1$$Register, $src2$$Register); 11862 __ movl($dst$$Register, -1); 11863 __ jccb(Assembler::less, done); 11864 __ setcc(Assembler::notZero, $dst$$Register); 11865 __ bind(done); 11866 %} 11867 ins_pipe(pipe_slow); 11868 %} 11869 11870 // Manifest a CmpUL result in an integer register. Very painful. 11871 // This is the test to avoid. 11872 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11873 %{ 11874 match(Set dst (CmpUL3 src1 src2)); 11875 effect(KILL flags); 11876 11877 ins_cost(275); // XXX 11878 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11879 "movl $dst, -1\n\t" 11880 "jb,u done\n\t" 11881 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11882 "done:" %} 11883 ins_encode %{ 11884 Label done; 11885 __ cmpq($src1$$Register, $src2$$Register); 11886 __ movl($dst$$Register, -1); 11887 __ jccb(Assembler::below, done); 11888 __ setcc(Assembler::notZero, $dst$$Register); 11889 __ bind(done); 11890 %} 11891 ins_pipe(pipe_slow); 11892 %} 11893 11894 // Unsigned long compare Instructions; really, same as signed long except they 11895 // produce an rFlagsRegU instead of rFlagsReg. 11896 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11897 %{ 11898 match(Set cr (CmpUL op1 op2)); 11899 11900 format %{ "cmpq $op1, $op2\t# unsigned" %} 11901 ins_encode %{ 11902 __ cmpq($op1$$Register, $op2$$Register); 11903 %} 11904 ins_pipe(ialu_cr_reg_reg); 11905 %} 11906 11907 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11908 %{ 11909 match(Set cr (CmpUL op1 op2)); 11910 11911 format %{ "cmpq $op1, $op2\t# unsigned" %} 11912 ins_encode %{ 11913 __ cmpq($op1$$Register, $op2$$constant); 11914 %} 11915 ins_pipe(ialu_cr_reg_imm); 11916 %} 11917 11918 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11919 %{ 11920 match(Set cr (CmpUL op1 (LoadL op2))); 11921 11922 format %{ "cmpq $op1, $op2\t# unsigned" %} 11923 ins_encode %{ 11924 __ cmpq($op1$$Register, $op2$$Address); 11925 %} 11926 ins_pipe(ialu_cr_reg_mem); 11927 %} 11928 11929 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11930 %{ 11931 match(Set cr (CmpUL src zero)); 11932 11933 format %{ "testq $src, $src\t# unsigned" %} 11934 ins_encode %{ 11935 __ testq($src$$Register, $src$$Register); 11936 %} 11937 ins_pipe(ialu_cr_reg_imm); 11938 %} 11939 11940 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11941 %{ 11942 match(Set cr (CmpI (LoadB mem) imm)); 11943 11944 ins_cost(125); 11945 format %{ "cmpb $mem, $imm" %} 11946 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11947 ins_pipe(ialu_cr_reg_mem); 11948 %} 11949 11950 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 11951 %{ 11952 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11953 11954 ins_cost(125); 11955 format %{ "testb $mem, $imm\t# ubyte" %} 11956 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11957 ins_pipe(ialu_cr_reg_mem); 11958 %} 11959 11960 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 11961 %{ 11962 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11963 11964 ins_cost(125); 11965 format %{ "testb $mem, $imm\t# byte" %} 11966 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11967 ins_pipe(ialu_cr_reg_mem); 11968 %} 11969 11970 //----------Max and Min-------------------------------------------------------- 11971 // Min Instructions 11972 11973 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11974 %{ 11975 effect(USE_DEF dst, USE src, USE cr); 11976 11977 format %{ "cmovlgt $dst, $src\t# min" %} 11978 ins_encode %{ 11979 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 11980 %} 11981 ins_pipe(pipe_cmov_reg); 11982 %} 11983 11984 11985 instruct minI_rReg(rRegI dst, rRegI src) 11986 %{ 11987 match(Set dst (MinI dst src)); 11988 11989 ins_cost(200); 11990 expand %{ 11991 rFlagsReg cr; 11992 compI_rReg(cr, dst, src); 11993 cmovI_reg_g(dst, src, cr); 11994 %} 11995 %} 11996 11997 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11998 %{ 11999 effect(USE_DEF dst, USE src, USE cr); 12000 12001 format %{ "cmovllt $dst, $src\t# max" %} 12002 ins_encode %{ 12003 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12004 %} 12005 ins_pipe(pipe_cmov_reg); 12006 %} 12007 12008 12009 instruct maxI_rReg(rRegI dst, rRegI src) 12010 %{ 12011 match(Set dst (MaxI dst src)); 12012 12013 ins_cost(200); 12014 expand %{ 12015 rFlagsReg cr; 12016 compI_rReg(cr, dst, src); 12017 cmovI_reg_l(dst, src, cr); 12018 %} 12019 %} 12020 12021 // ============================================================================ 12022 // Branch Instructions 12023 12024 // Jump Direct - Label defines a relative address from JMP+1 12025 instruct jmpDir(label labl) 12026 %{ 12027 match(Goto); 12028 effect(USE labl); 12029 12030 ins_cost(300); 12031 format %{ "jmp $labl" %} 12032 size(5); 12033 ins_encode %{ 12034 Label* L = $labl$$label; 12035 __ jmp(*L, false); // Always long jump 12036 %} 12037 ins_pipe(pipe_jmp); 12038 %} 12039 12040 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12041 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12042 %{ 12043 match(If cop cr); 12044 effect(USE labl); 12045 12046 ins_cost(300); 12047 format %{ "j$cop $labl" %} 12048 size(6); 12049 ins_encode %{ 12050 Label* L = $labl$$label; 12051 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12052 %} 12053 ins_pipe(pipe_jcc); 12054 %} 12055 12056 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12057 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12058 %{ 12059 match(CountedLoopEnd cop cr); 12060 effect(USE labl); 12061 12062 ins_cost(300); 12063 format %{ "j$cop $labl\t# loop end" %} 12064 size(6); 12065 ins_encode %{ 12066 Label* L = $labl$$label; 12067 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12068 %} 12069 ins_pipe(pipe_jcc); 12070 %} 12071 12072 // Jump Direct Conditional - using unsigned comparison 12073 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12074 match(If cop cmp); 12075 effect(USE labl); 12076 12077 ins_cost(300); 12078 format %{ "j$cop,u $labl" %} 12079 size(6); 12080 ins_encode %{ 12081 Label* L = $labl$$label; 12082 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12083 %} 12084 ins_pipe(pipe_jcc); 12085 %} 12086 12087 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12088 match(If cop cmp); 12089 effect(USE labl); 12090 12091 ins_cost(200); 12092 format %{ "j$cop,u $labl" %} 12093 size(6); 12094 ins_encode %{ 12095 Label* L = $labl$$label; 12096 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12097 %} 12098 ins_pipe(pipe_jcc); 12099 %} 12100 12101 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12102 match(If cop cmp); 12103 effect(USE labl); 12104 12105 ins_cost(200); 12106 format %{ $$template 12107 if ($cop$$cmpcode == Assembler::notEqual) { 12108 $$emit$$"jp,u $labl\n\t" 12109 $$emit$$"j$cop,u $labl" 12110 } else { 12111 $$emit$$"jp,u done\n\t" 12112 $$emit$$"j$cop,u $labl\n\t" 12113 $$emit$$"done:" 12114 } 12115 %} 12116 ins_encode %{ 12117 Label* l = $labl$$label; 12118 if ($cop$$cmpcode == Assembler::notEqual) { 12119 __ jcc(Assembler::parity, *l, false); 12120 __ jcc(Assembler::notEqual, *l, false); 12121 } else if ($cop$$cmpcode == Assembler::equal) { 12122 Label done; 12123 __ jccb(Assembler::parity, done); 12124 __ jcc(Assembler::equal, *l, false); 12125 __ bind(done); 12126 } else { 12127 ShouldNotReachHere(); 12128 } 12129 %} 12130 ins_pipe(pipe_jcc); 12131 %} 12132 12133 // ============================================================================ 12134 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12135 // superklass array for an instance of the superklass. Set a hidden 12136 // internal cache on a hit (cache is checked with exposed code in 12137 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12138 // encoding ALSO sets flags. 12139 12140 instruct partialSubtypeCheck(rdi_RegP result, 12141 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12142 rFlagsReg cr) 12143 %{ 12144 match(Set result (PartialSubtypeCheck sub super)); 12145 predicate(!UseSecondarySupersTable); 12146 effect(KILL rcx, KILL cr); 12147 12148 ins_cost(1100); // slightly larger than the next version 12149 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12150 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12151 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12152 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12153 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12154 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12155 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12156 "miss:\t" %} 12157 12158 ins_encode %{ 12159 Label miss; 12160 // NB: Callers may assume that, when $result is a valid register, 12161 // check_klass_subtype_slow_path_linear sets it to a nonzero 12162 // value. 12163 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 12164 $rcx$$Register, $result$$Register, 12165 nullptr, &miss, 12166 /*set_cond_codes:*/ true); 12167 __ xorptr($result$$Register, $result$$Register); 12168 __ bind(miss); 12169 %} 12170 12171 ins_pipe(pipe_slow); 12172 %} 12173 12174 // ============================================================================ 12175 // Two versions of hashtable-based partialSubtypeCheck, both used when 12176 // we need to search for a super class in the secondary supers array. 12177 // The first is used when we don't know _a priori_ the class being 12178 // searched for. The second, far more common, is used when we do know: 12179 // this is used for instanceof, checkcast, and any case where C2 can 12180 // determine it by constant propagation. 12181 12182 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 12183 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12184 rFlagsReg cr) 12185 %{ 12186 match(Set result (PartialSubtypeCheck sub super)); 12187 predicate(UseSecondarySupersTable); 12188 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12189 12190 ins_cost(1000); 12191 format %{ "partialSubtypeCheck $result, $sub, $super" %} 12192 12193 ins_encode %{ 12194 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 12195 $temp3$$Register, $temp4$$Register, $result$$Register); 12196 %} 12197 12198 ins_pipe(pipe_slow); 12199 %} 12200 12201 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12202 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12203 rFlagsReg cr) 12204 %{ 12205 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12206 predicate(UseSecondarySupersTable); 12207 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12208 12209 ins_cost(700); // smaller than the next version 12210 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12211 12212 ins_encode %{ 12213 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12214 if (InlineSecondarySupersTest) { 12215 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12216 $temp3$$Register, $temp4$$Register, $result$$Register, 12217 super_klass_slot); 12218 } else { 12219 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12220 } 12221 %} 12222 12223 ins_pipe(pipe_slow); 12224 %} 12225 12226 // ============================================================================ 12227 // Branch Instructions -- short offset versions 12228 // 12229 // These instructions are used to replace jumps of a long offset (the default 12230 // match) with jumps of a shorter offset. These instructions are all tagged 12231 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12232 // match rules in general matching. Instead, the ADLC generates a conversion 12233 // method in the MachNode which can be used to do in-place replacement of the 12234 // long variant with the shorter variant. The compiler will determine if a 12235 // branch can be taken by the is_short_branch_offset() predicate in the machine 12236 // specific code section of the file. 12237 12238 // Jump Direct - Label defines a relative address from JMP+1 12239 instruct jmpDir_short(label labl) %{ 12240 match(Goto); 12241 effect(USE labl); 12242 12243 ins_cost(300); 12244 format %{ "jmp,s $labl" %} 12245 size(2); 12246 ins_encode %{ 12247 Label* L = $labl$$label; 12248 __ jmpb(*L); 12249 %} 12250 ins_pipe(pipe_jmp); 12251 ins_short_branch(1); 12252 %} 12253 12254 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12255 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12256 match(If cop cr); 12257 effect(USE labl); 12258 12259 ins_cost(300); 12260 format %{ "j$cop,s $labl" %} 12261 size(2); 12262 ins_encode %{ 12263 Label* L = $labl$$label; 12264 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12265 %} 12266 ins_pipe(pipe_jcc); 12267 ins_short_branch(1); 12268 %} 12269 12270 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12271 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12272 match(CountedLoopEnd cop cr); 12273 effect(USE labl); 12274 12275 ins_cost(300); 12276 format %{ "j$cop,s $labl\t# loop end" %} 12277 size(2); 12278 ins_encode %{ 12279 Label* L = $labl$$label; 12280 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12281 %} 12282 ins_pipe(pipe_jcc); 12283 ins_short_branch(1); 12284 %} 12285 12286 // Jump Direct Conditional - using unsigned comparison 12287 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12288 match(If cop cmp); 12289 effect(USE labl); 12290 12291 ins_cost(300); 12292 format %{ "j$cop,us $labl" %} 12293 size(2); 12294 ins_encode %{ 12295 Label* L = $labl$$label; 12296 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12297 %} 12298 ins_pipe(pipe_jcc); 12299 ins_short_branch(1); 12300 %} 12301 12302 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12303 match(If cop cmp); 12304 effect(USE labl); 12305 12306 ins_cost(300); 12307 format %{ "j$cop,us $labl" %} 12308 size(2); 12309 ins_encode %{ 12310 Label* L = $labl$$label; 12311 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12312 %} 12313 ins_pipe(pipe_jcc); 12314 ins_short_branch(1); 12315 %} 12316 12317 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12318 match(If cop cmp); 12319 effect(USE labl); 12320 12321 ins_cost(300); 12322 format %{ $$template 12323 if ($cop$$cmpcode == Assembler::notEqual) { 12324 $$emit$$"jp,u,s $labl\n\t" 12325 $$emit$$"j$cop,u,s $labl" 12326 } else { 12327 $$emit$$"jp,u,s done\n\t" 12328 $$emit$$"j$cop,u,s $labl\n\t" 12329 $$emit$$"done:" 12330 } 12331 %} 12332 size(4); 12333 ins_encode %{ 12334 Label* l = $labl$$label; 12335 if ($cop$$cmpcode == Assembler::notEqual) { 12336 __ jccb(Assembler::parity, *l); 12337 __ jccb(Assembler::notEqual, *l); 12338 } else if ($cop$$cmpcode == Assembler::equal) { 12339 Label done; 12340 __ jccb(Assembler::parity, done); 12341 __ jccb(Assembler::equal, *l); 12342 __ bind(done); 12343 } else { 12344 ShouldNotReachHere(); 12345 } 12346 %} 12347 ins_pipe(pipe_jcc); 12348 ins_short_branch(1); 12349 %} 12350 12351 // ============================================================================ 12352 // inlined locking and unlocking 12353 12354 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12355 predicate(LockingMode != LM_LIGHTWEIGHT); 12356 match(Set cr (FastLock object box)); 12357 effect(TEMP tmp, TEMP scr, USE_KILL box); 12358 ins_cost(300); 12359 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12360 ins_encode %{ 12361 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12362 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12363 %} 12364 ins_pipe(pipe_slow); 12365 %} 12366 12367 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12368 predicate(LockingMode != LM_LIGHTWEIGHT); 12369 match(Set cr (FastUnlock object box)); 12370 effect(TEMP tmp, USE_KILL box); 12371 ins_cost(300); 12372 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12373 ins_encode %{ 12374 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12375 %} 12376 ins_pipe(pipe_slow); 12377 %} 12378 12379 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12380 predicate(LockingMode == LM_LIGHTWEIGHT); 12381 match(Set cr (FastLock object box)); 12382 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12383 ins_cost(300); 12384 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12385 ins_encode %{ 12386 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12387 %} 12388 ins_pipe(pipe_slow); 12389 %} 12390 12391 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12392 predicate(LockingMode == LM_LIGHTWEIGHT); 12393 match(Set cr (FastUnlock object rax_reg)); 12394 effect(TEMP tmp, USE_KILL rax_reg); 12395 ins_cost(300); 12396 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12397 ins_encode %{ 12398 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12399 %} 12400 ins_pipe(pipe_slow); 12401 %} 12402 12403 12404 // ============================================================================ 12405 // Safepoint Instructions 12406 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12407 %{ 12408 match(SafePoint poll); 12409 effect(KILL cr, USE poll); 12410 12411 format %{ "testl rax, [$poll]\t" 12412 "# Safepoint: poll for GC" %} 12413 ins_cost(125); 12414 ins_encode %{ 12415 __ relocate(relocInfo::poll_type); 12416 address pre_pc = __ pc(); 12417 __ testl(rax, Address($poll$$Register, 0)); 12418 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12419 %} 12420 ins_pipe(ialu_reg_mem); 12421 %} 12422 12423 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12424 match(Set dst (MaskAll src)); 12425 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12426 ins_encode %{ 12427 int mask_len = Matcher::vector_length(this); 12428 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12429 %} 12430 ins_pipe( pipe_slow ); 12431 %} 12432 12433 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12434 predicate(Matcher::vector_length(n) > 32); 12435 match(Set dst (MaskAll src)); 12436 effect(TEMP tmp); 12437 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12438 ins_encode %{ 12439 int mask_len = Matcher::vector_length(this); 12440 __ movslq($tmp$$Register, $src$$Register); 12441 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12442 %} 12443 ins_pipe( pipe_slow ); 12444 %} 12445 12446 // ============================================================================ 12447 // Procedure Call/Return Instructions 12448 // Call Java Static Instruction 12449 // Note: If this code changes, the corresponding ret_addr_offset() and 12450 // compute_padding() functions will have to be adjusted. 12451 instruct CallStaticJavaDirect(method meth) %{ 12452 match(CallStaticJava); 12453 effect(USE meth); 12454 12455 ins_cost(300); 12456 format %{ "call,static " %} 12457 opcode(0xE8); /* E8 cd */ 12458 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12459 ins_pipe(pipe_slow); 12460 ins_alignment(4); 12461 %} 12462 12463 // Call Java Dynamic Instruction 12464 // Note: If this code changes, the corresponding ret_addr_offset() and 12465 // compute_padding() functions will have to be adjusted. 12466 instruct CallDynamicJavaDirect(method meth) 12467 %{ 12468 match(CallDynamicJava); 12469 effect(USE meth); 12470 12471 ins_cost(300); 12472 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12473 "call,dynamic " %} 12474 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12475 ins_pipe(pipe_slow); 12476 ins_alignment(4); 12477 %} 12478 12479 // Call Runtime Instruction 12480 instruct CallRuntimeDirect(method meth) 12481 %{ 12482 match(CallRuntime); 12483 effect(USE meth); 12484 12485 ins_cost(300); 12486 format %{ "call,runtime " %} 12487 ins_encode(clear_avx, Java_To_Runtime(meth)); 12488 ins_pipe(pipe_slow); 12489 %} 12490 12491 // Call runtime without safepoint 12492 instruct CallLeafDirect(method meth) 12493 %{ 12494 match(CallLeaf); 12495 effect(USE meth); 12496 12497 ins_cost(300); 12498 format %{ "call_leaf,runtime " %} 12499 ins_encode(clear_avx, Java_To_Runtime(meth)); 12500 ins_pipe(pipe_slow); 12501 %} 12502 12503 // Call runtime without safepoint and with vector arguments 12504 instruct CallLeafDirectVector(method meth) 12505 %{ 12506 match(CallLeafVector); 12507 effect(USE meth); 12508 12509 ins_cost(300); 12510 format %{ "call_leaf,vector " %} 12511 ins_encode(Java_To_Runtime(meth)); 12512 ins_pipe(pipe_slow); 12513 %} 12514 12515 // Call runtime without safepoint 12516 instruct CallLeafNoFPDirect(method meth) 12517 %{ 12518 match(CallLeafNoFP); 12519 effect(USE meth); 12520 12521 ins_cost(300); 12522 format %{ "call_leaf_nofp,runtime " %} 12523 ins_encode(clear_avx, Java_To_Runtime(meth)); 12524 ins_pipe(pipe_slow); 12525 %} 12526 12527 // Return Instruction 12528 // Remove the return address & jump to it. 12529 // Notice: We always emit a nop after a ret to make sure there is room 12530 // for safepoint patching 12531 instruct Ret() 12532 %{ 12533 match(Return); 12534 12535 format %{ "ret" %} 12536 ins_encode %{ 12537 __ ret(0); 12538 %} 12539 ins_pipe(pipe_jmp); 12540 %} 12541 12542 // Tail Call; Jump from runtime stub to Java code. 12543 // Also known as an 'interprocedural jump'. 12544 // Target of jump will eventually return to caller. 12545 // TailJump below removes the return address. 12546 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12547 // emitted just above the TailCall which has reset rbp to the caller state. 12548 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12549 %{ 12550 match(TailCall jump_target method_ptr); 12551 12552 ins_cost(300); 12553 format %{ "jmp $jump_target\t# rbx holds method" %} 12554 ins_encode %{ 12555 __ jmp($jump_target$$Register); 12556 %} 12557 ins_pipe(pipe_jmp); 12558 %} 12559 12560 // Tail Jump; remove the return address; jump to target. 12561 // TailCall above leaves the return address around. 12562 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12563 %{ 12564 match(TailJump jump_target ex_oop); 12565 12566 ins_cost(300); 12567 format %{ "popq rdx\t# pop return address\n\t" 12568 "jmp $jump_target" %} 12569 ins_encode %{ 12570 __ popq(as_Register(RDX_enc)); 12571 __ jmp($jump_target$$Register); 12572 %} 12573 ins_pipe(pipe_jmp); 12574 %} 12575 12576 // Forward exception. 12577 instruct ForwardExceptionjmp() 12578 %{ 12579 match(ForwardException); 12580 12581 format %{ "jmp forward_exception_stub" %} 12582 ins_encode %{ 12583 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 12584 %} 12585 ins_pipe(pipe_jmp); 12586 %} 12587 12588 // Create exception oop: created by stack-crawling runtime code. 12589 // Created exception is now available to this handler, and is setup 12590 // just prior to jumping to this handler. No code emitted. 12591 instruct CreateException(rax_RegP ex_oop) 12592 %{ 12593 match(Set ex_oop (CreateEx)); 12594 12595 size(0); 12596 // use the following format syntax 12597 format %{ "# exception oop is in rax; no code emitted" %} 12598 ins_encode(); 12599 ins_pipe(empty); 12600 %} 12601 12602 // Rethrow exception: 12603 // The exception oop will come in the first argument position. 12604 // Then JUMP (not call) to the rethrow stub code. 12605 instruct RethrowException() 12606 %{ 12607 match(Rethrow); 12608 12609 // use the following format syntax 12610 format %{ "jmp rethrow_stub" %} 12611 ins_encode %{ 12612 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12613 %} 12614 ins_pipe(pipe_jmp); 12615 %} 12616 12617 // ============================================================================ 12618 // This name is KNOWN by the ADLC and cannot be changed. 12619 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12620 // for this guy. 12621 instruct tlsLoadP(r15_RegP dst) %{ 12622 match(Set dst (ThreadLocal)); 12623 effect(DEF dst); 12624 12625 size(0); 12626 format %{ "# TLS is in R15" %} 12627 ins_encode( /*empty encoding*/ ); 12628 ins_pipe(ialu_reg_reg); 12629 %} 12630 12631 12632 //----------PEEPHOLE RULES----------------------------------------------------- 12633 // These must follow all instruction definitions as they use the names 12634 // defined in the instructions definitions. 12635 // 12636 // peeppredicate ( rule_predicate ); 12637 // // the predicate unless which the peephole rule will be ignored 12638 // 12639 // peepmatch ( root_instr_name [preceding_instruction]* ); 12640 // 12641 // peepprocedure ( procedure_name ); 12642 // // provide a procedure name to perform the optimization, the procedure should 12643 // // reside in the architecture dependent peephole file, the method has the 12644 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12645 // // with the arguments being the basic block, the current node index inside the 12646 // // block, the register allocator, the functions upon invoked return a new node 12647 // // defined in peepreplace, and the rules of the nodes appearing in the 12648 // // corresponding peepmatch, the function return true if successful, else 12649 // // return false 12650 // 12651 // peepconstraint %{ 12652 // (instruction_number.operand_name relational_op instruction_number.operand_name 12653 // [, ...] ); 12654 // // instruction numbers are zero-based using left to right order in peepmatch 12655 // 12656 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12657 // // provide an instruction_number.operand_name for each operand that appears 12658 // // in the replacement instruction's match rule 12659 // 12660 // ---------VM FLAGS--------------------------------------------------------- 12661 // 12662 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12663 // 12664 // Each peephole rule is given an identifying number starting with zero and 12665 // increasing by one in the order seen by the parser. An individual peephole 12666 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12667 // on the command-line. 12668 // 12669 // ---------CURRENT LIMITATIONS---------------------------------------------- 12670 // 12671 // Only transformations inside a basic block (do we need more for peephole) 12672 // 12673 // ---------EXAMPLE---------------------------------------------------------- 12674 // 12675 // // pertinent parts of existing instructions in architecture description 12676 // instruct movI(rRegI dst, rRegI src) 12677 // %{ 12678 // match(Set dst (CopyI src)); 12679 // %} 12680 // 12681 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12682 // %{ 12683 // match(Set dst (AddI dst src)); 12684 // effect(KILL cr); 12685 // %} 12686 // 12687 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12688 // %{ 12689 // match(Set dst (AddI dst src)); 12690 // %} 12691 // 12692 // 1. Simple replacement 12693 // - Only match adjacent instructions in same basic block 12694 // - Only equality constraints 12695 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12696 // - Only one replacement instruction 12697 // 12698 // // Change (inc mov) to lea 12699 // peephole %{ 12700 // // lea should only be emitted when beneficial 12701 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12702 // // increment preceded by register-register move 12703 // peepmatch ( incI_rReg movI ); 12704 // // require that the destination register of the increment 12705 // // match the destination register of the move 12706 // peepconstraint ( 0.dst == 1.dst ); 12707 // // construct a replacement instruction that sets 12708 // // the destination to ( move's source register + one ) 12709 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12710 // %} 12711 // 12712 // 2. Procedural replacement 12713 // - More flexible finding relevent nodes 12714 // - More flexible constraints 12715 // - More flexible transformations 12716 // - May utilise architecture-dependent API more effectively 12717 // - Currently only one replacement instruction due to adlc parsing capabilities 12718 // 12719 // // Change (inc mov) to lea 12720 // peephole %{ 12721 // // lea should only be emitted when beneficial 12722 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12723 // // the rule numbers of these nodes inside are passed into the function below 12724 // peepmatch ( incI_rReg movI ); 12725 // // the method that takes the responsibility of transformation 12726 // peepprocedure ( inc_mov_to_lea ); 12727 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12728 // // node is passed into the function above 12729 // peepreplace ( leaI_rReg_immI() ); 12730 // %} 12731 12732 // These instructions is not matched by the matcher but used by the peephole 12733 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12734 %{ 12735 predicate(false); 12736 match(Set dst (AddI src1 src2)); 12737 format %{ "leal $dst, [$src1 + $src2]" %} 12738 ins_encode %{ 12739 Register dst = $dst$$Register; 12740 Register src1 = $src1$$Register; 12741 Register src2 = $src2$$Register; 12742 if (src1 != rbp && src1 != r13) { 12743 __ leal(dst, Address(src1, src2, Address::times_1)); 12744 } else { 12745 assert(src2 != rbp && src2 != r13, ""); 12746 __ leal(dst, Address(src2, src1, Address::times_1)); 12747 } 12748 %} 12749 ins_pipe(ialu_reg_reg); 12750 %} 12751 12752 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 12753 %{ 12754 predicate(false); 12755 match(Set dst (AddI src1 src2)); 12756 format %{ "leal $dst, [$src1 + $src2]" %} 12757 ins_encode %{ 12758 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 12759 %} 12760 ins_pipe(ialu_reg_reg); 12761 %} 12762 12763 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 12764 %{ 12765 predicate(false); 12766 match(Set dst (LShiftI src shift)); 12767 format %{ "leal $dst, [$src << $shift]" %} 12768 ins_encode %{ 12769 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12770 Register src = $src$$Register; 12771 if (scale == Address::times_2 && src != rbp && src != r13) { 12772 __ leal($dst$$Register, Address(src, src, Address::times_1)); 12773 } else { 12774 __ leal($dst$$Register, Address(noreg, src, scale)); 12775 } 12776 %} 12777 ins_pipe(ialu_reg_reg); 12778 %} 12779 12780 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 12781 %{ 12782 predicate(false); 12783 match(Set dst (AddL src1 src2)); 12784 format %{ "leaq $dst, [$src1 + $src2]" %} 12785 ins_encode %{ 12786 Register dst = $dst$$Register; 12787 Register src1 = $src1$$Register; 12788 Register src2 = $src2$$Register; 12789 if (src1 != rbp && src1 != r13) { 12790 __ leaq(dst, Address(src1, src2, Address::times_1)); 12791 } else { 12792 assert(src2 != rbp && src2 != r13, ""); 12793 __ leaq(dst, Address(src2, src1, Address::times_1)); 12794 } 12795 %} 12796 ins_pipe(ialu_reg_reg); 12797 %} 12798 12799 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 12800 %{ 12801 predicate(false); 12802 match(Set dst (AddL src1 src2)); 12803 format %{ "leaq $dst, [$src1 + $src2]" %} 12804 ins_encode %{ 12805 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 12806 %} 12807 ins_pipe(ialu_reg_reg); 12808 %} 12809 12810 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 12811 %{ 12812 predicate(false); 12813 match(Set dst (LShiftL src shift)); 12814 format %{ "leaq $dst, [$src << $shift]" %} 12815 ins_encode %{ 12816 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12817 Register src = $src$$Register; 12818 if (scale == Address::times_2 && src != rbp && src != r13) { 12819 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 12820 } else { 12821 __ leaq($dst$$Register, Address(noreg, src, scale)); 12822 } 12823 %} 12824 ins_pipe(ialu_reg_reg); 12825 %} 12826 12827 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 12828 // sal}) with lea instructions. The {add, sal} rules are beneficial in 12829 // processors with at least partial ALU support for lea 12830 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 12831 // beneficial for processors with full ALU support 12832 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 12833 12834 peephole 12835 %{ 12836 peeppredicate(VM_Version::supports_fast_2op_lea()); 12837 peepmatch (addI_rReg); 12838 peepprocedure (lea_coalesce_reg); 12839 peepreplace (leaI_rReg_rReg_peep()); 12840 %} 12841 12842 peephole 12843 %{ 12844 peeppredicate(VM_Version::supports_fast_2op_lea()); 12845 peepmatch (addI_rReg_imm); 12846 peepprocedure (lea_coalesce_imm); 12847 peepreplace (leaI_rReg_immI_peep()); 12848 %} 12849 12850 peephole 12851 %{ 12852 peeppredicate(VM_Version::supports_fast_3op_lea() || 12853 VM_Version::is_intel_cascade_lake()); 12854 peepmatch (incI_rReg); 12855 peepprocedure (lea_coalesce_imm); 12856 peepreplace (leaI_rReg_immI_peep()); 12857 %} 12858 12859 peephole 12860 %{ 12861 peeppredicate(VM_Version::supports_fast_3op_lea() || 12862 VM_Version::is_intel_cascade_lake()); 12863 peepmatch (decI_rReg); 12864 peepprocedure (lea_coalesce_imm); 12865 peepreplace (leaI_rReg_immI_peep()); 12866 %} 12867 12868 peephole 12869 %{ 12870 peeppredicate(VM_Version::supports_fast_2op_lea()); 12871 peepmatch (salI_rReg_immI2); 12872 peepprocedure (lea_coalesce_imm); 12873 peepreplace (leaI_rReg_immI2_peep()); 12874 %} 12875 12876 peephole 12877 %{ 12878 peeppredicate(VM_Version::supports_fast_2op_lea()); 12879 peepmatch (addL_rReg); 12880 peepprocedure (lea_coalesce_reg); 12881 peepreplace (leaL_rReg_rReg_peep()); 12882 %} 12883 12884 peephole 12885 %{ 12886 peeppredicate(VM_Version::supports_fast_2op_lea()); 12887 peepmatch (addL_rReg_imm); 12888 peepprocedure (lea_coalesce_imm); 12889 peepreplace (leaL_rReg_immL32_peep()); 12890 %} 12891 12892 peephole 12893 %{ 12894 peeppredicate(VM_Version::supports_fast_3op_lea() || 12895 VM_Version::is_intel_cascade_lake()); 12896 peepmatch (incL_rReg); 12897 peepprocedure (lea_coalesce_imm); 12898 peepreplace (leaL_rReg_immL32_peep()); 12899 %} 12900 12901 peephole 12902 %{ 12903 peeppredicate(VM_Version::supports_fast_3op_lea() || 12904 VM_Version::is_intel_cascade_lake()); 12905 peepmatch (decL_rReg); 12906 peepprocedure (lea_coalesce_imm); 12907 peepreplace (leaL_rReg_immL32_peep()); 12908 %} 12909 12910 peephole 12911 %{ 12912 peeppredicate(VM_Version::supports_fast_2op_lea()); 12913 peepmatch (salL_rReg_immI2); 12914 peepprocedure (lea_coalesce_imm); 12915 peepreplace (leaL_rReg_immI2_peep()); 12916 %} 12917 12918 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 12919 // 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 12920 12921 //int variant 12922 peephole 12923 %{ 12924 peepmatch (testI_reg); 12925 peepprocedure (test_may_remove); 12926 %} 12927 12928 //long variant 12929 peephole 12930 %{ 12931 peepmatch (testL_reg); 12932 peepprocedure (test_may_remove); 12933 %} 12934 12935 12936 //----------SMARTSPILL RULES--------------------------------------------------- 12937 // These must follow all instruction definitions as they use the names 12938 // defined in the instructions definitions.