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 predicate(n->as_Load()->barrier_data() == 0); 4345 match(Set dst (LoadN mem)); 4346 4347 ins_cost(125); // XXX 4348 format %{ "movl $dst, $mem\t# compressed ptr" %} 4349 ins_encode %{ 4350 __ movl($dst$$Register, $mem$$Address); 4351 %} 4352 ins_pipe(ialu_reg_mem); // XXX 4353 %} 4354 4355 4356 // Load Klass Pointer 4357 instruct loadKlass(rRegP dst, memory mem) 4358 %{ 4359 match(Set dst (LoadKlass mem)); 4360 4361 ins_cost(125); // XXX 4362 format %{ "movq $dst, $mem\t# class" %} 4363 ins_encode %{ 4364 __ movq($dst$$Register, $mem$$Address); 4365 %} 4366 ins_pipe(ialu_reg_mem); // XXX 4367 %} 4368 4369 // Load narrow Klass Pointer 4370 instruct loadNKlass(rRegN dst, memory mem) 4371 %{ 4372 match(Set dst (LoadNKlass mem)); 4373 4374 ins_cost(125); // XXX 4375 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4376 ins_encode %{ 4377 __ movl($dst$$Register, $mem$$Address); 4378 %} 4379 ins_pipe(ialu_reg_mem); // XXX 4380 %} 4381 4382 // Load Float 4383 instruct loadF(regF dst, memory mem) 4384 %{ 4385 match(Set dst (LoadF mem)); 4386 4387 ins_cost(145); // XXX 4388 format %{ "movss $dst, $mem\t# float" %} 4389 ins_encode %{ 4390 __ movflt($dst$$XMMRegister, $mem$$Address); 4391 %} 4392 ins_pipe(pipe_slow); // XXX 4393 %} 4394 4395 // Load Double 4396 instruct loadD_partial(regD dst, memory mem) 4397 %{ 4398 predicate(!UseXmmLoadAndClearUpper); 4399 match(Set dst (LoadD mem)); 4400 4401 ins_cost(145); // XXX 4402 format %{ "movlpd $dst, $mem\t# double" %} 4403 ins_encode %{ 4404 __ movdbl($dst$$XMMRegister, $mem$$Address); 4405 %} 4406 ins_pipe(pipe_slow); // XXX 4407 %} 4408 4409 instruct loadD(regD dst, memory mem) 4410 %{ 4411 predicate(UseXmmLoadAndClearUpper); 4412 match(Set dst (LoadD mem)); 4413 4414 ins_cost(145); // XXX 4415 format %{ "movsd $dst, $mem\t# double" %} 4416 ins_encode %{ 4417 __ movdbl($dst$$XMMRegister, $mem$$Address); 4418 %} 4419 ins_pipe(pipe_slow); // XXX 4420 %} 4421 4422 // max = java.lang.Math.max(float a, float b) 4423 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4424 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4425 match(Set dst (MaxF a b)); 4426 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4427 format %{ "maxF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4428 ins_encode %{ 4429 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4430 %} 4431 ins_pipe( pipe_slow ); 4432 %} 4433 4434 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4435 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4436 match(Set dst (MaxF a b)); 4437 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4438 4439 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 4440 ins_encode %{ 4441 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4442 false /*min*/, true /*single*/); 4443 %} 4444 ins_pipe( pipe_slow ); 4445 %} 4446 4447 // max = java.lang.Math.max(double a, double b) 4448 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4449 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4450 match(Set dst (MaxD a b)); 4451 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4452 format %{ "maxD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4453 ins_encode %{ 4454 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4455 %} 4456 ins_pipe( pipe_slow ); 4457 %} 4458 4459 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4460 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4461 match(Set dst (MaxD a b)); 4462 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4463 4464 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 4465 ins_encode %{ 4466 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4467 false /*min*/, false /*single*/); 4468 %} 4469 ins_pipe( pipe_slow ); 4470 %} 4471 4472 // min = java.lang.Math.min(float a, float b) 4473 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4474 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4475 match(Set dst (MinF a b)); 4476 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4477 format %{ "minF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4478 ins_encode %{ 4479 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4480 %} 4481 ins_pipe( pipe_slow ); 4482 %} 4483 4484 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4485 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4486 match(Set dst (MinF a b)); 4487 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4488 4489 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 4490 ins_encode %{ 4491 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4492 true /*min*/, true /*single*/); 4493 %} 4494 ins_pipe( pipe_slow ); 4495 %} 4496 4497 // min = java.lang.Math.min(double a, double b) 4498 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4499 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4500 match(Set dst (MinD a b)); 4501 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4502 format %{ "minD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4503 ins_encode %{ 4504 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4505 %} 4506 ins_pipe( pipe_slow ); 4507 %} 4508 4509 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4510 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4511 match(Set dst (MinD a b)); 4512 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4513 4514 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 4515 ins_encode %{ 4516 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4517 true /*min*/, false /*single*/); 4518 %} 4519 ins_pipe( pipe_slow ); 4520 %} 4521 4522 // Load Effective Address 4523 instruct leaP8(rRegP dst, indOffset8 mem) 4524 %{ 4525 match(Set dst mem); 4526 4527 ins_cost(110); // XXX 4528 format %{ "leaq $dst, $mem\t# ptr 8" %} 4529 ins_encode %{ 4530 __ leaq($dst$$Register, $mem$$Address); 4531 %} 4532 ins_pipe(ialu_reg_reg_fat); 4533 %} 4534 4535 instruct leaP32(rRegP dst, indOffset32 mem) 4536 %{ 4537 match(Set dst mem); 4538 4539 ins_cost(110); 4540 format %{ "leaq $dst, $mem\t# ptr 32" %} 4541 ins_encode %{ 4542 __ leaq($dst$$Register, $mem$$Address); 4543 %} 4544 ins_pipe(ialu_reg_reg_fat); 4545 %} 4546 4547 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4548 %{ 4549 match(Set dst mem); 4550 4551 ins_cost(110); 4552 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4553 ins_encode %{ 4554 __ leaq($dst$$Register, $mem$$Address); 4555 %} 4556 ins_pipe(ialu_reg_reg_fat); 4557 %} 4558 4559 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4560 %{ 4561 match(Set dst mem); 4562 4563 ins_cost(110); 4564 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4565 ins_encode %{ 4566 __ leaq($dst$$Register, $mem$$Address); 4567 %} 4568 ins_pipe(ialu_reg_reg_fat); 4569 %} 4570 4571 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4572 %{ 4573 match(Set dst mem); 4574 4575 ins_cost(110); 4576 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4577 ins_encode %{ 4578 __ leaq($dst$$Register, $mem$$Address); 4579 %} 4580 ins_pipe(ialu_reg_reg_fat); 4581 %} 4582 4583 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4584 %{ 4585 match(Set dst mem); 4586 4587 ins_cost(110); 4588 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4589 ins_encode %{ 4590 __ leaq($dst$$Register, $mem$$Address); 4591 %} 4592 ins_pipe(ialu_reg_reg_fat); 4593 %} 4594 4595 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4596 %{ 4597 match(Set dst mem); 4598 4599 ins_cost(110); 4600 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4601 ins_encode %{ 4602 __ leaq($dst$$Register, $mem$$Address); 4603 %} 4604 ins_pipe(ialu_reg_reg_fat); 4605 %} 4606 4607 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4608 %{ 4609 match(Set dst mem); 4610 4611 ins_cost(110); 4612 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4613 ins_encode %{ 4614 __ leaq($dst$$Register, $mem$$Address); 4615 %} 4616 ins_pipe(ialu_reg_reg_fat); 4617 %} 4618 4619 // Load Effective Address which uses Narrow (32-bits) oop 4620 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4621 %{ 4622 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4623 match(Set dst mem); 4624 4625 ins_cost(110); 4626 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4627 ins_encode %{ 4628 __ leaq($dst$$Register, $mem$$Address); 4629 %} 4630 ins_pipe(ialu_reg_reg_fat); 4631 %} 4632 4633 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4634 %{ 4635 predicate(CompressedOops::shift() == 0); 4636 match(Set dst mem); 4637 4638 ins_cost(110); // XXX 4639 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4640 ins_encode %{ 4641 __ leaq($dst$$Register, $mem$$Address); 4642 %} 4643 ins_pipe(ialu_reg_reg_fat); 4644 %} 4645 4646 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4647 %{ 4648 predicate(CompressedOops::shift() == 0); 4649 match(Set dst mem); 4650 4651 ins_cost(110); 4652 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4653 ins_encode %{ 4654 __ leaq($dst$$Register, $mem$$Address); 4655 %} 4656 ins_pipe(ialu_reg_reg_fat); 4657 %} 4658 4659 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4660 %{ 4661 predicate(CompressedOops::shift() == 0); 4662 match(Set dst mem); 4663 4664 ins_cost(110); 4665 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4666 ins_encode %{ 4667 __ leaq($dst$$Register, $mem$$Address); 4668 %} 4669 ins_pipe(ialu_reg_reg_fat); 4670 %} 4671 4672 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4673 %{ 4674 predicate(CompressedOops::shift() == 0); 4675 match(Set dst mem); 4676 4677 ins_cost(110); 4678 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4679 ins_encode %{ 4680 __ leaq($dst$$Register, $mem$$Address); 4681 %} 4682 ins_pipe(ialu_reg_reg_fat); 4683 %} 4684 4685 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4686 %{ 4687 predicate(CompressedOops::shift() == 0); 4688 match(Set dst mem); 4689 4690 ins_cost(110); 4691 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4692 ins_encode %{ 4693 __ leaq($dst$$Register, $mem$$Address); 4694 %} 4695 ins_pipe(ialu_reg_reg_fat); 4696 %} 4697 4698 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4699 %{ 4700 predicate(CompressedOops::shift() == 0); 4701 match(Set dst mem); 4702 4703 ins_cost(110); 4704 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4705 ins_encode %{ 4706 __ leaq($dst$$Register, $mem$$Address); 4707 %} 4708 ins_pipe(ialu_reg_reg_fat); 4709 %} 4710 4711 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4712 %{ 4713 predicate(CompressedOops::shift() == 0); 4714 match(Set dst mem); 4715 4716 ins_cost(110); 4717 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4718 ins_encode %{ 4719 __ leaq($dst$$Register, $mem$$Address); 4720 %} 4721 ins_pipe(ialu_reg_reg_fat); 4722 %} 4723 4724 instruct loadConI(rRegI dst, immI src) 4725 %{ 4726 match(Set dst src); 4727 4728 format %{ "movl $dst, $src\t# int" %} 4729 ins_encode %{ 4730 __ movl($dst$$Register, $src$$constant); 4731 %} 4732 ins_pipe(ialu_reg_fat); // XXX 4733 %} 4734 4735 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4736 %{ 4737 match(Set dst src); 4738 effect(KILL cr); 4739 4740 ins_cost(50); 4741 format %{ "xorl $dst, $dst\t# int" %} 4742 ins_encode %{ 4743 __ xorl($dst$$Register, $dst$$Register); 4744 %} 4745 ins_pipe(ialu_reg); 4746 %} 4747 4748 instruct loadConL(rRegL dst, immL src) 4749 %{ 4750 match(Set dst src); 4751 4752 ins_cost(150); 4753 format %{ "movq $dst, $src\t# long" %} 4754 ins_encode %{ 4755 __ mov64($dst$$Register, $src$$constant); 4756 %} 4757 ins_pipe(ialu_reg); 4758 %} 4759 4760 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4761 %{ 4762 match(Set dst src); 4763 effect(KILL cr); 4764 4765 ins_cost(50); 4766 format %{ "xorl $dst, $dst\t# long" %} 4767 ins_encode %{ 4768 __ xorl($dst$$Register, $dst$$Register); 4769 %} 4770 ins_pipe(ialu_reg); // XXX 4771 %} 4772 4773 instruct loadConUL32(rRegL dst, immUL32 src) 4774 %{ 4775 match(Set dst src); 4776 4777 ins_cost(60); 4778 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4779 ins_encode %{ 4780 __ movl($dst$$Register, $src$$constant); 4781 %} 4782 ins_pipe(ialu_reg); 4783 %} 4784 4785 instruct loadConL32(rRegL dst, immL32 src) 4786 %{ 4787 match(Set dst src); 4788 4789 ins_cost(70); 4790 format %{ "movq $dst, $src\t# long (32-bit)" %} 4791 ins_encode %{ 4792 __ movq($dst$$Register, $src$$constant); 4793 %} 4794 ins_pipe(ialu_reg); 4795 %} 4796 4797 instruct loadConP(rRegP dst, immP con) %{ 4798 match(Set dst con); 4799 4800 format %{ "movq $dst, $con\t# ptr" %} 4801 ins_encode %{ 4802 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4803 %} 4804 ins_pipe(ialu_reg_fat); // XXX 4805 %} 4806 4807 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4808 %{ 4809 match(Set dst src); 4810 effect(KILL cr); 4811 4812 ins_cost(50); 4813 format %{ "xorl $dst, $dst\t# ptr" %} 4814 ins_encode %{ 4815 __ xorl($dst$$Register, $dst$$Register); 4816 %} 4817 ins_pipe(ialu_reg); 4818 %} 4819 4820 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4821 %{ 4822 match(Set dst src); 4823 effect(KILL cr); 4824 4825 ins_cost(60); 4826 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4827 ins_encode %{ 4828 __ movl($dst$$Register, $src$$constant); 4829 %} 4830 ins_pipe(ialu_reg); 4831 %} 4832 4833 instruct loadConF(regF dst, immF con) %{ 4834 match(Set dst con); 4835 ins_cost(125); 4836 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4837 ins_encode %{ 4838 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4839 %} 4840 ins_pipe(pipe_slow); 4841 %} 4842 4843 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4844 match(Set dst src); 4845 effect(KILL cr); 4846 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4847 ins_encode %{ 4848 __ xorq($dst$$Register, $dst$$Register); 4849 %} 4850 ins_pipe(ialu_reg); 4851 %} 4852 4853 instruct loadConN(rRegN dst, immN src) %{ 4854 match(Set dst src); 4855 4856 ins_cost(125); 4857 format %{ "movl $dst, $src\t# compressed ptr" %} 4858 ins_encode %{ 4859 address con = (address)$src$$constant; 4860 if (con == nullptr) { 4861 ShouldNotReachHere(); 4862 } else { 4863 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4864 } 4865 %} 4866 ins_pipe(ialu_reg_fat); // XXX 4867 %} 4868 4869 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4870 match(Set dst src); 4871 4872 ins_cost(125); 4873 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4874 ins_encode %{ 4875 address con = (address)$src$$constant; 4876 if (con == nullptr) { 4877 ShouldNotReachHere(); 4878 } else { 4879 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4880 } 4881 %} 4882 ins_pipe(ialu_reg_fat); // XXX 4883 %} 4884 4885 instruct loadConF0(regF dst, immF0 src) 4886 %{ 4887 match(Set dst src); 4888 ins_cost(100); 4889 4890 format %{ "xorps $dst, $dst\t# float 0.0" %} 4891 ins_encode %{ 4892 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4893 %} 4894 ins_pipe(pipe_slow); 4895 %} 4896 4897 // Use the same format since predicate() can not be used here. 4898 instruct loadConD(regD dst, immD con) %{ 4899 match(Set dst con); 4900 ins_cost(125); 4901 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4902 ins_encode %{ 4903 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4904 %} 4905 ins_pipe(pipe_slow); 4906 %} 4907 4908 instruct loadConD0(regD dst, immD0 src) 4909 %{ 4910 match(Set dst src); 4911 ins_cost(100); 4912 4913 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4914 ins_encode %{ 4915 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4916 %} 4917 ins_pipe(pipe_slow); 4918 %} 4919 4920 instruct loadSSI(rRegI dst, stackSlotI src) 4921 %{ 4922 match(Set dst src); 4923 4924 ins_cost(125); 4925 format %{ "movl $dst, $src\t# int stk" %} 4926 ins_encode %{ 4927 __ movl($dst$$Register, $src$$Address); 4928 %} 4929 ins_pipe(ialu_reg_mem); 4930 %} 4931 4932 instruct loadSSL(rRegL dst, stackSlotL src) 4933 %{ 4934 match(Set dst src); 4935 4936 ins_cost(125); 4937 format %{ "movq $dst, $src\t# long stk" %} 4938 ins_encode %{ 4939 __ movq($dst$$Register, $src$$Address); 4940 %} 4941 ins_pipe(ialu_reg_mem); 4942 %} 4943 4944 instruct loadSSP(rRegP dst, stackSlotP src) 4945 %{ 4946 match(Set dst src); 4947 4948 ins_cost(125); 4949 format %{ "movq $dst, $src\t# ptr stk" %} 4950 ins_encode %{ 4951 __ movq($dst$$Register, $src$$Address); 4952 %} 4953 ins_pipe(ialu_reg_mem); 4954 %} 4955 4956 instruct loadSSF(regF dst, stackSlotF src) 4957 %{ 4958 match(Set dst src); 4959 4960 ins_cost(125); 4961 format %{ "movss $dst, $src\t# float stk" %} 4962 ins_encode %{ 4963 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 4964 %} 4965 ins_pipe(pipe_slow); // XXX 4966 %} 4967 4968 // Use the same format since predicate() can not be used here. 4969 instruct loadSSD(regD dst, stackSlotD src) 4970 %{ 4971 match(Set dst src); 4972 4973 ins_cost(125); 4974 format %{ "movsd $dst, $src\t# double stk" %} 4975 ins_encode %{ 4976 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 4977 %} 4978 ins_pipe(pipe_slow); // XXX 4979 %} 4980 4981 // Prefetch instructions for allocation. 4982 // Must be safe to execute with invalid address (cannot fault). 4983 4984 instruct prefetchAlloc( memory mem ) %{ 4985 predicate(AllocatePrefetchInstr==3); 4986 match(PrefetchAllocation mem); 4987 ins_cost(125); 4988 4989 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 4990 ins_encode %{ 4991 __ prefetchw($mem$$Address); 4992 %} 4993 ins_pipe(ialu_mem); 4994 %} 4995 4996 instruct prefetchAllocNTA( memory mem ) %{ 4997 predicate(AllocatePrefetchInstr==0); 4998 match(PrefetchAllocation mem); 4999 ins_cost(125); 5000 5001 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5002 ins_encode %{ 5003 __ prefetchnta($mem$$Address); 5004 %} 5005 ins_pipe(ialu_mem); 5006 %} 5007 5008 instruct prefetchAllocT0( memory mem ) %{ 5009 predicate(AllocatePrefetchInstr==1); 5010 match(PrefetchAllocation mem); 5011 ins_cost(125); 5012 5013 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5014 ins_encode %{ 5015 __ prefetcht0($mem$$Address); 5016 %} 5017 ins_pipe(ialu_mem); 5018 %} 5019 5020 instruct prefetchAllocT2( memory mem ) %{ 5021 predicate(AllocatePrefetchInstr==2); 5022 match(PrefetchAllocation mem); 5023 ins_cost(125); 5024 5025 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5026 ins_encode %{ 5027 __ prefetcht2($mem$$Address); 5028 %} 5029 ins_pipe(ialu_mem); 5030 %} 5031 5032 //----------Store Instructions------------------------------------------------- 5033 5034 // Store Byte 5035 instruct storeB(memory mem, rRegI src) 5036 %{ 5037 match(Set mem (StoreB mem src)); 5038 5039 ins_cost(125); // XXX 5040 format %{ "movb $mem, $src\t# byte" %} 5041 ins_encode %{ 5042 __ movb($mem$$Address, $src$$Register); 5043 %} 5044 ins_pipe(ialu_mem_reg); 5045 %} 5046 5047 // Store Char/Short 5048 instruct storeC(memory mem, rRegI src) 5049 %{ 5050 match(Set mem (StoreC mem src)); 5051 5052 ins_cost(125); // XXX 5053 format %{ "movw $mem, $src\t# char/short" %} 5054 ins_encode %{ 5055 __ movw($mem$$Address, $src$$Register); 5056 %} 5057 ins_pipe(ialu_mem_reg); 5058 %} 5059 5060 // Store Integer 5061 instruct storeI(memory mem, rRegI src) 5062 %{ 5063 match(Set mem (StoreI mem src)); 5064 5065 ins_cost(125); // XXX 5066 format %{ "movl $mem, $src\t# int" %} 5067 ins_encode %{ 5068 __ movl($mem$$Address, $src$$Register); 5069 %} 5070 ins_pipe(ialu_mem_reg); 5071 %} 5072 5073 // Store Long 5074 instruct storeL(memory mem, rRegL src) 5075 %{ 5076 match(Set mem (StoreL mem src)); 5077 5078 ins_cost(125); // XXX 5079 format %{ "movq $mem, $src\t# long" %} 5080 ins_encode %{ 5081 __ movq($mem$$Address, $src$$Register); 5082 %} 5083 ins_pipe(ialu_mem_reg); // XXX 5084 %} 5085 5086 // Store Pointer 5087 instruct storeP(memory mem, any_RegP src) 5088 %{ 5089 predicate(n->as_Store()->barrier_data() == 0); 5090 match(Set mem (StoreP mem src)); 5091 5092 ins_cost(125); // XXX 5093 format %{ "movq $mem, $src\t# ptr" %} 5094 ins_encode %{ 5095 __ movq($mem$$Address, $src$$Register); 5096 %} 5097 ins_pipe(ialu_mem_reg); 5098 %} 5099 5100 instruct storeImmP0(memory mem, immP0 zero) 5101 %{ 5102 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5103 match(Set mem (StoreP mem zero)); 5104 5105 ins_cost(125); // XXX 5106 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5107 ins_encode %{ 5108 __ movq($mem$$Address, r12); 5109 %} 5110 ins_pipe(ialu_mem_reg); 5111 %} 5112 5113 // Store Null Pointer, mark word, or other simple pointer constant. 5114 instruct storeImmP(memory mem, immP31 src) 5115 %{ 5116 predicate(n->as_Store()->barrier_data() == 0); 5117 match(Set mem (StoreP mem src)); 5118 5119 ins_cost(150); // XXX 5120 format %{ "movq $mem, $src\t# ptr" %} 5121 ins_encode %{ 5122 __ movq($mem$$Address, $src$$constant); 5123 %} 5124 ins_pipe(ialu_mem_imm); 5125 %} 5126 5127 // Store Compressed Pointer 5128 instruct storeN(memory mem, rRegN src) 5129 %{ 5130 predicate(n->as_Store()->barrier_data() == 0); 5131 match(Set mem (StoreN mem src)); 5132 5133 ins_cost(125); // XXX 5134 format %{ "movl $mem, $src\t# compressed ptr" %} 5135 ins_encode %{ 5136 __ movl($mem$$Address, $src$$Register); 5137 %} 5138 ins_pipe(ialu_mem_reg); 5139 %} 5140 5141 instruct storeNKlass(memory mem, rRegN src) 5142 %{ 5143 match(Set mem (StoreNKlass mem src)); 5144 5145 ins_cost(125); // XXX 5146 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5147 ins_encode %{ 5148 __ movl($mem$$Address, $src$$Register); 5149 %} 5150 ins_pipe(ialu_mem_reg); 5151 %} 5152 5153 instruct storeImmN0(memory mem, immN0 zero) 5154 %{ 5155 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5156 match(Set mem (StoreN mem zero)); 5157 5158 ins_cost(125); // XXX 5159 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5160 ins_encode %{ 5161 __ movl($mem$$Address, r12); 5162 %} 5163 ins_pipe(ialu_mem_reg); 5164 %} 5165 5166 instruct storeImmN(memory mem, immN src) 5167 %{ 5168 predicate(n->as_Store()->barrier_data() == 0); 5169 match(Set mem (StoreN mem src)); 5170 5171 ins_cost(150); // XXX 5172 format %{ "movl $mem, $src\t# compressed ptr" %} 5173 ins_encode %{ 5174 address con = (address)$src$$constant; 5175 if (con == nullptr) { 5176 __ movl($mem$$Address, 0); 5177 } else { 5178 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5179 } 5180 %} 5181 ins_pipe(ialu_mem_imm); 5182 %} 5183 5184 instruct storeImmNKlass(memory mem, immNKlass src) 5185 %{ 5186 match(Set mem (StoreNKlass mem src)); 5187 5188 ins_cost(150); // XXX 5189 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5190 ins_encode %{ 5191 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5192 %} 5193 ins_pipe(ialu_mem_imm); 5194 %} 5195 5196 // Store Integer Immediate 5197 instruct storeImmI0(memory mem, immI_0 zero) 5198 %{ 5199 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5200 match(Set mem (StoreI mem zero)); 5201 5202 ins_cost(125); // XXX 5203 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5204 ins_encode %{ 5205 __ movl($mem$$Address, r12); 5206 %} 5207 ins_pipe(ialu_mem_reg); 5208 %} 5209 5210 instruct storeImmI(memory mem, immI src) 5211 %{ 5212 match(Set mem (StoreI mem src)); 5213 5214 ins_cost(150); 5215 format %{ "movl $mem, $src\t# int" %} 5216 ins_encode %{ 5217 __ movl($mem$$Address, $src$$constant); 5218 %} 5219 ins_pipe(ialu_mem_imm); 5220 %} 5221 5222 // Store Long Immediate 5223 instruct storeImmL0(memory mem, immL0 zero) 5224 %{ 5225 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5226 match(Set mem (StoreL mem zero)); 5227 5228 ins_cost(125); // XXX 5229 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5230 ins_encode %{ 5231 __ movq($mem$$Address, r12); 5232 %} 5233 ins_pipe(ialu_mem_reg); 5234 %} 5235 5236 instruct storeImmL(memory mem, immL32 src) 5237 %{ 5238 match(Set mem (StoreL mem src)); 5239 5240 ins_cost(150); 5241 format %{ "movq $mem, $src\t# long" %} 5242 ins_encode %{ 5243 __ movq($mem$$Address, $src$$constant); 5244 %} 5245 ins_pipe(ialu_mem_imm); 5246 %} 5247 5248 // Store Short/Char Immediate 5249 instruct storeImmC0(memory mem, immI_0 zero) 5250 %{ 5251 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5252 match(Set mem (StoreC mem zero)); 5253 5254 ins_cost(125); // XXX 5255 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5256 ins_encode %{ 5257 __ movw($mem$$Address, r12); 5258 %} 5259 ins_pipe(ialu_mem_reg); 5260 %} 5261 5262 instruct storeImmI16(memory mem, immI16 src) 5263 %{ 5264 predicate(UseStoreImmI16); 5265 match(Set mem (StoreC mem src)); 5266 5267 ins_cost(150); 5268 format %{ "movw $mem, $src\t# short/char" %} 5269 ins_encode %{ 5270 __ movw($mem$$Address, $src$$constant); 5271 %} 5272 ins_pipe(ialu_mem_imm); 5273 %} 5274 5275 // Store Byte Immediate 5276 instruct storeImmB0(memory mem, immI_0 zero) 5277 %{ 5278 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5279 match(Set mem (StoreB mem zero)); 5280 5281 ins_cost(125); // XXX 5282 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5283 ins_encode %{ 5284 __ movb($mem$$Address, r12); 5285 %} 5286 ins_pipe(ialu_mem_reg); 5287 %} 5288 5289 instruct storeImmB(memory mem, immI8 src) 5290 %{ 5291 match(Set mem (StoreB mem src)); 5292 5293 ins_cost(150); // XXX 5294 format %{ "movb $mem, $src\t# byte" %} 5295 ins_encode %{ 5296 __ movb($mem$$Address, $src$$constant); 5297 %} 5298 ins_pipe(ialu_mem_imm); 5299 %} 5300 5301 // Store Float 5302 instruct storeF(memory mem, regF src) 5303 %{ 5304 match(Set mem (StoreF mem src)); 5305 5306 ins_cost(95); // XXX 5307 format %{ "movss $mem, $src\t# float" %} 5308 ins_encode %{ 5309 __ movflt($mem$$Address, $src$$XMMRegister); 5310 %} 5311 ins_pipe(pipe_slow); // XXX 5312 %} 5313 5314 // Store immediate Float value (it is faster than store from XMM register) 5315 instruct storeF0(memory mem, immF0 zero) 5316 %{ 5317 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5318 match(Set mem (StoreF mem zero)); 5319 5320 ins_cost(25); // XXX 5321 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5322 ins_encode %{ 5323 __ movl($mem$$Address, r12); 5324 %} 5325 ins_pipe(ialu_mem_reg); 5326 %} 5327 5328 instruct storeF_imm(memory mem, immF src) 5329 %{ 5330 match(Set mem (StoreF mem src)); 5331 5332 ins_cost(50); 5333 format %{ "movl $mem, $src\t# float" %} 5334 ins_encode %{ 5335 __ movl($mem$$Address, jint_cast($src$$constant)); 5336 %} 5337 ins_pipe(ialu_mem_imm); 5338 %} 5339 5340 // Store Double 5341 instruct storeD(memory mem, regD src) 5342 %{ 5343 match(Set mem (StoreD mem src)); 5344 5345 ins_cost(95); // XXX 5346 format %{ "movsd $mem, $src\t# double" %} 5347 ins_encode %{ 5348 __ movdbl($mem$$Address, $src$$XMMRegister); 5349 %} 5350 ins_pipe(pipe_slow); // XXX 5351 %} 5352 5353 // Store immediate double 0.0 (it is faster than store from XMM register) 5354 instruct storeD0_imm(memory mem, immD0 src) 5355 %{ 5356 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5357 match(Set mem (StoreD mem src)); 5358 5359 ins_cost(50); 5360 format %{ "movq $mem, $src\t# double 0." %} 5361 ins_encode %{ 5362 __ movq($mem$$Address, $src$$constant); 5363 %} 5364 ins_pipe(ialu_mem_imm); 5365 %} 5366 5367 instruct storeD0(memory mem, immD0 zero) 5368 %{ 5369 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5370 match(Set mem (StoreD mem zero)); 5371 5372 ins_cost(25); // XXX 5373 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5374 ins_encode %{ 5375 __ movq($mem$$Address, r12); 5376 %} 5377 ins_pipe(ialu_mem_reg); 5378 %} 5379 5380 instruct storeSSI(stackSlotI dst, rRegI src) 5381 %{ 5382 match(Set dst src); 5383 5384 ins_cost(100); 5385 format %{ "movl $dst, $src\t# int stk" %} 5386 ins_encode %{ 5387 __ movl($dst$$Address, $src$$Register); 5388 %} 5389 ins_pipe( ialu_mem_reg ); 5390 %} 5391 5392 instruct storeSSL(stackSlotL dst, rRegL src) 5393 %{ 5394 match(Set dst src); 5395 5396 ins_cost(100); 5397 format %{ "movq $dst, $src\t# long stk" %} 5398 ins_encode %{ 5399 __ movq($dst$$Address, $src$$Register); 5400 %} 5401 ins_pipe(ialu_mem_reg); 5402 %} 5403 5404 instruct storeSSP(stackSlotP dst, rRegP src) 5405 %{ 5406 match(Set dst src); 5407 5408 ins_cost(100); 5409 format %{ "movq $dst, $src\t# ptr stk" %} 5410 ins_encode %{ 5411 __ movq($dst$$Address, $src$$Register); 5412 %} 5413 ins_pipe(ialu_mem_reg); 5414 %} 5415 5416 instruct storeSSF(stackSlotF dst, regF src) 5417 %{ 5418 match(Set dst src); 5419 5420 ins_cost(95); // XXX 5421 format %{ "movss $dst, $src\t# float stk" %} 5422 ins_encode %{ 5423 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5424 %} 5425 ins_pipe(pipe_slow); // XXX 5426 %} 5427 5428 instruct storeSSD(stackSlotD dst, regD src) 5429 %{ 5430 match(Set dst src); 5431 5432 ins_cost(95); // XXX 5433 format %{ "movsd $dst, $src\t# double stk" %} 5434 ins_encode %{ 5435 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5436 %} 5437 ins_pipe(pipe_slow); // XXX 5438 %} 5439 5440 instruct cacheWB(indirect addr) 5441 %{ 5442 predicate(VM_Version::supports_data_cache_line_flush()); 5443 match(CacheWB addr); 5444 5445 ins_cost(100); 5446 format %{"cache wb $addr" %} 5447 ins_encode %{ 5448 assert($addr->index_position() < 0, "should be"); 5449 assert($addr$$disp == 0, "should be"); 5450 __ cache_wb(Address($addr$$base$$Register, 0)); 5451 %} 5452 ins_pipe(pipe_slow); // XXX 5453 %} 5454 5455 instruct cacheWBPreSync() 5456 %{ 5457 predicate(VM_Version::supports_data_cache_line_flush()); 5458 match(CacheWBPreSync); 5459 5460 ins_cost(100); 5461 format %{"cache wb presync" %} 5462 ins_encode %{ 5463 __ cache_wbsync(true); 5464 %} 5465 ins_pipe(pipe_slow); // XXX 5466 %} 5467 5468 instruct cacheWBPostSync() 5469 %{ 5470 predicate(VM_Version::supports_data_cache_line_flush()); 5471 match(CacheWBPostSync); 5472 5473 ins_cost(100); 5474 format %{"cache wb postsync" %} 5475 ins_encode %{ 5476 __ cache_wbsync(false); 5477 %} 5478 ins_pipe(pipe_slow); // XXX 5479 %} 5480 5481 //----------BSWAP Instructions------------------------------------------------- 5482 instruct bytes_reverse_int(rRegI dst) %{ 5483 match(Set dst (ReverseBytesI dst)); 5484 5485 format %{ "bswapl $dst" %} 5486 ins_encode %{ 5487 __ bswapl($dst$$Register); 5488 %} 5489 ins_pipe( ialu_reg ); 5490 %} 5491 5492 instruct bytes_reverse_long(rRegL dst) %{ 5493 match(Set dst (ReverseBytesL dst)); 5494 5495 format %{ "bswapq $dst" %} 5496 ins_encode %{ 5497 __ bswapq($dst$$Register); 5498 %} 5499 ins_pipe( ialu_reg); 5500 %} 5501 5502 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5503 match(Set dst (ReverseBytesUS dst)); 5504 effect(KILL cr); 5505 5506 format %{ "bswapl $dst\n\t" 5507 "shrl $dst,16\n\t" %} 5508 ins_encode %{ 5509 __ bswapl($dst$$Register); 5510 __ shrl($dst$$Register, 16); 5511 %} 5512 ins_pipe( ialu_reg ); 5513 %} 5514 5515 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5516 match(Set dst (ReverseBytesS dst)); 5517 effect(KILL cr); 5518 5519 format %{ "bswapl $dst\n\t" 5520 "sar $dst,16\n\t" %} 5521 ins_encode %{ 5522 __ bswapl($dst$$Register); 5523 __ sarl($dst$$Register, 16); 5524 %} 5525 ins_pipe( ialu_reg ); 5526 %} 5527 5528 //---------- Zeros Count Instructions ------------------------------------------ 5529 5530 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5531 predicate(UseCountLeadingZerosInstruction); 5532 match(Set dst (CountLeadingZerosI src)); 5533 effect(KILL cr); 5534 5535 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5536 ins_encode %{ 5537 __ lzcntl($dst$$Register, $src$$Register); 5538 %} 5539 ins_pipe(ialu_reg); 5540 %} 5541 5542 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5543 predicate(UseCountLeadingZerosInstruction); 5544 match(Set dst (CountLeadingZerosI (LoadI src))); 5545 effect(KILL cr); 5546 ins_cost(175); 5547 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5548 ins_encode %{ 5549 __ lzcntl($dst$$Register, $src$$Address); 5550 %} 5551 ins_pipe(ialu_reg_mem); 5552 %} 5553 5554 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5555 predicate(!UseCountLeadingZerosInstruction); 5556 match(Set dst (CountLeadingZerosI src)); 5557 effect(KILL cr); 5558 5559 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5560 "jnz skip\n\t" 5561 "movl $dst, -1\n" 5562 "skip:\n\t" 5563 "negl $dst\n\t" 5564 "addl $dst, 31" %} 5565 ins_encode %{ 5566 Register Rdst = $dst$$Register; 5567 Register Rsrc = $src$$Register; 5568 Label skip; 5569 __ bsrl(Rdst, Rsrc); 5570 __ jccb(Assembler::notZero, skip); 5571 __ movl(Rdst, -1); 5572 __ bind(skip); 5573 __ negl(Rdst); 5574 __ addl(Rdst, BitsPerInt - 1); 5575 %} 5576 ins_pipe(ialu_reg); 5577 %} 5578 5579 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5580 predicate(UseCountLeadingZerosInstruction); 5581 match(Set dst (CountLeadingZerosL src)); 5582 effect(KILL cr); 5583 5584 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5585 ins_encode %{ 5586 __ lzcntq($dst$$Register, $src$$Register); 5587 %} 5588 ins_pipe(ialu_reg); 5589 %} 5590 5591 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5592 predicate(UseCountLeadingZerosInstruction); 5593 match(Set dst (CountLeadingZerosL (LoadL src))); 5594 effect(KILL cr); 5595 ins_cost(175); 5596 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5597 ins_encode %{ 5598 __ lzcntq($dst$$Register, $src$$Address); 5599 %} 5600 ins_pipe(ialu_reg_mem); 5601 %} 5602 5603 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5604 predicate(!UseCountLeadingZerosInstruction); 5605 match(Set dst (CountLeadingZerosL src)); 5606 effect(KILL cr); 5607 5608 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5609 "jnz skip\n\t" 5610 "movl $dst, -1\n" 5611 "skip:\n\t" 5612 "negl $dst\n\t" 5613 "addl $dst, 63" %} 5614 ins_encode %{ 5615 Register Rdst = $dst$$Register; 5616 Register Rsrc = $src$$Register; 5617 Label skip; 5618 __ bsrq(Rdst, Rsrc); 5619 __ jccb(Assembler::notZero, skip); 5620 __ movl(Rdst, -1); 5621 __ bind(skip); 5622 __ negl(Rdst); 5623 __ addl(Rdst, BitsPerLong - 1); 5624 %} 5625 ins_pipe(ialu_reg); 5626 %} 5627 5628 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5629 predicate(UseCountTrailingZerosInstruction); 5630 match(Set dst (CountTrailingZerosI src)); 5631 effect(KILL cr); 5632 5633 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5634 ins_encode %{ 5635 __ tzcntl($dst$$Register, $src$$Register); 5636 %} 5637 ins_pipe(ialu_reg); 5638 %} 5639 5640 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5641 predicate(UseCountTrailingZerosInstruction); 5642 match(Set dst (CountTrailingZerosI (LoadI src))); 5643 effect(KILL cr); 5644 ins_cost(175); 5645 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5646 ins_encode %{ 5647 __ tzcntl($dst$$Register, $src$$Address); 5648 %} 5649 ins_pipe(ialu_reg_mem); 5650 %} 5651 5652 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5653 predicate(!UseCountTrailingZerosInstruction); 5654 match(Set dst (CountTrailingZerosI src)); 5655 effect(KILL cr); 5656 5657 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5658 "jnz done\n\t" 5659 "movl $dst, 32\n" 5660 "done:" %} 5661 ins_encode %{ 5662 Register Rdst = $dst$$Register; 5663 Label done; 5664 __ bsfl(Rdst, $src$$Register); 5665 __ jccb(Assembler::notZero, done); 5666 __ movl(Rdst, BitsPerInt); 5667 __ bind(done); 5668 %} 5669 ins_pipe(ialu_reg); 5670 %} 5671 5672 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5673 predicate(UseCountTrailingZerosInstruction); 5674 match(Set dst (CountTrailingZerosL src)); 5675 effect(KILL cr); 5676 5677 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5678 ins_encode %{ 5679 __ tzcntq($dst$$Register, $src$$Register); 5680 %} 5681 ins_pipe(ialu_reg); 5682 %} 5683 5684 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5685 predicate(UseCountTrailingZerosInstruction); 5686 match(Set dst (CountTrailingZerosL (LoadL src))); 5687 effect(KILL cr); 5688 ins_cost(175); 5689 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5690 ins_encode %{ 5691 __ tzcntq($dst$$Register, $src$$Address); 5692 %} 5693 ins_pipe(ialu_reg_mem); 5694 %} 5695 5696 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5697 predicate(!UseCountTrailingZerosInstruction); 5698 match(Set dst (CountTrailingZerosL src)); 5699 effect(KILL cr); 5700 5701 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5702 "jnz done\n\t" 5703 "movl $dst, 64\n" 5704 "done:" %} 5705 ins_encode %{ 5706 Register Rdst = $dst$$Register; 5707 Label done; 5708 __ bsfq(Rdst, $src$$Register); 5709 __ jccb(Assembler::notZero, done); 5710 __ movl(Rdst, BitsPerLong); 5711 __ bind(done); 5712 %} 5713 ins_pipe(ialu_reg); 5714 %} 5715 5716 //--------------- Reverse Operation Instructions ---------------- 5717 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5718 predicate(!VM_Version::supports_gfni()); 5719 match(Set dst (ReverseI src)); 5720 effect(TEMP dst, TEMP rtmp, KILL cr); 5721 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5722 ins_encode %{ 5723 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5724 %} 5725 ins_pipe( ialu_reg ); 5726 %} 5727 5728 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5729 predicate(VM_Version::supports_gfni()); 5730 match(Set dst (ReverseI src)); 5731 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5732 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5733 ins_encode %{ 5734 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5735 %} 5736 ins_pipe( ialu_reg ); 5737 %} 5738 5739 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5740 predicate(!VM_Version::supports_gfni()); 5741 match(Set dst (ReverseL src)); 5742 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5743 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5744 ins_encode %{ 5745 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5746 %} 5747 ins_pipe( ialu_reg ); 5748 %} 5749 5750 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5751 predicate(VM_Version::supports_gfni()); 5752 match(Set dst (ReverseL src)); 5753 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5754 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5755 ins_encode %{ 5756 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5757 %} 5758 ins_pipe( ialu_reg ); 5759 %} 5760 5761 //---------- Population Count Instructions ------------------------------------- 5762 5763 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5764 predicate(UsePopCountInstruction); 5765 match(Set dst (PopCountI src)); 5766 effect(KILL cr); 5767 5768 format %{ "popcnt $dst, $src" %} 5769 ins_encode %{ 5770 __ popcntl($dst$$Register, $src$$Register); 5771 %} 5772 ins_pipe(ialu_reg); 5773 %} 5774 5775 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5776 predicate(UsePopCountInstruction); 5777 match(Set dst (PopCountI (LoadI mem))); 5778 effect(KILL cr); 5779 5780 format %{ "popcnt $dst, $mem" %} 5781 ins_encode %{ 5782 __ popcntl($dst$$Register, $mem$$Address); 5783 %} 5784 ins_pipe(ialu_reg); 5785 %} 5786 5787 // Note: Long.bitCount(long) returns an int. 5788 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5789 predicate(UsePopCountInstruction); 5790 match(Set dst (PopCountL src)); 5791 effect(KILL cr); 5792 5793 format %{ "popcnt $dst, $src" %} 5794 ins_encode %{ 5795 __ popcntq($dst$$Register, $src$$Register); 5796 %} 5797 ins_pipe(ialu_reg); 5798 %} 5799 5800 // Note: Long.bitCount(long) returns an int. 5801 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5802 predicate(UsePopCountInstruction); 5803 match(Set dst (PopCountL (LoadL mem))); 5804 effect(KILL cr); 5805 5806 format %{ "popcnt $dst, $mem" %} 5807 ins_encode %{ 5808 __ popcntq($dst$$Register, $mem$$Address); 5809 %} 5810 ins_pipe(ialu_reg); 5811 %} 5812 5813 5814 //----------MemBar Instructions----------------------------------------------- 5815 // Memory barrier flavors 5816 5817 instruct membar_acquire() 5818 %{ 5819 match(MemBarAcquire); 5820 match(LoadFence); 5821 ins_cost(0); 5822 5823 size(0); 5824 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5825 ins_encode(); 5826 ins_pipe(empty); 5827 %} 5828 5829 instruct membar_acquire_lock() 5830 %{ 5831 match(MemBarAcquireLock); 5832 ins_cost(0); 5833 5834 size(0); 5835 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5836 ins_encode(); 5837 ins_pipe(empty); 5838 %} 5839 5840 instruct membar_release() 5841 %{ 5842 match(MemBarRelease); 5843 match(StoreFence); 5844 ins_cost(0); 5845 5846 size(0); 5847 format %{ "MEMBAR-release ! (empty encoding)" %} 5848 ins_encode(); 5849 ins_pipe(empty); 5850 %} 5851 5852 instruct membar_release_lock() 5853 %{ 5854 match(MemBarReleaseLock); 5855 ins_cost(0); 5856 5857 size(0); 5858 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5859 ins_encode(); 5860 ins_pipe(empty); 5861 %} 5862 5863 instruct membar_volatile(rFlagsReg cr) %{ 5864 match(MemBarVolatile); 5865 effect(KILL cr); 5866 ins_cost(400); 5867 5868 format %{ 5869 $$template 5870 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5871 %} 5872 ins_encode %{ 5873 __ membar(Assembler::StoreLoad); 5874 %} 5875 ins_pipe(pipe_slow); 5876 %} 5877 5878 instruct unnecessary_membar_volatile() 5879 %{ 5880 match(MemBarVolatile); 5881 predicate(Matcher::post_store_load_barrier(n)); 5882 ins_cost(0); 5883 5884 size(0); 5885 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5886 ins_encode(); 5887 ins_pipe(empty); 5888 %} 5889 5890 instruct membar_storestore() %{ 5891 match(MemBarStoreStore); 5892 match(StoreStoreFence); 5893 ins_cost(0); 5894 5895 size(0); 5896 format %{ "MEMBAR-storestore (empty encoding)" %} 5897 ins_encode( ); 5898 ins_pipe(empty); 5899 %} 5900 5901 //----------Move Instructions-------------------------------------------------- 5902 5903 instruct castX2P(rRegP dst, rRegL src) 5904 %{ 5905 match(Set dst (CastX2P src)); 5906 5907 format %{ "movq $dst, $src\t# long->ptr" %} 5908 ins_encode %{ 5909 if ($dst$$reg != $src$$reg) { 5910 __ movptr($dst$$Register, $src$$Register); 5911 } 5912 %} 5913 ins_pipe(ialu_reg_reg); // XXX 5914 %} 5915 5916 instruct castP2X(rRegL dst, rRegP src) 5917 %{ 5918 match(Set dst (CastP2X src)); 5919 5920 format %{ "movq $dst, $src\t# ptr -> long" %} 5921 ins_encode %{ 5922 if ($dst$$reg != $src$$reg) { 5923 __ movptr($dst$$Register, $src$$Register); 5924 } 5925 %} 5926 ins_pipe(ialu_reg_reg); // XXX 5927 %} 5928 5929 // Convert oop into int for vectors alignment masking 5930 instruct convP2I(rRegI dst, rRegP src) 5931 %{ 5932 match(Set dst (ConvL2I (CastP2X src))); 5933 5934 format %{ "movl $dst, $src\t# ptr -> int" %} 5935 ins_encode %{ 5936 __ movl($dst$$Register, $src$$Register); 5937 %} 5938 ins_pipe(ialu_reg_reg); // XXX 5939 %} 5940 5941 // Convert compressed oop into int for vectors alignment masking 5942 // in case of 32bit oops (heap < 4Gb). 5943 instruct convN2I(rRegI dst, rRegN src) 5944 %{ 5945 predicate(CompressedOops::shift() == 0); 5946 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5947 5948 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5949 ins_encode %{ 5950 __ movl($dst$$Register, $src$$Register); 5951 %} 5952 ins_pipe(ialu_reg_reg); // XXX 5953 %} 5954 5955 // Convert oop pointer into compressed form 5956 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5957 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5958 match(Set dst (EncodeP src)); 5959 effect(KILL cr); 5960 format %{ "encode_heap_oop $dst,$src" %} 5961 ins_encode %{ 5962 Register s = $src$$Register; 5963 Register d = $dst$$Register; 5964 if (s != d) { 5965 __ movq(d, s); 5966 } 5967 __ encode_heap_oop(d); 5968 %} 5969 ins_pipe(ialu_reg_long); 5970 %} 5971 5972 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5973 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 5974 match(Set dst (EncodeP src)); 5975 effect(KILL cr); 5976 format %{ "encode_heap_oop_not_null $dst,$src" %} 5977 ins_encode %{ 5978 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 5979 %} 5980 ins_pipe(ialu_reg_long); 5981 %} 5982 5983 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 5984 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 5985 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 5986 match(Set dst (DecodeN src)); 5987 effect(KILL cr); 5988 format %{ "decode_heap_oop $dst,$src" %} 5989 ins_encode %{ 5990 Register s = $src$$Register; 5991 Register d = $dst$$Register; 5992 if (s != d) { 5993 __ movq(d, s); 5994 } 5995 __ decode_heap_oop(d); 5996 %} 5997 ins_pipe(ialu_reg_long); 5998 %} 5999 6000 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6001 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6002 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6003 match(Set dst (DecodeN src)); 6004 effect(KILL cr); 6005 format %{ "decode_heap_oop_not_null $dst,$src" %} 6006 ins_encode %{ 6007 Register s = $src$$Register; 6008 Register d = $dst$$Register; 6009 if (s != d) { 6010 __ decode_heap_oop_not_null(d, s); 6011 } else { 6012 __ decode_heap_oop_not_null(d); 6013 } 6014 %} 6015 ins_pipe(ialu_reg_long); 6016 %} 6017 6018 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6019 match(Set dst (EncodePKlass src)); 6020 effect(TEMP dst, KILL cr); 6021 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6022 ins_encode %{ 6023 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6024 %} 6025 ins_pipe(ialu_reg_long); 6026 %} 6027 6028 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6029 match(Set dst (DecodeNKlass src)); 6030 effect(TEMP dst, KILL cr); 6031 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6032 ins_encode %{ 6033 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6034 %} 6035 ins_pipe(ialu_reg_long); 6036 %} 6037 6038 //----------Conditional Move--------------------------------------------------- 6039 // Jump 6040 // dummy instruction for generating temp registers 6041 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6042 match(Jump (LShiftL switch_val shift)); 6043 ins_cost(350); 6044 predicate(false); 6045 effect(TEMP dest); 6046 6047 format %{ "leaq $dest, [$constantaddress]\n\t" 6048 "jmp [$dest + $switch_val << $shift]\n\t" %} 6049 ins_encode %{ 6050 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6051 // to do that and the compiler is using that register as one it can allocate. 6052 // So we build it all by hand. 6053 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6054 // ArrayAddress dispatch(table, index); 6055 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6056 __ lea($dest$$Register, $constantaddress); 6057 __ jmp(dispatch); 6058 %} 6059 ins_pipe(pipe_jmp); 6060 %} 6061 6062 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6063 match(Jump (AddL (LShiftL switch_val shift) offset)); 6064 ins_cost(350); 6065 effect(TEMP dest); 6066 6067 format %{ "leaq $dest, [$constantaddress]\n\t" 6068 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6069 ins_encode %{ 6070 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6071 // to do that and the compiler is using that register as one it can allocate. 6072 // So we build it all by hand. 6073 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6074 // ArrayAddress dispatch(table, index); 6075 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6076 __ lea($dest$$Register, $constantaddress); 6077 __ jmp(dispatch); 6078 %} 6079 ins_pipe(pipe_jmp); 6080 %} 6081 6082 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6083 match(Jump switch_val); 6084 ins_cost(350); 6085 effect(TEMP dest); 6086 6087 format %{ "leaq $dest, [$constantaddress]\n\t" 6088 "jmp [$dest + $switch_val]\n\t" %} 6089 ins_encode %{ 6090 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6091 // to do that and the compiler is using that register as one it can allocate. 6092 // So we build it all by hand. 6093 // Address index(noreg, switch_reg, Address::times_1); 6094 // ArrayAddress dispatch(table, index); 6095 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6096 __ lea($dest$$Register, $constantaddress); 6097 __ jmp(dispatch); 6098 %} 6099 ins_pipe(pipe_jmp); 6100 %} 6101 6102 // Conditional move 6103 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6104 %{ 6105 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6106 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6107 6108 ins_cost(100); // XXX 6109 format %{ "setbn$cop $dst\t# signed, int" %} 6110 ins_encode %{ 6111 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6112 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6113 %} 6114 ins_pipe(ialu_reg); 6115 %} 6116 6117 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6118 %{ 6119 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6120 6121 ins_cost(200); // XXX 6122 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6123 ins_encode %{ 6124 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6125 %} 6126 ins_pipe(pipe_cmov_reg); 6127 %} 6128 6129 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6130 %{ 6131 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6132 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6133 6134 ins_cost(100); // XXX 6135 format %{ "setbn$cop $dst\t# unsigned, int" %} 6136 ins_encode %{ 6137 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6138 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6139 %} 6140 ins_pipe(ialu_reg); 6141 %} 6142 6143 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6144 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6145 6146 ins_cost(200); // XXX 6147 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6148 ins_encode %{ 6149 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6150 %} 6151 ins_pipe(pipe_cmov_reg); 6152 %} 6153 6154 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6155 %{ 6156 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6157 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6158 6159 ins_cost(100); // XXX 6160 format %{ "setbn$cop $dst\t# unsigned, int" %} 6161 ins_encode %{ 6162 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6163 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6164 %} 6165 ins_pipe(ialu_reg); 6166 %} 6167 6168 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6169 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6170 ins_cost(200); 6171 expand %{ 6172 cmovI_regU(cop, cr, dst, src); 6173 %} 6174 %} 6175 6176 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6177 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6178 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6179 6180 ins_cost(200); // XXX 6181 format %{ "cmovpl $dst, $src\n\t" 6182 "cmovnel $dst, $src" %} 6183 ins_encode %{ 6184 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6185 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6186 %} 6187 ins_pipe(pipe_cmov_reg); 6188 %} 6189 6190 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6191 // inputs of the CMove 6192 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6193 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6194 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6195 6196 ins_cost(200); // XXX 6197 format %{ "cmovpl $dst, $src\n\t" 6198 "cmovnel $dst, $src" %} 6199 ins_encode %{ 6200 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6201 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6202 %} 6203 ins_pipe(pipe_cmov_reg); 6204 %} 6205 6206 // Conditional move 6207 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6208 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6209 6210 ins_cost(250); // XXX 6211 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6212 ins_encode %{ 6213 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6214 %} 6215 ins_pipe(pipe_cmov_mem); 6216 %} 6217 6218 // Conditional move 6219 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6220 %{ 6221 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6222 6223 ins_cost(250); // XXX 6224 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6225 ins_encode %{ 6226 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6227 %} 6228 ins_pipe(pipe_cmov_mem); 6229 %} 6230 6231 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6232 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6233 ins_cost(250); 6234 expand %{ 6235 cmovI_memU(cop, cr, dst, src); 6236 %} 6237 %} 6238 6239 // Conditional move 6240 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6241 %{ 6242 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6243 6244 ins_cost(200); // XXX 6245 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6246 ins_encode %{ 6247 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6248 %} 6249 ins_pipe(pipe_cmov_reg); 6250 %} 6251 6252 // Conditional move 6253 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6254 %{ 6255 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6256 6257 ins_cost(200); // XXX 6258 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6259 ins_encode %{ 6260 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6261 %} 6262 ins_pipe(pipe_cmov_reg); 6263 %} 6264 6265 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6266 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6267 ins_cost(200); 6268 expand %{ 6269 cmovN_regU(cop, cr, dst, src); 6270 %} 6271 %} 6272 6273 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6274 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6275 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6276 6277 ins_cost(200); // XXX 6278 format %{ "cmovpl $dst, $src\n\t" 6279 "cmovnel $dst, $src" %} 6280 ins_encode %{ 6281 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6282 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6283 %} 6284 ins_pipe(pipe_cmov_reg); 6285 %} 6286 6287 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6288 // inputs of the CMove 6289 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6290 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6291 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6292 6293 ins_cost(200); // XXX 6294 format %{ "cmovpl $dst, $src\n\t" 6295 "cmovnel $dst, $src" %} 6296 ins_encode %{ 6297 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6298 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6299 %} 6300 ins_pipe(pipe_cmov_reg); 6301 %} 6302 6303 // Conditional move 6304 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6305 %{ 6306 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6307 6308 ins_cost(200); // XXX 6309 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6310 ins_encode %{ 6311 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6312 %} 6313 ins_pipe(pipe_cmov_reg); // XXX 6314 %} 6315 6316 // Conditional move 6317 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6318 %{ 6319 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6320 6321 ins_cost(200); // XXX 6322 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6323 ins_encode %{ 6324 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6325 %} 6326 ins_pipe(pipe_cmov_reg); // XXX 6327 %} 6328 6329 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6330 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6331 ins_cost(200); 6332 expand %{ 6333 cmovP_regU(cop, cr, dst, src); 6334 %} 6335 %} 6336 6337 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6338 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6339 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6340 6341 ins_cost(200); // XXX 6342 format %{ "cmovpq $dst, $src\n\t" 6343 "cmovneq $dst, $src" %} 6344 ins_encode %{ 6345 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6346 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6347 %} 6348 ins_pipe(pipe_cmov_reg); 6349 %} 6350 6351 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6352 // inputs of the CMove 6353 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6354 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6355 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6356 6357 ins_cost(200); // XXX 6358 format %{ "cmovpq $dst, $src\n\t" 6359 "cmovneq $dst, $src" %} 6360 ins_encode %{ 6361 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6362 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6363 %} 6364 ins_pipe(pipe_cmov_reg); 6365 %} 6366 6367 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6368 %{ 6369 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6370 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6371 6372 ins_cost(100); // XXX 6373 format %{ "setbn$cop $dst\t# signed, long" %} 6374 ins_encode %{ 6375 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6376 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6377 %} 6378 ins_pipe(ialu_reg); 6379 %} 6380 6381 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6382 %{ 6383 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6384 6385 ins_cost(200); // XXX 6386 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6387 ins_encode %{ 6388 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6389 %} 6390 ins_pipe(pipe_cmov_reg); // XXX 6391 %} 6392 6393 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6394 %{ 6395 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6396 6397 ins_cost(200); // XXX 6398 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6399 ins_encode %{ 6400 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6401 %} 6402 ins_pipe(pipe_cmov_mem); // XXX 6403 %} 6404 6405 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6406 %{ 6407 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6408 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6409 6410 ins_cost(100); // XXX 6411 format %{ "setbn$cop $dst\t# unsigned, long" %} 6412 ins_encode %{ 6413 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6414 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6415 %} 6416 ins_pipe(ialu_reg); 6417 %} 6418 6419 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6420 %{ 6421 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6422 6423 ins_cost(200); // XXX 6424 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6425 ins_encode %{ 6426 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6427 %} 6428 ins_pipe(pipe_cmov_reg); // XXX 6429 %} 6430 6431 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6432 %{ 6433 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6434 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6435 6436 ins_cost(100); // XXX 6437 format %{ "setbn$cop $dst\t# unsigned, long" %} 6438 ins_encode %{ 6439 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6440 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6441 %} 6442 ins_pipe(ialu_reg); 6443 %} 6444 6445 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6446 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6447 ins_cost(200); 6448 expand %{ 6449 cmovL_regU(cop, cr, dst, src); 6450 %} 6451 %} 6452 6453 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6454 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6455 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6456 6457 ins_cost(200); // XXX 6458 format %{ "cmovpq $dst, $src\n\t" 6459 "cmovneq $dst, $src" %} 6460 ins_encode %{ 6461 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6462 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6463 %} 6464 ins_pipe(pipe_cmov_reg); 6465 %} 6466 6467 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6468 // inputs of the CMove 6469 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6470 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6471 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6472 6473 ins_cost(200); // XXX 6474 format %{ "cmovpq $dst, $src\n\t" 6475 "cmovneq $dst, $src" %} 6476 ins_encode %{ 6477 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6478 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6479 %} 6480 ins_pipe(pipe_cmov_reg); 6481 %} 6482 6483 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6484 %{ 6485 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6486 6487 ins_cost(200); // XXX 6488 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6489 ins_encode %{ 6490 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6491 %} 6492 ins_pipe(pipe_cmov_mem); // XXX 6493 %} 6494 6495 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6496 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6497 ins_cost(200); 6498 expand %{ 6499 cmovL_memU(cop, cr, dst, src); 6500 %} 6501 %} 6502 6503 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6504 %{ 6505 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6506 6507 ins_cost(200); // XXX 6508 format %{ "jn$cop skip\t# signed cmove float\n\t" 6509 "movss $dst, $src\n" 6510 "skip:" %} 6511 ins_encode %{ 6512 Label Lskip; 6513 // Invert sense of branch from sense of CMOV 6514 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6515 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6516 __ bind(Lskip); 6517 %} 6518 ins_pipe(pipe_slow); 6519 %} 6520 6521 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6522 %{ 6523 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6524 6525 ins_cost(200); // XXX 6526 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6527 "movss $dst, $src\n" 6528 "skip:" %} 6529 ins_encode %{ 6530 Label Lskip; 6531 // Invert sense of branch from sense of CMOV 6532 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6533 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6534 __ bind(Lskip); 6535 %} 6536 ins_pipe(pipe_slow); 6537 %} 6538 6539 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6540 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6541 ins_cost(200); 6542 expand %{ 6543 cmovF_regU(cop, cr, dst, src); 6544 %} 6545 %} 6546 6547 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6548 %{ 6549 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6550 6551 ins_cost(200); // XXX 6552 format %{ "jn$cop skip\t# signed cmove double\n\t" 6553 "movsd $dst, $src\n" 6554 "skip:" %} 6555 ins_encode %{ 6556 Label Lskip; 6557 // Invert sense of branch from sense of CMOV 6558 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6559 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6560 __ bind(Lskip); 6561 %} 6562 ins_pipe(pipe_slow); 6563 %} 6564 6565 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6566 %{ 6567 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6568 6569 ins_cost(200); // XXX 6570 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6571 "movsd $dst, $src\n" 6572 "skip:" %} 6573 ins_encode %{ 6574 Label Lskip; 6575 // Invert sense of branch from sense of CMOV 6576 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6577 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6578 __ bind(Lskip); 6579 %} 6580 ins_pipe(pipe_slow); 6581 %} 6582 6583 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6584 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6585 ins_cost(200); 6586 expand %{ 6587 cmovD_regU(cop, cr, dst, src); 6588 %} 6589 %} 6590 6591 //----------Arithmetic Instructions-------------------------------------------- 6592 //----------Addition Instructions---------------------------------------------- 6593 6594 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6595 %{ 6596 match(Set dst (AddI dst src)); 6597 effect(KILL cr); 6598 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6599 format %{ "addl $dst, $src\t# int" %} 6600 ins_encode %{ 6601 __ addl($dst$$Register, $src$$Register); 6602 %} 6603 ins_pipe(ialu_reg_reg); 6604 %} 6605 6606 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6607 %{ 6608 match(Set dst (AddI dst src)); 6609 effect(KILL cr); 6610 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6611 6612 format %{ "addl $dst, $src\t# int" %} 6613 ins_encode %{ 6614 __ addl($dst$$Register, $src$$constant); 6615 %} 6616 ins_pipe( ialu_reg ); 6617 %} 6618 6619 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6620 %{ 6621 match(Set dst (AddI dst (LoadI src))); 6622 effect(KILL cr); 6623 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6624 6625 ins_cost(150); // XXX 6626 format %{ "addl $dst, $src\t# int" %} 6627 ins_encode %{ 6628 __ addl($dst$$Register, $src$$Address); 6629 %} 6630 ins_pipe(ialu_reg_mem); 6631 %} 6632 6633 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6634 %{ 6635 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6636 effect(KILL cr); 6637 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6638 6639 ins_cost(150); // XXX 6640 format %{ "addl $dst, $src\t# int" %} 6641 ins_encode %{ 6642 __ addl($dst$$Address, $src$$Register); 6643 %} 6644 ins_pipe(ialu_mem_reg); 6645 %} 6646 6647 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6648 %{ 6649 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6650 effect(KILL cr); 6651 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6652 6653 6654 ins_cost(125); // XXX 6655 format %{ "addl $dst, $src\t# int" %} 6656 ins_encode %{ 6657 __ addl($dst$$Address, $src$$constant); 6658 %} 6659 ins_pipe(ialu_mem_imm); 6660 %} 6661 6662 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6663 %{ 6664 predicate(UseIncDec); 6665 match(Set dst (AddI dst src)); 6666 effect(KILL cr); 6667 6668 format %{ "incl $dst\t# int" %} 6669 ins_encode %{ 6670 __ incrementl($dst$$Register); 6671 %} 6672 ins_pipe(ialu_reg); 6673 %} 6674 6675 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6676 %{ 6677 predicate(UseIncDec); 6678 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6679 effect(KILL cr); 6680 6681 ins_cost(125); // XXX 6682 format %{ "incl $dst\t# int" %} 6683 ins_encode %{ 6684 __ incrementl($dst$$Address); 6685 %} 6686 ins_pipe(ialu_mem_imm); 6687 %} 6688 6689 // XXX why does that use AddI 6690 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6691 %{ 6692 predicate(UseIncDec); 6693 match(Set dst (AddI dst src)); 6694 effect(KILL cr); 6695 6696 format %{ "decl $dst\t# int" %} 6697 ins_encode %{ 6698 __ decrementl($dst$$Register); 6699 %} 6700 ins_pipe(ialu_reg); 6701 %} 6702 6703 // XXX why does that use AddI 6704 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6705 %{ 6706 predicate(UseIncDec); 6707 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6708 effect(KILL cr); 6709 6710 ins_cost(125); // XXX 6711 format %{ "decl $dst\t# int" %} 6712 ins_encode %{ 6713 __ decrementl($dst$$Address); 6714 %} 6715 ins_pipe(ialu_mem_imm); 6716 %} 6717 6718 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6719 %{ 6720 predicate(VM_Version::supports_fast_2op_lea()); 6721 match(Set dst (AddI (LShiftI index scale) disp)); 6722 6723 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6724 ins_encode %{ 6725 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6726 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6727 %} 6728 ins_pipe(ialu_reg_reg); 6729 %} 6730 6731 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6732 %{ 6733 predicate(VM_Version::supports_fast_3op_lea()); 6734 match(Set dst (AddI (AddI base index) disp)); 6735 6736 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6737 ins_encode %{ 6738 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6739 %} 6740 ins_pipe(ialu_reg_reg); 6741 %} 6742 6743 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6744 %{ 6745 predicate(VM_Version::supports_fast_2op_lea()); 6746 match(Set dst (AddI base (LShiftI index scale))); 6747 6748 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6749 ins_encode %{ 6750 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6751 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6752 %} 6753 ins_pipe(ialu_reg_reg); 6754 %} 6755 6756 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6757 %{ 6758 predicate(VM_Version::supports_fast_3op_lea()); 6759 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6760 6761 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6762 ins_encode %{ 6763 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6764 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6765 %} 6766 ins_pipe(ialu_reg_reg); 6767 %} 6768 6769 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6770 %{ 6771 match(Set dst (AddL dst src)); 6772 effect(KILL cr); 6773 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6774 6775 format %{ "addq $dst, $src\t# long" %} 6776 ins_encode %{ 6777 __ addq($dst$$Register, $src$$Register); 6778 %} 6779 ins_pipe(ialu_reg_reg); 6780 %} 6781 6782 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6783 %{ 6784 match(Set dst (AddL dst src)); 6785 effect(KILL cr); 6786 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6787 6788 format %{ "addq $dst, $src\t# long" %} 6789 ins_encode %{ 6790 __ addq($dst$$Register, $src$$constant); 6791 %} 6792 ins_pipe( ialu_reg ); 6793 %} 6794 6795 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6796 %{ 6797 match(Set dst (AddL dst (LoadL src))); 6798 effect(KILL cr); 6799 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6800 6801 ins_cost(150); // XXX 6802 format %{ "addq $dst, $src\t# long" %} 6803 ins_encode %{ 6804 __ addq($dst$$Register, $src$$Address); 6805 %} 6806 ins_pipe(ialu_reg_mem); 6807 %} 6808 6809 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6810 %{ 6811 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6812 effect(KILL cr); 6813 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6814 6815 ins_cost(150); // XXX 6816 format %{ "addq $dst, $src\t# long" %} 6817 ins_encode %{ 6818 __ addq($dst$$Address, $src$$Register); 6819 %} 6820 ins_pipe(ialu_mem_reg); 6821 %} 6822 6823 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6824 %{ 6825 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6826 effect(KILL cr); 6827 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6828 6829 ins_cost(125); // XXX 6830 format %{ "addq $dst, $src\t# long" %} 6831 ins_encode %{ 6832 __ addq($dst$$Address, $src$$constant); 6833 %} 6834 ins_pipe(ialu_mem_imm); 6835 %} 6836 6837 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6838 %{ 6839 predicate(UseIncDec); 6840 match(Set dst (AddL dst src)); 6841 effect(KILL cr); 6842 6843 format %{ "incq $dst\t# long" %} 6844 ins_encode %{ 6845 __ incrementq($dst$$Register); 6846 %} 6847 ins_pipe(ialu_reg); 6848 %} 6849 6850 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6851 %{ 6852 predicate(UseIncDec); 6853 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6854 effect(KILL cr); 6855 6856 ins_cost(125); // XXX 6857 format %{ "incq $dst\t# long" %} 6858 ins_encode %{ 6859 __ incrementq($dst$$Address); 6860 %} 6861 ins_pipe(ialu_mem_imm); 6862 %} 6863 6864 // XXX why does that use AddL 6865 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6866 %{ 6867 predicate(UseIncDec); 6868 match(Set dst (AddL dst src)); 6869 effect(KILL cr); 6870 6871 format %{ "decq $dst\t# long" %} 6872 ins_encode %{ 6873 __ decrementq($dst$$Register); 6874 %} 6875 ins_pipe(ialu_reg); 6876 %} 6877 6878 // XXX why does that use AddL 6879 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6880 %{ 6881 predicate(UseIncDec); 6882 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6883 effect(KILL cr); 6884 6885 ins_cost(125); // XXX 6886 format %{ "decq $dst\t# long" %} 6887 ins_encode %{ 6888 __ decrementq($dst$$Address); 6889 %} 6890 ins_pipe(ialu_mem_imm); 6891 %} 6892 6893 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6894 %{ 6895 predicate(VM_Version::supports_fast_2op_lea()); 6896 match(Set dst (AddL (LShiftL index scale) disp)); 6897 6898 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6899 ins_encode %{ 6900 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6901 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6902 %} 6903 ins_pipe(ialu_reg_reg); 6904 %} 6905 6906 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6907 %{ 6908 predicate(VM_Version::supports_fast_3op_lea()); 6909 match(Set dst (AddL (AddL base index) disp)); 6910 6911 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6912 ins_encode %{ 6913 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6914 %} 6915 ins_pipe(ialu_reg_reg); 6916 %} 6917 6918 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6919 %{ 6920 predicate(VM_Version::supports_fast_2op_lea()); 6921 match(Set dst (AddL base (LShiftL index scale))); 6922 6923 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6924 ins_encode %{ 6925 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6926 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6927 %} 6928 ins_pipe(ialu_reg_reg); 6929 %} 6930 6931 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6932 %{ 6933 predicate(VM_Version::supports_fast_3op_lea()); 6934 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6935 6936 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6937 ins_encode %{ 6938 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6939 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6940 %} 6941 ins_pipe(ialu_reg_reg); 6942 %} 6943 6944 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6945 %{ 6946 match(Set dst (AddP dst src)); 6947 effect(KILL cr); 6948 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6949 6950 format %{ "addq $dst, $src\t# ptr" %} 6951 ins_encode %{ 6952 __ addq($dst$$Register, $src$$Register); 6953 %} 6954 ins_pipe(ialu_reg_reg); 6955 %} 6956 6957 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6958 %{ 6959 match(Set dst (AddP dst src)); 6960 effect(KILL cr); 6961 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6962 6963 format %{ "addq $dst, $src\t# ptr" %} 6964 ins_encode %{ 6965 __ addq($dst$$Register, $src$$constant); 6966 %} 6967 ins_pipe( ialu_reg ); 6968 %} 6969 6970 // XXX addP mem ops ???? 6971 6972 instruct checkCastPP(rRegP dst) 6973 %{ 6974 match(Set dst (CheckCastPP dst)); 6975 6976 size(0); 6977 format %{ "# checkcastPP of $dst" %} 6978 ins_encode(/* empty encoding */); 6979 ins_pipe(empty); 6980 %} 6981 6982 instruct castPP(rRegP dst) 6983 %{ 6984 match(Set dst (CastPP dst)); 6985 6986 size(0); 6987 format %{ "# castPP of $dst" %} 6988 ins_encode(/* empty encoding */); 6989 ins_pipe(empty); 6990 %} 6991 6992 instruct castII(rRegI dst) 6993 %{ 6994 match(Set dst (CastII dst)); 6995 6996 size(0); 6997 format %{ "# castII of $dst" %} 6998 ins_encode(/* empty encoding */); 6999 ins_cost(0); 7000 ins_pipe(empty); 7001 %} 7002 7003 instruct castLL(rRegL dst) 7004 %{ 7005 match(Set dst (CastLL dst)); 7006 7007 size(0); 7008 format %{ "# castLL of $dst" %} 7009 ins_encode(/* empty encoding */); 7010 ins_cost(0); 7011 ins_pipe(empty); 7012 %} 7013 7014 instruct castFF(regF dst) 7015 %{ 7016 match(Set dst (CastFF dst)); 7017 7018 size(0); 7019 format %{ "# castFF of $dst" %} 7020 ins_encode(/* empty encoding */); 7021 ins_cost(0); 7022 ins_pipe(empty); 7023 %} 7024 7025 instruct castDD(regD dst) 7026 %{ 7027 match(Set dst (CastDD dst)); 7028 7029 size(0); 7030 format %{ "# castDD of $dst" %} 7031 ins_encode(/* empty encoding */); 7032 ins_cost(0); 7033 ins_pipe(empty); 7034 %} 7035 7036 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7037 instruct compareAndSwapP(rRegI res, 7038 memory mem_ptr, 7039 rax_RegP oldval, rRegP newval, 7040 rFlagsReg cr) 7041 %{ 7042 predicate(n->as_LoadStore()->barrier_data() == 0); 7043 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7044 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7045 effect(KILL cr, KILL oldval); 7046 7047 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7048 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7049 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7050 ins_encode %{ 7051 __ lock(); 7052 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7053 __ setcc(Assembler::equal, $res$$Register); 7054 %} 7055 ins_pipe( pipe_cmpxchg ); 7056 %} 7057 7058 instruct compareAndSwapL(rRegI res, 7059 memory mem_ptr, 7060 rax_RegL oldval, rRegL newval, 7061 rFlagsReg cr) 7062 %{ 7063 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7064 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7065 effect(KILL cr, KILL oldval); 7066 7067 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7068 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7069 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7070 ins_encode %{ 7071 __ lock(); 7072 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7073 __ setcc(Assembler::equal, $res$$Register); 7074 %} 7075 ins_pipe( pipe_cmpxchg ); 7076 %} 7077 7078 instruct compareAndSwapI(rRegI res, 7079 memory mem_ptr, 7080 rax_RegI oldval, rRegI newval, 7081 rFlagsReg cr) 7082 %{ 7083 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7084 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7085 effect(KILL cr, KILL oldval); 7086 7087 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7088 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7089 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7090 ins_encode %{ 7091 __ lock(); 7092 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7093 __ setcc(Assembler::equal, $res$$Register); 7094 %} 7095 ins_pipe( pipe_cmpxchg ); 7096 %} 7097 7098 instruct compareAndSwapB(rRegI res, 7099 memory mem_ptr, 7100 rax_RegI oldval, rRegI newval, 7101 rFlagsReg cr) 7102 %{ 7103 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7104 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7105 effect(KILL cr, KILL oldval); 7106 7107 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7108 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7109 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7110 ins_encode %{ 7111 __ lock(); 7112 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7113 __ setcc(Assembler::equal, $res$$Register); 7114 %} 7115 ins_pipe( pipe_cmpxchg ); 7116 %} 7117 7118 instruct compareAndSwapS(rRegI res, 7119 memory mem_ptr, 7120 rax_RegI oldval, rRegI newval, 7121 rFlagsReg cr) 7122 %{ 7123 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7124 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7125 effect(KILL cr, KILL oldval); 7126 7127 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7128 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7129 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7130 ins_encode %{ 7131 __ lock(); 7132 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7133 __ setcc(Assembler::equal, $res$$Register); 7134 %} 7135 ins_pipe( pipe_cmpxchg ); 7136 %} 7137 7138 instruct compareAndSwapN(rRegI res, 7139 memory mem_ptr, 7140 rax_RegN oldval, rRegN newval, 7141 rFlagsReg cr) %{ 7142 predicate(n->as_LoadStore()->barrier_data() == 0); 7143 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7144 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7145 effect(KILL cr, KILL oldval); 7146 7147 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7148 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7149 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7150 ins_encode %{ 7151 __ lock(); 7152 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7153 __ setcc(Assembler::equal, $res$$Register); 7154 %} 7155 ins_pipe( pipe_cmpxchg ); 7156 %} 7157 7158 instruct compareAndExchangeB( 7159 memory mem_ptr, 7160 rax_RegI oldval, rRegI newval, 7161 rFlagsReg cr) 7162 %{ 7163 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7164 effect(KILL cr); 7165 7166 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7167 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7168 ins_encode %{ 7169 __ lock(); 7170 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7171 %} 7172 ins_pipe( pipe_cmpxchg ); 7173 %} 7174 7175 instruct compareAndExchangeS( 7176 memory mem_ptr, 7177 rax_RegI oldval, rRegI newval, 7178 rFlagsReg cr) 7179 %{ 7180 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7181 effect(KILL cr); 7182 7183 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7184 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7185 ins_encode %{ 7186 __ lock(); 7187 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7188 %} 7189 ins_pipe( pipe_cmpxchg ); 7190 %} 7191 7192 instruct compareAndExchangeI( 7193 memory mem_ptr, 7194 rax_RegI oldval, rRegI newval, 7195 rFlagsReg cr) 7196 %{ 7197 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7198 effect(KILL cr); 7199 7200 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7201 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7202 ins_encode %{ 7203 __ lock(); 7204 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7205 %} 7206 ins_pipe( pipe_cmpxchg ); 7207 %} 7208 7209 instruct compareAndExchangeL( 7210 memory mem_ptr, 7211 rax_RegL oldval, rRegL newval, 7212 rFlagsReg cr) 7213 %{ 7214 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7215 effect(KILL cr); 7216 7217 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7218 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7219 ins_encode %{ 7220 __ lock(); 7221 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7222 %} 7223 ins_pipe( pipe_cmpxchg ); 7224 %} 7225 7226 instruct compareAndExchangeN( 7227 memory mem_ptr, 7228 rax_RegN oldval, rRegN newval, 7229 rFlagsReg cr) %{ 7230 predicate(n->as_LoadStore()->barrier_data() == 0); 7231 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7232 effect(KILL cr); 7233 7234 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7235 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7236 ins_encode %{ 7237 __ lock(); 7238 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7239 %} 7240 ins_pipe( pipe_cmpxchg ); 7241 %} 7242 7243 instruct compareAndExchangeP( 7244 memory mem_ptr, 7245 rax_RegP oldval, rRegP newval, 7246 rFlagsReg cr) 7247 %{ 7248 predicate(n->as_LoadStore()->barrier_data() == 0); 7249 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7250 effect(KILL cr); 7251 7252 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7253 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7254 ins_encode %{ 7255 __ lock(); 7256 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7257 %} 7258 ins_pipe( pipe_cmpxchg ); 7259 %} 7260 7261 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7262 predicate(n->as_LoadStore()->result_not_used()); 7263 match(Set dummy (GetAndAddB mem add)); 7264 effect(KILL cr); 7265 format %{ "addb_lock $mem, $add" %} 7266 ins_encode %{ 7267 __ lock(); 7268 __ addb($mem$$Address, $add$$Register); 7269 %} 7270 ins_pipe(pipe_cmpxchg); 7271 %} 7272 7273 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7274 predicate(n->as_LoadStore()->result_not_used()); 7275 match(Set dummy (GetAndAddB mem add)); 7276 effect(KILL cr); 7277 format %{ "addb_lock $mem, $add" %} 7278 ins_encode %{ 7279 __ lock(); 7280 __ addb($mem$$Address, $add$$constant); 7281 %} 7282 ins_pipe(pipe_cmpxchg); 7283 %} 7284 7285 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7286 predicate(!n->as_LoadStore()->result_not_used()); 7287 match(Set newval (GetAndAddB mem newval)); 7288 effect(KILL cr); 7289 format %{ "xaddb_lock $mem, $newval" %} 7290 ins_encode %{ 7291 __ lock(); 7292 __ xaddb($mem$$Address, $newval$$Register); 7293 %} 7294 ins_pipe(pipe_cmpxchg); 7295 %} 7296 7297 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7298 predicate(n->as_LoadStore()->result_not_used()); 7299 match(Set dummy (GetAndAddS mem add)); 7300 effect(KILL cr); 7301 format %{ "addw_lock $mem, $add" %} 7302 ins_encode %{ 7303 __ lock(); 7304 __ addw($mem$$Address, $add$$Register); 7305 %} 7306 ins_pipe(pipe_cmpxchg); 7307 %} 7308 7309 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7310 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7311 match(Set dummy (GetAndAddS mem add)); 7312 effect(KILL cr); 7313 format %{ "addw_lock $mem, $add" %} 7314 ins_encode %{ 7315 __ lock(); 7316 __ addw($mem$$Address, $add$$constant); 7317 %} 7318 ins_pipe(pipe_cmpxchg); 7319 %} 7320 7321 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7322 predicate(!n->as_LoadStore()->result_not_used()); 7323 match(Set newval (GetAndAddS mem newval)); 7324 effect(KILL cr); 7325 format %{ "xaddw_lock $mem, $newval" %} 7326 ins_encode %{ 7327 __ lock(); 7328 __ xaddw($mem$$Address, $newval$$Register); 7329 %} 7330 ins_pipe(pipe_cmpxchg); 7331 %} 7332 7333 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7334 predicate(n->as_LoadStore()->result_not_used()); 7335 match(Set dummy (GetAndAddI mem add)); 7336 effect(KILL cr); 7337 format %{ "addl_lock $mem, $add" %} 7338 ins_encode %{ 7339 __ lock(); 7340 __ addl($mem$$Address, $add$$Register); 7341 %} 7342 ins_pipe(pipe_cmpxchg); 7343 %} 7344 7345 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7346 predicate(n->as_LoadStore()->result_not_used()); 7347 match(Set dummy (GetAndAddI mem add)); 7348 effect(KILL cr); 7349 format %{ "addl_lock $mem, $add" %} 7350 ins_encode %{ 7351 __ lock(); 7352 __ addl($mem$$Address, $add$$constant); 7353 %} 7354 ins_pipe(pipe_cmpxchg); 7355 %} 7356 7357 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7358 predicate(!n->as_LoadStore()->result_not_used()); 7359 match(Set newval (GetAndAddI mem newval)); 7360 effect(KILL cr); 7361 format %{ "xaddl_lock $mem, $newval" %} 7362 ins_encode %{ 7363 __ lock(); 7364 __ xaddl($mem$$Address, $newval$$Register); 7365 %} 7366 ins_pipe(pipe_cmpxchg); 7367 %} 7368 7369 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7370 predicate(n->as_LoadStore()->result_not_used()); 7371 match(Set dummy (GetAndAddL mem add)); 7372 effect(KILL cr); 7373 format %{ "addq_lock $mem, $add" %} 7374 ins_encode %{ 7375 __ lock(); 7376 __ addq($mem$$Address, $add$$Register); 7377 %} 7378 ins_pipe(pipe_cmpxchg); 7379 %} 7380 7381 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7382 predicate(n->as_LoadStore()->result_not_used()); 7383 match(Set dummy (GetAndAddL mem add)); 7384 effect(KILL cr); 7385 format %{ "addq_lock $mem, $add" %} 7386 ins_encode %{ 7387 __ lock(); 7388 __ addq($mem$$Address, $add$$constant); 7389 %} 7390 ins_pipe(pipe_cmpxchg); 7391 %} 7392 7393 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7394 predicate(!n->as_LoadStore()->result_not_used()); 7395 match(Set newval (GetAndAddL mem newval)); 7396 effect(KILL cr); 7397 format %{ "xaddq_lock $mem, $newval" %} 7398 ins_encode %{ 7399 __ lock(); 7400 __ xaddq($mem$$Address, $newval$$Register); 7401 %} 7402 ins_pipe(pipe_cmpxchg); 7403 %} 7404 7405 instruct xchgB( memory mem, rRegI newval) %{ 7406 match(Set newval (GetAndSetB mem newval)); 7407 format %{ "XCHGB $newval,[$mem]" %} 7408 ins_encode %{ 7409 __ xchgb($newval$$Register, $mem$$Address); 7410 %} 7411 ins_pipe( pipe_cmpxchg ); 7412 %} 7413 7414 instruct xchgS( memory mem, rRegI newval) %{ 7415 match(Set newval (GetAndSetS mem newval)); 7416 format %{ "XCHGW $newval,[$mem]" %} 7417 ins_encode %{ 7418 __ xchgw($newval$$Register, $mem$$Address); 7419 %} 7420 ins_pipe( pipe_cmpxchg ); 7421 %} 7422 7423 instruct xchgI( memory mem, rRegI newval) %{ 7424 match(Set newval (GetAndSetI mem newval)); 7425 format %{ "XCHGL $newval,[$mem]" %} 7426 ins_encode %{ 7427 __ xchgl($newval$$Register, $mem$$Address); 7428 %} 7429 ins_pipe( pipe_cmpxchg ); 7430 %} 7431 7432 instruct xchgL( memory mem, rRegL newval) %{ 7433 match(Set newval (GetAndSetL mem newval)); 7434 format %{ "XCHGL $newval,[$mem]" %} 7435 ins_encode %{ 7436 __ xchgq($newval$$Register, $mem$$Address); 7437 %} 7438 ins_pipe( pipe_cmpxchg ); 7439 %} 7440 7441 instruct xchgP( memory mem, rRegP newval) %{ 7442 match(Set newval (GetAndSetP mem newval)); 7443 predicate(n->as_LoadStore()->barrier_data() == 0); 7444 format %{ "XCHGQ $newval,[$mem]" %} 7445 ins_encode %{ 7446 __ xchgq($newval$$Register, $mem$$Address); 7447 %} 7448 ins_pipe( pipe_cmpxchg ); 7449 %} 7450 7451 instruct xchgN( memory mem, rRegN newval) %{ 7452 predicate(n->as_LoadStore()->barrier_data() == 0); 7453 match(Set newval (GetAndSetN mem newval)); 7454 format %{ "XCHGL $newval,$mem]" %} 7455 ins_encode %{ 7456 __ xchgl($newval$$Register, $mem$$Address); 7457 %} 7458 ins_pipe( pipe_cmpxchg ); 7459 %} 7460 7461 //----------Abs Instructions------------------------------------------- 7462 7463 // Integer Absolute Instructions 7464 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7465 %{ 7466 match(Set dst (AbsI src)); 7467 effect(TEMP dst, KILL cr); 7468 format %{ "xorl $dst, $dst\t# abs int\n\t" 7469 "subl $dst, $src\n\t" 7470 "cmovll $dst, $src" %} 7471 ins_encode %{ 7472 __ xorl($dst$$Register, $dst$$Register); 7473 __ subl($dst$$Register, $src$$Register); 7474 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7475 %} 7476 7477 ins_pipe(ialu_reg_reg); 7478 %} 7479 7480 // Long Absolute Instructions 7481 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7482 %{ 7483 match(Set dst (AbsL src)); 7484 effect(TEMP dst, KILL cr); 7485 format %{ "xorl $dst, $dst\t# abs long\n\t" 7486 "subq $dst, $src\n\t" 7487 "cmovlq $dst, $src" %} 7488 ins_encode %{ 7489 __ xorl($dst$$Register, $dst$$Register); 7490 __ subq($dst$$Register, $src$$Register); 7491 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7492 %} 7493 7494 ins_pipe(ialu_reg_reg); 7495 %} 7496 7497 //----------Subtraction Instructions------------------------------------------- 7498 7499 // Integer Subtraction Instructions 7500 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7501 %{ 7502 match(Set dst (SubI dst src)); 7503 effect(KILL cr); 7504 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7505 7506 format %{ "subl $dst, $src\t# int" %} 7507 ins_encode %{ 7508 __ subl($dst$$Register, $src$$Register); 7509 %} 7510 ins_pipe(ialu_reg_reg); 7511 %} 7512 7513 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7514 %{ 7515 match(Set dst (SubI dst (LoadI src))); 7516 effect(KILL cr); 7517 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7518 7519 ins_cost(150); 7520 format %{ "subl $dst, $src\t# int" %} 7521 ins_encode %{ 7522 __ subl($dst$$Register, $src$$Address); 7523 %} 7524 ins_pipe(ialu_reg_mem); 7525 %} 7526 7527 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7528 %{ 7529 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7530 effect(KILL cr); 7531 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7532 7533 ins_cost(150); 7534 format %{ "subl $dst, $src\t# int" %} 7535 ins_encode %{ 7536 __ subl($dst$$Address, $src$$Register); 7537 %} 7538 ins_pipe(ialu_mem_reg); 7539 %} 7540 7541 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7542 %{ 7543 match(Set dst (SubL dst src)); 7544 effect(KILL cr); 7545 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7546 7547 format %{ "subq $dst, $src\t# long" %} 7548 ins_encode %{ 7549 __ subq($dst$$Register, $src$$Register); 7550 %} 7551 ins_pipe(ialu_reg_reg); 7552 %} 7553 7554 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7555 %{ 7556 match(Set dst (SubL dst (LoadL src))); 7557 effect(KILL cr); 7558 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7559 7560 ins_cost(150); 7561 format %{ "subq $dst, $src\t# long" %} 7562 ins_encode %{ 7563 __ subq($dst$$Register, $src$$Address); 7564 %} 7565 ins_pipe(ialu_reg_mem); 7566 %} 7567 7568 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7569 %{ 7570 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7571 effect(KILL cr); 7572 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7573 7574 ins_cost(150); 7575 format %{ "subq $dst, $src\t# long" %} 7576 ins_encode %{ 7577 __ subq($dst$$Address, $src$$Register); 7578 %} 7579 ins_pipe(ialu_mem_reg); 7580 %} 7581 7582 // Subtract from a pointer 7583 // XXX hmpf??? 7584 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7585 %{ 7586 match(Set dst (AddP dst (SubI zero src))); 7587 effect(KILL cr); 7588 7589 format %{ "subq $dst, $src\t# ptr - int" %} 7590 ins_encode %{ 7591 __ subq($dst$$Register, $src$$Register); 7592 %} 7593 ins_pipe(ialu_reg_reg); 7594 %} 7595 7596 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7597 %{ 7598 match(Set dst (SubI zero dst)); 7599 effect(KILL cr); 7600 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7601 7602 format %{ "negl $dst\t# int" %} 7603 ins_encode %{ 7604 __ negl($dst$$Register); 7605 %} 7606 ins_pipe(ialu_reg); 7607 %} 7608 7609 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7610 %{ 7611 match(Set dst (NegI dst)); 7612 effect(KILL cr); 7613 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7614 7615 format %{ "negl $dst\t# int" %} 7616 ins_encode %{ 7617 __ negl($dst$$Register); 7618 %} 7619 ins_pipe(ialu_reg); 7620 %} 7621 7622 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7623 %{ 7624 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7625 effect(KILL cr); 7626 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7627 7628 format %{ "negl $dst\t# int" %} 7629 ins_encode %{ 7630 __ negl($dst$$Address); 7631 %} 7632 ins_pipe(ialu_reg); 7633 %} 7634 7635 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7636 %{ 7637 match(Set dst (SubL zero dst)); 7638 effect(KILL cr); 7639 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7640 7641 format %{ "negq $dst\t# long" %} 7642 ins_encode %{ 7643 __ negq($dst$$Register); 7644 %} 7645 ins_pipe(ialu_reg); 7646 %} 7647 7648 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7649 %{ 7650 match(Set dst (NegL dst)); 7651 effect(KILL cr); 7652 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7653 7654 format %{ "negq $dst\t# int" %} 7655 ins_encode %{ 7656 __ negq($dst$$Register); 7657 %} 7658 ins_pipe(ialu_reg); 7659 %} 7660 7661 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7662 %{ 7663 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7664 effect(KILL cr); 7665 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7666 7667 format %{ "negq $dst\t# long" %} 7668 ins_encode %{ 7669 __ negq($dst$$Address); 7670 %} 7671 ins_pipe(ialu_reg); 7672 %} 7673 7674 //----------Multiplication/Division Instructions------------------------------- 7675 // Integer Multiplication Instructions 7676 // Multiply Register 7677 7678 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7679 %{ 7680 match(Set dst (MulI dst src)); 7681 effect(KILL cr); 7682 7683 ins_cost(300); 7684 format %{ "imull $dst, $src\t# int" %} 7685 ins_encode %{ 7686 __ imull($dst$$Register, $src$$Register); 7687 %} 7688 ins_pipe(ialu_reg_reg_alu0); 7689 %} 7690 7691 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7692 %{ 7693 match(Set dst (MulI src imm)); 7694 effect(KILL cr); 7695 7696 ins_cost(300); 7697 format %{ "imull $dst, $src, $imm\t# int" %} 7698 ins_encode %{ 7699 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7700 %} 7701 ins_pipe(ialu_reg_reg_alu0); 7702 %} 7703 7704 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7705 %{ 7706 match(Set dst (MulI dst (LoadI src))); 7707 effect(KILL cr); 7708 7709 ins_cost(350); 7710 format %{ "imull $dst, $src\t# int" %} 7711 ins_encode %{ 7712 __ imull($dst$$Register, $src$$Address); 7713 %} 7714 ins_pipe(ialu_reg_mem_alu0); 7715 %} 7716 7717 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7718 %{ 7719 match(Set dst (MulI (LoadI src) imm)); 7720 effect(KILL cr); 7721 7722 ins_cost(300); 7723 format %{ "imull $dst, $src, $imm\t# int" %} 7724 ins_encode %{ 7725 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7726 %} 7727 ins_pipe(ialu_reg_mem_alu0); 7728 %} 7729 7730 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7731 %{ 7732 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7733 effect(KILL cr, KILL src2); 7734 7735 expand %{ mulI_rReg(dst, src1, cr); 7736 mulI_rReg(src2, src3, cr); 7737 addI_rReg(dst, src2, cr); %} 7738 %} 7739 7740 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7741 %{ 7742 match(Set dst (MulL dst src)); 7743 effect(KILL cr); 7744 7745 ins_cost(300); 7746 format %{ "imulq $dst, $src\t# long" %} 7747 ins_encode %{ 7748 __ imulq($dst$$Register, $src$$Register); 7749 %} 7750 ins_pipe(ialu_reg_reg_alu0); 7751 %} 7752 7753 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7754 %{ 7755 match(Set dst (MulL src imm)); 7756 effect(KILL cr); 7757 7758 ins_cost(300); 7759 format %{ "imulq $dst, $src, $imm\t# long" %} 7760 ins_encode %{ 7761 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7762 %} 7763 ins_pipe(ialu_reg_reg_alu0); 7764 %} 7765 7766 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7767 %{ 7768 match(Set dst (MulL dst (LoadL src))); 7769 effect(KILL cr); 7770 7771 ins_cost(350); 7772 format %{ "imulq $dst, $src\t# long" %} 7773 ins_encode %{ 7774 __ imulq($dst$$Register, $src$$Address); 7775 %} 7776 ins_pipe(ialu_reg_mem_alu0); 7777 %} 7778 7779 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7780 %{ 7781 match(Set dst (MulL (LoadL src) imm)); 7782 effect(KILL cr); 7783 7784 ins_cost(300); 7785 format %{ "imulq $dst, $src, $imm\t# long" %} 7786 ins_encode %{ 7787 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7788 %} 7789 ins_pipe(ialu_reg_mem_alu0); 7790 %} 7791 7792 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7793 %{ 7794 match(Set dst (MulHiL src rax)); 7795 effect(USE_KILL rax, KILL cr); 7796 7797 ins_cost(300); 7798 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7799 ins_encode %{ 7800 __ imulq($src$$Register); 7801 %} 7802 ins_pipe(ialu_reg_reg_alu0); 7803 %} 7804 7805 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7806 %{ 7807 match(Set dst (UMulHiL src rax)); 7808 effect(USE_KILL rax, KILL cr); 7809 7810 ins_cost(300); 7811 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7812 ins_encode %{ 7813 __ mulq($src$$Register); 7814 %} 7815 ins_pipe(ialu_reg_reg_alu0); 7816 %} 7817 7818 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7819 rFlagsReg cr) 7820 %{ 7821 match(Set rax (DivI rax div)); 7822 effect(KILL rdx, KILL cr); 7823 7824 ins_cost(30*100+10*100); // XXX 7825 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7826 "jne,s normal\n\t" 7827 "xorl rdx, rdx\n\t" 7828 "cmpl $div, -1\n\t" 7829 "je,s done\n" 7830 "normal: cdql\n\t" 7831 "idivl $div\n" 7832 "done:" %} 7833 ins_encode(cdql_enc(div)); 7834 ins_pipe(ialu_reg_reg_alu0); 7835 %} 7836 7837 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7838 rFlagsReg cr) 7839 %{ 7840 match(Set rax (DivL rax div)); 7841 effect(KILL rdx, KILL cr); 7842 7843 ins_cost(30*100+10*100); // XXX 7844 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7845 "cmpq rax, rdx\n\t" 7846 "jne,s normal\n\t" 7847 "xorl rdx, rdx\n\t" 7848 "cmpq $div, -1\n\t" 7849 "je,s done\n" 7850 "normal: cdqq\n\t" 7851 "idivq $div\n" 7852 "done:" %} 7853 ins_encode(cdqq_enc(div)); 7854 ins_pipe(ialu_reg_reg_alu0); 7855 %} 7856 7857 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7858 %{ 7859 match(Set rax (UDivI rax div)); 7860 effect(KILL rdx, KILL cr); 7861 7862 ins_cost(300); 7863 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7864 ins_encode %{ 7865 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7866 %} 7867 ins_pipe(ialu_reg_reg_alu0); 7868 %} 7869 7870 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7871 %{ 7872 match(Set rax (UDivL rax div)); 7873 effect(KILL rdx, KILL cr); 7874 7875 ins_cost(300); 7876 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7877 ins_encode %{ 7878 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7879 %} 7880 ins_pipe(ialu_reg_reg_alu0); 7881 %} 7882 7883 // Integer DIVMOD with Register, both quotient and mod results 7884 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7885 rFlagsReg cr) 7886 %{ 7887 match(DivModI rax div); 7888 effect(KILL cr); 7889 7890 ins_cost(30*100+10*100); // XXX 7891 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7892 "jne,s normal\n\t" 7893 "xorl rdx, rdx\n\t" 7894 "cmpl $div, -1\n\t" 7895 "je,s done\n" 7896 "normal: cdql\n\t" 7897 "idivl $div\n" 7898 "done:" %} 7899 ins_encode(cdql_enc(div)); 7900 ins_pipe(pipe_slow); 7901 %} 7902 7903 // Long DIVMOD with Register, both quotient and mod results 7904 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7905 rFlagsReg cr) 7906 %{ 7907 match(DivModL rax div); 7908 effect(KILL cr); 7909 7910 ins_cost(30*100+10*100); // XXX 7911 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7912 "cmpq rax, rdx\n\t" 7913 "jne,s normal\n\t" 7914 "xorl rdx, rdx\n\t" 7915 "cmpq $div, -1\n\t" 7916 "je,s done\n" 7917 "normal: cdqq\n\t" 7918 "idivq $div\n" 7919 "done:" %} 7920 ins_encode(cdqq_enc(div)); 7921 ins_pipe(pipe_slow); 7922 %} 7923 7924 // Unsigned integer DIVMOD with Register, both quotient and mod results 7925 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7926 no_rax_rdx_RegI div, rFlagsReg cr) 7927 %{ 7928 match(UDivModI rax div); 7929 effect(TEMP tmp, KILL cr); 7930 7931 ins_cost(300); 7932 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7933 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7934 %} 7935 ins_encode %{ 7936 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7937 %} 7938 ins_pipe(pipe_slow); 7939 %} 7940 7941 // Unsigned long DIVMOD with Register, both quotient and mod results 7942 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7943 no_rax_rdx_RegL div, rFlagsReg cr) 7944 %{ 7945 match(UDivModL rax div); 7946 effect(TEMP tmp, KILL cr); 7947 7948 ins_cost(300); 7949 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7950 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7951 %} 7952 ins_encode %{ 7953 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7954 %} 7955 ins_pipe(pipe_slow); 7956 %} 7957 7958 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7959 rFlagsReg cr) 7960 %{ 7961 match(Set rdx (ModI rax div)); 7962 effect(KILL rax, KILL cr); 7963 7964 ins_cost(300); // XXX 7965 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7966 "jne,s normal\n\t" 7967 "xorl rdx, rdx\n\t" 7968 "cmpl $div, -1\n\t" 7969 "je,s done\n" 7970 "normal: cdql\n\t" 7971 "idivl $div\n" 7972 "done:" %} 7973 ins_encode(cdql_enc(div)); 7974 ins_pipe(ialu_reg_reg_alu0); 7975 %} 7976 7977 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7978 rFlagsReg cr) 7979 %{ 7980 match(Set rdx (ModL rax div)); 7981 effect(KILL rax, KILL cr); 7982 7983 ins_cost(300); // XXX 7984 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7985 "cmpq rax, rdx\n\t" 7986 "jne,s normal\n\t" 7987 "xorl rdx, rdx\n\t" 7988 "cmpq $div, -1\n\t" 7989 "je,s done\n" 7990 "normal: cdqq\n\t" 7991 "idivq $div\n" 7992 "done:" %} 7993 ins_encode(cdqq_enc(div)); 7994 ins_pipe(ialu_reg_reg_alu0); 7995 %} 7996 7997 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 7998 %{ 7999 match(Set rdx (UModI rax div)); 8000 effect(KILL rax, KILL cr); 8001 8002 ins_cost(300); 8003 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8004 ins_encode %{ 8005 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8006 %} 8007 ins_pipe(ialu_reg_reg_alu0); 8008 %} 8009 8010 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8011 %{ 8012 match(Set rdx (UModL rax div)); 8013 effect(KILL rax, KILL cr); 8014 8015 ins_cost(300); 8016 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8017 ins_encode %{ 8018 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8019 %} 8020 ins_pipe(ialu_reg_reg_alu0); 8021 %} 8022 8023 // Integer Shift Instructions 8024 // Shift Left by one, two, three 8025 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8026 %{ 8027 match(Set dst (LShiftI dst shift)); 8028 effect(KILL cr); 8029 8030 format %{ "sall $dst, $shift" %} 8031 ins_encode %{ 8032 __ sall($dst$$Register, $shift$$constant); 8033 %} 8034 ins_pipe(ialu_reg); 8035 %} 8036 8037 // Shift Left by 8-bit immediate 8038 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8039 %{ 8040 match(Set dst (LShiftI dst shift)); 8041 effect(KILL cr); 8042 8043 format %{ "sall $dst, $shift" %} 8044 ins_encode %{ 8045 __ sall($dst$$Register, $shift$$constant); 8046 %} 8047 ins_pipe(ialu_reg); 8048 %} 8049 8050 // Shift Left by 8-bit immediate 8051 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8052 %{ 8053 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8054 effect(KILL cr); 8055 8056 format %{ "sall $dst, $shift" %} 8057 ins_encode %{ 8058 __ sall($dst$$Address, $shift$$constant); 8059 %} 8060 ins_pipe(ialu_mem_imm); 8061 %} 8062 8063 // Shift Left by variable 8064 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8065 %{ 8066 predicate(!VM_Version::supports_bmi2()); 8067 match(Set dst (LShiftI dst shift)); 8068 effect(KILL cr); 8069 8070 format %{ "sall $dst, $shift" %} 8071 ins_encode %{ 8072 __ sall($dst$$Register); 8073 %} 8074 ins_pipe(ialu_reg_reg); 8075 %} 8076 8077 // Shift Left by variable 8078 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8079 %{ 8080 predicate(!VM_Version::supports_bmi2()); 8081 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8082 effect(KILL cr); 8083 8084 format %{ "sall $dst, $shift" %} 8085 ins_encode %{ 8086 __ sall($dst$$Address); 8087 %} 8088 ins_pipe(ialu_mem_reg); 8089 %} 8090 8091 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8092 %{ 8093 predicate(VM_Version::supports_bmi2()); 8094 match(Set dst (LShiftI src shift)); 8095 8096 format %{ "shlxl $dst, $src, $shift" %} 8097 ins_encode %{ 8098 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8099 %} 8100 ins_pipe(ialu_reg_reg); 8101 %} 8102 8103 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8104 %{ 8105 predicate(VM_Version::supports_bmi2()); 8106 match(Set dst (LShiftI (LoadI src) shift)); 8107 ins_cost(175); 8108 format %{ "shlxl $dst, $src, $shift" %} 8109 ins_encode %{ 8110 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8111 %} 8112 ins_pipe(ialu_reg_mem); 8113 %} 8114 8115 // Arithmetic Shift Right by 8-bit immediate 8116 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8117 %{ 8118 match(Set dst (RShiftI dst shift)); 8119 effect(KILL cr); 8120 8121 format %{ "sarl $dst, $shift" %} 8122 ins_encode %{ 8123 __ sarl($dst$$Register, $shift$$constant); 8124 %} 8125 ins_pipe(ialu_mem_imm); 8126 %} 8127 8128 // Arithmetic Shift Right by 8-bit immediate 8129 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8130 %{ 8131 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8132 effect(KILL cr); 8133 8134 format %{ "sarl $dst, $shift" %} 8135 ins_encode %{ 8136 __ sarl($dst$$Address, $shift$$constant); 8137 %} 8138 ins_pipe(ialu_mem_imm); 8139 %} 8140 8141 // Arithmetic Shift Right by variable 8142 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8143 %{ 8144 predicate(!VM_Version::supports_bmi2()); 8145 match(Set dst (RShiftI dst shift)); 8146 effect(KILL cr); 8147 8148 format %{ "sarl $dst, $shift" %} 8149 ins_encode %{ 8150 __ sarl($dst$$Register); 8151 %} 8152 ins_pipe(ialu_reg_reg); 8153 %} 8154 8155 // Arithmetic Shift Right by variable 8156 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8157 %{ 8158 predicate(!VM_Version::supports_bmi2()); 8159 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8160 effect(KILL cr); 8161 8162 format %{ "sarl $dst, $shift" %} 8163 ins_encode %{ 8164 __ sarl($dst$$Address); 8165 %} 8166 ins_pipe(ialu_mem_reg); 8167 %} 8168 8169 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8170 %{ 8171 predicate(VM_Version::supports_bmi2()); 8172 match(Set dst (RShiftI src shift)); 8173 8174 format %{ "sarxl $dst, $src, $shift" %} 8175 ins_encode %{ 8176 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8177 %} 8178 ins_pipe(ialu_reg_reg); 8179 %} 8180 8181 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8182 %{ 8183 predicate(VM_Version::supports_bmi2()); 8184 match(Set dst (RShiftI (LoadI src) shift)); 8185 ins_cost(175); 8186 format %{ "sarxl $dst, $src, $shift" %} 8187 ins_encode %{ 8188 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8189 %} 8190 ins_pipe(ialu_reg_mem); 8191 %} 8192 8193 // Logical Shift Right by 8-bit immediate 8194 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8195 %{ 8196 match(Set dst (URShiftI dst shift)); 8197 effect(KILL cr); 8198 8199 format %{ "shrl $dst, $shift" %} 8200 ins_encode %{ 8201 __ shrl($dst$$Register, $shift$$constant); 8202 %} 8203 ins_pipe(ialu_reg); 8204 %} 8205 8206 // Logical Shift Right by 8-bit immediate 8207 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8208 %{ 8209 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8210 effect(KILL cr); 8211 8212 format %{ "shrl $dst, $shift" %} 8213 ins_encode %{ 8214 __ shrl($dst$$Address, $shift$$constant); 8215 %} 8216 ins_pipe(ialu_mem_imm); 8217 %} 8218 8219 // Logical Shift Right by variable 8220 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8221 %{ 8222 predicate(!VM_Version::supports_bmi2()); 8223 match(Set dst (URShiftI dst shift)); 8224 effect(KILL cr); 8225 8226 format %{ "shrl $dst, $shift" %} 8227 ins_encode %{ 8228 __ shrl($dst$$Register); 8229 %} 8230 ins_pipe(ialu_reg_reg); 8231 %} 8232 8233 // Logical Shift Right by variable 8234 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8235 %{ 8236 predicate(!VM_Version::supports_bmi2()); 8237 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8238 effect(KILL cr); 8239 8240 format %{ "shrl $dst, $shift" %} 8241 ins_encode %{ 8242 __ shrl($dst$$Address); 8243 %} 8244 ins_pipe(ialu_mem_reg); 8245 %} 8246 8247 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8248 %{ 8249 predicate(VM_Version::supports_bmi2()); 8250 match(Set dst (URShiftI src shift)); 8251 8252 format %{ "shrxl $dst, $src, $shift" %} 8253 ins_encode %{ 8254 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8255 %} 8256 ins_pipe(ialu_reg_reg); 8257 %} 8258 8259 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8260 %{ 8261 predicate(VM_Version::supports_bmi2()); 8262 match(Set dst (URShiftI (LoadI src) shift)); 8263 ins_cost(175); 8264 format %{ "shrxl $dst, $src, $shift" %} 8265 ins_encode %{ 8266 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8267 %} 8268 ins_pipe(ialu_reg_mem); 8269 %} 8270 8271 // Long Shift Instructions 8272 // Shift Left by one, two, three 8273 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8274 %{ 8275 match(Set dst (LShiftL dst shift)); 8276 effect(KILL cr); 8277 8278 format %{ "salq $dst, $shift" %} 8279 ins_encode %{ 8280 __ salq($dst$$Register, $shift$$constant); 8281 %} 8282 ins_pipe(ialu_reg); 8283 %} 8284 8285 // Shift Left by 8-bit immediate 8286 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8287 %{ 8288 match(Set dst (LShiftL dst shift)); 8289 effect(KILL cr); 8290 8291 format %{ "salq $dst, $shift" %} 8292 ins_encode %{ 8293 __ salq($dst$$Register, $shift$$constant); 8294 %} 8295 ins_pipe(ialu_reg); 8296 %} 8297 8298 // Shift Left by 8-bit immediate 8299 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8300 %{ 8301 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8302 effect(KILL cr); 8303 8304 format %{ "salq $dst, $shift" %} 8305 ins_encode %{ 8306 __ salq($dst$$Address, $shift$$constant); 8307 %} 8308 ins_pipe(ialu_mem_imm); 8309 %} 8310 8311 // Shift Left by variable 8312 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8313 %{ 8314 predicate(!VM_Version::supports_bmi2()); 8315 match(Set dst (LShiftL dst shift)); 8316 effect(KILL cr); 8317 8318 format %{ "salq $dst, $shift" %} 8319 ins_encode %{ 8320 __ salq($dst$$Register); 8321 %} 8322 ins_pipe(ialu_reg_reg); 8323 %} 8324 8325 // Shift Left by variable 8326 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8327 %{ 8328 predicate(!VM_Version::supports_bmi2()); 8329 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8330 effect(KILL cr); 8331 8332 format %{ "salq $dst, $shift" %} 8333 ins_encode %{ 8334 __ salq($dst$$Address); 8335 %} 8336 ins_pipe(ialu_mem_reg); 8337 %} 8338 8339 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8340 %{ 8341 predicate(VM_Version::supports_bmi2()); 8342 match(Set dst (LShiftL src shift)); 8343 8344 format %{ "shlxq $dst, $src, $shift" %} 8345 ins_encode %{ 8346 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8347 %} 8348 ins_pipe(ialu_reg_reg); 8349 %} 8350 8351 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8352 %{ 8353 predicate(VM_Version::supports_bmi2()); 8354 match(Set dst (LShiftL (LoadL src) shift)); 8355 ins_cost(175); 8356 format %{ "shlxq $dst, $src, $shift" %} 8357 ins_encode %{ 8358 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8359 %} 8360 ins_pipe(ialu_reg_mem); 8361 %} 8362 8363 // Arithmetic Shift Right by 8-bit immediate 8364 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8365 %{ 8366 match(Set dst (RShiftL dst shift)); 8367 effect(KILL cr); 8368 8369 format %{ "sarq $dst, $shift" %} 8370 ins_encode %{ 8371 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8372 %} 8373 ins_pipe(ialu_mem_imm); 8374 %} 8375 8376 // Arithmetic Shift Right by 8-bit immediate 8377 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8378 %{ 8379 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8380 effect(KILL cr); 8381 8382 format %{ "sarq $dst, $shift" %} 8383 ins_encode %{ 8384 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8385 %} 8386 ins_pipe(ialu_mem_imm); 8387 %} 8388 8389 // Arithmetic Shift Right by variable 8390 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8391 %{ 8392 predicate(!VM_Version::supports_bmi2()); 8393 match(Set dst (RShiftL dst shift)); 8394 effect(KILL cr); 8395 8396 format %{ "sarq $dst, $shift" %} 8397 ins_encode %{ 8398 __ sarq($dst$$Register); 8399 %} 8400 ins_pipe(ialu_reg_reg); 8401 %} 8402 8403 // Arithmetic Shift Right by variable 8404 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8405 %{ 8406 predicate(!VM_Version::supports_bmi2()); 8407 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8408 effect(KILL cr); 8409 8410 format %{ "sarq $dst, $shift" %} 8411 ins_encode %{ 8412 __ sarq($dst$$Address); 8413 %} 8414 ins_pipe(ialu_mem_reg); 8415 %} 8416 8417 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8418 %{ 8419 predicate(VM_Version::supports_bmi2()); 8420 match(Set dst (RShiftL src shift)); 8421 8422 format %{ "sarxq $dst, $src, $shift" %} 8423 ins_encode %{ 8424 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8425 %} 8426 ins_pipe(ialu_reg_reg); 8427 %} 8428 8429 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8430 %{ 8431 predicate(VM_Version::supports_bmi2()); 8432 match(Set dst (RShiftL (LoadL src) shift)); 8433 ins_cost(175); 8434 format %{ "sarxq $dst, $src, $shift" %} 8435 ins_encode %{ 8436 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8437 %} 8438 ins_pipe(ialu_reg_mem); 8439 %} 8440 8441 // Logical Shift Right by 8-bit immediate 8442 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8443 %{ 8444 match(Set dst (URShiftL dst shift)); 8445 effect(KILL cr); 8446 8447 format %{ "shrq $dst, $shift" %} 8448 ins_encode %{ 8449 __ shrq($dst$$Register, $shift$$constant); 8450 %} 8451 ins_pipe(ialu_reg); 8452 %} 8453 8454 // Logical Shift Right by 8-bit immediate 8455 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8456 %{ 8457 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8458 effect(KILL cr); 8459 8460 format %{ "shrq $dst, $shift" %} 8461 ins_encode %{ 8462 __ shrq($dst$$Address, $shift$$constant); 8463 %} 8464 ins_pipe(ialu_mem_imm); 8465 %} 8466 8467 // Logical Shift Right by variable 8468 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8469 %{ 8470 predicate(!VM_Version::supports_bmi2()); 8471 match(Set dst (URShiftL dst shift)); 8472 effect(KILL cr); 8473 8474 format %{ "shrq $dst, $shift" %} 8475 ins_encode %{ 8476 __ shrq($dst$$Register); 8477 %} 8478 ins_pipe(ialu_reg_reg); 8479 %} 8480 8481 // Logical Shift Right by variable 8482 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8483 %{ 8484 predicate(!VM_Version::supports_bmi2()); 8485 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8486 effect(KILL cr); 8487 8488 format %{ "shrq $dst, $shift" %} 8489 ins_encode %{ 8490 __ shrq($dst$$Address); 8491 %} 8492 ins_pipe(ialu_mem_reg); 8493 %} 8494 8495 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8496 %{ 8497 predicate(VM_Version::supports_bmi2()); 8498 match(Set dst (URShiftL src shift)); 8499 8500 format %{ "shrxq $dst, $src, $shift" %} 8501 ins_encode %{ 8502 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8503 %} 8504 ins_pipe(ialu_reg_reg); 8505 %} 8506 8507 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8508 %{ 8509 predicate(VM_Version::supports_bmi2()); 8510 match(Set dst (URShiftL (LoadL src) shift)); 8511 ins_cost(175); 8512 format %{ "shrxq $dst, $src, $shift" %} 8513 ins_encode %{ 8514 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8515 %} 8516 ins_pipe(ialu_reg_mem); 8517 %} 8518 8519 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8520 // This idiom is used by the compiler for the i2b bytecode. 8521 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8522 %{ 8523 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8524 8525 format %{ "movsbl $dst, $src\t# i2b" %} 8526 ins_encode %{ 8527 __ movsbl($dst$$Register, $src$$Register); 8528 %} 8529 ins_pipe(ialu_reg_reg); 8530 %} 8531 8532 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8533 // This idiom is used by the compiler the i2s bytecode. 8534 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8535 %{ 8536 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8537 8538 format %{ "movswl $dst, $src\t# i2s" %} 8539 ins_encode %{ 8540 __ movswl($dst$$Register, $src$$Register); 8541 %} 8542 ins_pipe(ialu_reg_reg); 8543 %} 8544 8545 // ROL/ROR instructions 8546 8547 // Rotate left by constant. 8548 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8549 %{ 8550 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8551 match(Set dst (RotateLeft dst shift)); 8552 effect(KILL cr); 8553 format %{ "roll $dst, $shift" %} 8554 ins_encode %{ 8555 __ roll($dst$$Register, $shift$$constant); 8556 %} 8557 ins_pipe(ialu_reg); 8558 %} 8559 8560 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8561 %{ 8562 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8563 match(Set dst (RotateLeft src shift)); 8564 format %{ "rolxl $dst, $src, $shift" %} 8565 ins_encode %{ 8566 int shift = 32 - ($shift$$constant & 31); 8567 __ rorxl($dst$$Register, $src$$Register, shift); 8568 %} 8569 ins_pipe(ialu_reg_reg); 8570 %} 8571 8572 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8573 %{ 8574 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8575 match(Set dst (RotateLeft (LoadI src) shift)); 8576 ins_cost(175); 8577 format %{ "rolxl $dst, $src, $shift" %} 8578 ins_encode %{ 8579 int shift = 32 - ($shift$$constant & 31); 8580 __ rorxl($dst$$Register, $src$$Address, shift); 8581 %} 8582 ins_pipe(ialu_reg_mem); 8583 %} 8584 8585 // Rotate Left by variable 8586 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8587 %{ 8588 predicate(n->bottom_type()->basic_type() == T_INT); 8589 match(Set dst (RotateLeft dst shift)); 8590 effect(KILL cr); 8591 format %{ "roll $dst, $shift" %} 8592 ins_encode %{ 8593 __ roll($dst$$Register); 8594 %} 8595 ins_pipe(ialu_reg_reg); 8596 %} 8597 8598 // Rotate Right by constant. 8599 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8600 %{ 8601 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8602 match(Set dst (RotateRight dst shift)); 8603 effect(KILL cr); 8604 format %{ "rorl $dst, $shift" %} 8605 ins_encode %{ 8606 __ rorl($dst$$Register, $shift$$constant); 8607 %} 8608 ins_pipe(ialu_reg); 8609 %} 8610 8611 // Rotate Right by constant. 8612 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8613 %{ 8614 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8615 match(Set dst (RotateRight src shift)); 8616 format %{ "rorxl $dst, $src, $shift" %} 8617 ins_encode %{ 8618 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8619 %} 8620 ins_pipe(ialu_reg_reg); 8621 %} 8622 8623 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8624 %{ 8625 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8626 match(Set dst (RotateRight (LoadI src) shift)); 8627 ins_cost(175); 8628 format %{ "rorxl $dst, $src, $shift" %} 8629 ins_encode %{ 8630 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8631 %} 8632 ins_pipe(ialu_reg_mem); 8633 %} 8634 8635 // Rotate Right by variable 8636 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8637 %{ 8638 predicate(n->bottom_type()->basic_type() == T_INT); 8639 match(Set dst (RotateRight dst shift)); 8640 effect(KILL cr); 8641 format %{ "rorl $dst, $shift" %} 8642 ins_encode %{ 8643 __ rorl($dst$$Register); 8644 %} 8645 ins_pipe(ialu_reg_reg); 8646 %} 8647 8648 // Rotate Left by constant. 8649 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8650 %{ 8651 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8652 match(Set dst (RotateLeft dst shift)); 8653 effect(KILL cr); 8654 format %{ "rolq $dst, $shift" %} 8655 ins_encode %{ 8656 __ rolq($dst$$Register, $shift$$constant); 8657 %} 8658 ins_pipe(ialu_reg); 8659 %} 8660 8661 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8662 %{ 8663 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8664 match(Set dst (RotateLeft src shift)); 8665 format %{ "rolxq $dst, $src, $shift" %} 8666 ins_encode %{ 8667 int shift = 64 - ($shift$$constant & 63); 8668 __ rorxq($dst$$Register, $src$$Register, shift); 8669 %} 8670 ins_pipe(ialu_reg_reg); 8671 %} 8672 8673 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8674 %{ 8675 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8676 match(Set dst (RotateLeft (LoadL src) shift)); 8677 ins_cost(175); 8678 format %{ "rolxq $dst, $src, $shift" %} 8679 ins_encode %{ 8680 int shift = 64 - ($shift$$constant & 63); 8681 __ rorxq($dst$$Register, $src$$Address, shift); 8682 %} 8683 ins_pipe(ialu_reg_mem); 8684 %} 8685 8686 // Rotate Left by variable 8687 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8688 %{ 8689 predicate(n->bottom_type()->basic_type() == T_LONG); 8690 match(Set dst (RotateLeft dst shift)); 8691 effect(KILL cr); 8692 format %{ "rolq $dst, $shift" %} 8693 ins_encode %{ 8694 __ rolq($dst$$Register); 8695 %} 8696 ins_pipe(ialu_reg_reg); 8697 %} 8698 8699 // Rotate Right by constant. 8700 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8701 %{ 8702 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8703 match(Set dst (RotateRight dst shift)); 8704 effect(KILL cr); 8705 format %{ "rorq $dst, $shift" %} 8706 ins_encode %{ 8707 __ rorq($dst$$Register, $shift$$constant); 8708 %} 8709 ins_pipe(ialu_reg); 8710 %} 8711 8712 // Rotate Right by constant 8713 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8714 %{ 8715 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8716 match(Set dst (RotateRight src shift)); 8717 format %{ "rorxq $dst, $src, $shift" %} 8718 ins_encode %{ 8719 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8720 %} 8721 ins_pipe(ialu_reg_reg); 8722 %} 8723 8724 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8725 %{ 8726 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8727 match(Set dst (RotateRight (LoadL src) shift)); 8728 ins_cost(175); 8729 format %{ "rorxq $dst, $src, $shift" %} 8730 ins_encode %{ 8731 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8732 %} 8733 ins_pipe(ialu_reg_mem); 8734 %} 8735 8736 // Rotate Right by variable 8737 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8738 %{ 8739 predicate(n->bottom_type()->basic_type() == T_LONG); 8740 match(Set dst (RotateRight dst shift)); 8741 effect(KILL cr); 8742 format %{ "rorq $dst, $shift" %} 8743 ins_encode %{ 8744 __ rorq($dst$$Register); 8745 %} 8746 ins_pipe(ialu_reg_reg); 8747 %} 8748 8749 //----------------------------- CompressBits/ExpandBits ------------------------ 8750 8751 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8752 predicate(n->bottom_type()->isa_long()); 8753 match(Set dst (CompressBits src mask)); 8754 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8755 ins_encode %{ 8756 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8757 %} 8758 ins_pipe( pipe_slow ); 8759 %} 8760 8761 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8762 predicate(n->bottom_type()->isa_long()); 8763 match(Set dst (ExpandBits src mask)); 8764 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8765 ins_encode %{ 8766 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8767 %} 8768 ins_pipe( pipe_slow ); 8769 %} 8770 8771 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8772 predicate(n->bottom_type()->isa_long()); 8773 match(Set dst (CompressBits src (LoadL mask))); 8774 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8775 ins_encode %{ 8776 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8777 %} 8778 ins_pipe( pipe_slow ); 8779 %} 8780 8781 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8782 predicate(n->bottom_type()->isa_long()); 8783 match(Set dst (ExpandBits src (LoadL mask))); 8784 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8785 ins_encode %{ 8786 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8787 %} 8788 ins_pipe( pipe_slow ); 8789 %} 8790 8791 8792 // Logical Instructions 8793 8794 // Integer Logical Instructions 8795 8796 // And Instructions 8797 // And Register with Register 8798 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8799 %{ 8800 match(Set dst (AndI dst src)); 8801 effect(KILL cr); 8802 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8803 8804 format %{ "andl $dst, $src\t# int" %} 8805 ins_encode %{ 8806 __ andl($dst$$Register, $src$$Register); 8807 %} 8808 ins_pipe(ialu_reg_reg); 8809 %} 8810 8811 // And Register with Immediate 255 8812 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8813 %{ 8814 match(Set dst (AndI src mask)); 8815 8816 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8817 ins_encode %{ 8818 __ movzbl($dst$$Register, $src$$Register); 8819 %} 8820 ins_pipe(ialu_reg); 8821 %} 8822 8823 // And Register with Immediate 255 and promote to long 8824 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8825 %{ 8826 match(Set dst (ConvI2L (AndI src mask))); 8827 8828 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8829 ins_encode %{ 8830 __ movzbl($dst$$Register, $src$$Register); 8831 %} 8832 ins_pipe(ialu_reg); 8833 %} 8834 8835 // And Register with Immediate 65535 8836 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8837 %{ 8838 match(Set dst (AndI src mask)); 8839 8840 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8841 ins_encode %{ 8842 __ movzwl($dst$$Register, $src$$Register); 8843 %} 8844 ins_pipe(ialu_reg); 8845 %} 8846 8847 // And Register with Immediate 65535 and promote to long 8848 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8849 %{ 8850 match(Set dst (ConvI2L (AndI src mask))); 8851 8852 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8853 ins_encode %{ 8854 __ movzwl($dst$$Register, $src$$Register); 8855 %} 8856 ins_pipe(ialu_reg); 8857 %} 8858 8859 // Can skip int2long conversions after AND with small bitmask 8860 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8861 %{ 8862 predicate(VM_Version::supports_bmi2()); 8863 ins_cost(125); 8864 effect(TEMP tmp, KILL cr); 8865 match(Set dst (ConvI2L (AndI src mask))); 8866 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8867 ins_encode %{ 8868 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8869 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8870 %} 8871 ins_pipe(ialu_reg_reg); 8872 %} 8873 8874 // And Register with Immediate 8875 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8876 %{ 8877 match(Set dst (AndI dst src)); 8878 effect(KILL cr); 8879 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8880 8881 format %{ "andl $dst, $src\t# int" %} 8882 ins_encode %{ 8883 __ andl($dst$$Register, $src$$constant); 8884 %} 8885 ins_pipe(ialu_reg); 8886 %} 8887 8888 // And Register with Memory 8889 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8890 %{ 8891 match(Set dst (AndI dst (LoadI src))); 8892 effect(KILL cr); 8893 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8894 8895 ins_cost(150); 8896 format %{ "andl $dst, $src\t# int" %} 8897 ins_encode %{ 8898 __ andl($dst$$Register, $src$$Address); 8899 %} 8900 ins_pipe(ialu_reg_mem); 8901 %} 8902 8903 // And Memory with Register 8904 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8905 %{ 8906 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8907 effect(KILL cr); 8908 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8909 8910 ins_cost(150); 8911 format %{ "andb $dst, $src\t# byte" %} 8912 ins_encode %{ 8913 __ andb($dst$$Address, $src$$Register); 8914 %} 8915 ins_pipe(ialu_mem_reg); 8916 %} 8917 8918 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8919 %{ 8920 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8921 effect(KILL cr); 8922 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8923 8924 ins_cost(150); 8925 format %{ "andl $dst, $src\t# int" %} 8926 ins_encode %{ 8927 __ andl($dst$$Address, $src$$Register); 8928 %} 8929 ins_pipe(ialu_mem_reg); 8930 %} 8931 8932 // And Memory with Immediate 8933 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8934 %{ 8935 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8936 effect(KILL cr); 8937 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8938 8939 ins_cost(125); 8940 format %{ "andl $dst, $src\t# int" %} 8941 ins_encode %{ 8942 __ andl($dst$$Address, $src$$constant); 8943 %} 8944 ins_pipe(ialu_mem_imm); 8945 %} 8946 8947 // BMI1 instructions 8948 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8949 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8950 predicate(UseBMI1Instructions); 8951 effect(KILL cr); 8952 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8953 8954 ins_cost(125); 8955 format %{ "andnl $dst, $src1, $src2" %} 8956 8957 ins_encode %{ 8958 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8959 %} 8960 ins_pipe(ialu_reg_mem); 8961 %} 8962 8963 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8964 match(Set dst (AndI (XorI src1 minus_1) src2)); 8965 predicate(UseBMI1Instructions); 8966 effect(KILL cr); 8967 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8968 8969 format %{ "andnl $dst, $src1, $src2" %} 8970 8971 ins_encode %{ 8972 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8973 %} 8974 ins_pipe(ialu_reg); 8975 %} 8976 8977 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 8978 match(Set dst (AndI (SubI imm_zero src) src)); 8979 predicate(UseBMI1Instructions); 8980 effect(KILL cr); 8981 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8982 8983 format %{ "blsil $dst, $src" %} 8984 8985 ins_encode %{ 8986 __ blsil($dst$$Register, $src$$Register); 8987 %} 8988 ins_pipe(ialu_reg); 8989 %} 8990 8991 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 8992 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8993 predicate(UseBMI1Instructions); 8994 effect(KILL cr); 8995 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8996 8997 ins_cost(125); 8998 format %{ "blsil $dst, $src" %} 8999 9000 ins_encode %{ 9001 __ blsil($dst$$Register, $src$$Address); 9002 %} 9003 ins_pipe(ialu_reg_mem); 9004 %} 9005 9006 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9007 %{ 9008 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9009 predicate(UseBMI1Instructions); 9010 effect(KILL cr); 9011 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9012 9013 ins_cost(125); 9014 format %{ "blsmskl $dst, $src" %} 9015 9016 ins_encode %{ 9017 __ blsmskl($dst$$Register, $src$$Address); 9018 %} 9019 ins_pipe(ialu_reg_mem); 9020 %} 9021 9022 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9023 %{ 9024 match(Set dst (XorI (AddI src minus_1) src)); 9025 predicate(UseBMI1Instructions); 9026 effect(KILL cr); 9027 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9028 9029 format %{ "blsmskl $dst, $src" %} 9030 9031 ins_encode %{ 9032 __ blsmskl($dst$$Register, $src$$Register); 9033 %} 9034 9035 ins_pipe(ialu_reg); 9036 %} 9037 9038 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9039 %{ 9040 match(Set dst (AndI (AddI src minus_1) src) ); 9041 predicate(UseBMI1Instructions); 9042 effect(KILL cr); 9043 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9044 9045 format %{ "blsrl $dst, $src" %} 9046 9047 ins_encode %{ 9048 __ blsrl($dst$$Register, $src$$Register); 9049 %} 9050 9051 ins_pipe(ialu_reg_mem); 9052 %} 9053 9054 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9055 %{ 9056 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9057 predicate(UseBMI1Instructions); 9058 effect(KILL cr); 9059 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9060 9061 ins_cost(125); 9062 format %{ "blsrl $dst, $src" %} 9063 9064 ins_encode %{ 9065 __ blsrl($dst$$Register, $src$$Address); 9066 %} 9067 9068 ins_pipe(ialu_reg); 9069 %} 9070 9071 // Or Instructions 9072 // Or Register with Register 9073 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9074 %{ 9075 match(Set dst (OrI dst src)); 9076 effect(KILL cr); 9077 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9078 9079 format %{ "orl $dst, $src\t# int" %} 9080 ins_encode %{ 9081 __ orl($dst$$Register, $src$$Register); 9082 %} 9083 ins_pipe(ialu_reg_reg); 9084 %} 9085 9086 // Or Register with Immediate 9087 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9088 %{ 9089 match(Set dst (OrI dst src)); 9090 effect(KILL cr); 9091 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9092 9093 format %{ "orl $dst, $src\t# int" %} 9094 ins_encode %{ 9095 __ orl($dst$$Register, $src$$constant); 9096 %} 9097 ins_pipe(ialu_reg); 9098 %} 9099 9100 // Or Register with Memory 9101 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9102 %{ 9103 match(Set dst (OrI dst (LoadI src))); 9104 effect(KILL cr); 9105 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9106 9107 ins_cost(150); 9108 format %{ "orl $dst, $src\t# int" %} 9109 ins_encode %{ 9110 __ orl($dst$$Register, $src$$Address); 9111 %} 9112 ins_pipe(ialu_reg_mem); 9113 %} 9114 9115 // Or Memory with Register 9116 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9117 %{ 9118 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9119 effect(KILL cr); 9120 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9121 9122 ins_cost(150); 9123 format %{ "orb $dst, $src\t# byte" %} 9124 ins_encode %{ 9125 __ orb($dst$$Address, $src$$Register); 9126 %} 9127 ins_pipe(ialu_mem_reg); 9128 %} 9129 9130 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9131 %{ 9132 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9133 effect(KILL cr); 9134 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9135 9136 ins_cost(150); 9137 format %{ "orl $dst, $src\t# int" %} 9138 ins_encode %{ 9139 __ orl($dst$$Address, $src$$Register); 9140 %} 9141 ins_pipe(ialu_mem_reg); 9142 %} 9143 9144 // Or Memory with Immediate 9145 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9146 %{ 9147 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9148 effect(KILL cr); 9149 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9150 9151 ins_cost(125); 9152 format %{ "orl $dst, $src\t# int" %} 9153 ins_encode %{ 9154 __ orl($dst$$Address, $src$$constant); 9155 %} 9156 ins_pipe(ialu_mem_imm); 9157 %} 9158 9159 // Xor Instructions 9160 // Xor Register with Register 9161 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9162 %{ 9163 match(Set dst (XorI dst src)); 9164 effect(KILL cr); 9165 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9166 9167 format %{ "xorl $dst, $src\t# int" %} 9168 ins_encode %{ 9169 __ xorl($dst$$Register, $src$$Register); 9170 %} 9171 ins_pipe(ialu_reg_reg); 9172 %} 9173 9174 // Xor Register with Immediate -1 9175 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9176 match(Set dst (XorI dst imm)); 9177 9178 format %{ "not $dst" %} 9179 ins_encode %{ 9180 __ notl($dst$$Register); 9181 %} 9182 ins_pipe(ialu_reg); 9183 %} 9184 9185 // Xor Register with Immediate 9186 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9187 %{ 9188 match(Set dst (XorI dst src)); 9189 effect(KILL cr); 9190 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9191 9192 format %{ "xorl $dst, $src\t# int" %} 9193 ins_encode %{ 9194 __ xorl($dst$$Register, $src$$constant); 9195 %} 9196 ins_pipe(ialu_reg); 9197 %} 9198 9199 // Xor Register with Memory 9200 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9201 %{ 9202 match(Set dst (XorI dst (LoadI src))); 9203 effect(KILL cr); 9204 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9205 9206 ins_cost(150); 9207 format %{ "xorl $dst, $src\t# int" %} 9208 ins_encode %{ 9209 __ xorl($dst$$Register, $src$$Address); 9210 %} 9211 ins_pipe(ialu_reg_mem); 9212 %} 9213 9214 // Xor Memory with Register 9215 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9216 %{ 9217 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9218 effect(KILL cr); 9219 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9220 9221 ins_cost(150); 9222 format %{ "xorb $dst, $src\t# byte" %} 9223 ins_encode %{ 9224 __ xorb($dst$$Address, $src$$Register); 9225 %} 9226 ins_pipe(ialu_mem_reg); 9227 %} 9228 9229 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9230 %{ 9231 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9232 effect(KILL cr); 9233 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9234 9235 ins_cost(150); 9236 format %{ "xorl $dst, $src\t# int" %} 9237 ins_encode %{ 9238 __ xorl($dst$$Address, $src$$Register); 9239 %} 9240 ins_pipe(ialu_mem_reg); 9241 %} 9242 9243 // Xor Memory with Immediate 9244 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9245 %{ 9246 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9247 effect(KILL cr); 9248 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9249 9250 ins_cost(125); 9251 format %{ "xorl $dst, $src\t# int" %} 9252 ins_encode %{ 9253 __ xorl($dst$$Address, $src$$constant); 9254 %} 9255 ins_pipe(ialu_mem_imm); 9256 %} 9257 9258 9259 // Long Logical Instructions 9260 9261 // And Instructions 9262 // And Register with Register 9263 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9264 %{ 9265 match(Set dst (AndL dst src)); 9266 effect(KILL cr); 9267 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9268 9269 format %{ "andq $dst, $src\t# long" %} 9270 ins_encode %{ 9271 __ andq($dst$$Register, $src$$Register); 9272 %} 9273 ins_pipe(ialu_reg_reg); 9274 %} 9275 9276 // And Register with Immediate 255 9277 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9278 %{ 9279 match(Set dst (AndL src mask)); 9280 9281 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9282 ins_encode %{ 9283 // movzbl zeroes out the upper 32-bit and does not need REX.W 9284 __ movzbl($dst$$Register, $src$$Register); 9285 %} 9286 ins_pipe(ialu_reg); 9287 %} 9288 9289 // And Register with Immediate 65535 9290 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9291 %{ 9292 match(Set dst (AndL src mask)); 9293 9294 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9295 ins_encode %{ 9296 // movzwl zeroes out the upper 32-bit and does not need REX.W 9297 __ movzwl($dst$$Register, $src$$Register); 9298 %} 9299 ins_pipe(ialu_reg); 9300 %} 9301 9302 // And Register with Immediate 9303 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9304 %{ 9305 match(Set dst (AndL dst src)); 9306 effect(KILL cr); 9307 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9308 9309 format %{ "andq $dst, $src\t# long" %} 9310 ins_encode %{ 9311 __ andq($dst$$Register, $src$$constant); 9312 %} 9313 ins_pipe(ialu_reg); 9314 %} 9315 9316 // And Register with Memory 9317 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9318 %{ 9319 match(Set dst (AndL dst (LoadL src))); 9320 effect(KILL cr); 9321 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9322 9323 ins_cost(150); 9324 format %{ "andq $dst, $src\t# long" %} 9325 ins_encode %{ 9326 __ andq($dst$$Register, $src$$Address); 9327 %} 9328 ins_pipe(ialu_reg_mem); 9329 %} 9330 9331 // And Memory with Register 9332 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9333 %{ 9334 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9335 effect(KILL cr); 9336 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9337 9338 ins_cost(150); 9339 format %{ "andq $dst, $src\t# long" %} 9340 ins_encode %{ 9341 __ andq($dst$$Address, $src$$Register); 9342 %} 9343 ins_pipe(ialu_mem_reg); 9344 %} 9345 9346 // And Memory with Immediate 9347 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9348 %{ 9349 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9350 effect(KILL cr); 9351 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9352 9353 ins_cost(125); 9354 format %{ "andq $dst, $src\t# long" %} 9355 ins_encode %{ 9356 __ andq($dst$$Address, $src$$constant); 9357 %} 9358 ins_pipe(ialu_mem_imm); 9359 %} 9360 9361 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9362 %{ 9363 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9364 // because AND/OR works well enough for 8/32-bit values. 9365 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9366 9367 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9368 effect(KILL cr); 9369 9370 ins_cost(125); 9371 format %{ "btrq $dst, log2(not($con))\t# long" %} 9372 ins_encode %{ 9373 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9374 %} 9375 ins_pipe(ialu_mem_imm); 9376 %} 9377 9378 // BMI1 instructions 9379 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9380 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9381 predicate(UseBMI1Instructions); 9382 effect(KILL cr); 9383 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9384 9385 ins_cost(125); 9386 format %{ "andnq $dst, $src1, $src2" %} 9387 9388 ins_encode %{ 9389 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9390 %} 9391 ins_pipe(ialu_reg_mem); 9392 %} 9393 9394 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9395 match(Set dst (AndL (XorL src1 minus_1) src2)); 9396 predicate(UseBMI1Instructions); 9397 effect(KILL cr); 9398 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9399 9400 format %{ "andnq $dst, $src1, $src2" %} 9401 9402 ins_encode %{ 9403 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9404 %} 9405 ins_pipe(ialu_reg_mem); 9406 %} 9407 9408 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9409 match(Set dst (AndL (SubL imm_zero src) src)); 9410 predicate(UseBMI1Instructions); 9411 effect(KILL cr); 9412 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9413 9414 format %{ "blsiq $dst, $src" %} 9415 9416 ins_encode %{ 9417 __ blsiq($dst$$Register, $src$$Register); 9418 %} 9419 ins_pipe(ialu_reg); 9420 %} 9421 9422 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9423 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9424 predicate(UseBMI1Instructions); 9425 effect(KILL cr); 9426 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9427 9428 ins_cost(125); 9429 format %{ "blsiq $dst, $src" %} 9430 9431 ins_encode %{ 9432 __ blsiq($dst$$Register, $src$$Address); 9433 %} 9434 ins_pipe(ialu_reg_mem); 9435 %} 9436 9437 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9438 %{ 9439 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9440 predicate(UseBMI1Instructions); 9441 effect(KILL cr); 9442 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9443 9444 ins_cost(125); 9445 format %{ "blsmskq $dst, $src" %} 9446 9447 ins_encode %{ 9448 __ blsmskq($dst$$Register, $src$$Address); 9449 %} 9450 ins_pipe(ialu_reg_mem); 9451 %} 9452 9453 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9454 %{ 9455 match(Set dst (XorL (AddL src minus_1) src)); 9456 predicate(UseBMI1Instructions); 9457 effect(KILL cr); 9458 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9459 9460 format %{ "blsmskq $dst, $src" %} 9461 9462 ins_encode %{ 9463 __ blsmskq($dst$$Register, $src$$Register); 9464 %} 9465 9466 ins_pipe(ialu_reg); 9467 %} 9468 9469 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9470 %{ 9471 match(Set dst (AndL (AddL src minus_1) src) ); 9472 predicate(UseBMI1Instructions); 9473 effect(KILL cr); 9474 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9475 9476 format %{ "blsrq $dst, $src" %} 9477 9478 ins_encode %{ 9479 __ blsrq($dst$$Register, $src$$Register); 9480 %} 9481 9482 ins_pipe(ialu_reg); 9483 %} 9484 9485 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9486 %{ 9487 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9488 predicate(UseBMI1Instructions); 9489 effect(KILL cr); 9490 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9491 9492 ins_cost(125); 9493 format %{ "blsrq $dst, $src" %} 9494 9495 ins_encode %{ 9496 __ blsrq($dst$$Register, $src$$Address); 9497 %} 9498 9499 ins_pipe(ialu_reg); 9500 %} 9501 9502 // Or Instructions 9503 // Or Register with Register 9504 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9505 %{ 9506 match(Set dst (OrL dst src)); 9507 effect(KILL cr); 9508 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9509 9510 format %{ "orq $dst, $src\t# long" %} 9511 ins_encode %{ 9512 __ orq($dst$$Register, $src$$Register); 9513 %} 9514 ins_pipe(ialu_reg_reg); 9515 %} 9516 9517 // Use any_RegP to match R15 (TLS register) without spilling. 9518 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9519 match(Set dst (OrL dst (CastP2X src))); 9520 effect(KILL cr); 9521 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9522 9523 format %{ "orq $dst, $src\t# long" %} 9524 ins_encode %{ 9525 __ orq($dst$$Register, $src$$Register); 9526 %} 9527 ins_pipe(ialu_reg_reg); 9528 %} 9529 9530 9531 // Or Register with Immediate 9532 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9533 %{ 9534 match(Set dst (OrL dst src)); 9535 effect(KILL cr); 9536 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9537 9538 format %{ "orq $dst, $src\t# long" %} 9539 ins_encode %{ 9540 __ orq($dst$$Register, $src$$constant); 9541 %} 9542 ins_pipe(ialu_reg); 9543 %} 9544 9545 // Or Register with Memory 9546 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9547 %{ 9548 match(Set dst (OrL dst (LoadL src))); 9549 effect(KILL cr); 9550 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9551 9552 ins_cost(150); 9553 format %{ "orq $dst, $src\t# long" %} 9554 ins_encode %{ 9555 __ orq($dst$$Register, $src$$Address); 9556 %} 9557 ins_pipe(ialu_reg_mem); 9558 %} 9559 9560 // Or Memory with Register 9561 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9562 %{ 9563 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9564 effect(KILL cr); 9565 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9566 9567 ins_cost(150); 9568 format %{ "orq $dst, $src\t# long" %} 9569 ins_encode %{ 9570 __ orq($dst$$Address, $src$$Register); 9571 %} 9572 ins_pipe(ialu_mem_reg); 9573 %} 9574 9575 // Or Memory with Immediate 9576 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9577 %{ 9578 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9579 effect(KILL cr); 9580 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9581 9582 ins_cost(125); 9583 format %{ "orq $dst, $src\t# long" %} 9584 ins_encode %{ 9585 __ orq($dst$$Address, $src$$constant); 9586 %} 9587 ins_pipe(ialu_mem_imm); 9588 %} 9589 9590 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9591 %{ 9592 // con should be a pure 64-bit power of 2 immediate 9593 // because AND/OR works well enough for 8/32-bit values. 9594 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9595 9596 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9597 effect(KILL cr); 9598 9599 ins_cost(125); 9600 format %{ "btsq $dst, log2($con)\t# long" %} 9601 ins_encode %{ 9602 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9603 %} 9604 ins_pipe(ialu_mem_imm); 9605 %} 9606 9607 // Xor Instructions 9608 // Xor Register with Register 9609 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9610 %{ 9611 match(Set dst (XorL dst src)); 9612 effect(KILL cr); 9613 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9614 9615 format %{ "xorq $dst, $src\t# long" %} 9616 ins_encode %{ 9617 __ xorq($dst$$Register, $src$$Register); 9618 %} 9619 ins_pipe(ialu_reg_reg); 9620 %} 9621 9622 // Xor Register with Immediate -1 9623 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9624 match(Set dst (XorL dst imm)); 9625 9626 format %{ "notq $dst" %} 9627 ins_encode %{ 9628 __ notq($dst$$Register); 9629 %} 9630 ins_pipe(ialu_reg); 9631 %} 9632 9633 // Xor Register with Immediate 9634 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9635 %{ 9636 match(Set dst (XorL dst src)); 9637 effect(KILL cr); 9638 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9639 9640 format %{ "xorq $dst, $src\t# long" %} 9641 ins_encode %{ 9642 __ xorq($dst$$Register, $src$$constant); 9643 %} 9644 ins_pipe(ialu_reg); 9645 %} 9646 9647 // Xor Register with Memory 9648 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9649 %{ 9650 match(Set dst (XorL dst (LoadL src))); 9651 effect(KILL cr); 9652 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9653 9654 ins_cost(150); 9655 format %{ "xorq $dst, $src\t# long" %} 9656 ins_encode %{ 9657 __ xorq($dst$$Register, $src$$Address); 9658 %} 9659 ins_pipe(ialu_reg_mem); 9660 %} 9661 9662 // Xor Memory with Register 9663 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9664 %{ 9665 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9666 effect(KILL cr); 9667 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9668 9669 ins_cost(150); 9670 format %{ "xorq $dst, $src\t# long" %} 9671 ins_encode %{ 9672 __ xorq($dst$$Address, $src$$Register); 9673 %} 9674 ins_pipe(ialu_mem_reg); 9675 %} 9676 9677 // Xor Memory with Immediate 9678 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9679 %{ 9680 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9681 effect(KILL cr); 9682 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9683 9684 ins_cost(125); 9685 format %{ "xorq $dst, $src\t# long" %} 9686 ins_encode %{ 9687 __ xorq($dst$$Address, $src$$constant); 9688 %} 9689 ins_pipe(ialu_mem_imm); 9690 %} 9691 9692 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9693 %{ 9694 match(Set dst (CmpLTMask p q)); 9695 effect(KILL cr); 9696 9697 ins_cost(400); 9698 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9699 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 9700 "negl $dst" %} 9701 ins_encode %{ 9702 __ cmpl($p$$Register, $q$$Register); 9703 __ setcc(Assembler::less, $dst$$Register); 9704 __ negl($dst$$Register); 9705 %} 9706 ins_pipe(pipe_slow); 9707 %} 9708 9709 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9710 %{ 9711 match(Set dst (CmpLTMask dst zero)); 9712 effect(KILL cr); 9713 9714 ins_cost(100); 9715 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9716 ins_encode %{ 9717 __ sarl($dst$$Register, 31); 9718 %} 9719 ins_pipe(ialu_reg); 9720 %} 9721 9722 /* Better to save a register than avoid a branch */ 9723 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9724 %{ 9725 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9726 effect(KILL cr); 9727 ins_cost(300); 9728 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9729 "jge done\n\t" 9730 "addl $p,$y\n" 9731 "done: " %} 9732 ins_encode %{ 9733 Register Rp = $p$$Register; 9734 Register Rq = $q$$Register; 9735 Register Ry = $y$$Register; 9736 Label done; 9737 __ subl(Rp, Rq); 9738 __ jccb(Assembler::greaterEqual, done); 9739 __ addl(Rp, Ry); 9740 __ bind(done); 9741 %} 9742 ins_pipe(pipe_cmplt); 9743 %} 9744 9745 /* Better to save a register than avoid a branch */ 9746 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9747 %{ 9748 match(Set y (AndI (CmpLTMask p q) y)); 9749 effect(KILL cr); 9750 9751 ins_cost(300); 9752 9753 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9754 "jlt done\n\t" 9755 "xorl $y, $y\n" 9756 "done: " %} 9757 ins_encode %{ 9758 Register Rp = $p$$Register; 9759 Register Rq = $q$$Register; 9760 Register Ry = $y$$Register; 9761 Label done; 9762 __ cmpl(Rp, Rq); 9763 __ jccb(Assembler::less, done); 9764 __ xorl(Ry, Ry); 9765 __ bind(done); 9766 %} 9767 ins_pipe(pipe_cmplt); 9768 %} 9769 9770 9771 //---------- FP Instructions------------------------------------------------ 9772 9773 // Really expensive, avoid 9774 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9775 %{ 9776 match(Set cr (CmpF src1 src2)); 9777 9778 ins_cost(500); 9779 format %{ "ucomiss $src1, $src2\n\t" 9780 "jnp,s exit\n\t" 9781 "pushfq\t# saw NaN, set CF\n\t" 9782 "andq [rsp], #0xffffff2b\n\t" 9783 "popfq\n" 9784 "exit:" %} 9785 ins_encode %{ 9786 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9787 emit_cmpfp_fixup(masm); 9788 %} 9789 ins_pipe(pipe_slow); 9790 %} 9791 9792 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9793 match(Set cr (CmpF src1 src2)); 9794 9795 ins_cost(100); 9796 format %{ "ucomiss $src1, $src2" %} 9797 ins_encode %{ 9798 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9799 %} 9800 ins_pipe(pipe_slow); 9801 %} 9802 9803 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9804 match(Set cr (CmpF src1 (LoadF src2))); 9805 9806 ins_cost(100); 9807 format %{ "ucomiss $src1, $src2" %} 9808 ins_encode %{ 9809 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9810 %} 9811 ins_pipe(pipe_slow); 9812 %} 9813 9814 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9815 match(Set cr (CmpF src con)); 9816 ins_cost(100); 9817 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9818 ins_encode %{ 9819 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9820 %} 9821 ins_pipe(pipe_slow); 9822 %} 9823 9824 // Really expensive, avoid 9825 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9826 %{ 9827 match(Set cr (CmpD src1 src2)); 9828 9829 ins_cost(500); 9830 format %{ "ucomisd $src1, $src2\n\t" 9831 "jnp,s exit\n\t" 9832 "pushfq\t# saw NaN, set CF\n\t" 9833 "andq [rsp], #0xffffff2b\n\t" 9834 "popfq\n" 9835 "exit:" %} 9836 ins_encode %{ 9837 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9838 emit_cmpfp_fixup(masm); 9839 %} 9840 ins_pipe(pipe_slow); 9841 %} 9842 9843 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9844 match(Set cr (CmpD src1 src2)); 9845 9846 ins_cost(100); 9847 format %{ "ucomisd $src1, $src2 test" %} 9848 ins_encode %{ 9849 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9850 %} 9851 ins_pipe(pipe_slow); 9852 %} 9853 9854 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9855 match(Set cr (CmpD src1 (LoadD src2))); 9856 9857 ins_cost(100); 9858 format %{ "ucomisd $src1, $src2" %} 9859 ins_encode %{ 9860 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9861 %} 9862 ins_pipe(pipe_slow); 9863 %} 9864 9865 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9866 match(Set cr (CmpD src con)); 9867 ins_cost(100); 9868 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9869 ins_encode %{ 9870 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9871 %} 9872 ins_pipe(pipe_slow); 9873 %} 9874 9875 // Compare into -1,0,1 9876 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9877 %{ 9878 match(Set dst (CmpF3 src1 src2)); 9879 effect(KILL cr); 9880 9881 ins_cost(275); 9882 format %{ "ucomiss $src1, $src2\n\t" 9883 "movl $dst, #-1\n\t" 9884 "jp,s done\n\t" 9885 "jb,s done\n\t" 9886 "setne $dst\n\t" 9887 "movzbl $dst, $dst\n" 9888 "done:" %} 9889 ins_encode %{ 9890 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9891 emit_cmpfp3(masm, $dst$$Register); 9892 %} 9893 ins_pipe(pipe_slow); 9894 %} 9895 9896 // Compare into -1,0,1 9897 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9898 %{ 9899 match(Set dst (CmpF3 src1 (LoadF src2))); 9900 effect(KILL cr); 9901 9902 ins_cost(275); 9903 format %{ "ucomiss $src1, $src2\n\t" 9904 "movl $dst, #-1\n\t" 9905 "jp,s done\n\t" 9906 "jb,s done\n\t" 9907 "setne $dst\n\t" 9908 "movzbl $dst, $dst\n" 9909 "done:" %} 9910 ins_encode %{ 9911 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9912 emit_cmpfp3(masm, $dst$$Register); 9913 %} 9914 ins_pipe(pipe_slow); 9915 %} 9916 9917 // Compare into -1,0,1 9918 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9919 match(Set dst (CmpF3 src con)); 9920 effect(KILL cr); 9921 9922 ins_cost(275); 9923 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9924 "movl $dst, #-1\n\t" 9925 "jp,s done\n\t" 9926 "jb,s done\n\t" 9927 "setne $dst\n\t" 9928 "movzbl $dst, $dst\n" 9929 "done:" %} 9930 ins_encode %{ 9931 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9932 emit_cmpfp3(masm, $dst$$Register); 9933 %} 9934 ins_pipe(pipe_slow); 9935 %} 9936 9937 // Compare into -1,0,1 9938 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9939 %{ 9940 match(Set dst (CmpD3 src1 src2)); 9941 effect(KILL cr); 9942 9943 ins_cost(275); 9944 format %{ "ucomisd $src1, $src2\n\t" 9945 "movl $dst, #-1\n\t" 9946 "jp,s done\n\t" 9947 "jb,s done\n\t" 9948 "setne $dst\n\t" 9949 "movzbl $dst, $dst\n" 9950 "done:" %} 9951 ins_encode %{ 9952 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9953 emit_cmpfp3(masm, $dst$$Register); 9954 %} 9955 ins_pipe(pipe_slow); 9956 %} 9957 9958 // Compare into -1,0,1 9959 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9960 %{ 9961 match(Set dst (CmpD3 src1 (LoadD src2))); 9962 effect(KILL cr); 9963 9964 ins_cost(275); 9965 format %{ "ucomisd $src1, $src2\n\t" 9966 "movl $dst, #-1\n\t" 9967 "jp,s done\n\t" 9968 "jb,s done\n\t" 9969 "setne $dst\n\t" 9970 "movzbl $dst, $dst\n" 9971 "done:" %} 9972 ins_encode %{ 9973 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9974 emit_cmpfp3(masm, $dst$$Register); 9975 %} 9976 ins_pipe(pipe_slow); 9977 %} 9978 9979 // Compare into -1,0,1 9980 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9981 match(Set dst (CmpD3 src con)); 9982 effect(KILL cr); 9983 9984 ins_cost(275); 9985 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9986 "movl $dst, #-1\n\t" 9987 "jp,s done\n\t" 9988 "jb,s done\n\t" 9989 "setne $dst\n\t" 9990 "movzbl $dst, $dst\n" 9991 "done:" %} 9992 ins_encode %{ 9993 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9994 emit_cmpfp3(masm, $dst$$Register); 9995 %} 9996 ins_pipe(pipe_slow); 9997 %} 9998 9999 //----------Arithmetic Conversion Instructions--------------------------------- 10000 10001 instruct convF2D_reg_reg(regD dst, regF src) 10002 %{ 10003 match(Set dst (ConvF2D src)); 10004 10005 format %{ "cvtss2sd $dst, $src" %} 10006 ins_encode %{ 10007 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10008 %} 10009 ins_pipe(pipe_slow); // XXX 10010 %} 10011 10012 instruct convF2D_reg_mem(regD dst, memory src) 10013 %{ 10014 predicate(UseAVX == 0); 10015 match(Set dst (ConvF2D (LoadF src))); 10016 10017 format %{ "cvtss2sd $dst, $src" %} 10018 ins_encode %{ 10019 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10020 %} 10021 ins_pipe(pipe_slow); // XXX 10022 %} 10023 10024 instruct convD2F_reg_reg(regF dst, regD src) 10025 %{ 10026 match(Set dst (ConvD2F src)); 10027 10028 format %{ "cvtsd2ss $dst, $src" %} 10029 ins_encode %{ 10030 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10031 %} 10032 ins_pipe(pipe_slow); // XXX 10033 %} 10034 10035 instruct convD2F_reg_mem(regF dst, memory src) 10036 %{ 10037 predicate(UseAVX == 0); 10038 match(Set dst (ConvD2F (LoadD src))); 10039 10040 format %{ "cvtsd2ss $dst, $src" %} 10041 ins_encode %{ 10042 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10043 %} 10044 ins_pipe(pipe_slow); // XXX 10045 %} 10046 10047 // XXX do mem variants 10048 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10049 %{ 10050 match(Set dst (ConvF2I src)); 10051 effect(KILL cr); 10052 format %{ "convert_f2i $dst, $src" %} 10053 ins_encode %{ 10054 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10055 %} 10056 ins_pipe(pipe_slow); 10057 %} 10058 10059 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10060 %{ 10061 match(Set dst (ConvF2L src)); 10062 effect(KILL cr); 10063 format %{ "convert_f2l $dst, $src"%} 10064 ins_encode %{ 10065 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10066 %} 10067 ins_pipe(pipe_slow); 10068 %} 10069 10070 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10071 %{ 10072 match(Set dst (ConvD2I src)); 10073 effect(KILL cr); 10074 format %{ "convert_d2i $dst, $src"%} 10075 ins_encode %{ 10076 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10077 %} 10078 ins_pipe(pipe_slow); 10079 %} 10080 10081 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10082 %{ 10083 match(Set dst (ConvD2L src)); 10084 effect(KILL cr); 10085 format %{ "convert_d2l $dst, $src"%} 10086 ins_encode %{ 10087 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10088 %} 10089 ins_pipe(pipe_slow); 10090 %} 10091 10092 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10093 %{ 10094 match(Set dst (RoundD src)); 10095 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10096 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10097 ins_encode %{ 10098 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10099 %} 10100 ins_pipe(pipe_slow); 10101 %} 10102 10103 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10104 %{ 10105 match(Set dst (RoundF src)); 10106 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10107 format %{ "round_float $dst,$src" %} 10108 ins_encode %{ 10109 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10110 %} 10111 ins_pipe(pipe_slow); 10112 %} 10113 10114 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10115 %{ 10116 predicate(!UseXmmI2F); 10117 match(Set dst (ConvI2F src)); 10118 10119 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10120 ins_encode %{ 10121 if (UseAVX > 0) { 10122 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10123 } 10124 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10125 %} 10126 ins_pipe(pipe_slow); // XXX 10127 %} 10128 10129 instruct convI2F_reg_mem(regF dst, memory src) 10130 %{ 10131 predicate(UseAVX == 0); 10132 match(Set dst (ConvI2F (LoadI src))); 10133 10134 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10135 ins_encode %{ 10136 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10137 %} 10138 ins_pipe(pipe_slow); // XXX 10139 %} 10140 10141 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10142 %{ 10143 predicate(!UseXmmI2D); 10144 match(Set dst (ConvI2D src)); 10145 10146 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10147 ins_encode %{ 10148 if (UseAVX > 0) { 10149 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10150 } 10151 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10152 %} 10153 ins_pipe(pipe_slow); // XXX 10154 %} 10155 10156 instruct convI2D_reg_mem(regD dst, memory src) 10157 %{ 10158 predicate(UseAVX == 0); 10159 match(Set dst (ConvI2D (LoadI src))); 10160 10161 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10162 ins_encode %{ 10163 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10164 %} 10165 ins_pipe(pipe_slow); // XXX 10166 %} 10167 10168 instruct convXI2F_reg(regF dst, rRegI src) 10169 %{ 10170 predicate(UseXmmI2F); 10171 match(Set dst (ConvI2F src)); 10172 10173 format %{ "movdl $dst, $src\n\t" 10174 "cvtdq2psl $dst, $dst\t# i2f" %} 10175 ins_encode %{ 10176 __ movdl($dst$$XMMRegister, $src$$Register); 10177 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10178 %} 10179 ins_pipe(pipe_slow); // XXX 10180 %} 10181 10182 instruct convXI2D_reg(regD dst, rRegI src) 10183 %{ 10184 predicate(UseXmmI2D); 10185 match(Set dst (ConvI2D src)); 10186 10187 format %{ "movdl $dst, $src\n\t" 10188 "cvtdq2pdl $dst, $dst\t# i2d" %} 10189 ins_encode %{ 10190 __ movdl($dst$$XMMRegister, $src$$Register); 10191 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10192 %} 10193 ins_pipe(pipe_slow); // XXX 10194 %} 10195 10196 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10197 %{ 10198 match(Set dst (ConvL2F src)); 10199 10200 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10201 ins_encode %{ 10202 if (UseAVX > 0) { 10203 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10204 } 10205 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10206 %} 10207 ins_pipe(pipe_slow); // XXX 10208 %} 10209 10210 instruct convL2F_reg_mem(regF dst, memory src) 10211 %{ 10212 predicate(UseAVX == 0); 10213 match(Set dst (ConvL2F (LoadL src))); 10214 10215 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10216 ins_encode %{ 10217 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10218 %} 10219 ins_pipe(pipe_slow); // XXX 10220 %} 10221 10222 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10223 %{ 10224 match(Set dst (ConvL2D src)); 10225 10226 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10227 ins_encode %{ 10228 if (UseAVX > 0) { 10229 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10230 } 10231 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10232 %} 10233 ins_pipe(pipe_slow); // XXX 10234 %} 10235 10236 instruct convL2D_reg_mem(regD dst, memory src) 10237 %{ 10238 predicate(UseAVX == 0); 10239 match(Set dst (ConvL2D (LoadL src))); 10240 10241 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10242 ins_encode %{ 10243 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10244 %} 10245 ins_pipe(pipe_slow); // XXX 10246 %} 10247 10248 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10249 %{ 10250 match(Set dst (ConvI2L src)); 10251 10252 ins_cost(125); 10253 format %{ "movslq $dst, $src\t# i2l" %} 10254 ins_encode %{ 10255 __ movslq($dst$$Register, $src$$Register); 10256 %} 10257 ins_pipe(ialu_reg_reg); 10258 %} 10259 10260 // Zero-extend convert int to long 10261 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10262 %{ 10263 match(Set dst (AndL (ConvI2L src) mask)); 10264 10265 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10266 ins_encode %{ 10267 if ($dst$$reg != $src$$reg) { 10268 __ movl($dst$$Register, $src$$Register); 10269 } 10270 %} 10271 ins_pipe(ialu_reg_reg); 10272 %} 10273 10274 // Zero-extend convert int to long 10275 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10276 %{ 10277 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10278 10279 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10280 ins_encode %{ 10281 __ movl($dst$$Register, $src$$Address); 10282 %} 10283 ins_pipe(ialu_reg_mem); 10284 %} 10285 10286 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10287 %{ 10288 match(Set dst (AndL src mask)); 10289 10290 format %{ "movl $dst, $src\t# zero-extend long" %} 10291 ins_encode %{ 10292 __ movl($dst$$Register, $src$$Register); 10293 %} 10294 ins_pipe(ialu_reg_reg); 10295 %} 10296 10297 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10298 %{ 10299 match(Set dst (ConvL2I src)); 10300 10301 format %{ "movl $dst, $src\t# l2i" %} 10302 ins_encode %{ 10303 __ movl($dst$$Register, $src$$Register); 10304 %} 10305 ins_pipe(ialu_reg_reg); 10306 %} 10307 10308 10309 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10310 match(Set dst (MoveF2I src)); 10311 effect(DEF dst, USE src); 10312 10313 ins_cost(125); 10314 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10315 ins_encode %{ 10316 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10317 %} 10318 ins_pipe(ialu_reg_mem); 10319 %} 10320 10321 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10322 match(Set dst (MoveI2F src)); 10323 effect(DEF dst, USE src); 10324 10325 ins_cost(125); 10326 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10327 ins_encode %{ 10328 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10329 %} 10330 ins_pipe(pipe_slow); 10331 %} 10332 10333 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10334 match(Set dst (MoveD2L src)); 10335 effect(DEF dst, USE src); 10336 10337 ins_cost(125); 10338 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10339 ins_encode %{ 10340 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10341 %} 10342 ins_pipe(ialu_reg_mem); 10343 %} 10344 10345 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10346 predicate(!UseXmmLoadAndClearUpper); 10347 match(Set dst (MoveL2D src)); 10348 effect(DEF dst, USE src); 10349 10350 ins_cost(125); 10351 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10352 ins_encode %{ 10353 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10354 %} 10355 ins_pipe(pipe_slow); 10356 %} 10357 10358 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10359 predicate(UseXmmLoadAndClearUpper); 10360 match(Set dst (MoveL2D src)); 10361 effect(DEF dst, USE src); 10362 10363 ins_cost(125); 10364 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10365 ins_encode %{ 10366 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10367 %} 10368 ins_pipe(pipe_slow); 10369 %} 10370 10371 10372 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10373 match(Set dst (MoveF2I src)); 10374 effect(DEF dst, USE src); 10375 10376 ins_cost(95); // XXX 10377 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10378 ins_encode %{ 10379 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10380 %} 10381 ins_pipe(pipe_slow); 10382 %} 10383 10384 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10385 match(Set dst (MoveI2F src)); 10386 effect(DEF dst, USE src); 10387 10388 ins_cost(100); 10389 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10390 ins_encode %{ 10391 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10392 %} 10393 ins_pipe( ialu_mem_reg ); 10394 %} 10395 10396 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10397 match(Set dst (MoveD2L src)); 10398 effect(DEF dst, USE src); 10399 10400 ins_cost(95); // XXX 10401 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10402 ins_encode %{ 10403 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10404 %} 10405 ins_pipe(pipe_slow); 10406 %} 10407 10408 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10409 match(Set dst (MoveL2D src)); 10410 effect(DEF dst, USE src); 10411 10412 ins_cost(100); 10413 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10414 ins_encode %{ 10415 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10416 %} 10417 ins_pipe(ialu_mem_reg); 10418 %} 10419 10420 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10421 match(Set dst (MoveF2I src)); 10422 effect(DEF dst, USE src); 10423 ins_cost(85); 10424 format %{ "movd $dst,$src\t# MoveF2I" %} 10425 ins_encode %{ 10426 __ movdl($dst$$Register, $src$$XMMRegister); 10427 %} 10428 ins_pipe( pipe_slow ); 10429 %} 10430 10431 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10432 match(Set dst (MoveD2L src)); 10433 effect(DEF dst, USE src); 10434 ins_cost(85); 10435 format %{ "movd $dst,$src\t# MoveD2L" %} 10436 ins_encode %{ 10437 __ movdq($dst$$Register, $src$$XMMRegister); 10438 %} 10439 ins_pipe( pipe_slow ); 10440 %} 10441 10442 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10443 match(Set dst (MoveI2F src)); 10444 effect(DEF dst, USE src); 10445 ins_cost(100); 10446 format %{ "movd $dst,$src\t# MoveI2F" %} 10447 ins_encode %{ 10448 __ movdl($dst$$XMMRegister, $src$$Register); 10449 %} 10450 ins_pipe( pipe_slow ); 10451 %} 10452 10453 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10454 match(Set dst (MoveL2D src)); 10455 effect(DEF dst, USE src); 10456 ins_cost(100); 10457 format %{ "movd $dst,$src\t# MoveL2D" %} 10458 ins_encode %{ 10459 __ movdq($dst$$XMMRegister, $src$$Register); 10460 %} 10461 ins_pipe( pipe_slow ); 10462 %} 10463 10464 // Fast clearing of an array 10465 // Small non-constant lenght ClearArray for non-AVX512 targets. 10466 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10467 Universe dummy, rFlagsReg cr) 10468 %{ 10469 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 10470 match(Set dummy (ClearArray cnt base)); 10471 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10472 10473 format %{ $$template 10474 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10475 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10476 $$emit$$"jg LARGE\n\t" 10477 $$emit$$"dec rcx\n\t" 10478 $$emit$$"js DONE\t# Zero length\n\t" 10479 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10480 $$emit$$"dec rcx\n\t" 10481 $$emit$$"jge LOOP\n\t" 10482 $$emit$$"jmp DONE\n\t" 10483 $$emit$$"# LARGE:\n\t" 10484 if (UseFastStosb) { 10485 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10486 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10487 } else if (UseXMMForObjInit) { 10488 $$emit$$"mov rdi,rax\n\t" 10489 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10490 $$emit$$"jmpq L_zero_64_bytes\n\t" 10491 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10492 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10493 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10494 $$emit$$"add 0x40,rax\n\t" 10495 $$emit$$"# L_zero_64_bytes:\n\t" 10496 $$emit$$"sub 0x8,rcx\n\t" 10497 $$emit$$"jge L_loop\n\t" 10498 $$emit$$"add 0x4,rcx\n\t" 10499 $$emit$$"jl L_tail\n\t" 10500 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10501 $$emit$$"add 0x20,rax\n\t" 10502 $$emit$$"sub 0x4,rcx\n\t" 10503 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10504 $$emit$$"add 0x4,rcx\n\t" 10505 $$emit$$"jle L_end\n\t" 10506 $$emit$$"dec rcx\n\t" 10507 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10508 $$emit$$"vmovq xmm0,(rax)\n\t" 10509 $$emit$$"add 0x8,rax\n\t" 10510 $$emit$$"dec rcx\n\t" 10511 $$emit$$"jge L_sloop\n\t" 10512 $$emit$$"# L_end:\n\t" 10513 } else { 10514 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10515 } 10516 $$emit$$"# DONE" 10517 %} 10518 ins_encode %{ 10519 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10520 $tmp$$XMMRegister, false, knoreg); 10521 %} 10522 ins_pipe(pipe_slow); 10523 %} 10524 10525 // Small non-constant length ClearArray for AVX512 targets. 10526 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10527 Universe dummy, rFlagsReg cr) 10528 %{ 10529 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 10530 match(Set dummy (ClearArray cnt base)); 10531 ins_cost(125); 10532 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10533 10534 format %{ $$template 10535 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10536 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10537 $$emit$$"jg LARGE\n\t" 10538 $$emit$$"dec rcx\n\t" 10539 $$emit$$"js DONE\t# Zero length\n\t" 10540 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10541 $$emit$$"dec rcx\n\t" 10542 $$emit$$"jge LOOP\n\t" 10543 $$emit$$"jmp DONE\n\t" 10544 $$emit$$"# LARGE:\n\t" 10545 if (UseFastStosb) { 10546 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10547 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10548 } else if (UseXMMForObjInit) { 10549 $$emit$$"mov rdi,rax\n\t" 10550 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10551 $$emit$$"jmpq L_zero_64_bytes\n\t" 10552 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10553 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10554 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10555 $$emit$$"add 0x40,rax\n\t" 10556 $$emit$$"# L_zero_64_bytes:\n\t" 10557 $$emit$$"sub 0x8,rcx\n\t" 10558 $$emit$$"jge L_loop\n\t" 10559 $$emit$$"add 0x4,rcx\n\t" 10560 $$emit$$"jl L_tail\n\t" 10561 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10562 $$emit$$"add 0x20,rax\n\t" 10563 $$emit$$"sub 0x4,rcx\n\t" 10564 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10565 $$emit$$"add 0x4,rcx\n\t" 10566 $$emit$$"jle L_end\n\t" 10567 $$emit$$"dec rcx\n\t" 10568 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10569 $$emit$$"vmovq xmm0,(rax)\n\t" 10570 $$emit$$"add 0x8,rax\n\t" 10571 $$emit$$"dec rcx\n\t" 10572 $$emit$$"jge L_sloop\n\t" 10573 $$emit$$"# L_end:\n\t" 10574 } else { 10575 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10576 } 10577 $$emit$$"# DONE" 10578 %} 10579 ins_encode %{ 10580 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10581 $tmp$$XMMRegister, false, $ktmp$$KRegister); 10582 %} 10583 ins_pipe(pipe_slow); 10584 %} 10585 10586 // Large non-constant length ClearArray for non-AVX512 targets. 10587 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10588 Universe dummy, rFlagsReg cr) 10589 %{ 10590 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 10591 match(Set dummy (ClearArray cnt base)); 10592 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10593 10594 format %{ $$template 10595 if (UseFastStosb) { 10596 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10597 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10598 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10599 } else if (UseXMMForObjInit) { 10600 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10601 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10602 $$emit$$"jmpq L_zero_64_bytes\n\t" 10603 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10604 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10605 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10606 $$emit$$"add 0x40,rax\n\t" 10607 $$emit$$"# L_zero_64_bytes:\n\t" 10608 $$emit$$"sub 0x8,rcx\n\t" 10609 $$emit$$"jge L_loop\n\t" 10610 $$emit$$"add 0x4,rcx\n\t" 10611 $$emit$$"jl L_tail\n\t" 10612 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10613 $$emit$$"add 0x20,rax\n\t" 10614 $$emit$$"sub 0x4,rcx\n\t" 10615 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10616 $$emit$$"add 0x4,rcx\n\t" 10617 $$emit$$"jle L_end\n\t" 10618 $$emit$$"dec rcx\n\t" 10619 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10620 $$emit$$"vmovq xmm0,(rax)\n\t" 10621 $$emit$$"add 0x8,rax\n\t" 10622 $$emit$$"dec rcx\n\t" 10623 $$emit$$"jge L_sloop\n\t" 10624 $$emit$$"# L_end:\n\t" 10625 } else { 10626 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10627 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10628 } 10629 %} 10630 ins_encode %{ 10631 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10632 $tmp$$XMMRegister, true, knoreg); 10633 %} 10634 ins_pipe(pipe_slow); 10635 %} 10636 10637 // Large non-constant length ClearArray for AVX512 targets. 10638 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10639 Universe dummy, rFlagsReg cr) 10640 %{ 10641 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 10642 match(Set dummy (ClearArray cnt base)); 10643 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10644 10645 format %{ $$template 10646 if (UseFastStosb) { 10647 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10648 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10649 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10650 } else if (UseXMMForObjInit) { 10651 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10652 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10653 $$emit$$"jmpq L_zero_64_bytes\n\t" 10654 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10655 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10656 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10657 $$emit$$"add 0x40,rax\n\t" 10658 $$emit$$"# L_zero_64_bytes:\n\t" 10659 $$emit$$"sub 0x8,rcx\n\t" 10660 $$emit$$"jge L_loop\n\t" 10661 $$emit$$"add 0x4,rcx\n\t" 10662 $$emit$$"jl L_tail\n\t" 10663 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10664 $$emit$$"add 0x20,rax\n\t" 10665 $$emit$$"sub 0x4,rcx\n\t" 10666 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10667 $$emit$$"add 0x4,rcx\n\t" 10668 $$emit$$"jle L_end\n\t" 10669 $$emit$$"dec rcx\n\t" 10670 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10671 $$emit$$"vmovq xmm0,(rax)\n\t" 10672 $$emit$$"add 0x8,rax\n\t" 10673 $$emit$$"dec rcx\n\t" 10674 $$emit$$"jge L_sloop\n\t" 10675 $$emit$$"# L_end:\n\t" 10676 } else { 10677 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10678 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10679 } 10680 %} 10681 ins_encode %{ 10682 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10683 $tmp$$XMMRegister, true, $ktmp$$KRegister); 10684 %} 10685 ins_pipe(pipe_slow); 10686 %} 10687 10688 // Small constant length ClearArray for AVX512 targets. 10689 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 10690 %{ 10691 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 10692 match(Set dummy (ClearArray cnt base)); 10693 ins_cost(100); 10694 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 10695 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10696 ins_encode %{ 10697 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10698 %} 10699 ins_pipe(pipe_slow); 10700 %} 10701 10702 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10703 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10704 %{ 10705 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10706 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10707 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10708 10709 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10710 ins_encode %{ 10711 __ string_compare($str1$$Register, $str2$$Register, 10712 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10713 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10714 %} 10715 ins_pipe( pipe_slow ); 10716 %} 10717 10718 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10719 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10720 %{ 10721 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10722 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10723 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10724 10725 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10726 ins_encode %{ 10727 __ string_compare($str1$$Register, $str2$$Register, 10728 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10729 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10730 %} 10731 ins_pipe( pipe_slow ); 10732 %} 10733 10734 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10735 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10736 %{ 10737 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10738 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10739 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10740 10741 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10742 ins_encode %{ 10743 __ string_compare($str1$$Register, $str2$$Register, 10744 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10745 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10746 %} 10747 ins_pipe( pipe_slow ); 10748 %} 10749 10750 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10751 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10752 %{ 10753 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10754 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10755 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10756 10757 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10758 ins_encode %{ 10759 __ string_compare($str1$$Register, $str2$$Register, 10760 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10761 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10762 %} 10763 ins_pipe( pipe_slow ); 10764 %} 10765 10766 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10767 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10768 %{ 10769 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10770 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10771 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10772 10773 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10774 ins_encode %{ 10775 __ string_compare($str1$$Register, $str2$$Register, 10776 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10777 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 10778 %} 10779 ins_pipe( pipe_slow ); 10780 %} 10781 10782 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10783 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10784 %{ 10785 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10786 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10787 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10788 10789 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10790 ins_encode %{ 10791 __ string_compare($str1$$Register, $str2$$Register, 10792 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10793 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 10794 %} 10795 ins_pipe( pipe_slow ); 10796 %} 10797 10798 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10799 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10800 %{ 10801 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10802 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10803 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10804 10805 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10806 ins_encode %{ 10807 __ string_compare($str2$$Register, $str1$$Register, 10808 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10809 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 10810 %} 10811 ins_pipe( pipe_slow ); 10812 %} 10813 10814 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10815 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10816 %{ 10817 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10818 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10819 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10820 10821 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10822 ins_encode %{ 10823 __ string_compare($str2$$Register, $str1$$Register, 10824 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10825 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 10826 %} 10827 ins_pipe( pipe_slow ); 10828 %} 10829 10830 // fast search of substring with known size. 10831 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10832 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10833 %{ 10834 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10835 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10836 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10837 10838 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10839 ins_encode %{ 10840 int icnt2 = (int)$int_cnt2$$constant; 10841 if (icnt2 >= 16) { 10842 // IndexOf for constant substrings with size >= 16 elements 10843 // which don't need to be loaded through stack. 10844 __ string_indexofC8($str1$$Register, $str2$$Register, 10845 $cnt1$$Register, $cnt2$$Register, 10846 icnt2, $result$$Register, 10847 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10848 } else { 10849 // Small strings are loaded through stack if they cross page boundary. 10850 __ string_indexof($str1$$Register, $str2$$Register, 10851 $cnt1$$Register, $cnt2$$Register, 10852 icnt2, $result$$Register, 10853 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10854 } 10855 %} 10856 ins_pipe( pipe_slow ); 10857 %} 10858 10859 // fast search of substring with known size. 10860 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10861 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10862 %{ 10863 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10864 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10865 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10866 10867 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10868 ins_encode %{ 10869 int icnt2 = (int)$int_cnt2$$constant; 10870 if (icnt2 >= 8) { 10871 // IndexOf for constant substrings with size >= 8 elements 10872 // which don't need to be loaded through stack. 10873 __ string_indexofC8($str1$$Register, $str2$$Register, 10874 $cnt1$$Register, $cnt2$$Register, 10875 icnt2, $result$$Register, 10876 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10877 } else { 10878 // Small strings are loaded through stack if they cross page boundary. 10879 __ string_indexof($str1$$Register, $str2$$Register, 10880 $cnt1$$Register, $cnt2$$Register, 10881 icnt2, $result$$Register, 10882 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10883 } 10884 %} 10885 ins_pipe( pipe_slow ); 10886 %} 10887 10888 // fast search of substring with known size. 10889 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10890 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10891 %{ 10892 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10893 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10894 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10895 10896 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10897 ins_encode %{ 10898 int icnt2 = (int)$int_cnt2$$constant; 10899 if (icnt2 >= 8) { 10900 // IndexOf for constant substrings with size >= 8 elements 10901 // which don't need to be loaded through stack. 10902 __ string_indexofC8($str1$$Register, $str2$$Register, 10903 $cnt1$$Register, $cnt2$$Register, 10904 icnt2, $result$$Register, 10905 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10906 } else { 10907 // Small strings are loaded through stack if they cross page boundary. 10908 __ string_indexof($str1$$Register, $str2$$Register, 10909 $cnt1$$Register, $cnt2$$Register, 10910 icnt2, $result$$Register, 10911 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10912 } 10913 %} 10914 ins_pipe( pipe_slow ); 10915 %} 10916 10917 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10918 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10919 %{ 10920 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10921 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10922 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10923 10924 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10925 ins_encode %{ 10926 __ string_indexof($str1$$Register, $str2$$Register, 10927 $cnt1$$Register, $cnt2$$Register, 10928 (-1), $result$$Register, 10929 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10930 %} 10931 ins_pipe( pipe_slow ); 10932 %} 10933 10934 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10935 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10936 %{ 10937 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10938 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10939 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10940 10941 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10942 ins_encode %{ 10943 __ string_indexof($str1$$Register, $str2$$Register, 10944 $cnt1$$Register, $cnt2$$Register, 10945 (-1), $result$$Register, 10946 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10947 %} 10948 ins_pipe( pipe_slow ); 10949 %} 10950 10951 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10952 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10953 %{ 10954 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10955 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10956 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10957 10958 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10959 ins_encode %{ 10960 __ string_indexof($str1$$Register, $str2$$Register, 10961 $cnt1$$Register, $cnt2$$Register, 10962 (-1), $result$$Register, 10963 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10964 %} 10965 ins_pipe( pipe_slow ); 10966 %} 10967 10968 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10969 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10970 %{ 10971 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 10972 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10973 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10974 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10975 ins_encode %{ 10976 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10977 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10978 %} 10979 ins_pipe( pipe_slow ); 10980 %} 10981 10982 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10983 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10984 %{ 10985 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 10986 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10987 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10988 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10989 ins_encode %{ 10990 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10991 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10992 %} 10993 ins_pipe( pipe_slow ); 10994 %} 10995 10996 // fast string equals 10997 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10998 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10999 %{ 11000 predicate(!VM_Version::supports_avx512vlbw()); 11001 match(Set result (StrEquals (Binary str1 str2) cnt)); 11002 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11003 11004 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11005 ins_encode %{ 11006 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11007 $cnt$$Register, $result$$Register, $tmp3$$Register, 11008 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11009 %} 11010 ins_pipe( pipe_slow ); 11011 %} 11012 11013 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11014 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11015 %{ 11016 predicate(VM_Version::supports_avx512vlbw()); 11017 match(Set result (StrEquals (Binary str1 str2) cnt)); 11018 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11019 11020 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11021 ins_encode %{ 11022 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11023 $cnt$$Register, $result$$Register, $tmp3$$Register, 11024 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11025 %} 11026 ins_pipe( pipe_slow ); 11027 %} 11028 11029 // fast array equals 11030 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11031 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11032 %{ 11033 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11034 match(Set result (AryEq ary1 ary2)); 11035 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11036 11037 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11038 ins_encode %{ 11039 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11040 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11041 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11042 %} 11043 ins_pipe( pipe_slow ); 11044 %} 11045 11046 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11047 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11048 %{ 11049 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11050 match(Set result (AryEq ary1 ary2)); 11051 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11052 11053 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11054 ins_encode %{ 11055 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11056 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11057 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11058 %} 11059 ins_pipe( pipe_slow ); 11060 %} 11061 11062 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11063 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11064 %{ 11065 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11066 match(Set result (AryEq ary1 ary2)); 11067 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11068 11069 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11070 ins_encode %{ 11071 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11072 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11073 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11074 %} 11075 ins_pipe( pipe_slow ); 11076 %} 11077 11078 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11079 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11080 %{ 11081 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11082 match(Set result (AryEq ary1 ary2)); 11083 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11084 11085 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11086 ins_encode %{ 11087 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11088 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11089 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11090 %} 11091 ins_pipe( pipe_slow ); 11092 %} 11093 11094 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11095 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11096 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11097 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11098 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11099 %{ 11100 predicate(UseAVX >= 2); 11101 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11102 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11103 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11104 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11105 USE basic_type, KILL cr); 11106 11107 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11108 ins_encode %{ 11109 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11110 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11111 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11112 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11113 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11114 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11115 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11116 %} 11117 ins_pipe( pipe_slow ); 11118 %} 11119 11120 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11121 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11122 %{ 11123 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11124 match(Set result (CountPositives ary1 len)); 11125 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11126 11127 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11128 ins_encode %{ 11129 __ count_positives($ary1$$Register, $len$$Register, 11130 $result$$Register, $tmp3$$Register, 11131 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11132 %} 11133 ins_pipe( pipe_slow ); 11134 %} 11135 11136 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11137 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11138 %{ 11139 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11140 match(Set result (CountPositives ary1 len)); 11141 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11142 11143 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11144 ins_encode %{ 11145 __ count_positives($ary1$$Register, $len$$Register, 11146 $result$$Register, $tmp3$$Register, 11147 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11148 %} 11149 ins_pipe( pipe_slow ); 11150 %} 11151 11152 // fast char[] to byte[] compression 11153 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11154 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11155 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11156 match(Set result (StrCompressedCopy src (Binary dst len))); 11157 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11158 USE_KILL len, KILL tmp5, KILL cr); 11159 11160 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11161 ins_encode %{ 11162 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11163 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11164 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11165 knoreg, knoreg); 11166 %} 11167 ins_pipe( pipe_slow ); 11168 %} 11169 11170 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11171 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11172 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11173 match(Set result (StrCompressedCopy src (Binary dst len))); 11174 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11175 USE_KILL len, KILL tmp5, KILL cr); 11176 11177 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11178 ins_encode %{ 11179 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11180 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11181 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11182 $ktmp1$$KRegister, $ktmp2$$KRegister); 11183 %} 11184 ins_pipe( pipe_slow ); 11185 %} 11186 // fast byte[] to char[] inflation 11187 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11188 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11189 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11190 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11191 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11192 11193 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11194 ins_encode %{ 11195 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11196 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11197 %} 11198 ins_pipe( pipe_slow ); 11199 %} 11200 11201 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11202 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11203 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11204 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11205 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11206 11207 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11208 ins_encode %{ 11209 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11210 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11211 %} 11212 ins_pipe( pipe_slow ); 11213 %} 11214 11215 // encode char[] to byte[] in ISO_8859_1 11216 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11217 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11218 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11219 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11220 match(Set result (EncodeISOArray src (Binary dst len))); 11221 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11222 11223 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11224 ins_encode %{ 11225 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11226 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11227 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11228 %} 11229 ins_pipe( pipe_slow ); 11230 %} 11231 11232 // encode char[] to byte[] in ASCII 11233 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11234 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11235 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11236 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11237 match(Set result (EncodeISOArray src (Binary dst len))); 11238 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11239 11240 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11241 ins_encode %{ 11242 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11243 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11244 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11245 %} 11246 ins_pipe( pipe_slow ); 11247 %} 11248 11249 //----------Overflow Math Instructions----------------------------------------- 11250 11251 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11252 %{ 11253 match(Set cr (OverflowAddI op1 op2)); 11254 effect(DEF cr, USE_KILL op1, USE op2); 11255 11256 format %{ "addl $op1, $op2\t# overflow check int" %} 11257 11258 ins_encode %{ 11259 __ addl($op1$$Register, $op2$$Register); 11260 %} 11261 ins_pipe(ialu_reg_reg); 11262 %} 11263 11264 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11265 %{ 11266 match(Set cr (OverflowAddI op1 op2)); 11267 effect(DEF cr, USE_KILL op1, USE op2); 11268 11269 format %{ "addl $op1, $op2\t# overflow check int" %} 11270 11271 ins_encode %{ 11272 __ addl($op1$$Register, $op2$$constant); 11273 %} 11274 ins_pipe(ialu_reg_reg); 11275 %} 11276 11277 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11278 %{ 11279 match(Set cr (OverflowAddL op1 op2)); 11280 effect(DEF cr, USE_KILL op1, USE op2); 11281 11282 format %{ "addq $op1, $op2\t# overflow check long" %} 11283 ins_encode %{ 11284 __ addq($op1$$Register, $op2$$Register); 11285 %} 11286 ins_pipe(ialu_reg_reg); 11287 %} 11288 11289 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11290 %{ 11291 match(Set cr (OverflowAddL op1 op2)); 11292 effect(DEF cr, USE_KILL op1, USE op2); 11293 11294 format %{ "addq $op1, $op2\t# overflow check long" %} 11295 ins_encode %{ 11296 __ addq($op1$$Register, $op2$$constant); 11297 %} 11298 ins_pipe(ialu_reg_reg); 11299 %} 11300 11301 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11302 %{ 11303 match(Set cr (OverflowSubI op1 op2)); 11304 11305 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11306 ins_encode %{ 11307 __ cmpl($op1$$Register, $op2$$Register); 11308 %} 11309 ins_pipe(ialu_reg_reg); 11310 %} 11311 11312 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11313 %{ 11314 match(Set cr (OverflowSubI op1 op2)); 11315 11316 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11317 ins_encode %{ 11318 __ cmpl($op1$$Register, $op2$$constant); 11319 %} 11320 ins_pipe(ialu_reg_reg); 11321 %} 11322 11323 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11324 %{ 11325 match(Set cr (OverflowSubL op1 op2)); 11326 11327 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11328 ins_encode %{ 11329 __ cmpq($op1$$Register, $op2$$Register); 11330 %} 11331 ins_pipe(ialu_reg_reg); 11332 %} 11333 11334 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11335 %{ 11336 match(Set cr (OverflowSubL op1 op2)); 11337 11338 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11339 ins_encode %{ 11340 __ cmpq($op1$$Register, $op2$$constant); 11341 %} 11342 ins_pipe(ialu_reg_reg); 11343 %} 11344 11345 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11346 %{ 11347 match(Set cr (OverflowSubI zero op2)); 11348 effect(DEF cr, USE_KILL op2); 11349 11350 format %{ "negl $op2\t# overflow check int" %} 11351 ins_encode %{ 11352 __ negl($op2$$Register); 11353 %} 11354 ins_pipe(ialu_reg_reg); 11355 %} 11356 11357 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11358 %{ 11359 match(Set cr (OverflowSubL zero op2)); 11360 effect(DEF cr, USE_KILL op2); 11361 11362 format %{ "negq $op2\t# overflow check long" %} 11363 ins_encode %{ 11364 __ negq($op2$$Register); 11365 %} 11366 ins_pipe(ialu_reg_reg); 11367 %} 11368 11369 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11370 %{ 11371 match(Set cr (OverflowMulI op1 op2)); 11372 effect(DEF cr, USE_KILL op1, USE op2); 11373 11374 format %{ "imull $op1, $op2\t# overflow check int" %} 11375 ins_encode %{ 11376 __ imull($op1$$Register, $op2$$Register); 11377 %} 11378 ins_pipe(ialu_reg_reg_alu0); 11379 %} 11380 11381 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11382 %{ 11383 match(Set cr (OverflowMulI op1 op2)); 11384 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11385 11386 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11387 ins_encode %{ 11388 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11389 %} 11390 ins_pipe(ialu_reg_reg_alu0); 11391 %} 11392 11393 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11394 %{ 11395 match(Set cr (OverflowMulL op1 op2)); 11396 effect(DEF cr, USE_KILL op1, USE op2); 11397 11398 format %{ "imulq $op1, $op2\t# overflow check long" %} 11399 ins_encode %{ 11400 __ imulq($op1$$Register, $op2$$Register); 11401 %} 11402 ins_pipe(ialu_reg_reg_alu0); 11403 %} 11404 11405 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11406 %{ 11407 match(Set cr (OverflowMulL op1 op2)); 11408 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11409 11410 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11411 ins_encode %{ 11412 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11413 %} 11414 ins_pipe(ialu_reg_reg_alu0); 11415 %} 11416 11417 11418 //----------Control Flow Instructions------------------------------------------ 11419 // Signed compare Instructions 11420 11421 // XXX more variants!! 11422 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11423 %{ 11424 match(Set cr (CmpI op1 op2)); 11425 effect(DEF cr, USE op1, USE op2); 11426 11427 format %{ "cmpl $op1, $op2" %} 11428 ins_encode %{ 11429 __ cmpl($op1$$Register, $op2$$Register); 11430 %} 11431 ins_pipe(ialu_cr_reg_reg); 11432 %} 11433 11434 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11435 %{ 11436 match(Set cr (CmpI op1 op2)); 11437 11438 format %{ "cmpl $op1, $op2" %} 11439 ins_encode %{ 11440 __ cmpl($op1$$Register, $op2$$constant); 11441 %} 11442 ins_pipe(ialu_cr_reg_imm); 11443 %} 11444 11445 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11446 %{ 11447 match(Set cr (CmpI op1 (LoadI op2))); 11448 11449 ins_cost(500); // XXX 11450 format %{ "cmpl $op1, $op2" %} 11451 ins_encode %{ 11452 __ cmpl($op1$$Register, $op2$$Address); 11453 %} 11454 ins_pipe(ialu_cr_reg_mem); 11455 %} 11456 11457 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11458 %{ 11459 match(Set cr (CmpI src zero)); 11460 11461 format %{ "testl $src, $src" %} 11462 ins_encode %{ 11463 __ testl($src$$Register, $src$$Register); 11464 %} 11465 ins_pipe(ialu_cr_reg_imm); 11466 %} 11467 11468 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11469 %{ 11470 match(Set cr (CmpI (AndI src con) zero)); 11471 11472 format %{ "testl $src, $con" %} 11473 ins_encode %{ 11474 __ testl($src$$Register, $con$$constant); 11475 %} 11476 ins_pipe(ialu_cr_reg_imm); 11477 %} 11478 11479 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11480 %{ 11481 match(Set cr (CmpI (AndI src1 src2) zero)); 11482 11483 format %{ "testl $src1, $src2" %} 11484 ins_encode %{ 11485 __ testl($src1$$Register, $src2$$Register); 11486 %} 11487 ins_pipe(ialu_cr_reg_imm); 11488 %} 11489 11490 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11491 %{ 11492 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11493 11494 format %{ "testl $src, $mem" %} 11495 ins_encode %{ 11496 __ testl($src$$Register, $mem$$Address); 11497 %} 11498 ins_pipe(ialu_cr_reg_mem); 11499 %} 11500 11501 // Unsigned compare Instructions; really, same as signed except they 11502 // produce an rFlagsRegU instead of rFlagsReg. 11503 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11504 %{ 11505 match(Set cr (CmpU op1 op2)); 11506 11507 format %{ "cmpl $op1, $op2\t# unsigned" %} 11508 ins_encode %{ 11509 __ cmpl($op1$$Register, $op2$$Register); 11510 %} 11511 ins_pipe(ialu_cr_reg_reg); 11512 %} 11513 11514 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11515 %{ 11516 match(Set cr (CmpU op1 op2)); 11517 11518 format %{ "cmpl $op1, $op2\t# unsigned" %} 11519 ins_encode %{ 11520 __ cmpl($op1$$Register, $op2$$constant); 11521 %} 11522 ins_pipe(ialu_cr_reg_imm); 11523 %} 11524 11525 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11526 %{ 11527 match(Set cr (CmpU op1 (LoadI op2))); 11528 11529 ins_cost(500); // XXX 11530 format %{ "cmpl $op1, $op2\t# unsigned" %} 11531 ins_encode %{ 11532 __ cmpl($op1$$Register, $op2$$Address); 11533 %} 11534 ins_pipe(ialu_cr_reg_mem); 11535 %} 11536 11537 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11538 %{ 11539 match(Set cr (CmpU src zero)); 11540 11541 format %{ "testl $src, $src\t# unsigned" %} 11542 ins_encode %{ 11543 __ testl($src$$Register, $src$$Register); 11544 %} 11545 ins_pipe(ialu_cr_reg_imm); 11546 %} 11547 11548 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11549 %{ 11550 match(Set cr (CmpP op1 op2)); 11551 11552 format %{ "cmpq $op1, $op2\t# ptr" %} 11553 ins_encode %{ 11554 __ cmpq($op1$$Register, $op2$$Register); 11555 %} 11556 ins_pipe(ialu_cr_reg_reg); 11557 %} 11558 11559 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11560 %{ 11561 match(Set cr (CmpP op1 (LoadP op2))); 11562 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11563 11564 ins_cost(500); // XXX 11565 format %{ "cmpq $op1, $op2\t# ptr" %} 11566 ins_encode %{ 11567 __ cmpq($op1$$Register, $op2$$Address); 11568 %} 11569 ins_pipe(ialu_cr_reg_mem); 11570 %} 11571 11572 // XXX this is generalized by compP_rReg_mem??? 11573 // Compare raw pointer (used in out-of-heap check). 11574 // Only works because non-oop pointers must be raw pointers 11575 // and raw pointers have no anti-dependencies. 11576 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11577 %{ 11578 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11579 n->in(2)->as_Load()->barrier_data() == 0); 11580 match(Set cr (CmpP op1 (LoadP op2))); 11581 11582 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11583 ins_encode %{ 11584 __ cmpq($op1$$Register, $op2$$Address); 11585 %} 11586 ins_pipe(ialu_cr_reg_mem); 11587 %} 11588 11589 // This will generate a signed flags result. This should be OK since 11590 // any compare to a zero should be eq/neq. 11591 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11592 %{ 11593 match(Set cr (CmpP src zero)); 11594 11595 format %{ "testq $src, $src\t# ptr" %} 11596 ins_encode %{ 11597 __ testq($src$$Register, $src$$Register); 11598 %} 11599 ins_pipe(ialu_cr_reg_imm); 11600 %} 11601 11602 // This will generate a signed flags result. This should be OK since 11603 // any compare to a zero should be eq/neq. 11604 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11605 %{ 11606 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11607 n->in(1)->as_Load()->barrier_data() == 0); 11608 match(Set cr (CmpP (LoadP op) zero)); 11609 11610 ins_cost(500); // XXX 11611 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11612 ins_encode %{ 11613 __ testq($op$$Address, 0xFFFFFFFF); 11614 %} 11615 ins_pipe(ialu_cr_reg_imm); 11616 %} 11617 11618 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11619 %{ 11620 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11621 n->in(1)->as_Load()->barrier_data() == 0); 11622 match(Set cr (CmpP (LoadP mem) zero)); 11623 11624 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11625 ins_encode %{ 11626 __ cmpq(r12, $mem$$Address); 11627 %} 11628 ins_pipe(ialu_cr_reg_mem); 11629 %} 11630 11631 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11632 %{ 11633 match(Set cr (CmpN op1 op2)); 11634 11635 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11636 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11637 ins_pipe(ialu_cr_reg_reg); 11638 %} 11639 11640 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11641 %{ 11642 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11643 match(Set cr (CmpN src (LoadN mem))); 11644 11645 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11646 ins_encode %{ 11647 __ cmpl($src$$Register, $mem$$Address); 11648 %} 11649 ins_pipe(ialu_cr_reg_mem); 11650 %} 11651 11652 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11653 match(Set cr (CmpN op1 op2)); 11654 11655 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11656 ins_encode %{ 11657 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11658 %} 11659 ins_pipe(ialu_cr_reg_imm); 11660 %} 11661 11662 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11663 %{ 11664 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11665 match(Set cr (CmpN src (LoadN mem))); 11666 11667 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11668 ins_encode %{ 11669 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11670 %} 11671 ins_pipe(ialu_cr_reg_mem); 11672 %} 11673 11674 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11675 match(Set cr (CmpN op1 op2)); 11676 11677 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11678 ins_encode %{ 11679 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11680 %} 11681 ins_pipe(ialu_cr_reg_imm); 11682 %} 11683 11684 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11685 %{ 11686 match(Set cr (CmpN src (LoadNKlass mem))); 11687 11688 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11689 ins_encode %{ 11690 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11691 %} 11692 ins_pipe(ialu_cr_reg_mem); 11693 %} 11694 11695 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11696 match(Set cr (CmpN src zero)); 11697 11698 format %{ "testl $src, $src\t# compressed ptr" %} 11699 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11700 ins_pipe(ialu_cr_reg_imm); 11701 %} 11702 11703 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11704 %{ 11705 predicate(CompressedOops::base() != nullptr && 11706 n->in(1)->as_Load()->barrier_data() == 0); 11707 match(Set cr (CmpN (LoadN mem) zero)); 11708 11709 ins_cost(500); // XXX 11710 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11711 ins_encode %{ 11712 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11713 %} 11714 ins_pipe(ialu_cr_reg_mem); 11715 %} 11716 11717 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11718 %{ 11719 predicate(CompressedOops::base() == nullptr && 11720 n->in(1)->as_Load()->barrier_data() == 0); 11721 match(Set cr (CmpN (LoadN mem) zero)); 11722 11723 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11724 ins_encode %{ 11725 __ cmpl(r12, $mem$$Address); 11726 %} 11727 ins_pipe(ialu_cr_reg_mem); 11728 %} 11729 11730 // Yanked all unsigned pointer compare operations. 11731 // Pointer compares are done with CmpP which is already unsigned. 11732 11733 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11734 %{ 11735 match(Set cr (CmpL op1 op2)); 11736 11737 format %{ "cmpq $op1, $op2" %} 11738 ins_encode %{ 11739 __ cmpq($op1$$Register, $op2$$Register); 11740 %} 11741 ins_pipe(ialu_cr_reg_reg); 11742 %} 11743 11744 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11745 %{ 11746 match(Set cr (CmpL op1 op2)); 11747 11748 format %{ "cmpq $op1, $op2" %} 11749 ins_encode %{ 11750 __ cmpq($op1$$Register, $op2$$constant); 11751 %} 11752 ins_pipe(ialu_cr_reg_imm); 11753 %} 11754 11755 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11756 %{ 11757 match(Set cr (CmpL op1 (LoadL op2))); 11758 11759 format %{ "cmpq $op1, $op2" %} 11760 ins_encode %{ 11761 __ cmpq($op1$$Register, $op2$$Address); 11762 %} 11763 ins_pipe(ialu_cr_reg_mem); 11764 %} 11765 11766 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11767 %{ 11768 match(Set cr (CmpL src zero)); 11769 11770 format %{ "testq $src, $src" %} 11771 ins_encode %{ 11772 __ testq($src$$Register, $src$$Register); 11773 %} 11774 ins_pipe(ialu_cr_reg_imm); 11775 %} 11776 11777 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11778 %{ 11779 match(Set cr (CmpL (AndL src con) zero)); 11780 11781 format %{ "testq $src, $con\t# long" %} 11782 ins_encode %{ 11783 __ testq($src$$Register, $con$$constant); 11784 %} 11785 ins_pipe(ialu_cr_reg_imm); 11786 %} 11787 11788 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 11789 %{ 11790 match(Set cr (CmpL (AndL src1 src2) zero)); 11791 11792 format %{ "testq $src1, $src2\t# long" %} 11793 ins_encode %{ 11794 __ testq($src1$$Register, $src2$$Register); 11795 %} 11796 ins_pipe(ialu_cr_reg_imm); 11797 %} 11798 11799 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11800 %{ 11801 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11802 11803 format %{ "testq $src, $mem" %} 11804 ins_encode %{ 11805 __ testq($src$$Register, $mem$$Address); 11806 %} 11807 ins_pipe(ialu_cr_reg_mem); 11808 %} 11809 11810 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11811 %{ 11812 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11813 11814 format %{ "testq $src, $mem" %} 11815 ins_encode %{ 11816 __ testq($src$$Register, $mem$$Address); 11817 %} 11818 ins_pipe(ialu_cr_reg_mem); 11819 %} 11820 11821 // Manifest a CmpU result in an integer register. Very painful. 11822 // This is the test to avoid. 11823 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 11824 %{ 11825 match(Set dst (CmpU3 src1 src2)); 11826 effect(KILL flags); 11827 11828 ins_cost(275); // XXX 11829 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 11830 "movl $dst, -1\n\t" 11831 "jb,u done\n\t" 11832 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11833 "done:" %} 11834 ins_encode %{ 11835 Label done; 11836 __ cmpl($src1$$Register, $src2$$Register); 11837 __ movl($dst$$Register, -1); 11838 __ jccb(Assembler::below, done); 11839 __ setcc(Assembler::notZero, $dst$$Register); 11840 __ bind(done); 11841 %} 11842 ins_pipe(pipe_slow); 11843 %} 11844 11845 // Manifest a CmpL result in an integer register. Very painful. 11846 // This is the test to avoid. 11847 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11848 %{ 11849 match(Set dst (CmpL3 src1 src2)); 11850 effect(KILL flags); 11851 11852 ins_cost(275); // XXX 11853 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11854 "movl $dst, -1\n\t" 11855 "jl,s done\n\t" 11856 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11857 "done:" %} 11858 ins_encode %{ 11859 Label done; 11860 __ cmpq($src1$$Register, $src2$$Register); 11861 __ movl($dst$$Register, -1); 11862 __ jccb(Assembler::less, done); 11863 __ setcc(Assembler::notZero, $dst$$Register); 11864 __ bind(done); 11865 %} 11866 ins_pipe(pipe_slow); 11867 %} 11868 11869 // Manifest a CmpUL result in an integer register. Very painful. 11870 // This is the test to avoid. 11871 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11872 %{ 11873 match(Set dst (CmpUL3 src1 src2)); 11874 effect(KILL flags); 11875 11876 ins_cost(275); // XXX 11877 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11878 "movl $dst, -1\n\t" 11879 "jb,u done\n\t" 11880 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11881 "done:" %} 11882 ins_encode %{ 11883 Label done; 11884 __ cmpq($src1$$Register, $src2$$Register); 11885 __ movl($dst$$Register, -1); 11886 __ jccb(Assembler::below, done); 11887 __ setcc(Assembler::notZero, $dst$$Register); 11888 __ bind(done); 11889 %} 11890 ins_pipe(pipe_slow); 11891 %} 11892 11893 // Unsigned long compare Instructions; really, same as signed long except they 11894 // produce an rFlagsRegU instead of rFlagsReg. 11895 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11896 %{ 11897 match(Set cr (CmpUL op1 op2)); 11898 11899 format %{ "cmpq $op1, $op2\t# unsigned" %} 11900 ins_encode %{ 11901 __ cmpq($op1$$Register, $op2$$Register); 11902 %} 11903 ins_pipe(ialu_cr_reg_reg); 11904 %} 11905 11906 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11907 %{ 11908 match(Set cr (CmpUL op1 op2)); 11909 11910 format %{ "cmpq $op1, $op2\t# unsigned" %} 11911 ins_encode %{ 11912 __ cmpq($op1$$Register, $op2$$constant); 11913 %} 11914 ins_pipe(ialu_cr_reg_imm); 11915 %} 11916 11917 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11918 %{ 11919 match(Set cr (CmpUL op1 (LoadL op2))); 11920 11921 format %{ "cmpq $op1, $op2\t# unsigned" %} 11922 ins_encode %{ 11923 __ cmpq($op1$$Register, $op2$$Address); 11924 %} 11925 ins_pipe(ialu_cr_reg_mem); 11926 %} 11927 11928 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11929 %{ 11930 match(Set cr (CmpUL src zero)); 11931 11932 format %{ "testq $src, $src\t# unsigned" %} 11933 ins_encode %{ 11934 __ testq($src$$Register, $src$$Register); 11935 %} 11936 ins_pipe(ialu_cr_reg_imm); 11937 %} 11938 11939 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11940 %{ 11941 match(Set cr (CmpI (LoadB mem) imm)); 11942 11943 ins_cost(125); 11944 format %{ "cmpb $mem, $imm" %} 11945 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11946 ins_pipe(ialu_cr_reg_mem); 11947 %} 11948 11949 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 11950 %{ 11951 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11952 11953 ins_cost(125); 11954 format %{ "testb $mem, $imm\t# ubyte" %} 11955 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11956 ins_pipe(ialu_cr_reg_mem); 11957 %} 11958 11959 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 11960 %{ 11961 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11962 11963 ins_cost(125); 11964 format %{ "testb $mem, $imm\t# byte" %} 11965 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11966 ins_pipe(ialu_cr_reg_mem); 11967 %} 11968 11969 //----------Max and Min-------------------------------------------------------- 11970 // Min Instructions 11971 11972 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11973 %{ 11974 effect(USE_DEF dst, USE src, USE cr); 11975 11976 format %{ "cmovlgt $dst, $src\t# min" %} 11977 ins_encode %{ 11978 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 11979 %} 11980 ins_pipe(pipe_cmov_reg); 11981 %} 11982 11983 11984 instruct minI_rReg(rRegI dst, rRegI src) 11985 %{ 11986 match(Set dst (MinI dst src)); 11987 11988 ins_cost(200); 11989 expand %{ 11990 rFlagsReg cr; 11991 compI_rReg(cr, dst, src); 11992 cmovI_reg_g(dst, src, cr); 11993 %} 11994 %} 11995 11996 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11997 %{ 11998 effect(USE_DEF dst, USE src, USE cr); 11999 12000 format %{ "cmovllt $dst, $src\t# max" %} 12001 ins_encode %{ 12002 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12003 %} 12004 ins_pipe(pipe_cmov_reg); 12005 %} 12006 12007 12008 instruct maxI_rReg(rRegI dst, rRegI src) 12009 %{ 12010 match(Set dst (MaxI dst src)); 12011 12012 ins_cost(200); 12013 expand %{ 12014 rFlagsReg cr; 12015 compI_rReg(cr, dst, src); 12016 cmovI_reg_l(dst, src, cr); 12017 %} 12018 %} 12019 12020 // ============================================================================ 12021 // Branch Instructions 12022 12023 // Jump Direct - Label defines a relative address from JMP+1 12024 instruct jmpDir(label labl) 12025 %{ 12026 match(Goto); 12027 effect(USE labl); 12028 12029 ins_cost(300); 12030 format %{ "jmp $labl" %} 12031 size(5); 12032 ins_encode %{ 12033 Label* L = $labl$$label; 12034 __ jmp(*L, false); // Always long jump 12035 %} 12036 ins_pipe(pipe_jmp); 12037 %} 12038 12039 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12040 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12041 %{ 12042 match(If cop cr); 12043 effect(USE labl); 12044 12045 ins_cost(300); 12046 format %{ "j$cop $labl" %} 12047 size(6); 12048 ins_encode %{ 12049 Label* L = $labl$$label; 12050 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12051 %} 12052 ins_pipe(pipe_jcc); 12053 %} 12054 12055 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12056 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12057 %{ 12058 match(CountedLoopEnd cop cr); 12059 effect(USE labl); 12060 12061 ins_cost(300); 12062 format %{ "j$cop $labl\t# loop end" %} 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 - using unsigned comparison 12072 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12073 match(If cop cmp); 12074 effect(USE labl); 12075 12076 ins_cost(300); 12077 format %{ "j$cop,u $labl" %} 12078 size(6); 12079 ins_encode %{ 12080 Label* L = $labl$$label; 12081 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12082 %} 12083 ins_pipe(pipe_jcc); 12084 %} 12085 12086 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12087 match(If cop cmp); 12088 effect(USE labl); 12089 12090 ins_cost(200); 12091 format %{ "j$cop,u $labl" %} 12092 size(6); 12093 ins_encode %{ 12094 Label* L = $labl$$label; 12095 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12096 %} 12097 ins_pipe(pipe_jcc); 12098 %} 12099 12100 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12101 match(If cop cmp); 12102 effect(USE labl); 12103 12104 ins_cost(200); 12105 format %{ $$template 12106 if ($cop$$cmpcode == Assembler::notEqual) { 12107 $$emit$$"jp,u $labl\n\t" 12108 $$emit$$"j$cop,u $labl" 12109 } else { 12110 $$emit$$"jp,u done\n\t" 12111 $$emit$$"j$cop,u $labl\n\t" 12112 $$emit$$"done:" 12113 } 12114 %} 12115 ins_encode %{ 12116 Label* l = $labl$$label; 12117 if ($cop$$cmpcode == Assembler::notEqual) { 12118 __ jcc(Assembler::parity, *l, false); 12119 __ jcc(Assembler::notEqual, *l, false); 12120 } else if ($cop$$cmpcode == Assembler::equal) { 12121 Label done; 12122 __ jccb(Assembler::parity, done); 12123 __ jcc(Assembler::equal, *l, false); 12124 __ bind(done); 12125 } else { 12126 ShouldNotReachHere(); 12127 } 12128 %} 12129 ins_pipe(pipe_jcc); 12130 %} 12131 12132 // ============================================================================ 12133 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12134 // superklass array for an instance of the superklass. Set a hidden 12135 // internal cache on a hit (cache is checked with exposed code in 12136 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12137 // encoding ALSO sets flags. 12138 12139 instruct partialSubtypeCheck(rdi_RegP result, 12140 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12141 rFlagsReg cr) 12142 %{ 12143 match(Set result (PartialSubtypeCheck sub super)); 12144 effect(KILL rcx, KILL cr); 12145 12146 ins_cost(1100); // slightly larger than the next version 12147 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12148 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12149 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12150 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12151 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12152 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12153 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12154 "miss:\t" %} 12155 12156 opcode(0x1); // Force a XOR of RDI 12157 ins_encode(enc_PartialSubtypeCheck()); 12158 ins_pipe(pipe_slow); 12159 %} 12160 12161 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12162 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12163 rFlagsReg cr) 12164 %{ 12165 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12166 predicate(UseSecondarySupersTable); 12167 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12168 12169 ins_cost(700); // smaller than the next version 12170 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12171 12172 ins_encode %{ 12173 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12174 if (InlineSecondarySupersTest) { 12175 __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12176 $temp3$$Register, $temp4$$Register, $result$$Register, 12177 super_klass_slot); 12178 } else { 12179 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12180 } 12181 %} 12182 12183 ins_pipe(pipe_slow); 12184 %} 12185 12186 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12187 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12188 immP0 zero, 12189 rdi_RegP result) 12190 %{ 12191 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12192 effect(KILL rcx, KILL result); 12193 12194 ins_cost(1000); 12195 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12196 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12197 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12198 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12199 "jne,s miss\t\t# Missed: flags nz\n\t" 12200 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12201 "miss:\t" %} 12202 12203 opcode(0x0); // No need to XOR RDI 12204 ins_encode(enc_PartialSubtypeCheck()); 12205 ins_pipe(pipe_slow); 12206 %} 12207 12208 // ============================================================================ 12209 // Branch Instructions -- short offset versions 12210 // 12211 // These instructions are used to replace jumps of a long offset (the default 12212 // match) with jumps of a shorter offset. These instructions are all tagged 12213 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12214 // match rules in general matching. Instead, the ADLC generates a conversion 12215 // method in the MachNode which can be used to do in-place replacement of the 12216 // long variant with the shorter variant. The compiler will determine if a 12217 // branch can be taken by the is_short_branch_offset() predicate in the machine 12218 // specific code section of the file. 12219 12220 // Jump Direct - Label defines a relative address from JMP+1 12221 instruct jmpDir_short(label labl) %{ 12222 match(Goto); 12223 effect(USE labl); 12224 12225 ins_cost(300); 12226 format %{ "jmp,s $labl" %} 12227 size(2); 12228 ins_encode %{ 12229 Label* L = $labl$$label; 12230 __ jmpb(*L); 12231 %} 12232 ins_pipe(pipe_jmp); 12233 ins_short_branch(1); 12234 %} 12235 12236 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12237 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12238 match(If cop cr); 12239 effect(USE labl); 12240 12241 ins_cost(300); 12242 format %{ "j$cop,s $labl" %} 12243 size(2); 12244 ins_encode %{ 12245 Label* L = $labl$$label; 12246 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12247 %} 12248 ins_pipe(pipe_jcc); 12249 ins_short_branch(1); 12250 %} 12251 12252 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12253 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12254 match(CountedLoopEnd cop cr); 12255 effect(USE labl); 12256 12257 ins_cost(300); 12258 format %{ "j$cop,s $labl\t# loop end" %} 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 - using unsigned comparison 12269 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12270 match(If cop cmp); 12271 effect(USE labl); 12272 12273 ins_cost(300); 12274 format %{ "j$cop,us $labl" %} 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 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12285 match(If cop cmp); 12286 effect(USE labl); 12287 12288 ins_cost(300); 12289 format %{ "j$cop,us $labl" %} 12290 size(2); 12291 ins_encode %{ 12292 Label* L = $labl$$label; 12293 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12294 %} 12295 ins_pipe(pipe_jcc); 12296 ins_short_branch(1); 12297 %} 12298 12299 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12300 match(If cop cmp); 12301 effect(USE labl); 12302 12303 ins_cost(300); 12304 format %{ $$template 12305 if ($cop$$cmpcode == Assembler::notEqual) { 12306 $$emit$$"jp,u,s $labl\n\t" 12307 $$emit$$"j$cop,u,s $labl" 12308 } else { 12309 $$emit$$"jp,u,s done\n\t" 12310 $$emit$$"j$cop,u,s $labl\n\t" 12311 $$emit$$"done:" 12312 } 12313 %} 12314 size(4); 12315 ins_encode %{ 12316 Label* l = $labl$$label; 12317 if ($cop$$cmpcode == Assembler::notEqual) { 12318 __ jccb(Assembler::parity, *l); 12319 __ jccb(Assembler::notEqual, *l); 12320 } else if ($cop$$cmpcode == Assembler::equal) { 12321 Label done; 12322 __ jccb(Assembler::parity, done); 12323 __ jccb(Assembler::equal, *l); 12324 __ bind(done); 12325 } else { 12326 ShouldNotReachHere(); 12327 } 12328 %} 12329 ins_pipe(pipe_jcc); 12330 ins_short_branch(1); 12331 %} 12332 12333 // ============================================================================ 12334 // inlined locking and unlocking 12335 12336 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12337 predicate(LockingMode != LM_LIGHTWEIGHT); 12338 match(Set cr (FastLock object box)); 12339 effect(TEMP tmp, TEMP scr, USE_KILL box); 12340 ins_cost(300); 12341 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12342 ins_encode %{ 12343 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12344 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12345 %} 12346 ins_pipe(pipe_slow); 12347 %} 12348 12349 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12350 predicate(LockingMode != LM_LIGHTWEIGHT); 12351 match(Set cr (FastUnlock object box)); 12352 effect(TEMP tmp, USE_KILL box); 12353 ins_cost(300); 12354 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12355 ins_encode %{ 12356 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12357 %} 12358 ins_pipe(pipe_slow); 12359 %} 12360 12361 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12362 predicate(LockingMode == LM_LIGHTWEIGHT); 12363 match(Set cr (FastLock object box)); 12364 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12365 ins_cost(300); 12366 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12367 ins_encode %{ 12368 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12369 %} 12370 ins_pipe(pipe_slow); 12371 %} 12372 12373 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12374 predicate(LockingMode == LM_LIGHTWEIGHT); 12375 match(Set cr (FastUnlock object rax_reg)); 12376 effect(TEMP tmp, USE_KILL rax_reg); 12377 ins_cost(300); 12378 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12379 ins_encode %{ 12380 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12381 %} 12382 ins_pipe(pipe_slow); 12383 %} 12384 12385 12386 // ============================================================================ 12387 // Safepoint Instructions 12388 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12389 %{ 12390 match(SafePoint poll); 12391 effect(KILL cr, USE poll); 12392 12393 format %{ "testl rax, [$poll]\t" 12394 "# Safepoint: poll for GC" %} 12395 ins_cost(125); 12396 ins_encode %{ 12397 __ relocate(relocInfo::poll_type); 12398 address pre_pc = __ pc(); 12399 __ testl(rax, Address($poll$$Register, 0)); 12400 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12401 %} 12402 ins_pipe(ialu_reg_mem); 12403 %} 12404 12405 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12406 match(Set dst (MaskAll src)); 12407 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12408 ins_encode %{ 12409 int mask_len = Matcher::vector_length(this); 12410 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12411 %} 12412 ins_pipe( pipe_slow ); 12413 %} 12414 12415 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12416 predicate(Matcher::vector_length(n) > 32); 12417 match(Set dst (MaskAll src)); 12418 effect(TEMP tmp); 12419 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12420 ins_encode %{ 12421 int mask_len = Matcher::vector_length(this); 12422 __ movslq($tmp$$Register, $src$$Register); 12423 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12424 %} 12425 ins_pipe( pipe_slow ); 12426 %} 12427 12428 // ============================================================================ 12429 // Procedure Call/Return Instructions 12430 // Call Java Static Instruction 12431 // Note: If this code changes, the corresponding ret_addr_offset() and 12432 // compute_padding() functions will have to be adjusted. 12433 instruct CallStaticJavaDirect(method meth) %{ 12434 match(CallStaticJava); 12435 effect(USE meth); 12436 12437 ins_cost(300); 12438 format %{ "call,static " %} 12439 opcode(0xE8); /* E8 cd */ 12440 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12441 ins_pipe(pipe_slow); 12442 ins_alignment(4); 12443 %} 12444 12445 // Call Java Dynamic Instruction 12446 // Note: If this code changes, the corresponding ret_addr_offset() and 12447 // compute_padding() functions will have to be adjusted. 12448 instruct CallDynamicJavaDirect(method meth) 12449 %{ 12450 match(CallDynamicJava); 12451 effect(USE meth); 12452 12453 ins_cost(300); 12454 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12455 "call,dynamic " %} 12456 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12457 ins_pipe(pipe_slow); 12458 ins_alignment(4); 12459 %} 12460 12461 // Call Runtime Instruction 12462 instruct CallRuntimeDirect(method meth) 12463 %{ 12464 match(CallRuntime); 12465 effect(USE meth); 12466 12467 ins_cost(300); 12468 format %{ "call,runtime " %} 12469 ins_encode(clear_avx, Java_To_Runtime(meth)); 12470 ins_pipe(pipe_slow); 12471 %} 12472 12473 // Call runtime without safepoint 12474 instruct CallLeafDirect(method meth) 12475 %{ 12476 match(CallLeaf); 12477 effect(USE meth); 12478 12479 ins_cost(300); 12480 format %{ "call_leaf,runtime " %} 12481 ins_encode(clear_avx, Java_To_Runtime(meth)); 12482 ins_pipe(pipe_slow); 12483 %} 12484 12485 // Call runtime without safepoint and with vector arguments 12486 instruct CallLeafDirectVector(method meth) 12487 %{ 12488 match(CallLeafVector); 12489 effect(USE meth); 12490 12491 ins_cost(300); 12492 format %{ "call_leaf,vector " %} 12493 ins_encode(Java_To_Runtime(meth)); 12494 ins_pipe(pipe_slow); 12495 %} 12496 12497 // Call runtime without safepoint 12498 instruct CallLeafNoFPDirect(method meth) 12499 %{ 12500 match(CallLeafNoFP); 12501 effect(USE meth); 12502 12503 ins_cost(300); 12504 format %{ "call_leaf_nofp,runtime " %} 12505 ins_encode(clear_avx, Java_To_Runtime(meth)); 12506 ins_pipe(pipe_slow); 12507 %} 12508 12509 // Return Instruction 12510 // Remove the return address & jump to it. 12511 // Notice: We always emit a nop after a ret to make sure there is room 12512 // for safepoint patching 12513 instruct Ret() 12514 %{ 12515 match(Return); 12516 12517 format %{ "ret" %} 12518 ins_encode %{ 12519 __ ret(0); 12520 %} 12521 ins_pipe(pipe_jmp); 12522 %} 12523 12524 // Tail Call; Jump from runtime stub to Java code. 12525 // Also known as an 'interprocedural jump'. 12526 // Target of jump will eventually return to caller. 12527 // TailJump below removes the return address. 12528 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12529 // emitted just above the TailCall which has reset rbp to the caller state. 12530 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12531 %{ 12532 match(TailCall jump_target method_ptr); 12533 12534 ins_cost(300); 12535 format %{ "jmp $jump_target\t# rbx holds method" %} 12536 ins_encode %{ 12537 __ jmp($jump_target$$Register); 12538 %} 12539 ins_pipe(pipe_jmp); 12540 %} 12541 12542 // Tail Jump; remove the return address; jump to target. 12543 // TailCall above leaves the return address around. 12544 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12545 %{ 12546 match(TailJump jump_target ex_oop); 12547 12548 ins_cost(300); 12549 format %{ "popq rdx\t# pop return address\n\t" 12550 "jmp $jump_target" %} 12551 ins_encode %{ 12552 __ popq(as_Register(RDX_enc)); 12553 __ jmp($jump_target$$Register); 12554 %} 12555 ins_pipe(pipe_jmp); 12556 %} 12557 12558 // Forward exception. 12559 instruct ForwardExceptionjmp() 12560 %{ 12561 match(ForwardException); 12562 12563 format %{ "jmp forward_exception_stub" %} 12564 ins_encode %{ 12565 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 12566 %} 12567 ins_pipe(pipe_jmp); 12568 %} 12569 12570 // Create exception oop: created by stack-crawling runtime code. 12571 // Created exception is now available to this handler, and is setup 12572 // just prior to jumping to this handler. No code emitted. 12573 instruct CreateException(rax_RegP ex_oop) 12574 %{ 12575 match(Set ex_oop (CreateEx)); 12576 12577 size(0); 12578 // use the following format syntax 12579 format %{ "# exception oop is in rax; no code emitted" %} 12580 ins_encode(); 12581 ins_pipe(empty); 12582 %} 12583 12584 // Rethrow exception: 12585 // The exception oop will come in the first argument position. 12586 // Then JUMP (not call) to the rethrow stub code. 12587 instruct RethrowException() 12588 %{ 12589 match(Rethrow); 12590 12591 // use the following format syntax 12592 format %{ "jmp rethrow_stub" %} 12593 ins_encode %{ 12594 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12595 %} 12596 ins_pipe(pipe_jmp); 12597 %} 12598 12599 // ============================================================================ 12600 // This name is KNOWN by the ADLC and cannot be changed. 12601 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12602 // for this guy. 12603 instruct tlsLoadP(r15_RegP dst) %{ 12604 match(Set dst (ThreadLocal)); 12605 effect(DEF dst); 12606 12607 size(0); 12608 format %{ "# TLS is in R15" %} 12609 ins_encode( /*empty encoding*/ ); 12610 ins_pipe(ialu_reg_reg); 12611 %} 12612 12613 12614 //----------PEEPHOLE RULES----------------------------------------------------- 12615 // These must follow all instruction definitions as they use the names 12616 // defined in the instructions definitions. 12617 // 12618 // peeppredicate ( rule_predicate ); 12619 // // the predicate unless which the peephole rule will be ignored 12620 // 12621 // peepmatch ( root_instr_name [preceding_instruction]* ); 12622 // 12623 // peepprocedure ( procedure_name ); 12624 // // provide a procedure name to perform the optimization, the procedure should 12625 // // reside in the architecture dependent peephole file, the method has the 12626 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12627 // // with the arguments being the basic block, the current node index inside the 12628 // // block, the register allocator, the functions upon invoked return a new node 12629 // // defined in peepreplace, and the rules of the nodes appearing in the 12630 // // corresponding peepmatch, the function return true if successful, else 12631 // // return false 12632 // 12633 // peepconstraint %{ 12634 // (instruction_number.operand_name relational_op instruction_number.operand_name 12635 // [, ...] ); 12636 // // instruction numbers are zero-based using left to right order in peepmatch 12637 // 12638 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12639 // // provide an instruction_number.operand_name for each operand that appears 12640 // // in the replacement instruction's match rule 12641 // 12642 // ---------VM FLAGS--------------------------------------------------------- 12643 // 12644 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12645 // 12646 // Each peephole rule is given an identifying number starting with zero and 12647 // increasing by one in the order seen by the parser. An individual peephole 12648 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12649 // on the command-line. 12650 // 12651 // ---------CURRENT LIMITATIONS---------------------------------------------- 12652 // 12653 // Only transformations inside a basic block (do we need more for peephole) 12654 // 12655 // ---------EXAMPLE---------------------------------------------------------- 12656 // 12657 // // pertinent parts of existing instructions in architecture description 12658 // instruct movI(rRegI dst, rRegI src) 12659 // %{ 12660 // match(Set dst (CopyI src)); 12661 // %} 12662 // 12663 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12664 // %{ 12665 // match(Set dst (AddI dst src)); 12666 // effect(KILL cr); 12667 // %} 12668 // 12669 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12670 // %{ 12671 // match(Set dst (AddI dst src)); 12672 // %} 12673 // 12674 // 1. Simple replacement 12675 // - Only match adjacent instructions in same basic block 12676 // - Only equality constraints 12677 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12678 // - Only one replacement instruction 12679 // 12680 // // Change (inc mov) to lea 12681 // peephole %{ 12682 // // lea should only be emitted when beneficial 12683 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12684 // // increment preceded by register-register move 12685 // peepmatch ( incI_rReg movI ); 12686 // // require that the destination register of the increment 12687 // // match the destination register of the move 12688 // peepconstraint ( 0.dst == 1.dst ); 12689 // // construct a replacement instruction that sets 12690 // // the destination to ( move's source register + one ) 12691 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12692 // %} 12693 // 12694 // 2. Procedural replacement 12695 // - More flexible finding relevent nodes 12696 // - More flexible constraints 12697 // - More flexible transformations 12698 // - May utilise architecture-dependent API more effectively 12699 // - Currently only one replacement instruction due to adlc parsing capabilities 12700 // 12701 // // Change (inc mov) to lea 12702 // peephole %{ 12703 // // lea should only be emitted when beneficial 12704 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12705 // // the rule numbers of these nodes inside are passed into the function below 12706 // peepmatch ( incI_rReg movI ); 12707 // // the method that takes the responsibility of transformation 12708 // peepprocedure ( inc_mov_to_lea ); 12709 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12710 // // node is passed into the function above 12711 // peepreplace ( leaI_rReg_immI() ); 12712 // %} 12713 12714 // These instructions is not matched by the matcher but used by the peephole 12715 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12716 %{ 12717 predicate(false); 12718 match(Set dst (AddI src1 src2)); 12719 format %{ "leal $dst, [$src1 + $src2]" %} 12720 ins_encode %{ 12721 Register dst = $dst$$Register; 12722 Register src1 = $src1$$Register; 12723 Register src2 = $src2$$Register; 12724 if (src1 != rbp && src1 != r13) { 12725 __ leal(dst, Address(src1, src2, Address::times_1)); 12726 } else { 12727 assert(src2 != rbp && src2 != r13, ""); 12728 __ leal(dst, Address(src2, src1, Address::times_1)); 12729 } 12730 %} 12731 ins_pipe(ialu_reg_reg); 12732 %} 12733 12734 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 12735 %{ 12736 predicate(false); 12737 match(Set dst (AddI src1 src2)); 12738 format %{ "leal $dst, [$src1 + $src2]" %} 12739 ins_encode %{ 12740 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 12741 %} 12742 ins_pipe(ialu_reg_reg); 12743 %} 12744 12745 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 12746 %{ 12747 predicate(false); 12748 match(Set dst (LShiftI src shift)); 12749 format %{ "leal $dst, [$src << $shift]" %} 12750 ins_encode %{ 12751 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12752 Register src = $src$$Register; 12753 if (scale == Address::times_2 && src != rbp && src != r13) { 12754 __ leal($dst$$Register, Address(src, src, Address::times_1)); 12755 } else { 12756 __ leal($dst$$Register, Address(noreg, src, scale)); 12757 } 12758 %} 12759 ins_pipe(ialu_reg_reg); 12760 %} 12761 12762 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 12763 %{ 12764 predicate(false); 12765 match(Set dst (AddL src1 src2)); 12766 format %{ "leaq $dst, [$src1 + $src2]" %} 12767 ins_encode %{ 12768 Register dst = $dst$$Register; 12769 Register src1 = $src1$$Register; 12770 Register src2 = $src2$$Register; 12771 if (src1 != rbp && src1 != r13) { 12772 __ leaq(dst, Address(src1, src2, Address::times_1)); 12773 } else { 12774 assert(src2 != rbp && src2 != r13, ""); 12775 __ leaq(dst, Address(src2, src1, Address::times_1)); 12776 } 12777 %} 12778 ins_pipe(ialu_reg_reg); 12779 %} 12780 12781 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 12782 %{ 12783 predicate(false); 12784 match(Set dst (AddL src1 src2)); 12785 format %{ "leaq $dst, [$src1 + $src2]" %} 12786 ins_encode %{ 12787 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 12788 %} 12789 ins_pipe(ialu_reg_reg); 12790 %} 12791 12792 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 12793 %{ 12794 predicate(false); 12795 match(Set dst (LShiftL src shift)); 12796 format %{ "leaq $dst, [$src << $shift]" %} 12797 ins_encode %{ 12798 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12799 Register src = $src$$Register; 12800 if (scale == Address::times_2 && src != rbp && src != r13) { 12801 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 12802 } else { 12803 __ leaq($dst$$Register, Address(noreg, src, scale)); 12804 } 12805 %} 12806 ins_pipe(ialu_reg_reg); 12807 %} 12808 12809 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 12810 // sal}) with lea instructions. The {add, sal} rules are beneficial in 12811 // processors with at least partial ALU support for lea 12812 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 12813 // beneficial for processors with full ALU support 12814 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 12815 12816 peephole 12817 %{ 12818 peeppredicate(VM_Version::supports_fast_2op_lea()); 12819 peepmatch (addI_rReg); 12820 peepprocedure (lea_coalesce_reg); 12821 peepreplace (leaI_rReg_rReg_peep()); 12822 %} 12823 12824 peephole 12825 %{ 12826 peeppredicate(VM_Version::supports_fast_2op_lea()); 12827 peepmatch (addI_rReg_imm); 12828 peepprocedure (lea_coalesce_imm); 12829 peepreplace (leaI_rReg_immI_peep()); 12830 %} 12831 12832 peephole 12833 %{ 12834 peeppredicate(VM_Version::supports_fast_3op_lea() || 12835 VM_Version::is_intel_cascade_lake()); 12836 peepmatch (incI_rReg); 12837 peepprocedure (lea_coalesce_imm); 12838 peepreplace (leaI_rReg_immI_peep()); 12839 %} 12840 12841 peephole 12842 %{ 12843 peeppredicate(VM_Version::supports_fast_3op_lea() || 12844 VM_Version::is_intel_cascade_lake()); 12845 peepmatch (decI_rReg); 12846 peepprocedure (lea_coalesce_imm); 12847 peepreplace (leaI_rReg_immI_peep()); 12848 %} 12849 12850 peephole 12851 %{ 12852 peeppredicate(VM_Version::supports_fast_2op_lea()); 12853 peepmatch (salI_rReg_immI2); 12854 peepprocedure (lea_coalesce_imm); 12855 peepreplace (leaI_rReg_immI2_peep()); 12856 %} 12857 12858 peephole 12859 %{ 12860 peeppredicate(VM_Version::supports_fast_2op_lea()); 12861 peepmatch (addL_rReg); 12862 peepprocedure (lea_coalesce_reg); 12863 peepreplace (leaL_rReg_rReg_peep()); 12864 %} 12865 12866 peephole 12867 %{ 12868 peeppredicate(VM_Version::supports_fast_2op_lea()); 12869 peepmatch (addL_rReg_imm); 12870 peepprocedure (lea_coalesce_imm); 12871 peepreplace (leaL_rReg_immL32_peep()); 12872 %} 12873 12874 peephole 12875 %{ 12876 peeppredicate(VM_Version::supports_fast_3op_lea() || 12877 VM_Version::is_intel_cascade_lake()); 12878 peepmatch (incL_rReg); 12879 peepprocedure (lea_coalesce_imm); 12880 peepreplace (leaL_rReg_immL32_peep()); 12881 %} 12882 12883 peephole 12884 %{ 12885 peeppredicate(VM_Version::supports_fast_3op_lea() || 12886 VM_Version::is_intel_cascade_lake()); 12887 peepmatch (decL_rReg); 12888 peepprocedure (lea_coalesce_imm); 12889 peepreplace (leaL_rReg_immL32_peep()); 12890 %} 12891 12892 peephole 12893 %{ 12894 peeppredicate(VM_Version::supports_fast_2op_lea()); 12895 peepmatch (salL_rReg_immI2); 12896 peepprocedure (lea_coalesce_imm); 12897 peepreplace (leaL_rReg_immI2_peep()); 12898 %} 12899 12900 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 12901 // 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 12902 12903 //int variant 12904 peephole 12905 %{ 12906 peepmatch (testI_reg); 12907 peepprocedure (test_may_remove); 12908 %} 12909 12910 //long variant 12911 peephole 12912 %{ 12913 peepmatch (testL_reg); 12914 peepprocedure (test_may_remove); 12915 %} 12916 12917 12918 //----------SMARTSPILL RULES--------------------------------------------------- 12919 // These must follow all instruction definitions as they use the names 12920 // defined in the instructions definitions.