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