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