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 __ setb(Assembler::notEqual, dst); 661 __ movzbl(dst, dst); 662 __ bind(done); 663 } 664 665 // Math.min() # Math.max() 666 // -------------------------- 667 // ucomis[s/d] # 668 // ja -> b # a 669 // jp -> NaN # NaN 670 // jb -> a # b 671 // je # 672 // |-jz -> a | b # a & b 673 // | -> a # 674 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 675 XMMRegister a, XMMRegister b, 676 XMMRegister xmmt, Register rt, 677 bool min, bool single) { 678 679 Label nan, zero, below, above, done; 680 681 if (single) 682 __ ucomiss(a, b); 683 else 684 __ ucomisd(a, b); 685 686 if (dst->encoding() != (min ? b : a)->encoding()) 687 __ jccb(Assembler::above, above); // CF=0 & ZF=0 688 else 689 __ jccb(Assembler::above, done); 690 691 __ jccb(Assembler::parity, nan); // PF=1 692 __ jccb(Assembler::below, below); // CF=1 693 694 // equal 695 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 696 if (single) { 697 __ ucomiss(a, xmmt); 698 __ jccb(Assembler::equal, zero); 699 700 __ movflt(dst, a); 701 __ jmp(done); 702 } 703 else { 704 __ ucomisd(a, xmmt); 705 __ jccb(Assembler::equal, zero); 706 707 __ movdbl(dst, a); 708 __ jmp(done); 709 } 710 711 __ bind(zero); 712 if (min) 713 __ vpor(dst, a, b, Assembler::AVX_128bit); 714 else 715 __ vpand(dst, a, b, Assembler::AVX_128bit); 716 717 __ jmp(done); 718 719 __ bind(above); 720 if (single) 721 __ movflt(dst, min ? b : a); 722 else 723 __ movdbl(dst, min ? b : a); 724 725 __ jmp(done); 726 727 __ bind(nan); 728 if (single) { 729 __ movl(rt, 0x7fc00000); // Float.NaN 730 __ movdl(dst, rt); 731 } 732 else { 733 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 734 __ movdq(dst, rt); 735 } 736 __ jmp(done); 737 738 __ bind(below); 739 if (single) 740 __ movflt(dst, min ? a : b); 741 else 742 __ movdbl(dst, min ? a : b); 743 744 __ bind(done); 745 } 746 747 //============================================================================= 748 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 749 750 int ConstantTable::calculate_table_base_offset() const { 751 return 0; // absolute addressing, no offset 752 } 753 754 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 755 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 756 ShouldNotReachHere(); 757 } 758 759 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 760 // Empty encoding 761 } 762 763 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 764 return 0; 765 } 766 767 #ifndef PRODUCT 768 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 769 st->print("# MachConstantBaseNode (empty encoding)"); 770 } 771 #endif 772 773 774 //============================================================================= 775 #ifndef PRODUCT 776 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 777 Compile* C = ra_->C; 778 779 int framesize = C->output()->frame_size_in_bytes(); 780 int bangsize = C->output()->bang_size_in_bytes(); 781 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 782 // Remove wordSize for return addr which is already pushed. 783 framesize -= wordSize; 784 785 if (C->output()->need_stack_bang(bangsize)) { 786 framesize -= wordSize; 787 st->print("# stack bang (%d bytes)", bangsize); 788 st->print("\n\t"); 789 st->print("pushq rbp\t# Save rbp"); 790 if (PreserveFramePointer) { 791 st->print("\n\t"); 792 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 793 } 794 if (framesize) { 795 st->print("\n\t"); 796 st->print("subq rsp, #%d\t# Create frame",framesize); 797 } 798 } else { 799 st->print("subq rsp, #%d\t# Create frame",framesize); 800 st->print("\n\t"); 801 framesize -= wordSize; 802 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 803 if (PreserveFramePointer) { 804 st->print("\n\t"); 805 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 806 if (framesize > 0) { 807 st->print("\n\t"); 808 st->print("addq rbp, #%d", framesize); 809 } 810 } 811 } 812 813 if (VerifyStackAtCalls) { 814 st->print("\n\t"); 815 framesize -= wordSize; 816 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 817 #ifdef ASSERT 818 st->print("\n\t"); 819 st->print("# stack alignment check"); 820 #endif 821 } 822 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 823 st->print("\n\t"); 824 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 825 st->print("\n\t"); 826 st->print("je fast_entry\t"); 827 st->print("\n\t"); 828 st->print("call #nmethod_entry_barrier_stub\t"); 829 st->print("\n\tfast_entry:"); 830 } 831 st->cr(); 832 } 833 #endif 834 835 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 836 Compile* C = ra_->C; 837 838 int framesize = C->output()->frame_size_in_bytes(); 839 int bangsize = C->output()->bang_size_in_bytes(); 840 841 if (C->clinit_barrier_on_entry()) { 842 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 843 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 844 845 Label L_skip_barrier; 846 Register klass = rscratch1; 847 848 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 849 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 850 851 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 852 853 __ bind(L_skip_barrier); 854 } 855 856 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 857 858 C->output()->set_frame_complete(__ offset()); 859 860 if (C->has_mach_constant_base_node()) { 861 // NOTE: We set the table base offset here because users might be 862 // emitted before MachConstantBaseNode. 863 ConstantTable& constant_table = C->output()->constant_table(); 864 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 865 } 866 } 867 868 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 869 { 870 return MachNode::size(ra_); // too many variables; just compute it 871 // the hard way 872 } 873 874 int MachPrologNode::reloc() const 875 { 876 return 0; // a large enough number 877 } 878 879 //============================================================================= 880 #ifndef PRODUCT 881 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 882 { 883 Compile* C = ra_->C; 884 if (generate_vzeroupper(C)) { 885 st->print("vzeroupper"); 886 st->cr(); st->print("\t"); 887 } 888 889 int framesize = C->output()->frame_size_in_bytes(); 890 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 891 // Remove word for return adr already pushed 892 // and RBP 893 framesize -= 2*wordSize; 894 895 if (framesize) { 896 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 897 st->print("\t"); 898 } 899 900 st->print_cr("popq rbp"); 901 if (do_polling() && C->is_method_compilation()) { 902 st->print("\t"); 903 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 904 "ja #safepoint_stub\t" 905 "# Safepoint: poll for GC"); 906 } 907 } 908 #endif 909 910 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 911 { 912 Compile* C = ra_->C; 913 914 if (generate_vzeroupper(C)) { 915 // Clear upper bits of YMM registers when current compiled code uses 916 // wide vectors to avoid AVX <-> SSE transition penalty during call. 917 __ vzeroupper(); 918 } 919 920 int framesize = C->output()->frame_size_in_bytes(); 921 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 922 // Remove word for return adr already pushed 923 // and RBP 924 framesize -= 2*wordSize; 925 926 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 927 928 if (framesize) { 929 __ addq(rsp, framesize); 930 } 931 932 __ popq(rbp); 933 934 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 935 __ reserved_stack_check(); 936 } 937 938 if (do_polling() && C->is_method_compilation()) { 939 Label dummy_label; 940 Label* code_stub = &dummy_label; 941 if (!C->output()->in_scratch_emit_size()) { 942 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 943 C->output()->add_stub(stub); 944 code_stub = &stub->entry(); 945 } 946 __ relocate(relocInfo::poll_return_type); 947 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 948 } 949 } 950 951 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 952 { 953 return MachNode::size(ra_); // too many variables; just compute it 954 // the hard way 955 } 956 957 int MachEpilogNode::reloc() const 958 { 959 return 2; // a large enough number 960 } 961 962 const Pipeline* MachEpilogNode::pipeline() const 963 { 964 return MachNode::pipeline_class(); 965 } 966 967 //============================================================================= 968 969 enum RC { 970 rc_bad, 971 rc_int, 972 rc_kreg, 973 rc_float, 974 rc_stack 975 }; 976 977 static enum RC rc_class(OptoReg::Name reg) 978 { 979 if( !OptoReg::is_valid(reg) ) return rc_bad; 980 981 if (OptoReg::is_stack(reg)) return rc_stack; 982 983 VMReg r = OptoReg::as_VMReg(reg); 984 985 if (r->is_Register()) return rc_int; 986 987 if (r->is_KRegister()) return rc_kreg; 988 989 assert(r->is_XMMRegister(), "must be"); 990 return rc_float; 991 } 992 993 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 994 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 995 int src_hi, int dst_hi, uint ireg, outputStream* st); 996 997 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 998 int stack_offset, int reg, uint ireg, outputStream* st); 999 1000 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 1001 int dst_offset, uint ireg, outputStream* st) { 1002 if (masm) { 1003 switch (ireg) { 1004 case Op_VecS: 1005 __ movq(Address(rsp, -8), rax); 1006 __ movl(rax, Address(rsp, src_offset)); 1007 __ movl(Address(rsp, dst_offset), rax); 1008 __ movq(rax, Address(rsp, -8)); 1009 break; 1010 case Op_VecD: 1011 __ pushq(Address(rsp, src_offset)); 1012 __ popq (Address(rsp, dst_offset)); 1013 break; 1014 case Op_VecX: 1015 __ pushq(Address(rsp, src_offset)); 1016 __ popq (Address(rsp, dst_offset)); 1017 __ pushq(Address(rsp, src_offset+8)); 1018 __ popq (Address(rsp, dst_offset+8)); 1019 break; 1020 case Op_VecY: 1021 __ vmovdqu(Address(rsp, -32), xmm0); 1022 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1023 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1024 __ vmovdqu(xmm0, Address(rsp, -32)); 1025 break; 1026 case Op_VecZ: 1027 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1028 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1029 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1030 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1031 break; 1032 default: 1033 ShouldNotReachHere(); 1034 } 1035 #ifndef PRODUCT 1036 } else { 1037 switch (ireg) { 1038 case Op_VecS: 1039 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1040 "movl rax, [rsp + #%d]\n\t" 1041 "movl [rsp + #%d], rax\n\t" 1042 "movq rax, [rsp - #8]", 1043 src_offset, dst_offset); 1044 break; 1045 case Op_VecD: 1046 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1047 "popq [rsp + #%d]", 1048 src_offset, dst_offset); 1049 break; 1050 case Op_VecX: 1051 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1052 "popq [rsp + #%d]\n\t" 1053 "pushq [rsp + #%d]\n\t" 1054 "popq [rsp + #%d]", 1055 src_offset, dst_offset, src_offset+8, dst_offset+8); 1056 break; 1057 case Op_VecY: 1058 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1059 "vmovdqu xmm0, [rsp + #%d]\n\t" 1060 "vmovdqu [rsp + #%d], xmm0\n\t" 1061 "vmovdqu xmm0, [rsp - #32]", 1062 src_offset, dst_offset); 1063 break; 1064 case Op_VecZ: 1065 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1066 "vmovdqu xmm0, [rsp + #%d]\n\t" 1067 "vmovdqu [rsp + #%d], xmm0\n\t" 1068 "vmovdqu xmm0, [rsp - #64]", 1069 src_offset, dst_offset); 1070 break; 1071 default: 1072 ShouldNotReachHere(); 1073 } 1074 #endif 1075 } 1076 } 1077 1078 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1079 PhaseRegAlloc* ra_, 1080 bool do_size, 1081 outputStream* st) const { 1082 assert(masm != nullptr || st != nullptr, "sanity"); 1083 // Get registers to move 1084 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1085 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1086 OptoReg::Name dst_second = ra_->get_reg_second(this); 1087 OptoReg::Name dst_first = ra_->get_reg_first(this); 1088 1089 enum RC src_second_rc = rc_class(src_second); 1090 enum RC src_first_rc = rc_class(src_first); 1091 enum RC dst_second_rc = rc_class(dst_second); 1092 enum RC dst_first_rc = rc_class(dst_first); 1093 1094 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1095 "must move at least 1 register" ); 1096 1097 if (src_first == dst_first && src_second == dst_second) { 1098 // Self copy, no move 1099 return 0; 1100 } 1101 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1102 uint ireg = ideal_reg(); 1103 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1104 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1105 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1106 // mem -> mem 1107 int src_offset = ra_->reg2offset(src_first); 1108 int dst_offset = ra_->reg2offset(dst_first); 1109 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1110 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1111 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1112 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1113 int stack_offset = ra_->reg2offset(dst_first); 1114 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1115 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1116 int stack_offset = ra_->reg2offset(src_first); 1117 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1118 } else { 1119 ShouldNotReachHere(); 1120 } 1121 return 0; 1122 } 1123 if (src_first_rc == rc_stack) { 1124 // mem -> 1125 if (dst_first_rc == rc_stack) { 1126 // mem -> mem 1127 assert(src_second != dst_first, "overlap"); 1128 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1129 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1130 // 64-bit 1131 int src_offset = ra_->reg2offset(src_first); 1132 int dst_offset = ra_->reg2offset(dst_first); 1133 if (masm) { 1134 __ pushq(Address(rsp, src_offset)); 1135 __ popq (Address(rsp, dst_offset)); 1136 #ifndef PRODUCT 1137 } else { 1138 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1139 "popq [rsp + #%d]", 1140 src_offset, dst_offset); 1141 #endif 1142 } 1143 } else { 1144 // 32-bit 1145 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1146 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1147 // No pushl/popl, so: 1148 int src_offset = ra_->reg2offset(src_first); 1149 int dst_offset = ra_->reg2offset(dst_first); 1150 if (masm) { 1151 __ movq(Address(rsp, -8), rax); 1152 __ movl(rax, Address(rsp, src_offset)); 1153 __ movl(Address(rsp, dst_offset), rax); 1154 __ movq(rax, Address(rsp, -8)); 1155 #ifndef PRODUCT 1156 } else { 1157 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1158 "movl rax, [rsp + #%d]\n\t" 1159 "movl [rsp + #%d], rax\n\t" 1160 "movq rax, [rsp - #8]", 1161 src_offset, dst_offset); 1162 #endif 1163 } 1164 } 1165 return 0; 1166 } else if (dst_first_rc == rc_int) { 1167 // mem -> gpr 1168 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1169 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1170 // 64-bit 1171 int offset = ra_->reg2offset(src_first); 1172 if (masm) { 1173 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1174 #ifndef PRODUCT 1175 } else { 1176 st->print("movq %s, [rsp + #%d]\t# spill", 1177 Matcher::regName[dst_first], 1178 offset); 1179 #endif 1180 } 1181 } else { 1182 // 32-bit 1183 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1184 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1185 int offset = ra_->reg2offset(src_first); 1186 if (masm) { 1187 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1188 #ifndef PRODUCT 1189 } else { 1190 st->print("movl %s, [rsp + #%d]\t# spill", 1191 Matcher::regName[dst_first], 1192 offset); 1193 #endif 1194 } 1195 } 1196 return 0; 1197 } else if (dst_first_rc == rc_float) { 1198 // mem-> xmm 1199 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1200 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1201 // 64-bit 1202 int offset = ra_->reg2offset(src_first); 1203 if (masm) { 1204 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1205 #ifndef PRODUCT 1206 } else { 1207 st->print("%s %s, [rsp + #%d]\t# spill", 1208 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1209 Matcher::regName[dst_first], 1210 offset); 1211 #endif 1212 } 1213 } else { 1214 // 32-bit 1215 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1216 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1217 int offset = ra_->reg2offset(src_first); 1218 if (masm) { 1219 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1220 #ifndef PRODUCT 1221 } else { 1222 st->print("movss %s, [rsp + #%d]\t# spill", 1223 Matcher::regName[dst_first], 1224 offset); 1225 #endif 1226 } 1227 } 1228 return 0; 1229 } else if (dst_first_rc == rc_kreg) { 1230 // mem -> kreg 1231 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1232 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1233 // 64-bit 1234 int offset = ra_->reg2offset(src_first); 1235 if (masm) { 1236 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1237 #ifndef PRODUCT 1238 } else { 1239 st->print("kmovq %s, [rsp + #%d]\t# spill", 1240 Matcher::regName[dst_first], 1241 offset); 1242 #endif 1243 } 1244 } 1245 return 0; 1246 } 1247 } else if (src_first_rc == rc_int) { 1248 // gpr -> 1249 if (dst_first_rc == rc_stack) { 1250 // gpr -> mem 1251 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1252 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1253 // 64-bit 1254 int offset = ra_->reg2offset(dst_first); 1255 if (masm) { 1256 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1257 #ifndef PRODUCT 1258 } else { 1259 st->print("movq [rsp + #%d], %s\t# spill", 1260 offset, 1261 Matcher::regName[src_first]); 1262 #endif 1263 } 1264 } else { 1265 // 32-bit 1266 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1267 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1268 int offset = ra_->reg2offset(dst_first); 1269 if (masm) { 1270 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1271 #ifndef PRODUCT 1272 } else { 1273 st->print("movl [rsp + #%d], %s\t# spill", 1274 offset, 1275 Matcher::regName[src_first]); 1276 #endif 1277 } 1278 } 1279 return 0; 1280 } else if (dst_first_rc == rc_int) { 1281 // gpr -> gpr 1282 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1283 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1284 // 64-bit 1285 if (masm) { 1286 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1287 as_Register(Matcher::_regEncode[src_first])); 1288 #ifndef PRODUCT 1289 } else { 1290 st->print("movq %s, %s\t# spill", 1291 Matcher::regName[dst_first], 1292 Matcher::regName[src_first]); 1293 #endif 1294 } 1295 return 0; 1296 } else { 1297 // 32-bit 1298 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1299 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1300 if (masm) { 1301 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1302 as_Register(Matcher::_regEncode[src_first])); 1303 #ifndef PRODUCT 1304 } else { 1305 st->print("movl %s, %s\t# spill", 1306 Matcher::regName[dst_first], 1307 Matcher::regName[src_first]); 1308 #endif 1309 } 1310 return 0; 1311 } 1312 } else if (dst_first_rc == rc_float) { 1313 // gpr -> xmm 1314 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1315 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1316 // 64-bit 1317 if (masm) { 1318 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1319 #ifndef PRODUCT 1320 } else { 1321 st->print("movdq %s, %s\t# spill", 1322 Matcher::regName[dst_first], 1323 Matcher::regName[src_first]); 1324 #endif 1325 } 1326 } else { 1327 // 32-bit 1328 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1329 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1330 if (masm) { 1331 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1332 #ifndef PRODUCT 1333 } else { 1334 st->print("movdl %s, %s\t# spill", 1335 Matcher::regName[dst_first], 1336 Matcher::regName[src_first]); 1337 #endif 1338 } 1339 } 1340 return 0; 1341 } else if (dst_first_rc == rc_kreg) { 1342 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1343 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1344 // 64-bit 1345 if (masm) { 1346 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1347 #ifndef PRODUCT 1348 } else { 1349 st->print("kmovq %s, %s\t# spill", 1350 Matcher::regName[dst_first], 1351 Matcher::regName[src_first]); 1352 #endif 1353 } 1354 } 1355 Unimplemented(); 1356 return 0; 1357 } 1358 } else if (src_first_rc == rc_float) { 1359 // xmm -> 1360 if (dst_first_rc == rc_stack) { 1361 // xmm -> mem 1362 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1363 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1364 // 64-bit 1365 int offset = ra_->reg2offset(dst_first); 1366 if (masm) { 1367 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1368 #ifndef PRODUCT 1369 } else { 1370 st->print("movsd [rsp + #%d], %s\t# spill", 1371 offset, 1372 Matcher::regName[src_first]); 1373 #endif 1374 } 1375 } else { 1376 // 32-bit 1377 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1378 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1379 int offset = ra_->reg2offset(dst_first); 1380 if (masm) { 1381 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1382 #ifndef PRODUCT 1383 } else { 1384 st->print("movss [rsp + #%d], %s\t# spill", 1385 offset, 1386 Matcher::regName[src_first]); 1387 #endif 1388 } 1389 } 1390 return 0; 1391 } else if (dst_first_rc == rc_int) { 1392 // xmm -> gpr 1393 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1394 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1395 // 64-bit 1396 if (masm) { 1397 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1398 #ifndef PRODUCT 1399 } else { 1400 st->print("movdq %s, %s\t# spill", 1401 Matcher::regName[dst_first], 1402 Matcher::regName[src_first]); 1403 #endif 1404 } 1405 } else { 1406 // 32-bit 1407 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1408 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1409 if (masm) { 1410 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1411 #ifndef PRODUCT 1412 } else { 1413 st->print("movdl %s, %s\t# spill", 1414 Matcher::regName[dst_first], 1415 Matcher::regName[src_first]); 1416 #endif 1417 } 1418 } 1419 return 0; 1420 } else if (dst_first_rc == rc_float) { 1421 // xmm -> xmm 1422 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1423 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1424 // 64-bit 1425 if (masm) { 1426 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1427 #ifndef PRODUCT 1428 } else { 1429 st->print("%s %s, %s\t# spill", 1430 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1431 Matcher::regName[dst_first], 1432 Matcher::regName[src_first]); 1433 #endif 1434 } 1435 } else { 1436 // 32-bit 1437 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1438 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1439 if (masm) { 1440 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1441 #ifndef PRODUCT 1442 } else { 1443 st->print("%s %s, %s\t# spill", 1444 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1445 Matcher::regName[dst_first], 1446 Matcher::regName[src_first]); 1447 #endif 1448 } 1449 } 1450 return 0; 1451 } else if (dst_first_rc == rc_kreg) { 1452 assert(false, "Illegal spilling"); 1453 return 0; 1454 } 1455 } else if (src_first_rc == rc_kreg) { 1456 if (dst_first_rc == rc_stack) { 1457 // mem -> kreg 1458 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1459 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1460 // 64-bit 1461 int offset = ra_->reg2offset(dst_first); 1462 if (masm) { 1463 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1464 #ifndef PRODUCT 1465 } else { 1466 st->print("kmovq [rsp + #%d] , %s\t# spill", 1467 offset, 1468 Matcher::regName[src_first]); 1469 #endif 1470 } 1471 } 1472 return 0; 1473 } else if (dst_first_rc == rc_int) { 1474 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1475 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1476 // 64-bit 1477 if (masm) { 1478 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1479 #ifndef PRODUCT 1480 } else { 1481 st->print("kmovq %s, %s\t# spill", 1482 Matcher::regName[dst_first], 1483 Matcher::regName[src_first]); 1484 #endif 1485 } 1486 } 1487 Unimplemented(); 1488 return 0; 1489 } else if (dst_first_rc == rc_kreg) { 1490 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1491 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1492 // 64-bit 1493 if (masm) { 1494 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1495 #ifndef PRODUCT 1496 } else { 1497 st->print("kmovq %s, %s\t# spill", 1498 Matcher::regName[dst_first], 1499 Matcher::regName[src_first]); 1500 #endif 1501 } 1502 } 1503 return 0; 1504 } else if (dst_first_rc == rc_float) { 1505 assert(false, "Illegal spill"); 1506 return 0; 1507 } 1508 } 1509 1510 assert(0," foo "); 1511 Unimplemented(); 1512 return 0; 1513 } 1514 1515 #ifndef PRODUCT 1516 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1517 implementation(nullptr, ra_, false, st); 1518 } 1519 #endif 1520 1521 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1522 implementation(masm, ra_, false, nullptr); 1523 } 1524 1525 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1526 return MachNode::size(ra_); 1527 } 1528 1529 //============================================================================= 1530 #ifndef PRODUCT 1531 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1532 { 1533 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1534 int reg = ra_->get_reg_first(this); 1535 st->print("leaq %s, [rsp + #%d]\t# box lock", 1536 Matcher::regName[reg], offset); 1537 } 1538 #endif 1539 1540 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1541 { 1542 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1543 int reg = ra_->get_encode(this); 1544 1545 __ lea(as_Register(reg), Address(rsp, offset)); 1546 } 1547 1548 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1549 { 1550 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1551 return (offset < 0x80) ? 5 : 8; // REX 1552 } 1553 1554 //============================================================================= 1555 #ifndef PRODUCT 1556 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1557 { 1558 if (UseCompressedClassPointers) { 1559 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1560 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1561 } else { 1562 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1563 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1564 } 1565 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1566 } 1567 #endif 1568 1569 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1570 { 1571 __ ic_check(InteriorEntryAlignment); 1572 } 1573 1574 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1575 { 1576 return MachNode::size(ra_); // too many variables; just compute it 1577 // the hard way 1578 } 1579 1580 1581 //============================================================================= 1582 1583 bool Matcher::supports_vector_calling_convention(void) { 1584 if (EnableVectorSupport && UseVectorStubs) { 1585 return true; 1586 } 1587 return false; 1588 } 1589 1590 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1591 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1592 int lo = XMM0_num; 1593 int hi = XMM0b_num; 1594 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1595 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1596 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1597 return OptoRegPair(hi, lo); 1598 } 1599 1600 // Is this branch offset short enough that a short branch can be used? 1601 // 1602 // NOTE: If the platform does not provide any short branch variants, then 1603 // this method should return false for offset 0. 1604 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1605 // The passed offset is relative to address of the branch. 1606 // On 86 a branch displacement is calculated relative to address 1607 // of a next instruction. 1608 offset -= br_size; 1609 1610 // the short version of jmpConUCF2 contains multiple branches, 1611 // making the reach slightly less 1612 if (rule == jmpConUCF2_rule) 1613 return (-126 <= offset && offset <= 125); 1614 return (-128 <= offset && offset <= 127); 1615 } 1616 1617 // Return whether or not this register is ever used as an argument. 1618 // This function is used on startup to build the trampoline stubs in 1619 // generateOptoStub. Registers not mentioned will be killed by the VM 1620 // call in the trampoline, and arguments in those registers not be 1621 // available to the callee. 1622 bool Matcher::can_be_java_arg(int reg) 1623 { 1624 return 1625 reg == RDI_num || reg == RDI_H_num || 1626 reg == RSI_num || reg == RSI_H_num || 1627 reg == RDX_num || reg == RDX_H_num || 1628 reg == RCX_num || reg == RCX_H_num || 1629 reg == R8_num || reg == R8_H_num || 1630 reg == R9_num || reg == R9_H_num || 1631 reg == R12_num || reg == R12_H_num || 1632 reg == XMM0_num || reg == XMM0b_num || 1633 reg == XMM1_num || reg == XMM1b_num || 1634 reg == XMM2_num || reg == XMM2b_num || 1635 reg == XMM3_num || reg == XMM3b_num || 1636 reg == XMM4_num || reg == XMM4b_num || 1637 reg == XMM5_num || reg == XMM5b_num || 1638 reg == XMM6_num || reg == XMM6b_num || 1639 reg == XMM7_num || reg == XMM7b_num; 1640 } 1641 1642 bool Matcher::is_spillable_arg(int reg) 1643 { 1644 return can_be_java_arg(reg); 1645 } 1646 1647 uint Matcher::int_pressure_limit() 1648 { 1649 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1650 } 1651 1652 uint Matcher::float_pressure_limit() 1653 { 1654 // After experiment around with different values, the following default threshold 1655 // works best for LCM's register pressure scheduling on x64. 1656 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1657 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1658 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1659 } 1660 1661 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1662 // In 64 bit mode a code which use multiply when 1663 // devisor is constant is faster than hardware 1664 // DIV instruction (it uses MulHiL). 1665 return false; 1666 } 1667 1668 // Register for DIVI projection of divmodI 1669 RegMask Matcher::divI_proj_mask() { 1670 return INT_RAX_REG_mask(); 1671 } 1672 1673 // Register for MODI projection of divmodI 1674 RegMask Matcher::modI_proj_mask() { 1675 return INT_RDX_REG_mask(); 1676 } 1677 1678 // Register for DIVL projection of divmodL 1679 RegMask Matcher::divL_proj_mask() { 1680 return LONG_RAX_REG_mask(); 1681 } 1682 1683 // Register for MODL projection of divmodL 1684 RegMask Matcher::modL_proj_mask() { 1685 return LONG_RDX_REG_mask(); 1686 } 1687 1688 // Register for saving SP into on method handle invokes. Not used on x86_64. 1689 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1690 return NO_REG_mask(); 1691 } 1692 1693 %} 1694 1695 //----------ENCODING BLOCK----------------------------------------------------- 1696 // This block specifies the encoding classes used by the compiler to 1697 // output byte streams. Encoding classes are parameterized macros 1698 // used by Machine Instruction Nodes in order to generate the bit 1699 // encoding of the instruction. Operands specify their base encoding 1700 // interface with the interface keyword. There are currently 1701 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1702 // COND_INTER. REG_INTER causes an operand to generate a function 1703 // which returns its register number when queried. CONST_INTER causes 1704 // an operand to generate a function which returns the value of the 1705 // constant when queried. MEMORY_INTER causes an operand to generate 1706 // four functions which return the Base Register, the Index Register, 1707 // the Scale Value, and the Offset Value of the operand when queried. 1708 // COND_INTER causes an operand to generate six functions which return 1709 // the encoding code (ie - encoding bits for the instruction) 1710 // associated with each basic boolean condition for a conditional 1711 // instruction. 1712 // 1713 // Instructions specify two basic values for encoding. Again, a 1714 // function is available to check if the constant displacement is an 1715 // oop. They use the ins_encode keyword to specify their encoding 1716 // classes (which must be a sequence of enc_class names, and their 1717 // parameters, specified in the encoding block), and they use the 1718 // opcode keyword to specify, in order, their primary, secondary, and 1719 // tertiary opcode. Only the opcode sections which a particular 1720 // instruction needs for encoding need to be specified. 1721 encode %{ 1722 enc_class cdql_enc(no_rax_rdx_RegI div) 1723 %{ 1724 // Full implementation of Java idiv and irem; checks for 1725 // special case as described in JVM spec., p.243 & p.271. 1726 // 1727 // normal case special case 1728 // 1729 // input : rax: dividend min_int 1730 // reg: divisor -1 1731 // 1732 // output: rax: quotient (= rax idiv reg) min_int 1733 // rdx: remainder (= rax irem reg) 0 1734 // 1735 // Code sequnce: 1736 // 1737 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1738 // 5: 75 07/08 jne e <normal> 1739 // 7: 33 d2 xor %edx,%edx 1740 // [div >= 8 -> offset + 1] 1741 // [REX_B] 1742 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1743 // c: 74 03/04 je 11 <done> 1744 // 000000000000000e <normal>: 1745 // e: 99 cltd 1746 // [div >= 8 -> offset + 1] 1747 // [REX_B] 1748 // f: f7 f9 idiv $div 1749 // 0000000000000011 <done>: 1750 Label normal; 1751 Label done; 1752 1753 // cmp $0x80000000,%eax 1754 __ cmpl(as_Register(RAX_enc), 0x80000000); 1755 1756 // jne e <normal> 1757 __ jccb(Assembler::notEqual, normal); 1758 1759 // xor %edx,%edx 1760 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1761 1762 // cmp $0xffffffffffffffff,%ecx 1763 __ cmpl($div$$Register, -1); 1764 1765 // je 11 <done> 1766 __ jccb(Assembler::equal, done); 1767 1768 // <normal> 1769 // cltd 1770 __ bind(normal); 1771 __ cdql(); 1772 1773 // idivl 1774 // <done> 1775 __ idivl($div$$Register); 1776 __ bind(done); 1777 %} 1778 1779 enc_class cdqq_enc(no_rax_rdx_RegL div) 1780 %{ 1781 // Full implementation of Java ldiv and lrem; checks for 1782 // special case as described in JVM spec., p.243 & p.271. 1783 // 1784 // normal case special case 1785 // 1786 // input : rax: dividend min_long 1787 // reg: divisor -1 1788 // 1789 // output: rax: quotient (= rax idiv reg) min_long 1790 // rdx: remainder (= rax irem reg) 0 1791 // 1792 // Code sequnce: 1793 // 1794 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1795 // 7: 00 00 80 1796 // a: 48 39 d0 cmp %rdx,%rax 1797 // d: 75 08 jne 17 <normal> 1798 // f: 33 d2 xor %edx,%edx 1799 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1800 // 15: 74 05 je 1c <done> 1801 // 0000000000000017 <normal>: 1802 // 17: 48 99 cqto 1803 // 19: 48 f7 f9 idiv $div 1804 // 000000000000001c <done>: 1805 Label normal; 1806 Label done; 1807 1808 // mov $0x8000000000000000,%rdx 1809 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1810 1811 // cmp %rdx,%rax 1812 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1813 1814 // jne 17 <normal> 1815 __ jccb(Assembler::notEqual, normal); 1816 1817 // xor %edx,%edx 1818 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1819 1820 // cmp $0xffffffffffffffff,$div 1821 __ cmpq($div$$Register, -1); 1822 1823 // je 1e <done> 1824 __ jccb(Assembler::equal, done); 1825 1826 // <normal> 1827 // cqto 1828 __ bind(normal); 1829 __ cdqq(); 1830 1831 // idivq (note: must be emitted by the user of this rule) 1832 // <done> 1833 __ idivq($div$$Register); 1834 __ bind(done); 1835 %} 1836 1837 enc_class enc_PartialSubtypeCheck() 1838 %{ 1839 Register Rrdi = as_Register(RDI_enc); // result register 1840 Register Rrax = as_Register(RAX_enc); // super class 1841 Register Rrcx = as_Register(RCX_enc); // killed 1842 Register Rrsi = as_Register(RSI_enc); // sub class 1843 Label miss; 1844 const bool set_cond_codes = true; 1845 1846 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1847 nullptr, &miss, 1848 /*set_cond_codes:*/ true); 1849 if ($primary) { 1850 __ xorptr(Rrdi, Rrdi); 1851 } 1852 __ bind(miss); 1853 %} 1854 1855 enc_class clear_avx %{ 1856 debug_only(int off0 = __ offset()); 1857 if (generate_vzeroupper(Compile::current())) { 1858 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1859 // Clear upper bits of YMM registers when current compiled code uses 1860 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1861 __ vzeroupper(); 1862 } 1863 debug_only(int off1 = __ offset()); 1864 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1865 %} 1866 1867 enc_class Java_To_Runtime(method meth) %{ 1868 // No relocation needed 1869 __ mov64(r10, (int64_t) $meth$$method); 1870 __ call(r10); 1871 __ post_call_nop(); 1872 %} 1873 1874 enc_class Java_Static_Call(method meth) 1875 %{ 1876 // JAVA STATIC CALL 1877 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1878 // determine who we intended to call. 1879 if (!_method) { 1880 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1881 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1882 // The NOP here is purely to ensure that eliding a call to 1883 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1884 __ addr_nop_5(); 1885 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1886 } else { 1887 int method_index = resolved_method_index(masm); 1888 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1889 : static_call_Relocation::spec(method_index); 1890 address mark = __ pc(); 1891 int call_offset = __ offset(); 1892 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1893 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1894 // Calls of the same statically bound method can share 1895 // a stub to the interpreter. 1896 __ code()->shared_stub_to_interp_for(_method, call_offset); 1897 } else { 1898 // Emit stubs for static call. 1899 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1900 __ clear_inst_mark(); 1901 if (stub == nullptr) { 1902 ciEnv::current()->record_failure("CodeCache is full"); 1903 return; 1904 } 1905 } 1906 } 1907 __ post_call_nop(); 1908 %} 1909 1910 enc_class Java_Dynamic_Call(method meth) %{ 1911 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1912 __ post_call_nop(); 1913 %} 1914 1915 %} 1916 1917 1918 1919 //----------FRAME-------------------------------------------------------------- 1920 // Definition of frame structure and management information. 1921 // 1922 // S T A C K L A Y O U T Allocators stack-slot number 1923 // | (to get allocators register number 1924 // G Owned by | | v add OptoReg::stack0()) 1925 // r CALLER | | 1926 // o | +--------+ pad to even-align allocators stack-slot 1927 // w V | pad0 | numbers; owned by CALLER 1928 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1929 // h ^ | in | 5 1930 // | | args | 4 Holes in incoming args owned by SELF 1931 // | | | | 3 1932 // | | +--------+ 1933 // V | | old out| Empty on Intel, window on Sparc 1934 // | old |preserve| Must be even aligned. 1935 // | SP-+--------+----> Matcher::_old_SP, even aligned 1936 // | | in | 3 area for Intel ret address 1937 // Owned by |preserve| Empty on Sparc. 1938 // SELF +--------+ 1939 // | | pad2 | 2 pad to align old SP 1940 // | +--------+ 1 1941 // | | locks | 0 1942 // | +--------+----> OptoReg::stack0(), even aligned 1943 // | | pad1 | 11 pad to align new SP 1944 // | +--------+ 1945 // | | | 10 1946 // | | spills | 9 spills 1947 // V | | 8 (pad0 slot for callee) 1948 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1949 // ^ | out | 7 1950 // | | args | 6 Holes in outgoing args owned by CALLEE 1951 // Owned by +--------+ 1952 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1953 // | new |preserve| Must be even-aligned. 1954 // | SP-+--------+----> Matcher::_new_SP, even aligned 1955 // | | | 1956 // 1957 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1958 // known from SELF's arguments and the Java calling convention. 1959 // Region 6-7 is determined per call site. 1960 // Note 2: If the calling convention leaves holes in the incoming argument 1961 // area, those holes are owned by SELF. Holes in the outgoing area 1962 // are owned by the CALLEE. Holes should not be necessary in the 1963 // incoming area, as the Java calling convention is completely under 1964 // the control of the AD file. Doubles can be sorted and packed to 1965 // avoid holes. Holes in the outgoing arguments may be necessary for 1966 // varargs C calling conventions. 1967 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1968 // even aligned with pad0 as needed. 1969 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1970 // region 6-11 is even aligned; it may be padded out more so that 1971 // the region from SP to FP meets the minimum stack alignment. 1972 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1973 // alignment. Region 11, pad1, may be dynamically extended so that 1974 // SP meets the minimum alignment. 1975 1976 frame 1977 %{ 1978 // These three registers define part of the calling convention 1979 // between compiled code and the interpreter. 1980 inline_cache_reg(RAX); // Inline Cache Register 1981 1982 // Optional: name the operand used by cisc-spilling to access 1983 // [stack_pointer + offset] 1984 cisc_spilling_operand_name(indOffset32); 1985 1986 // Number of stack slots consumed by locking an object 1987 sync_stack_slots(2); 1988 1989 // Compiled code's Frame Pointer 1990 frame_pointer(RSP); 1991 1992 // Interpreter stores its frame pointer in a register which is 1993 // stored to the stack by I2CAdaptors. 1994 // I2CAdaptors convert from interpreted java to compiled java. 1995 interpreter_frame_pointer(RBP); 1996 1997 // Stack alignment requirement 1998 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1999 2000 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2001 // for calls to C. Supports the var-args backing area for register parms. 2002 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2003 2004 // The after-PROLOG location of the return address. Location of 2005 // return address specifies a type (REG or STACK) and a number 2006 // representing the register number (i.e. - use a register name) or 2007 // stack slot. 2008 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2009 // Otherwise, it is above the locks and verification slot and alignment word 2010 return_addr(STACK - 2 + 2011 align_up((Compile::current()->in_preserve_stack_slots() + 2012 Compile::current()->fixed_slots()), 2013 stack_alignment_in_slots())); 2014 2015 // Location of compiled Java return values. Same as C for now. 2016 return_value 2017 %{ 2018 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2019 "only return normal values"); 2020 2021 static const int lo[Op_RegL + 1] = { 2022 0, 2023 0, 2024 RAX_num, // Op_RegN 2025 RAX_num, // Op_RegI 2026 RAX_num, // Op_RegP 2027 XMM0_num, // Op_RegF 2028 XMM0_num, // Op_RegD 2029 RAX_num // Op_RegL 2030 }; 2031 static const int hi[Op_RegL + 1] = { 2032 0, 2033 0, 2034 OptoReg::Bad, // Op_RegN 2035 OptoReg::Bad, // Op_RegI 2036 RAX_H_num, // Op_RegP 2037 OptoReg::Bad, // Op_RegF 2038 XMM0b_num, // Op_RegD 2039 RAX_H_num // Op_RegL 2040 }; 2041 // Excluded flags and vector registers. 2042 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2043 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2044 %} 2045 %} 2046 2047 //----------ATTRIBUTES--------------------------------------------------------- 2048 //----------Operand Attributes------------------------------------------------- 2049 op_attrib op_cost(0); // Required cost attribute 2050 2051 //----------Instruction Attributes--------------------------------------------- 2052 ins_attrib ins_cost(100); // Required cost attribute 2053 ins_attrib ins_size(8); // Required size attribute (in bits) 2054 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2055 // a non-matching short branch variant 2056 // of some long branch? 2057 ins_attrib ins_alignment(1); // Required alignment attribute (must 2058 // be a power of 2) specifies the 2059 // alignment that some part of the 2060 // instruction (not necessarily the 2061 // start) requires. If > 1, a 2062 // compute_padding() function must be 2063 // provided for the instruction 2064 2065 //----------OPERANDS----------------------------------------------------------- 2066 // Operand definitions must precede instruction definitions for correct parsing 2067 // in the ADLC because operands constitute user defined types which are used in 2068 // instruction definitions. 2069 2070 //----------Simple Operands---------------------------------------------------- 2071 // Immediate Operands 2072 // Integer Immediate 2073 operand immI() 2074 %{ 2075 match(ConI); 2076 2077 op_cost(10); 2078 format %{ %} 2079 interface(CONST_INTER); 2080 %} 2081 2082 // Constant for test vs zero 2083 operand immI_0() 2084 %{ 2085 predicate(n->get_int() == 0); 2086 match(ConI); 2087 2088 op_cost(0); 2089 format %{ %} 2090 interface(CONST_INTER); 2091 %} 2092 2093 // Constant for increment 2094 operand immI_1() 2095 %{ 2096 predicate(n->get_int() == 1); 2097 match(ConI); 2098 2099 op_cost(0); 2100 format %{ %} 2101 interface(CONST_INTER); 2102 %} 2103 2104 // Constant for decrement 2105 operand immI_M1() 2106 %{ 2107 predicate(n->get_int() == -1); 2108 match(ConI); 2109 2110 op_cost(0); 2111 format %{ %} 2112 interface(CONST_INTER); 2113 %} 2114 2115 operand immI_2() 2116 %{ 2117 predicate(n->get_int() == 2); 2118 match(ConI); 2119 2120 op_cost(0); 2121 format %{ %} 2122 interface(CONST_INTER); 2123 %} 2124 2125 operand immI_4() 2126 %{ 2127 predicate(n->get_int() == 4); 2128 match(ConI); 2129 2130 op_cost(0); 2131 format %{ %} 2132 interface(CONST_INTER); 2133 %} 2134 2135 operand immI_8() 2136 %{ 2137 predicate(n->get_int() == 8); 2138 match(ConI); 2139 2140 op_cost(0); 2141 format %{ %} 2142 interface(CONST_INTER); 2143 %} 2144 2145 // Valid scale values for addressing modes 2146 operand immI2() 2147 %{ 2148 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2149 match(ConI); 2150 2151 format %{ %} 2152 interface(CONST_INTER); 2153 %} 2154 2155 operand immU7() 2156 %{ 2157 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2158 match(ConI); 2159 2160 op_cost(5); 2161 format %{ %} 2162 interface(CONST_INTER); 2163 %} 2164 2165 operand immI8() 2166 %{ 2167 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2168 match(ConI); 2169 2170 op_cost(5); 2171 format %{ %} 2172 interface(CONST_INTER); 2173 %} 2174 2175 operand immU8() 2176 %{ 2177 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2178 match(ConI); 2179 2180 op_cost(5); 2181 format %{ %} 2182 interface(CONST_INTER); 2183 %} 2184 2185 operand immI16() 2186 %{ 2187 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2188 match(ConI); 2189 2190 op_cost(10); 2191 format %{ %} 2192 interface(CONST_INTER); 2193 %} 2194 2195 // Int Immediate non-negative 2196 operand immU31() 2197 %{ 2198 predicate(n->get_int() >= 0); 2199 match(ConI); 2200 2201 op_cost(0); 2202 format %{ %} 2203 interface(CONST_INTER); 2204 %} 2205 2206 // Pointer Immediate 2207 operand immP() 2208 %{ 2209 match(ConP); 2210 2211 op_cost(10); 2212 format %{ %} 2213 interface(CONST_INTER); 2214 %} 2215 2216 // Null Pointer Immediate 2217 operand immP0() 2218 %{ 2219 predicate(n->get_ptr() == 0); 2220 match(ConP); 2221 2222 op_cost(5); 2223 format %{ %} 2224 interface(CONST_INTER); 2225 %} 2226 2227 // Pointer Immediate 2228 operand immN() %{ 2229 match(ConN); 2230 2231 op_cost(10); 2232 format %{ %} 2233 interface(CONST_INTER); 2234 %} 2235 2236 operand immNKlass() %{ 2237 match(ConNKlass); 2238 2239 op_cost(10); 2240 format %{ %} 2241 interface(CONST_INTER); 2242 %} 2243 2244 // Null Pointer Immediate 2245 operand immN0() %{ 2246 predicate(n->get_narrowcon() == 0); 2247 match(ConN); 2248 2249 op_cost(5); 2250 format %{ %} 2251 interface(CONST_INTER); 2252 %} 2253 2254 operand immP31() 2255 %{ 2256 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2257 && (n->get_ptr() >> 31) == 0); 2258 match(ConP); 2259 2260 op_cost(5); 2261 format %{ %} 2262 interface(CONST_INTER); 2263 %} 2264 2265 2266 // Long Immediate 2267 operand immL() 2268 %{ 2269 match(ConL); 2270 2271 op_cost(20); 2272 format %{ %} 2273 interface(CONST_INTER); 2274 %} 2275 2276 // Long Immediate 8-bit 2277 operand immL8() 2278 %{ 2279 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2280 match(ConL); 2281 2282 op_cost(5); 2283 format %{ %} 2284 interface(CONST_INTER); 2285 %} 2286 2287 // Long Immediate 32-bit unsigned 2288 operand immUL32() 2289 %{ 2290 predicate(n->get_long() == (unsigned int) (n->get_long())); 2291 match(ConL); 2292 2293 op_cost(10); 2294 format %{ %} 2295 interface(CONST_INTER); 2296 %} 2297 2298 // Long Immediate 32-bit signed 2299 operand immL32() 2300 %{ 2301 predicate(n->get_long() == (int) (n->get_long())); 2302 match(ConL); 2303 2304 op_cost(15); 2305 format %{ %} 2306 interface(CONST_INTER); 2307 %} 2308 2309 operand immL_Pow2() 2310 %{ 2311 predicate(is_power_of_2((julong)n->get_long())); 2312 match(ConL); 2313 2314 op_cost(15); 2315 format %{ %} 2316 interface(CONST_INTER); 2317 %} 2318 2319 operand immL_NotPow2() 2320 %{ 2321 predicate(is_power_of_2((julong)~n->get_long())); 2322 match(ConL); 2323 2324 op_cost(15); 2325 format %{ %} 2326 interface(CONST_INTER); 2327 %} 2328 2329 // Long Immediate zero 2330 operand immL0() 2331 %{ 2332 predicate(n->get_long() == 0L); 2333 match(ConL); 2334 2335 op_cost(10); 2336 format %{ %} 2337 interface(CONST_INTER); 2338 %} 2339 2340 // Constant for increment 2341 operand immL1() 2342 %{ 2343 predicate(n->get_long() == 1); 2344 match(ConL); 2345 2346 format %{ %} 2347 interface(CONST_INTER); 2348 %} 2349 2350 // Constant for decrement 2351 operand immL_M1() 2352 %{ 2353 predicate(n->get_long() == -1); 2354 match(ConL); 2355 2356 format %{ %} 2357 interface(CONST_INTER); 2358 %} 2359 2360 // Long Immediate: low 32-bit mask 2361 operand immL_32bits() 2362 %{ 2363 predicate(n->get_long() == 0xFFFFFFFFL); 2364 match(ConL); 2365 op_cost(20); 2366 2367 format %{ %} 2368 interface(CONST_INTER); 2369 %} 2370 2371 // Int Immediate: 2^n-1, positive 2372 operand immI_Pow2M1() 2373 %{ 2374 predicate((n->get_int() > 0) 2375 && is_power_of_2((juint)n->get_int() + 1)); 2376 match(ConI); 2377 2378 op_cost(20); 2379 format %{ %} 2380 interface(CONST_INTER); 2381 %} 2382 2383 // Float Immediate zero 2384 operand immF0() 2385 %{ 2386 predicate(jint_cast(n->getf()) == 0); 2387 match(ConF); 2388 2389 op_cost(5); 2390 format %{ %} 2391 interface(CONST_INTER); 2392 %} 2393 2394 // Float Immediate 2395 operand immF() 2396 %{ 2397 match(ConF); 2398 2399 op_cost(15); 2400 format %{ %} 2401 interface(CONST_INTER); 2402 %} 2403 2404 // Double Immediate zero 2405 operand immD0() 2406 %{ 2407 predicate(jlong_cast(n->getd()) == 0); 2408 match(ConD); 2409 2410 op_cost(5); 2411 format %{ %} 2412 interface(CONST_INTER); 2413 %} 2414 2415 // Double Immediate 2416 operand immD() 2417 %{ 2418 match(ConD); 2419 2420 op_cost(15); 2421 format %{ %} 2422 interface(CONST_INTER); 2423 %} 2424 2425 // Immediates for special shifts (sign extend) 2426 2427 // Constants for increment 2428 operand immI_16() 2429 %{ 2430 predicate(n->get_int() == 16); 2431 match(ConI); 2432 2433 format %{ %} 2434 interface(CONST_INTER); 2435 %} 2436 2437 operand immI_24() 2438 %{ 2439 predicate(n->get_int() == 24); 2440 match(ConI); 2441 2442 format %{ %} 2443 interface(CONST_INTER); 2444 %} 2445 2446 // Constant for byte-wide masking 2447 operand immI_255() 2448 %{ 2449 predicate(n->get_int() == 255); 2450 match(ConI); 2451 2452 format %{ %} 2453 interface(CONST_INTER); 2454 %} 2455 2456 // Constant for short-wide masking 2457 operand immI_65535() 2458 %{ 2459 predicate(n->get_int() == 65535); 2460 match(ConI); 2461 2462 format %{ %} 2463 interface(CONST_INTER); 2464 %} 2465 2466 // Constant for byte-wide masking 2467 operand immL_255() 2468 %{ 2469 predicate(n->get_long() == 255); 2470 match(ConL); 2471 2472 format %{ %} 2473 interface(CONST_INTER); 2474 %} 2475 2476 // Constant for short-wide masking 2477 operand immL_65535() 2478 %{ 2479 predicate(n->get_long() == 65535); 2480 match(ConL); 2481 2482 format %{ %} 2483 interface(CONST_INTER); 2484 %} 2485 2486 operand kReg() 2487 %{ 2488 constraint(ALLOC_IN_RC(vectmask_reg)); 2489 match(RegVectMask); 2490 format %{%} 2491 interface(REG_INTER); 2492 %} 2493 2494 // Register Operands 2495 // Integer Register 2496 operand rRegI() 2497 %{ 2498 constraint(ALLOC_IN_RC(int_reg)); 2499 match(RegI); 2500 2501 match(rax_RegI); 2502 match(rbx_RegI); 2503 match(rcx_RegI); 2504 match(rdx_RegI); 2505 match(rdi_RegI); 2506 2507 format %{ %} 2508 interface(REG_INTER); 2509 %} 2510 2511 // Special Registers 2512 operand rax_RegI() 2513 %{ 2514 constraint(ALLOC_IN_RC(int_rax_reg)); 2515 match(RegI); 2516 match(rRegI); 2517 2518 format %{ "RAX" %} 2519 interface(REG_INTER); 2520 %} 2521 2522 // Special Registers 2523 operand rbx_RegI() 2524 %{ 2525 constraint(ALLOC_IN_RC(int_rbx_reg)); 2526 match(RegI); 2527 match(rRegI); 2528 2529 format %{ "RBX" %} 2530 interface(REG_INTER); 2531 %} 2532 2533 operand rcx_RegI() 2534 %{ 2535 constraint(ALLOC_IN_RC(int_rcx_reg)); 2536 match(RegI); 2537 match(rRegI); 2538 2539 format %{ "RCX" %} 2540 interface(REG_INTER); 2541 %} 2542 2543 operand rdx_RegI() 2544 %{ 2545 constraint(ALLOC_IN_RC(int_rdx_reg)); 2546 match(RegI); 2547 match(rRegI); 2548 2549 format %{ "RDX" %} 2550 interface(REG_INTER); 2551 %} 2552 2553 operand rdi_RegI() 2554 %{ 2555 constraint(ALLOC_IN_RC(int_rdi_reg)); 2556 match(RegI); 2557 match(rRegI); 2558 2559 format %{ "RDI" %} 2560 interface(REG_INTER); 2561 %} 2562 2563 operand no_rax_rdx_RegI() 2564 %{ 2565 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2566 match(RegI); 2567 match(rbx_RegI); 2568 match(rcx_RegI); 2569 match(rdi_RegI); 2570 2571 format %{ %} 2572 interface(REG_INTER); 2573 %} 2574 2575 operand no_rbp_r13_RegI() 2576 %{ 2577 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2578 match(RegI); 2579 match(rRegI); 2580 match(rax_RegI); 2581 match(rbx_RegI); 2582 match(rcx_RegI); 2583 match(rdx_RegI); 2584 match(rdi_RegI); 2585 2586 format %{ %} 2587 interface(REG_INTER); 2588 %} 2589 2590 // Pointer Register 2591 operand any_RegP() 2592 %{ 2593 constraint(ALLOC_IN_RC(any_reg)); 2594 match(RegP); 2595 match(rax_RegP); 2596 match(rbx_RegP); 2597 match(rdi_RegP); 2598 match(rsi_RegP); 2599 match(rbp_RegP); 2600 match(r15_RegP); 2601 match(rRegP); 2602 2603 format %{ %} 2604 interface(REG_INTER); 2605 %} 2606 2607 operand rRegP() 2608 %{ 2609 constraint(ALLOC_IN_RC(ptr_reg)); 2610 match(RegP); 2611 match(rax_RegP); 2612 match(rbx_RegP); 2613 match(rdi_RegP); 2614 match(rsi_RegP); 2615 match(rbp_RegP); // See Q&A below about 2616 match(r15_RegP); // r15_RegP and rbp_RegP. 2617 2618 format %{ %} 2619 interface(REG_INTER); 2620 %} 2621 2622 operand rRegN() %{ 2623 constraint(ALLOC_IN_RC(int_reg)); 2624 match(RegN); 2625 2626 format %{ %} 2627 interface(REG_INTER); 2628 %} 2629 2630 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2631 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2632 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2633 // The output of an instruction is controlled by the allocator, which respects 2634 // register class masks, not match rules. Unless an instruction mentions 2635 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2636 // by the allocator as an input. 2637 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2638 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2639 // result, RBP is not included in the output of the instruction either. 2640 2641 // This operand is not allowed to use RBP even if 2642 // RBP is not used to hold the frame pointer. 2643 operand no_rbp_RegP() 2644 %{ 2645 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2646 match(RegP); 2647 match(rbx_RegP); 2648 match(rsi_RegP); 2649 match(rdi_RegP); 2650 2651 format %{ %} 2652 interface(REG_INTER); 2653 %} 2654 2655 // Special Registers 2656 // Return a pointer value 2657 operand rax_RegP() 2658 %{ 2659 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2660 match(RegP); 2661 match(rRegP); 2662 2663 format %{ %} 2664 interface(REG_INTER); 2665 %} 2666 2667 // Special Registers 2668 // Return a compressed pointer value 2669 operand rax_RegN() 2670 %{ 2671 constraint(ALLOC_IN_RC(int_rax_reg)); 2672 match(RegN); 2673 match(rRegN); 2674 2675 format %{ %} 2676 interface(REG_INTER); 2677 %} 2678 2679 // Used in AtomicAdd 2680 operand rbx_RegP() 2681 %{ 2682 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2683 match(RegP); 2684 match(rRegP); 2685 2686 format %{ %} 2687 interface(REG_INTER); 2688 %} 2689 2690 operand rsi_RegP() 2691 %{ 2692 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2693 match(RegP); 2694 match(rRegP); 2695 2696 format %{ %} 2697 interface(REG_INTER); 2698 %} 2699 2700 operand rbp_RegP() 2701 %{ 2702 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2703 match(RegP); 2704 match(rRegP); 2705 2706 format %{ %} 2707 interface(REG_INTER); 2708 %} 2709 2710 // Used in rep stosq 2711 operand rdi_RegP() 2712 %{ 2713 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2714 match(RegP); 2715 match(rRegP); 2716 2717 format %{ %} 2718 interface(REG_INTER); 2719 %} 2720 2721 operand r15_RegP() 2722 %{ 2723 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2724 match(RegP); 2725 match(rRegP); 2726 2727 format %{ %} 2728 interface(REG_INTER); 2729 %} 2730 2731 operand rRegL() 2732 %{ 2733 constraint(ALLOC_IN_RC(long_reg)); 2734 match(RegL); 2735 match(rax_RegL); 2736 match(rdx_RegL); 2737 2738 format %{ %} 2739 interface(REG_INTER); 2740 %} 2741 2742 // Special Registers 2743 operand no_rax_rdx_RegL() 2744 %{ 2745 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2746 match(RegL); 2747 match(rRegL); 2748 2749 format %{ %} 2750 interface(REG_INTER); 2751 %} 2752 2753 operand rax_RegL() 2754 %{ 2755 constraint(ALLOC_IN_RC(long_rax_reg)); 2756 match(RegL); 2757 match(rRegL); 2758 2759 format %{ "RAX" %} 2760 interface(REG_INTER); 2761 %} 2762 2763 operand rcx_RegL() 2764 %{ 2765 constraint(ALLOC_IN_RC(long_rcx_reg)); 2766 match(RegL); 2767 match(rRegL); 2768 2769 format %{ %} 2770 interface(REG_INTER); 2771 %} 2772 2773 operand rdx_RegL() 2774 %{ 2775 constraint(ALLOC_IN_RC(long_rdx_reg)); 2776 match(RegL); 2777 match(rRegL); 2778 2779 format %{ %} 2780 interface(REG_INTER); 2781 %} 2782 2783 operand r11_RegL() 2784 %{ 2785 constraint(ALLOC_IN_RC(long_r11_reg)); 2786 match(RegL); 2787 match(rRegL); 2788 2789 format %{ %} 2790 interface(REG_INTER); 2791 %} 2792 2793 operand no_rbp_r13_RegL() 2794 %{ 2795 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2796 match(RegL); 2797 match(rRegL); 2798 match(rax_RegL); 2799 match(rcx_RegL); 2800 match(rdx_RegL); 2801 2802 format %{ %} 2803 interface(REG_INTER); 2804 %} 2805 2806 // Flags register, used as output of compare instructions 2807 operand rFlagsReg() 2808 %{ 2809 constraint(ALLOC_IN_RC(int_flags)); 2810 match(RegFlags); 2811 2812 format %{ "RFLAGS" %} 2813 interface(REG_INTER); 2814 %} 2815 2816 // Flags register, used as output of FLOATING POINT compare instructions 2817 operand rFlagsRegU() 2818 %{ 2819 constraint(ALLOC_IN_RC(int_flags)); 2820 match(RegFlags); 2821 2822 format %{ "RFLAGS_U" %} 2823 interface(REG_INTER); 2824 %} 2825 2826 operand rFlagsRegUCF() %{ 2827 constraint(ALLOC_IN_RC(int_flags)); 2828 match(RegFlags); 2829 predicate(false); 2830 2831 format %{ "RFLAGS_U_CF" %} 2832 interface(REG_INTER); 2833 %} 2834 2835 // Float register operands 2836 operand regF() %{ 2837 constraint(ALLOC_IN_RC(float_reg)); 2838 match(RegF); 2839 2840 format %{ %} 2841 interface(REG_INTER); 2842 %} 2843 2844 // Float register operands 2845 operand legRegF() %{ 2846 constraint(ALLOC_IN_RC(float_reg_legacy)); 2847 match(RegF); 2848 2849 format %{ %} 2850 interface(REG_INTER); 2851 %} 2852 2853 // Float register operands 2854 operand vlRegF() %{ 2855 constraint(ALLOC_IN_RC(float_reg_vl)); 2856 match(RegF); 2857 2858 format %{ %} 2859 interface(REG_INTER); 2860 %} 2861 2862 // Double register operands 2863 operand regD() %{ 2864 constraint(ALLOC_IN_RC(double_reg)); 2865 match(RegD); 2866 2867 format %{ %} 2868 interface(REG_INTER); 2869 %} 2870 2871 // Double register operands 2872 operand legRegD() %{ 2873 constraint(ALLOC_IN_RC(double_reg_legacy)); 2874 match(RegD); 2875 2876 format %{ %} 2877 interface(REG_INTER); 2878 %} 2879 2880 // Double register operands 2881 operand vlRegD() %{ 2882 constraint(ALLOC_IN_RC(double_reg_vl)); 2883 match(RegD); 2884 2885 format %{ %} 2886 interface(REG_INTER); 2887 %} 2888 2889 //----------Memory Operands---------------------------------------------------- 2890 // Direct Memory Operand 2891 // operand direct(immP addr) 2892 // %{ 2893 // match(addr); 2894 2895 // format %{ "[$addr]" %} 2896 // interface(MEMORY_INTER) %{ 2897 // base(0xFFFFFFFF); 2898 // index(0x4); 2899 // scale(0x0); 2900 // disp($addr); 2901 // %} 2902 // %} 2903 2904 // Indirect Memory Operand 2905 operand indirect(any_RegP reg) 2906 %{ 2907 constraint(ALLOC_IN_RC(ptr_reg)); 2908 match(reg); 2909 2910 format %{ "[$reg]" %} 2911 interface(MEMORY_INTER) %{ 2912 base($reg); 2913 index(0x4); 2914 scale(0x0); 2915 disp(0x0); 2916 %} 2917 %} 2918 2919 // Indirect Memory Plus Short Offset Operand 2920 operand indOffset8(any_RegP reg, immL8 off) 2921 %{ 2922 constraint(ALLOC_IN_RC(ptr_reg)); 2923 match(AddP reg off); 2924 2925 format %{ "[$reg + $off (8-bit)]" %} 2926 interface(MEMORY_INTER) %{ 2927 base($reg); 2928 index(0x4); 2929 scale(0x0); 2930 disp($off); 2931 %} 2932 %} 2933 2934 // Indirect Memory Plus Long Offset Operand 2935 operand indOffset32(any_RegP reg, immL32 off) 2936 %{ 2937 constraint(ALLOC_IN_RC(ptr_reg)); 2938 match(AddP reg off); 2939 2940 format %{ "[$reg + $off (32-bit)]" %} 2941 interface(MEMORY_INTER) %{ 2942 base($reg); 2943 index(0x4); 2944 scale(0x0); 2945 disp($off); 2946 %} 2947 %} 2948 2949 // Indirect Memory Plus Index Register Plus Offset Operand 2950 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2951 %{ 2952 constraint(ALLOC_IN_RC(ptr_reg)); 2953 match(AddP (AddP reg lreg) off); 2954 2955 op_cost(10); 2956 format %{"[$reg + $off + $lreg]" %} 2957 interface(MEMORY_INTER) %{ 2958 base($reg); 2959 index($lreg); 2960 scale(0x0); 2961 disp($off); 2962 %} 2963 %} 2964 2965 // Indirect Memory Plus Index Register Plus Offset Operand 2966 operand indIndex(any_RegP reg, rRegL lreg) 2967 %{ 2968 constraint(ALLOC_IN_RC(ptr_reg)); 2969 match(AddP reg lreg); 2970 2971 op_cost(10); 2972 format %{"[$reg + $lreg]" %} 2973 interface(MEMORY_INTER) %{ 2974 base($reg); 2975 index($lreg); 2976 scale(0x0); 2977 disp(0x0); 2978 %} 2979 %} 2980 2981 // Indirect Memory Times Scale Plus Index Register 2982 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2983 %{ 2984 constraint(ALLOC_IN_RC(ptr_reg)); 2985 match(AddP reg (LShiftL lreg scale)); 2986 2987 op_cost(10); 2988 format %{"[$reg + $lreg << $scale]" %} 2989 interface(MEMORY_INTER) %{ 2990 base($reg); 2991 index($lreg); 2992 scale($scale); 2993 disp(0x0); 2994 %} 2995 %} 2996 2997 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 2998 %{ 2999 constraint(ALLOC_IN_RC(ptr_reg)); 3000 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3001 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3002 3003 op_cost(10); 3004 format %{"[$reg + pos $idx << $scale]" %} 3005 interface(MEMORY_INTER) %{ 3006 base($reg); 3007 index($idx); 3008 scale($scale); 3009 disp(0x0); 3010 %} 3011 %} 3012 3013 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3014 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3015 %{ 3016 constraint(ALLOC_IN_RC(ptr_reg)); 3017 match(AddP (AddP reg (LShiftL lreg scale)) off); 3018 3019 op_cost(10); 3020 format %{"[$reg + $off + $lreg << $scale]" %} 3021 interface(MEMORY_INTER) %{ 3022 base($reg); 3023 index($lreg); 3024 scale($scale); 3025 disp($off); 3026 %} 3027 %} 3028 3029 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3030 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3031 %{ 3032 constraint(ALLOC_IN_RC(ptr_reg)); 3033 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3034 match(AddP (AddP reg (ConvI2L idx)) off); 3035 3036 op_cost(10); 3037 format %{"[$reg + $off + $idx]" %} 3038 interface(MEMORY_INTER) %{ 3039 base($reg); 3040 index($idx); 3041 scale(0x0); 3042 disp($off); 3043 %} 3044 %} 3045 3046 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3047 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3048 %{ 3049 constraint(ALLOC_IN_RC(ptr_reg)); 3050 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3051 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3052 3053 op_cost(10); 3054 format %{"[$reg + $off + $idx << $scale]" %} 3055 interface(MEMORY_INTER) %{ 3056 base($reg); 3057 index($idx); 3058 scale($scale); 3059 disp($off); 3060 %} 3061 %} 3062 3063 // Indirect Narrow Oop Plus Offset Operand 3064 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3065 // we can't free r12 even with CompressedOops::base() == nullptr. 3066 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3067 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3068 constraint(ALLOC_IN_RC(ptr_reg)); 3069 match(AddP (DecodeN reg) off); 3070 3071 op_cost(10); 3072 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3073 interface(MEMORY_INTER) %{ 3074 base(0xc); // R12 3075 index($reg); 3076 scale(0x3); 3077 disp($off); 3078 %} 3079 %} 3080 3081 // Indirect Memory Operand 3082 operand indirectNarrow(rRegN reg) 3083 %{ 3084 predicate(CompressedOops::shift() == 0); 3085 constraint(ALLOC_IN_RC(ptr_reg)); 3086 match(DecodeN reg); 3087 3088 format %{ "[$reg]" %} 3089 interface(MEMORY_INTER) %{ 3090 base($reg); 3091 index(0x4); 3092 scale(0x0); 3093 disp(0x0); 3094 %} 3095 %} 3096 3097 // Indirect Memory Plus Short Offset Operand 3098 operand indOffset8Narrow(rRegN reg, immL8 off) 3099 %{ 3100 predicate(CompressedOops::shift() == 0); 3101 constraint(ALLOC_IN_RC(ptr_reg)); 3102 match(AddP (DecodeN reg) off); 3103 3104 format %{ "[$reg + $off (8-bit)]" %} 3105 interface(MEMORY_INTER) %{ 3106 base($reg); 3107 index(0x4); 3108 scale(0x0); 3109 disp($off); 3110 %} 3111 %} 3112 3113 // Indirect Memory Plus Long Offset Operand 3114 operand indOffset32Narrow(rRegN reg, immL32 off) 3115 %{ 3116 predicate(CompressedOops::shift() == 0); 3117 constraint(ALLOC_IN_RC(ptr_reg)); 3118 match(AddP (DecodeN reg) off); 3119 3120 format %{ "[$reg + $off (32-bit)]" %} 3121 interface(MEMORY_INTER) %{ 3122 base($reg); 3123 index(0x4); 3124 scale(0x0); 3125 disp($off); 3126 %} 3127 %} 3128 3129 // Indirect Memory Plus Index Register Plus Offset Operand 3130 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3131 %{ 3132 predicate(CompressedOops::shift() == 0); 3133 constraint(ALLOC_IN_RC(ptr_reg)); 3134 match(AddP (AddP (DecodeN reg) lreg) off); 3135 3136 op_cost(10); 3137 format %{"[$reg + $off + $lreg]" %} 3138 interface(MEMORY_INTER) %{ 3139 base($reg); 3140 index($lreg); 3141 scale(0x0); 3142 disp($off); 3143 %} 3144 %} 3145 3146 // Indirect Memory Plus Index Register Plus Offset Operand 3147 operand indIndexNarrow(rRegN reg, rRegL lreg) 3148 %{ 3149 predicate(CompressedOops::shift() == 0); 3150 constraint(ALLOC_IN_RC(ptr_reg)); 3151 match(AddP (DecodeN reg) lreg); 3152 3153 op_cost(10); 3154 format %{"[$reg + $lreg]" %} 3155 interface(MEMORY_INTER) %{ 3156 base($reg); 3157 index($lreg); 3158 scale(0x0); 3159 disp(0x0); 3160 %} 3161 %} 3162 3163 // Indirect Memory Times Scale Plus Index Register 3164 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3165 %{ 3166 predicate(CompressedOops::shift() == 0); 3167 constraint(ALLOC_IN_RC(ptr_reg)); 3168 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3169 3170 op_cost(10); 3171 format %{"[$reg + $lreg << $scale]" %} 3172 interface(MEMORY_INTER) %{ 3173 base($reg); 3174 index($lreg); 3175 scale($scale); 3176 disp(0x0); 3177 %} 3178 %} 3179 3180 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3181 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3182 %{ 3183 predicate(CompressedOops::shift() == 0); 3184 constraint(ALLOC_IN_RC(ptr_reg)); 3185 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3186 3187 op_cost(10); 3188 format %{"[$reg + $off + $lreg << $scale]" %} 3189 interface(MEMORY_INTER) %{ 3190 base($reg); 3191 index($lreg); 3192 scale($scale); 3193 disp($off); 3194 %} 3195 %} 3196 3197 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3198 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3199 %{ 3200 constraint(ALLOC_IN_RC(ptr_reg)); 3201 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3202 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3203 3204 op_cost(10); 3205 format %{"[$reg + $off + $idx]" %} 3206 interface(MEMORY_INTER) %{ 3207 base($reg); 3208 index($idx); 3209 scale(0x0); 3210 disp($off); 3211 %} 3212 %} 3213 3214 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3215 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3216 %{ 3217 constraint(ALLOC_IN_RC(ptr_reg)); 3218 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3219 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3220 3221 op_cost(10); 3222 format %{"[$reg + $off + $idx << $scale]" %} 3223 interface(MEMORY_INTER) %{ 3224 base($reg); 3225 index($idx); 3226 scale($scale); 3227 disp($off); 3228 %} 3229 %} 3230 3231 //----------Special Memory Operands-------------------------------------------- 3232 // Stack Slot Operand - This operand is used for loading and storing temporary 3233 // values on the stack where a match requires a value to 3234 // flow through memory. 3235 operand stackSlotP(sRegP reg) 3236 %{ 3237 constraint(ALLOC_IN_RC(stack_slots)); 3238 // No match rule because this operand is only generated in matching 3239 3240 format %{ "[$reg]" %} 3241 interface(MEMORY_INTER) %{ 3242 base(0x4); // RSP 3243 index(0x4); // No Index 3244 scale(0x0); // No Scale 3245 disp($reg); // Stack Offset 3246 %} 3247 %} 3248 3249 operand stackSlotI(sRegI reg) 3250 %{ 3251 constraint(ALLOC_IN_RC(stack_slots)); 3252 // No match rule because this operand is only generated in matching 3253 3254 format %{ "[$reg]" %} 3255 interface(MEMORY_INTER) %{ 3256 base(0x4); // RSP 3257 index(0x4); // No Index 3258 scale(0x0); // No Scale 3259 disp($reg); // Stack Offset 3260 %} 3261 %} 3262 3263 operand stackSlotF(sRegF reg) 3264 %{ 3265 constraint(ALLOC_IN_RC(stack_slots)); 3266 // No match rule because this operand is only generated in matching 3267 3268 format %{ "[$reg]" %} 3269 interface(MEMORY_INTER) %{ 3270 base(0x4); // RSP 3271 index(0x4); // No Index 3272 scale(0x0); // No Scale 3273 disp($reg); // Stack Offset 3274 %} 3275 %} 3276 3277 operand stackSlotD(sRegD reg) 3278 %{ 3279 constraint(ALLOC_IN_RC(stack_slots)); 3280 // No match rule because this operand is only generated in matching 3281 3282 format %{ "[$reg]" %} 3283 interface(MEMORY_INTER) %{ 3284 base(0x4); // RSP 3285 index(0x4); // No Index 3286 scale(0x0); // No Scale 3287 disp($reg); // Stack Offset 3288 %} 3289 %} 3290 operand stackSlotL(sRegL reg) 3291 %{ 3292 constraint(ALLOC_IN_RC(stack_slots)); 3293 // No match rule because this operand is only generated in matching 3294 3295 format %{ "[$reg]" %} 3296 interface(MEMORY_INTER) %{ 3297 base(0x4); // RSP 3298 index(0x4); // No Index 3299 scale(0x0); // No Scale 3300 disp($reg); // Stack Offset 3301 %} 3302 %} 3303 3304 //----------Conditional Branch Operands---------------------------------------- 3305 // Comparison Op - This is the operation of the comparison, and is limited to 3306 // the following set of codes: 3307 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3308 // 3309 // Other attributes of the comparison, such as unsignedness, are specified 3310 // by the comparison instruction that sets a condition code flags register. 3311 // That result is represented by a flags operand whose subtype is appropriate 3312 // to the unsignedness (etc.) of the comparison. 3313 // 3314 // Later, the instruction which matches both the Comparison Op (a Bool) and 3315 // the flags (produced by the Cmp) specifies the coding of the comparison op 3316 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3317 3318 // Comparison Code 3319 operand cmpOp() 3320 %{ 3321 match(Bool); 3322 3323 format %{ "" %} 3324 interface(COND_INTER) %{ 3325 equal(0x4, "e"); 3326 not_equal(0x5, "ne"); 3327 less(0xC, "l"); 3328 greater_equal(0xD, "ge"); 3329 less_equal(0xE, "le"); 3330 greater(0xF, "g"); 3331 overflow(0x0, "o"); 3332 no_overflow(0x1, "no"); 3333 %} 3334 %} 3335 3336 // Comparison Code, unsigned compare. Used by FP also, with 3337 // C2 (unordered) turned into GT or LT already. The other bits 3338 // C0 and C3 are turned into Carry & Zero flags. 3339 operand cmpOpU() 3340 %{ 3341 match(Bool); 3342 3343 format %{ "" %} 3344 interface(COND_INTER) %{ 3345 equal(0x4, "e"); 3346 not_equal(0x5, "ne"); 3347 less(0x2, "b"); 3348 greater_equal(0x3, "ae"); 3349 less_equal(0x6, "be"); 3350 greater(0x7, "a"); 3351 overflow(0x0, "o"); 3352 no_overflow(0x1, "no"); 3353 %} 3354 %} 3355 3356 3357 // Floating comparisons that don't require any fixup for the unordered case, 3358 // If both inputs of the comparison are the same, ZF is always set so we 3359 // don't need to use cmpOpUCF2 for eq/ne 3360 operand cmpOpUCF() %{ 3361 match(Bool); 3362 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3363 n->as_Bool()->_test._test == BoolTest::ge || 3364 n->as_Bool()->_test._test == BoolTest::le || 3365 n->as_Bool()->_test._test == BoolTest::gt || 3366 n->in(1)->in(1) == n->in(1)->in(2)); 3367 format %{ "" %} 3368 interface(COND_INTER) %{ 3369 equal(0xb, "np"); 3370 not_equal(0xa, "p"); 3371 less(0x2, "b"); 3372 greater_equal(0x3, "ae"); 3373 less_equal(0x6, "be"); 3374 greater(0x7, "a"); 3375 overflow(0x0, "o"); 3376 no_overflow(0x1, "no"); 3377 %} 3378 %} 3379 3380 3381 // Floating comparisons that can be fixed up with extra conditional jumps 3382 operand cmpOpUCF2() %{ 3383 match(Bool); 3384 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3385 n->as_Bool()->_test._test == BoolTest::eq) && 3386 n->in(1)->in(1) != n->in(1)->in(2)); 3387 format %{ "" %} 3388 interface(COND_INTER) %{ 3389 equal(0x4, "e"); 3390 not_equal(0x5, "ne"); 3391 less(0x2, "b"); 3392 greater_equal(0x3, "ae"); 3393 less_equal(0x6, "be"); 3394 greater(0x7, "a"); 3395 overflow(0x0, "o"); 3396 no_overflow(0x1, "no"); 3397 %} 3398 %} 3399 3400 //----------OPERAND CLASSES---------------------------------------------------- 3401 // Operand Classes are groups of operands that are used as to simplify 3402 // instruction definitions by not requiring the AD writer to specify separate 3403 // instructions for every form of operand when the instruction accepts 3404 // multiple operand types with the same basic encoding and format. The classic 3405 // case of this is memory operands. 3406 3407 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3408 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3409 indCompressedOopOffset, 3410 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3411 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3412 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3413 3414 //----------PIPELINE----------------------------------------------------------- 3415 // Rules which define the behavior of the target architectures pipeline. 3416 pipeline %{ 3417 3418 //----------ATTRIBUTES--------------------------------------------------------- 3419 attributes %{ 3420 variable_size_instructions; // Fixed size instructions 3421 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3422 instruction_unit_size = 1; // An instruction is 1 bytes long 3423 instruction_fetch_unit_size = 16; // The processor fetches one line 3424 instruction_fetch_units = 1; // of 16 bytes 3425 3426 // List of nop instructions 3427 nops( MachNop ); 3428 %} 3429 3430 //----------RESOURCES---------------------------------------------------------- 3431 // Resources are the functional units available to the machine 3432 3433 // Generic P2/P3 pipeline 3434 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3435 // 3 instructions decoded per cycle. 3436 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3437 // 3 ALU op, only ALU0 handles mul instructions. 3438 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3439 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3440 BR, FPU, 3441 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3442 3443 //----------PIPELINE DESCRIPTION----------------------------------------------- 3444 // Pipeline Description specifies the stages in the machine's pipeline 3445 3446 // Generic P2/P3 pipeline 3447 pipe_desc(S0, S1, S2, S3, S4, S5); 3448 3449 //----------PIPELINE CLASSES--------------------------------------------------- 3450 // Pipeline Classes describe the stages in which input and output are 3451 // referenced by the hardware pipeline. 3452 3453 // Naming convention: ialu or fpu 3454 // Then: _reg 3455 // Then: _reg if there is a 2nd register 3456 // Then: _long if it's a pair of instructions implementing a long 3457 // Then: _fat if it requires the big decoder 3458 // Or: _mem if it requires the big decoder and a memory unit. 3459 3460 // Integer ALU reg operation 3461 pipe_class ialu_reg(rRegI dst) 3462 %{ 3463 single_instruction; 3464 dst : S4(write); 3465 dst : S3(read); 3466 DECODE : S0; // any decoder 3467 ALU : S3; // any alu 3468 %} 3469 3470 // Long ALU reg operation 3471 pipe_class ialu_reg_long(rRegL dst) 3472 %{ 3473 instruction_count(2); 3474 dst : S4(write); 3475 dst : S3(read); 3476 DECODE : S0(2); // any 2 decoders 3477 ALU : S3(2); // both alus 3478 %} 3479 3480 // Integer ALU reg operation using big decoder 3481 pipe_class ialu_reg_fat(rRegI dst) 3482 %{ 3483 single_instruction; 3484 dst : S4(write); 3485 dst : S3(read); 3486 D0 : S0; // big decoder only 3487 ALU : S3; // any alu 3488 %} 3489 3490 // Integer ALU reg-reg operation 3491 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3492 %{ 3493 single_instruction; 3494 dst : S4(write); 3495 src : S3(read); 3496 DECODE : S0; // any decoder 3497 ALU : S3; // any alu 3498 %} 3499 3500 // Integer ALU reg-reg operation 3501 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3502 %{ 3503 single_instruction; 3504 dst : S4(write); 3505 src : S3(read); 3506 D0 : S0; // big decoder only 3507 ALU : S3; // any alu 3508 %} 3509 3510 // Integer ALU reg-mem operation 3511 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3512 %{ 3513 single_instruction; 3514 dst : S5(write); 3515 mem : S3(read); 3516 D0 : S0; // big decoder only 3517 ALU : S4; // any alu 3518 MEM : S3; // any mem 3519 %} 3520 3521 // Integer mem operation (prefetch) 3522 pipe_class ialu_mem(memory mem) 3523 %{ 3524 single_instruction; 3525 mem : S3(read); 3526 D0 : S0; // big decoder only 3527 MEM : S3; // any mem 3528 %} 3529 3530 // Integer Store to Memory 3531 pipe_class ialu_mem_reg(memory mem, rRegI src) 3532 %{ 3533 single_instruction; 3534 mem : S3(read); 3535 src : S5(read); 3536 D0 : S0; // big decoder only 3537 ALU : S4; // any alu 3538 MEM : S3; 3539 %} 3540 3541 // // Long Store to Memory 3542 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3543 // %{ 3544 // instruction_count(2); 3545 // mem : S3(read); 3546 // src : S5(read); 3547 // D0 : S0(2); // big decoder only; twice 3548 // ALU : S4(2); // any 2 alus 3549 // MEM : S3(2); // Both mems 3550 // %} 3551 3552 // Integer Store to Memory 3553 pipe_class ialu_mem_imm(memory mem) 3554 %{ 3555 single_instruction; 3556 mem : S3(read); 3557 D0 : S0; // big decoder only 3558 ALU : S4; // any alu 3559 MEM : S3; 3560 %} 3561 3562 // Integer ALU0 reg-reg operation 3563 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3564 %{ 3565 single_instruction; 3566 dst : S4(write); 3567 src : S3(read); 3568 D0 : S0; // Big decoder only 3569 ALU0 : S3; // only alu0 3570 %} 3571 3572 // Integer ALU0 reg-mem operation 3573 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3574 %{ 3575 single_instruction; 3576 dst : S5(write); 3577 mem : S3(read); 3578 D0 : S0; // big decoder only 3579 ALU0 : S4; // ALU0 only 3580 MEM : S3; // any mem 3581 %} 3582 3583 // Integer ALU reg-reg operation 3584 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3585 %{ 3586 single_instruction; 3587 cr : S4(write); 3588 src1 : S3(read); 3589 src2 : S3(read); 3590 DECODE : S0; // any decoder 3591 ALU : S3; // any alu 3592 %} 3593 3594 // Integer ALU reg-imm operation 3595 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3596 %{ 3597 single_instruction; 3598 cr : S4(write); 3599 src1 : S3(read); 3600 DECODE : S0; // any decoder 3601 ALU : S3; // any alu 3602 %} 3603 3604 // Integer ALU reg-mem operation 3605 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3606 %{ 3607 single_instruction; 3608 cr : S4(write); 3609 src1 : S3(read); 3610 src2 : S3(read); 3611 D0 : S0; // big decoder only 3612 ALU : S4; // any alu 3613 MEM : S3; 3614 %} 3615 3616 // Conditional move reg-reg 3617 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3618 %{ 3619 instruction_count(4); 3620 y : S4(read); 3621 q : S3(read); 3622 p : S3(read); 3623 DECODE : S0(4); // any decoder 3624 %} 3625 3626 // Conditional move reg-reg 3627 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3628 %{ 3629 single_instruction; 3630 dst : S4(write); 3631 src : S3(read); 3632 cr : S3(read); 3633 DECODE : S0; // any decoder 3634 %} 3635 3636 // Conditional move reg-mem 3637 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3638 %{ 3639 single_instruction; 3640 dst : S4(write); 3641 src : S3(read); 3642 cr : S3(read); 3643 DECODE : S0; // any decoder 3644 MEM : S3; 3645 %} 3646 3647 // Conditional move reg-reg long 3648 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3649 %{ 3650 single_instruction; 3651 dst : S4(write); 3652 src : S3(read); 3653 cr : S3(read); 3654 DECODE : S0(2); // any 2 decoders 3655 %} 3656 3657 // Float reg-reg operation 3658 pipe_class fpu_reg(regD dst) 3659 %{ 3660 instruction_count(2); 3661 dst : S3(read); 3662 DECODE : S0(2); // any 2 decoders 3663 FPU : S3; 3664 %} 3665 3666 // Float reg-reg operation 3667 pipe_class fpu_reg_reg(regD dst, regD src) 3668 %{ 3669 instruction_count(2); 3670 dst : S4(write); 3671 src : S3(read); 3672 DECODE : S0(2); // any 2 decoders 3673 FPU : S3; 3674 %} 3675 3676 // Float reg-reg operation 3677 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3678 %{ 3679 instruction_count(3); 3680 dst : S4(write); 3681 src1 : S3(read); 3682 src2 : S3(read); 3683 DECODE : S0(3); // any 3 decoders 3684 FPU : S3(2); 3685 %} 3686 3687 // Float reg-reg operation 3688 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3689 %{ 3690 instruction_count(4); 3691 dst : S4(write); 3692 src1 : S3(read); 3693 src2 : S3(read); 3694 src3 : S3(read); 3695 DECODE : S0(4); // any 3 decoders 3696 FPU : S3(2); 3697 %} 3698 3699 // Float reg-reg operation 3700 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3701 %{ 3702 instruction_count(4); 3703 dst : S4(write); 3704 src1 : S3(read); 3705 src2 : S3(read); 3706 src3 : S3(read); 3707 DECODE : S1(3); // any 3 decoders 3708 D0 : S0; // Big decoder only 3709 FPU : S3(2); 3710 MEM : S3; 3711 %} 3712 3713 // Float reg-mem operation 3714 pipe_class fpu_reg_mem(regD dst, memory mem) 3715 %{ 3716 instruction_count(2); 3717 dst : S5(write); 3718 mem : S3(read); 3719 D0 : S0; // big decoder only 3720 DECODE : S1; // any decoder for FPU POP 3721 FPU : S4; 3722 MEM : S3; // any mem 3723 %} 3724 3725 // Float reg-mem operation 3726 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3727 %{ 3728 instruction_count(3); 3729 dst : S5(write); 3730 src1 : S3(read); 3731 mem : S3(read); 3732 D0 : S0; // big decoder only 3733 DECODE : S1(2); // any decoder for FPU POP 3734 FPU : S4; 3735 MEM : S3; // any mem 3736 %} 3737 3738 // Float mem-reg operation 3739 pipe_class fpu_mem_reg(memory mem, regD src) 3740 %{ 3741 instruction_count(2); 3742 src : S5(read); 3743 mem : S3(read); 3744 DECODE : S0; // any decoder for FPU PUSH 3745 D0 : S1; // big decoder only 3746 FPU : S4; 3747 MEM : S3; // any mem 3748 %} 3749 3750 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3751 %{ 3752 instruction_count(3); 3753 src1 : S3(read); 3754 src2 : S3(read); 3755 mem : S3(read); 3756 DECODE : S0(2); // any decoder for FPU PUSH 3757 D0 : S1; // big decoder only 3758 FPU : S4; 3759 MEM : S3; // any mem 3760 %} 3761 3762 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3763 %{ 3764 instruction_count(3); 3765 src1 : S3(read); 3766 src2 : S3(read); 3767 mem : S4(read); 3768 DECODE : S0; // any decoder for FPU PUSH 3769 D0 : S0(2); // big decoder only 3770 FPU : S4; 3771 MEM : S3(2); // any mem 3772 %} 3773 3774 pipe_class fpu_mem_mem(memory dst, memory src1) 3775 %{ 3776 instruction_count(2); 3777 src1 : S3(read); 3778 dst : S4(read); 3779 D0 : S0(2); // big decoder only 3780 MEM : S3(2); // any mem 3781 %} 3782 3783 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3784 %{ 3785 instruction_count(3); 3786 src1 : S3(read); 3787 src2 : S3(read); 3788 dst : S4(read); 3789 D0 : S0(3); // big decoder only 3790 FPU : S4; 3791 MEM : S3(3); // any mem 3792 %} 3793 3794 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3795 %{ 3796 instruction_count(3); 3797 src1 : S4(read); 3798 mem : S4(read); 3799 DECODE : S0; // any decoder for FPU PUSH 3800 D0 : S0(2); // big decoder only 3801 FPU : S4; 3802 MEM : S3(2); // any mem 3803 %} 3804 3805 // Float load constant 3806 pipe_class fpu_reg_con(regD dst) 3807 %{ 3808 instruction_count(2); 3809 dst : S5(write); 3810 D0 : S0; // big decoder only for the load 3811 DECODE : S1; // any decoder for FPU POP 3812 FPU : S4; 3813 MEM : S3; // any mem 3814 %} 3815 3816 // Float load constant 3817 pipe_class fpu_reg_reg_con(regD dst, regD src) 3818 %{ 3819 instruction_count(3); 3820 dst : S5(write); 3821 src : S3(read); 3822 D0 : S0; // big decoder only for the load 3823 DECODE : S1(2); // any decoder for FPU POP 3824 FPU : S4; 3825 MEM : S3; // any mem 3826 %} 3827 3828 // UnConditional branch 3829 pipe_class pipe_jmp(label labl) 3830 %{ 3831 single_instruction; 3832 BR : S3; 3833 %} 3834 3835 // Conditional branch 3836 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3837 %{ 3838 single_instruction; 3839 cr : S1(read); 3840 BR : S3; 3841 %} 3842 3843 // Allocation idiom 3844 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3845 %{ 3846 instruction_count(1); force_serialization; 3847 fixed_latency(6); 3848 heap_ptr : S3(read); 3849 DECODE : S0(3); 3850 D0 : S2; 3851 MEM : S3; 3852 ALU : S3(2); 3853 dst : S5(write); 3854 BR : S5; 3855 %} 3856 3857 // Generic big/slow expanded idiom 3858 pipe_class pipe_slow() 3859 %{ 3860 instruction_count(10); multiple_bundles; force_serialization; 3861 fixed_latency(100); 3862 D0 : S0(2); 3863 MEM : S3(2); 3864 %} 3865 3866 // The real do-nothing guy 3867 pipe_class empty() 3868 %{ 3869 instruction_count(0); 3870 %} 3871 3872 // Define the class for the Nop node 3873 define 3874 %{ 3875 MachNop = empty; 3876 %} 3877 3878 %} 3879 3880 //----------INSTRUCTIONS------------------------------------------------------- 3881 // 3882 // match -- States which machine-independent subtree may be replaced 3883 // by this instruction. 3884 // ins_cost -- The estimated cost of this instruction is used by instruction 3885 // selection to identify a minimum cost tree of machine 3886 // instructions that matches a tree of machine-independent 3887 // instructions. 3888 // format -- A string providing the disassembly for this instruction. 3889 // The value of an instruction's operand may be inserted 3890 // by referring to it with a '$' prefix. 3891 // opcode -- Three instruction opcodes may be provided. These are referred 3892 // to within an encode class as $primary, $secondary, and $tertiary 3893 // rrspectively. The primary opcode is commonly used to 3894 // indicate the type of machine instruction, while secondary 3895 // and tertiary are often used for prefix options or addressing 3896 // modes. 3897 // ins_encode -- A list of encode classes with parameters. The encode class 3898 // name must have been defined in an 'enc_class' specification 3899 // in the encode section of the architecture description. 3900 3901 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3902 // Load Float 3903 instruct MoveF2VL(vlRegF dst, regF src) %{ 3904 match(Set dst src); 3905 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3906 ins_encode %{ 3907 ShouldNotReachHere(); 3908 %} 3909 ins_pipe( fpu_reg_reg ); 3910 %} 3911 3912 // Load Float 3913 instruct MoveF2LEG(legRegF dst, regF src) %{ 3914 match(Set dst src); 3915 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3916 ins_encode %{ 3917 ShouldNotReachHere(); 3918 %} 3919 ins_pipe( fpu_reg_reg ); 3920 %} 3921 3922 // Load Float 3923 instruct MoveVL2F(regF dst, vlRegF src) %{ 3924 match(Set dst src); 3925 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3926 ins_encode %{ 3927 ShouldNotReachHere(); 3928 %} 3929 ins_pipe( fpu_reg_reg ); 3930 %} 3931 3932 // Load Float 3933 instruct MoveLEG2F(regF dst, legRegF src) %{ 3934 match(Set dst src); 3935 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3936 ins_encode %{ 3937 ShouldNotReachHere(); 3938 %} 3939 ins_pipe( fpu_reg_reg ); 3940 %} 3941 3942 // Load Double 3943 instruct MoveD2VL(vlRegD dst, regD src) %{ 3944 match(Set dst src); 3945 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3946 ins_encode %{ 3947 ShouldNotReachHere(); 3948 %} 3949 ins_pipe( fpu_reg_reg ); 3950 %} 3951 3952 // Load Double 3953 instruct MoveD2LEG(legRegD dst, regD src) %{ 3954 match(Set dst src); 3955 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3956 ins_encode %{ 3957 ShouldNotReachHere(); 3958 %} 3959 ins_pipe( fpu_reg_reg ); 3960 %} 3961 3962 // Load Double 3963 instruct MoveVL2D(regD dst, vlRegD src) %{ 3964 match(Set dst src); 3965 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3966 ins_encode %{ 3967 ShouldNotReachHere(); 3968 %} 3969 ins_pipe( fpu_reg_reg ); 3970 %} 3971 3972 // Load Double 3973 instruct MoveLEG2D(regD dst, legRegD src) %{ 3974 match(Set dst src); 3975 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3976 ins_encode %{ 3977 ShouldNotReachHere(); 3978 %} 3979 ins_pipe( fpu_reg_reg ); 3980 %} 3981 3982 //----------Load/Store/Move Instructions--------------------------------------- 3983 //----------Load Instructions-------------------------------------------------- 3984 3985 // Load Byte (8 bit signed) 3986 instruct loadB(rRegI dst, memory mem) 3987 %{ 3988 match(Set dst (LoadB mem)); 3989 3990 ins_cost(125); 3991 format %{ "movsbl $dst, $mem\t# byte" %} 3992 3993 ins_encode %{ 3994 __ movsbl($dst$$Register, $mem$$Address); 3995 %} 3996 3997 ins_pipe(ialu_reg_mem); 3998 %} 3999 4000 // Load Byte (8 bit signed) into Long Register 4001 instruct loadB2L(rRegL dst, memory mem) 4002 %{ 4003 match(Set dst (ConvI2L (LoadB mem))); 4004 4005 ins_cost(125); 4006 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4007 4008 ins_encode %{ 4009 __ movsbq($dst$$Register, $mem$$Address); 4010 %} 4011 4012 ins_pipe(ialu_reg_mem); 4013 %} 4014 4015 // Load Unsigned Byte (8 bit UNsigned) 4016 instruct loadUB(rRegI dst, memory mem) 4017 %{ 4018 match(Set dst (LoadUB mem)); 4019 4020 ins_cost(125); 4021 format %{ "movzbl $dst, $mem\t# ubyte" %} 4022 4023 ins_encode %{ 4024 __ movzbl($dst$$Register, $mem$$Address); 4025 %} 4026 4027 ins_pipe(ialu_reg_mem); 4028 %} 4029 4030 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4031 instruct loadUB2L(rRegL dst, memory mem) 4032 %{ 4033 match(Set dst (ConvI2L (LoadUB mem))); 4034 4035 ins_cost(125); 4036 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4037 4038 ins_encode %{ 4039 __ movzbq($dst$$Register, $mem$$Address); 4040 %} 4041 4042 ins_pipe(ialu_reg_mem); 4043 %} 4044 4045 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4046 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4047 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4048 effect(KILL cr); 4049 4050 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4051 "andl $dst, right_n_bits($mask, 8)" %} 4052 ins_encode %{ 4053 Register Rdst = $dst$$Register; 4054 __ movzbq(Rdst, $mem$$Address); 4055 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4056 %} 4057 ins_pipe(ialu_reg_mem); 4058 %} 4059 4060 // Load Short (16 bit signed) 4061 instruct loadS(rRegI dst, memory mem) 4062 %{ 4063 match(Set dst (LoadS mem)); 4064 4065 ins_cost(125); 4066 format %{ "movswl $dst, $mem\t# short" %} 4067 4068 ins_encode %{ 4069 __ movswl($dst$$Register, $mem$$Address); 4070 %} 4071 4072 ins_pipe(ialu_reg_mem); 4073 %} 4074 4075 // Load Short (16 bit signed) to Byte (8 bit signed) 4076 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4077 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4078 4079 ins_cost(125); 4080 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4081 ins_encode %{ 4082 __ movsbl($dst$$Register, $mem$$Address); 4083 %} 4084 ins_pipe(ialu_reg_mem); 4085 %} 4086 4087 // Load Short (16 bit signed) into Long Register 4088 instruct loadS2L(rRegL dst, memory mem) 4089 %{ 4090 match(Set dst (ConvI2L (LoadS mem))); 4091 4092 ins_cost(125); 4093 format %{ "movswq $dst, $mem\t# short -> long" %} 4094 4095 ins_encode %{ 4096 __ movswq($dst$$Register, $mem$$Address); 4097 %} 4098 4099 ins_pipe(ialu_reg_mem); 4100 %} 4101 4102 // Load Unsigned Short/Char (16 bit UNsigned) 4103 instruct loadUS(rRegI dst, memory mem) 4104 %{ 4105 match(Set dst (LoadUS mem)); 4106 4107 ins_cost(125); 4108 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4109 4110 ins_encode %{ 4111 __ movzwl($dst$$Register, $mem$$Address); 4112 %} 4113 4114 ins_pipe(ialu_reg_mem); 4115 %} 4116 4117 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4118 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4119 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4120 4121 ins_cost(125); 4122 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4123 ins_encode %{ 4124 __ movsbl($dst$$Register, $mem$$Address); 4125 %} 4126 ins_pipe(ialu_reg_mem); 4127 %} 4128 4129 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4130 instruct loadUS2L(rRegL dst, memory mem) 4131 %{ 4132 match(Set dst (ConvI2L (LoadUS mem))); 4133 4134 ins_cost(125); 4135 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4136 4137 ins_encode %{ 4138 __ movzwq($dst$$Register, $mem$$Address); 4139 %} 4140 4141 ins_pipe(ialu_reg_mem); 4142 %} 4143 4144 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4145 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4146 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4147 4148 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4149 ins_encode %{ 4150 __ movzbq($dst$$Register, $mem$$Address); 4151 %} 4152 ins_pipe(ialu_reg_mem); 4153 %} 4154 4155 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4156 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4157 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4158 effect(KILL cr); 4159 4160 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4161 "andl $dst, right_n_bits($mask, 16)" %} 4162 ins_encode %{ 4163 Register Rdst = $dst$$Register; 4164 __ movzwq(Rdst, $mem$$Address); 4165 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4166 %} 4167 ins_pipe(ialu_reg_mem); 4168 %} 4169 4170 // Load Integer 4171 instruct loadI(rRegI dst, memory mem) 4172 %{ 4173 match(Set dst (LoadI mem)); 4174 4175 ins_cost(125); 4176 format %{ "movl $dst, $mem\t# int" %} 4177 4178 ins_encode %{ 4179 __ movl($dst$$Register, $mem$$Address); 4180 %} 4181 4182 ins_pipe(ialu_reg_mem); 4183 %} 4184 4185 // Load Integer (32 bit signed) to Byte (8 bit signed) 4186 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4187 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4188 4189 ins_cost(125); 4190 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4191 ins_encode %{ 4192 __ movsbl($dst$$Register, $mem$$Address); 4193 %} 4194 ins_pipe(ialu_reg_mem); 4195 %} 4196 4197 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4198 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4199 match(Set dst (AndI (LoadI mem) mask)); 4200 4201 ins_cost(125); 4202 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4203 ins_encode %{ 4204 __ movzbl($dst$$Register, $mem$$Address); 4205 %} 4206 ins_pipe(ialu_reg_mem); 4207 %} 4208 4209 // Load Integer (32 bit signed) to Short (16 bit signed) 4210 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4211 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4212 4213 ins_cost(125); 4214 format %{ "movswl $dst, $mem\t# int -> short" %} 4215 ins_encode %{ 4216 __ movswl($dst$$Register, $mem$$Address); 4217 %} 4218 ins_pipe(ialu_reg_mem); 4219 %} 4220 4221 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4222 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4223 match(Set dst (AndI (LoadI mem) mask)); 4224 4225 ins_cost(125); 4226 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4227 ins_encode %{ 4228 __ movzwl($dst$$Register, $mem$$Address); 4229 %} 4230 ins_pipe(ialu_reg_mem); 4231 %} 4232 4233 // Load Integer into Long Register 4234 instruct loadI2L(rRegL dst, memory mem) 4235 %{ 4236 match(Set dst (ConvI2L (LoadI mem))); 4237 4238 ins_cost(125); 4239 format %{ "movslq $dst, $mem\t# int -> long" %} 4240 4241 ins_encode %{ 4242 __ movslq($dst$$Register, $mem$$Address); 4243 %} 4244 4245 ins_pipe(ialu_reg_mem); 4246 %} 4247 4248 // Load Integer with mask 0xFF into Long Register 4249 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4250 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4251 4252 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4253 ins_encode %{ 4254 __ movzbq($dst$$Register, $mem$$Address); 4255 %} 4256 ins_pipe(ialu_reg_mem); 4257 %} 4258 4259 // Load Integer with mask 0xFFFF into Long Register 4260 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4261 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4262 4263 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4264 ins_encode %{ 4265 __ movzwq($dst$$Register, $mem$$Address); 4266 %} 4267 ins_pipe(ialu_reg_mem); 4268 %} 4269 4270 // Load Integer with a 31-bit mask into Long Register 4271 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4272 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4273 effect(KILL cr); 4274 4275 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4276 "andl $dst, $mask" %} 4277 ins_encode %{ 4278 Register Rdst = $dst$$Register; 4279 __ movl(Rdst, $mem$$Address); 4280 __ andl(Rdst, $mask$$constant); 4281 %} 4282 ins_pipe(ialu_reg_mem); 4283 %} 4284 4285 // Load Unsigned Integer into Long Register 4286 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4287 %{ 4288 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4289 4290 ins_cost(125); 4291 format %{ "movl $dst, $mem\t# uint -> long" %} 4292 4293 ins_encode %{ 4294 __ movl($dst$$Register, $mem$$Address); 4295 %} 4296 4297 ins_pipe(ialu_reg_mem); 4298 %} 4299 4300 // Load Long 4301 instruct loadL(rRegL dst, memory mem) 4302 %{ 4303 match(Set dst (LoadL mem)); 4304 4305 ins_cost(125); 4306 format %{ "movq $dst, $mem\t# long" %} 4307 4308 ins_encode %{ 4309 __ movq($dst$$Register, $mem$$Address); 4310 %} 4311 4312 ins_pipe(ialu_reg_mem); // XXX 4313 %} 4314 4315 // Load Range 4316 instruct loadRange(rRegI dst, memory mem) 4317 %{ 4318 match(Set dst (LoadRange mem)); 4319 4320 ins_cost(125); // XXX 4321 format %{ "movl $dst, $mem\t# range" %} 4322 ins_encode %{ 4323 __ movl($dst$$Register, $mem$$Address); 4324 %} 4325 ins_pipe(ialu_reg_mem); 4326 %} 4327 4328 // Load Pointer 4329 instruct loadP(rRegP dst, memory mem) 4330 %{ 4331 match(Set dst (LoadP mem)); 4332 predicate(n->as_Load()->barrier_data() == 0); 4333 4334 ins_cost(125); // XXX 4335 format %{ "movq $dst, $mem\t# ptr" %} 4336 ins_encode %{ 4337 __ movq($dst$$Register, $mem$$Address); 4338 %} 4339 ins_pipe(ialu_reg_mem); // XXX 4340 %} 4341 4342 // Load Compressed Pointer 4343 instruct loadN(rRegN dst, memory mem) 4344 %{ 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 match(Set mem (StoreN mem src)); 5131 5132 ins_cost(125); // XXX 5133 format %{ "movl $mem, $src\t# compressed ptr" %} 5134 ins_encode %{ 5135 __ movl($mem$$Address, $src$$Register); 5136 %} 5137 ins_pipe(ialu_mem_reg); 5138 %} 5139 5140 instruct storeNKlass(memory mem, rRegN src) 5141 %{ 5142 match(Set mem (StoreNKlass mem src)); 5143 5144 ins_cost(125); // XXX 5145 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5146 ins_encode %{ 5147 __ movl($mem$$Address, $src$$Register); 5148 %} 5149 ins_pipe(ialu_mem_reg); 5150 %} 5151 5152 instruct storeImmN0(memory mem, immN0 zero) 5153 %{ 5154 predicate(CompressedOops::base() == nullptr); 5155 match(Set mem (StoreN mem zero)); 5156 5157 ins_cost(125); // XXX 5158 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5159 ins_encode %{ 5160 __ movl($mem$$Address, r12); 5161 %} 5162 ins_pipe(ialu_mem_reg); 5163 %} 5164 5165 instruct storeImmN(memory mem, immN src) 5166 %{ 5167 match(Set mem (StoreN mem src)); 5168 5169 ins_cost(150); // XXX 5170 format %{ "movl $mem, $src\t# compressed ptr" %} 5171 ins_encode %{ 5172 address con = (address)$src$$constant; 5173 if (con == nullptr) { 5174 __ movl($mem$$Address, 0); 5175 } else { 5176 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5177 } 5178 %} 5179 ins_pipe(ialu_mem_imm); 5180 %} 5181 5182 instruct storeImmNKlass(memory mem, immNKlass src) 5183 %{ 5184 match(Set mem (StoreNKlass mem src)); 5185 5186 ins_cost(150); // XXX 5187 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5188 ins_encode %{ 5189 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5190 %} 5191 ins_pipe(ialu_mem_imm); 5192 %} 5193 5194 // Store Integer Immediate 5195 instruct storeImmI0(memory mem, immI_0 zero) 5196 %{ 5197 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5198 match(Set mem (StoreI mem zero)); 5199 5200 ins_cost(125); // XXX 5201 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5202 ins_encode %{ 5203 __ movl($mem$$Address, r12); 5204 %} 5205 ins_pipe(ialu_mem_reg); 5206 %} 5207 5208 instruct storeImmI(memory mem, immI src) 5209 %{ 5210 match(Set mem (StoreI mem src)); 5211 5212 ins_cost(150); 5213 format %{ "movl $mem, $src\t# int" %} 5214 ins_encode %{ 5215 __ movl($mem$$Address, $src$$constant); 5216 %} 5217 ins_pipe(ialu_mem_imm); 5218 %} 5219 5220 // Store Long Immediate 5221 instruct storeImmL0(memory mem, immL0 zero) 5222 %{ 5223 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5224 match(Set mem (StoreL mem zero)); 5225 5226 ins_cost(125); // XXX 5227 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5228 ins_encode %{ 5229 __ movq($mem$$Address, r12); 5230 %} 5231 ins_pipe(ialu_mem_reg); 5232 %} 5233 5234 instruct storeImmL(memory mem, immL32 src) 5235 %{ 5236 match(Set mem (StoreL mem src)); 5237 5238 ins_cost(150); 5239 format %{ "movq $mem, $src\t# long" %} 5240 ins_encode %{ 5241 __ movq($mem$$Address, $src$$constant); 5242 %} 5243 ins_pipe(ialu_mem_imm); 5244 %} 5245 5246 // Store Short/Char Immediate 5247 instruct storeImmC0(memory mem, immI_0 zero) 5248 %{ 5249 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5250 match(Set mem (StoreC mem zero)); 5251 5252 ins_cost(125); // XXX 5253 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5254 ins_encode %{ 5255 __ movw($mem$$Address, r12); 5256 %} 5257 ins_pipe(ialu_mem_reg); 5258 %} 5259 5260 instruct storeImmI16(memory mem, immI16 src) 5261 %{ 5262 predicate(UseStoreImmI16); 5263 match(Set mem (StoreC mem src)); 5264 5265 ins_cost(150); 5266 format %{ "movw $mem, $src\t# short/char" %} 5267 ins_encode %{ 5268 __ movw($mem$$Address, $src$$constant); 5269 %} 5270 ins_pipe(ialu_mem_imm); 5271 %} 5272 5273 // Store Byte Immediate 5274 instruct storeImmB0(memory mem, immI_0 zero) 5275 %{ 5276 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5277 match(Set mem (StoreB mem zero)); 5278 5279 ins_cost(125); // XXX 5280 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5281 ins_encode %{ 5282 __ movb($mem$$Address, r12); 5283 %} 5284 ins_pipe(ialu_mem_reg); 5285 %} 5286 5287 instruct storeImmB(memory mem, immI8 src) 5288 %{ 5289 match(Set mem (StoreB mem src)); 5290 5291 ins_cost(150); // XXX 5292 format %{ "movb $mem, $src\t# byte" %} 5293 ins_encode %{ 5294 __ movb($mem$$Address, $src$$constant); 5295 %} 5296 ins_pipe(ialu_mem_imm); 5297 %} 5298 5299 // Store CMS card-mark Immediate 5300 instruct storeImmCM0_reg(memory mem, immI_0 zero) 5301 %{ 5302 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5303 match(Set mem (StoreCM mem zero)); 5304 5305 ins_cost(125); // XXX 5306 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5307 ins_encode %{ 5308 __ movb($mem$$Address, r12); 5309 %} 5310 ins_pipe(ialu_mem_reg); 5311 %} 5312 5313 instruct storeImmCM0(memory mem, immI_0 src) 5314 %{ 5315 match(Set mem (StoreCM mem src)); 5316 5317 ins_cost(150); // XXX 5318 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5319 ins_encode %{ 5320 __ movb($mem$$Address, $src$$constant); 5321 %} 5322 ins_pipe(ialu_mem_imm); 5323 %} 5324 5325 // Store Float 5326 instruct storeF(memory mem, regF src) 5327 %{ 5328 match(Set mem (StoreF mem src)); 5329 5330 ins_cost(95); // XXX 5331 format %{ "movss $mem, $src\t# float" %} 5332 ins_encode %{ 5333 __ movflt($mem$$Address, $src$$XMMRegister); 5334 %} 5335 ins_pipe(pipe_slow); // XXX 5336 %} 5337 5338 // Store immediate Float value (it is faster than store from XMM register) 5339 instruct storeF0(memory mem, immF0 zero) 5340 %{ 5341 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5342 match(Set mem (StoreF mem zero)); 5343 5344 ins_cost(25); // XXX 5345 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5346 ins_encode %{ 5347 __ movl($mem$$Address, r12); 5348 %} 5349 ins_pipe(ialu_mem_reg); 5350 %} 5351 5352 instruct storeF_imm(memory mem, immF src) 5353 %{ 5354 match(Set mem (StoreF mem src)); 5355 5356 ins_cost(50); 5357 format %{ "movl $mem, $src\t# float" %} 5358 ins_encode %{ 5359 __ movl($mem$$Address, jint_cast($src$$constant)); 5360 %} 5361 ins_pipe(ialu_mem_imm); 5362 %} 5363 5364 // Store Double 5365 instruct storeD(memory mem, regD src) 5366 %{ 5367 match(Set mem (StoreD mem src)); 5368 5369 ins_cost(95); // XXX 5370 format %{ "movsd $mem, $src\t# double" %} 5371 ins_encode %{ 5372 __ movdbl($mem$$Address, $src$$XMMRegister); 5373 %} 5374 ins_pipe(pipe_slow); // XXX 5375 %} 5376 5377 // Store immediate double 0.0 (it is faster than store from XMM register) 5378 instruct storeD0_imm(memory mem, immD0 src) 5379 %{ 5380 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5381 match(Set mem (StoreD mem src)); 5382 5383 ins_cost(50); 5384 format %{ "movq $mem, $src\t# double 0." %} 5385 ins_encode %{ 5386 __ movq($mem$$Address, $src$$constant); 5387 %} 5388 ins_pipe(ialu_mem_imm); 5389 %} 5390 5391 instruct storeD0(memory mem, immD0 zero) 5392 %{ 5393 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5394 match(Set mem (StoreD mem zero)); 5395 5396 ins_cost(25); // XXX 5397 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5398 ins_encode %{ 5399 __ movq($mem$$Address, r12); 5400 %} 5401 ins_pipe(ialu_mem_reg); 5402 %} 5403 5404 instruct storeSSI(stackSlotI dst, rRegI src) 5405 %{ 5406 match(Set dst src); 5407 5408 ins_cost(100); 5409 format %{ "movl $dst, $src\t# int stk" %} 5410 ins_encode %{ 5411 __ movl($dst$$Address, $src$$Register); 5412 %} 5413 ins_pipe( ialu_mem_reg ); 5414 %} 5415 5416 instruct storeSSL(stackSlotL dst, rRegL src) 5417 %{ 5418 match(Set dst src); 5419 5420 ins_cost(100); 5421 format %{ "movq $dst, $src\t# long stk" %} 5422 ins_encode %{ 5423 __ movq($dst$$Address, $src$$Register); 5424 %} 5425 ins_pipe(ialu_mem_reg); 5426 %} 5427 5428 instruct storeSSP(stackSlotP dst, rRegP src) 5429 %{ 5430 match(Set dst src); 5431 5432 ins_cost(100); 5433 format %{ "movq $dst, $src\t# ptr stk" %} 5434 ins_encode %{ 5435 __ movq($dst$$Address, $src$$Register); 5436 %} 5437 ins_pipe(ialu_mem_reg); 5438 %} 5439 5440 instruct storeSSF(stackSlotF dst, regF src) 5441 %{ 5442 match(Set dst src); 5443 5444 ins_cost(95); // XXX 5445 format %{ "movss $dst, $src\t# float stk" %} 5446 ins_encode %{ 5447 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5448 %} 5449 ins_pipe(pipe_slow); // XXX 5450 %} 5451 5452 instruct storeSSD(stackSlotD dst, regD src) 5453 %{ 5454 match(Set dst src); 5455 5456 ins_cost(95); // XXX 5457 format %{ "movsd $dst, $src\t# double stk" %} 5458 ins_encode %{ 5459 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5460 %} 5461 ins_pipe(pipe_slow); // XXX 5462 %} 5463 5464 instruct cacheWB(indirect addr) 5465 %{ 5466 predicate(VM_Version::supports_data_cache_line_flush()); 5467 match(CacheWB addr); 5468 5469 ins_cost(100); 5470 format %{"cache wb $addr" %} 5471 ins_encode %{ 5472 assert($addr->index_position() < 0, "should be"); 5473 assert($addr$$disp == 0, "should be"); 5474 __ cache_wb(Address($addr$$base$$Register, 0)); 5475 %} 5476 ins_pipe(pipe_slow); // XXX 5477 %} 5478 5479 instruct cacheWBPreSync() 5480 %{ 5481 predicate(VM_Version::supports_data_cache_line_flush()); 5482 match(CacheWBPreSync); 5483 5484 ins_cost(100); 5485 format %{"cache wb presync" %} 5486 ins_encode %{ 5487 __ cache_wbsync(true); 5488 %} 5489 ins_pipe(pipe_slow); // XXX 5490 %} 5491 5492 instruct cacheWBPostSync() 5493 %{ 5494 predicate(VM_Version::supports_data_cache_line_flush()); 5495 match(CacheWBPostSync); 5496 5497 ins_cost(100); 5498 format %{"cache wb postsync" %} 5499 ins_encode %{ 5500 __ cache_wbsync(false); 5501 %} 5502 ins_pipe(pipe_slow); // XXX 5503 %} 5504 5505 //----------BSWAP Instructions------------------------------------------------- 5506 instruct bytes_reverse_int(rRegI dst) %{ 5507 match(Set dst (ReverseBytesI dst)); 5508 5509 format %{ "bswapl $dst" %} 5510 ins_encode %{ 5511 __ bswapl($dst$$Register); 5512 %} 5513 ins_pipe( ialu_reg ); 5514 %} 5515 5516 instruct bytes_reverse_long(rRegL dst) %{ 5517 match(Set dst (ReverseBytesL dst)); 5518 5519 format %{ "bswapq $dst" %} 5520 ins_encode %{ 5521 __ bswapq($dst$$Register); 5522 %} 5523 ins_pipe( ialu_reg); 5524 %} 5525 5526 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5527 match(Set dst (ReverseBytesUS dst)); 5528 effect(KILL cr); 5529 5530 format %{ "bswapl $dst\n\t" 5531 "shrl $dst,16\n\t" %} 5532 ins_encode %{ 5533 __ bswapl($dst$$Register); 5534 __ shrl($dst$$Register, 16); 5535 %} 5536 ins_pipe( ialu_reg ); 5537 %} 5538 5539 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5540 match(Set dst (ReverseBytesS dst)); 5541 effect(KILL cr); 5542 5543 format %{ "bswapl $dst\n\t" 5544 "sar $dst,16\n\t" %} 5545 ins_encode %{ 5546 __ bswapl($dst$$Register); 5547 __ sarl($dst$$Register, 16); 5548 %} 5549 ins_pipe( ialu_reg ); 5550 %} 5551 5552 //---------- Zeros Count Instructions ------------------------------------------ 5553 5554 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5555 predicate(UseCountLeadingZerosInstruction); 5556 match(Set dst (CountLeadingZerosI src)); 5557 effect(KILL cr); 5558 5559 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5560 ins_encode %{ 5561 __ lzcntl($dst$$Register, $src$$Register); 5562 %} 5563 ins_pipe(ialu_reg); 5564 %} 5565 5566 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5567 predicate(UseCountLeadingZerosInstruction); 5568 match(Set dst (CountLeadingZerosI (LoadI src))); 5569 effect(KILL cr); 5570 ins_cost(175); 5571 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5572 ins_encode %{ 5573 __ lzcntl($dst$$Register, $src$$Address); 5574 %} 5575 ins_pipe(ialu_reg_mem); 5576 %} 5577 5578 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5579 predicate(!UseCountLeadingZerosInstruction); 5580 match(Set dst (CountLeadingZerosI src)); 5581 effect(KILL cr); 5582 5583 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5584 "jnz skip\n\t" 5585 "movl $dst, -1\n" 5586 "skip:\n\t" 5587 "negl $dst\n\t" 5588 "addl $dst, 31" %} 5589 ins_encode %{ 5590 Register Rdst = $dst$$Register; 5591 Register Rsrc = $src$$Register; 5592 Label skip; 5593 __ bsrl(Rdst, Rsrc); 5594 __ jccb(Assembler::notZero, skip); 5595 __ movl(Rdst, -1); 5596 __ bind(skip); 5597 __ negl(Rdst); 5598 __ addl(Rdst, BitsPerInt - 1); 5599 %} 5600 ins_pipe(ialu_reg); 5601 %} 5602 5603 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5604 predicate(UseCountLeadingZerosInstruction); 5605 match(Set dst (CountLeadingZerosL src)); 5606 effect(KILL cr); 5607 5608 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5609 ins_encode %{ 5610 __ lzcntq($dst$$Register, $src$$Register); 5611 %} 5612 ins_pipe(ialu_reg); 5613 %} 5614 5615 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5616 predicate(UseCountLeadingZerosInstruction); 5617 match(Set dst (CountLeadingZerosL (LoadL src))); 5618 effect(KILL cr); 5619 ins_cost(175); 5620 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5621 ins_encode %{ 5622 __ lzcntq($dst$$Register, $src$$Address); 5623 %} 5624 ins_pipe(ialu_reg_mem); 5625 %} 5626 5627 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5628 predicate(!UseCountLeadingZerosInstruction); 5629 match(Set dst (CountLeadingZerosL src)); 5630 effect(KILL cr); 5631 5632 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5633 "jnz skip\n\t" 5634 "movl $dst, -1\n" 5635 "skip:\n\t" 5636 "negl $dst\n\t" 5637 "addl $dst, 63" %} 5638 ins_encode %{ 5639 Register Rdst = $dst$$Register; 5640 Register Rsrc = $src$$Register; 5641 Label skip; 5642 __ bsrq(Rdst, Rsrc); 5643 __ jccb(Assembler::notZero, skip); 5644 __ movl(Rdst, -1); 5645 __ bind(skip); 5646 __ negl(Rdst); 5647 __ addl(Rdst, BitsPerLong - 1); 5648 %} 5649 ins_pipe(ialu_reg); 5650 %} 5651 5652 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5653 predicate(UseCountTrailingZerosInstruction); 5654 match(Set dst (CountTrailingZerosI src)); 5655 effect(KILL cr); 5656 5657 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5658 ins_encode %{ 5659 __ tzcntl($dst$$Register, $src$$Register); 5660 %} 5661 ins_pipe(ialu_reg); 5662 %} 5663 5664 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5665 predicate(UseCountTrailingZerosInstruction); 5666 match(Set dst (CountTrailingZerosI (LoadI src))); 5667 effect(KILL cr); 5668 ins_cost(175); 5669 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5670 ins_encode %{ 5671 __ tzcntl($dst$$Register, $src$$Address); 5672 %} 5673 ins_pipe(ialu_reg_mem); 5674 %} 5675 5676 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5677 predicate(!UseCountTrailingZerosInstruction); 5678 match(Set dst (CountTrailingZerosI src)); 5679 effect(KILL cr); 5680 5681 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5682 "jnz done\n\t" 5683 "movl $dst, 32\n" 5684 "done:" %} 5685 ins_encode %{ 5686 Register Rdst = $dst$$Register; 5687 Label done; 5688 __ bsfl(Rdst, $src$$Register); 5689 __ jccb(Assembler::notZero, done); 5690 __ movl(Rdst, BitsPerInt); 5691 __ bind(done); 5692 %} 5693 ins_pipe(ialu_reg); 5694 %} 5695 5696 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5697 predicate(UseCountTrailingZerosInstruction); 5698 match(Set dst (CountTrailingZerosL src)); 5699 effect(KILL cr); 5700 5701 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5702 ins_encode %{ 5703 __ tzcntq($dst$$Register, $src$$Register); 5704 %} 5705 ins_pipe(ialu_reg); 5706 %} 5707 5708 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5709 predicate(UseCountTrailingZerosInstruction); 5710 match(Set dst (CountTrailingZerosL (LoadL src))); 5711 effect(KILL cr); 5712 ins_cost(175); 5713 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5714 ins_encode %{ 5715 __ tzcntq($dst$$Register, $src$$Address); 5716 %} 5717 ins_pipe(ialu_reg_mem); 5718 %} 5719 5720 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5721 predicate(!UseCountTrailingZerosInstruction); 5722 match(Set dst (CountTrailingZerosL src)); 5723 effect(KILL cr); 5724 5725 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5726 "jnz done\n\t" 5727 "movl $dst, 64\n" 5728 "done:" %} 5729 ins_encode %{ 5730 Register Rdst = $dst$$Register; 5731 Label done; 5732 __ bsfq(Rdst, $src$$Register); 5733 __ jccb(Assembler::notZero, done); 5734 __ movl(Rdst, BitsPerLong); 5735 __ bind(done); 5736 %} 5737 ins_pipe(ialu_reg); 5738 %} 5739 5740 //--------------- Reverse Operation Instructions ---------------- 5741 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5742 predicate(!VM_Version::supports_gfni()); 5743 match(Set dst (ReverseI src)); 5744 effect(TEMP dst, TEMP rtmp, KILL cr); 5745 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5746 ins_encode %{ 5747 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5748 %} 5749 ins_pipe( ialu_reg ); 5750 %} 5751 5752 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5753 predicate(VM_Version::supports_gfni()); 5754 match(Set dst (ReverseI src)); 5755 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5756 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5757 ins_encode %{ 5758 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5759 %} 5760 ins_pipe( ialu_reg ); 5761 %} 5762 5763 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5764 predicate(!VM_Version::supports_gfni()); 5765 match(Set dst (ReverseL src)); 5766 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5767 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5768 ins_encode %{ 5769 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5770 %} 5771 ins_pipe( ialu_reg ); 5772 %} 5773 5774 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5775 predicate(VM_Version::supports_gfni()); 5776 match(Set dst (ReverseL src)); 5777 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5778 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5779 ins_encode %{ 5780 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5781 %} 5782 ins_pipe( ialu_reg ); 5783 %} 5784 5785 //---------- Population Count Instructions ------------------------------------- 5786 5787 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5788 predicate(UsePopCountInstruction); 5789 match(Set dst (PopCountI src)); 5790 effect(KILL cr); 5791 5792 format %{ "popcnt $dst, $src" %} 5793 ins_encode %{ 5794 __ popcntl($dst$$Register, $src$$Register); 5795 %} 5796 ins_pipe(ialu_reg); 5797 %} 5798 5799 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5800 predicate(UsePopCountInstruction); 5801 match(Set dst (PopCountI (LoadI mem))); 5802 effect(KILL cr); 5803 5804 format %{ "popcnt $dst, $mem" %} 5805 ins_encode %{ 5806 __ popcntl($dst$$Register, $mem$$Address); 5807 %} 5808 ins_pipe(ialu_reg); 5809 %} 5810 5811 // Note: Long.bitCount(long) returns an int. 5812 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5813 predicate(UsePopCountInstruction); 5814 match(Set dst (PopCountL src)); 5815 effect(KILL cr); 5816 5817 format %{ "popcnt $dst, $src" %} 5818 ins_encode %{ 5819 __ popcntq($dst$$Register, $src$$Register); 5820 %} 5821 ins_pipe(ialu_reg); 5822 %} 5823 5824 // Note: Long.bitCount(long) returns an int. 5825 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5826 predicate(UsePopCountInstruction); 5827 match(Set dst (PopCountL (LoadL mem))); 5828 effect(KILL cr); 5829 5830 format %{ "popcnt $dst, $mem" %} 5831 ins_encode %{ 5832 __ popcntq($dst$$Register, $mem$$Address); 5833 %} 5834 ins_pipe(ialu_reg); 5835 %} 5836 5837 5838 //----------MemBar Instructions----------------------------------------------- 5839 // Memory barrier flavors 5840 5841 instruct membar_acquire() 5842 %{ 5843 match(MemBarAcquire); 5844 match(LoadFence); 5845 ins_cost(0); 5846 5847 size(0); 5848 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5849 ins_encode(); 5850 ins_pipe(empty); 5851 %} 5852 5853 instruct membar_acquire_lock() 5854 %{ 5855 match(MemBarAcquireLock); 5856 ins_cost(0); 5857 5858 size(0); 5859 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5860 ins_encode(); 5861 ins_pipe(empty); 5862 %} 5863 5864 instruct membar_release() 5865 %{ 5866 match(MemBarRelease); 5867 match(StoreFence); 5868 ins_cost(0); 5869 5870 size(0); 5871 format %{ "MEMBAR-release ! (empty encoding)" %} 5872 ins_encode(); 5873 ins_pipe(empty); 5874 %} 5875 5876 instruct membar_release_lock() 5877 %{ 5878 match(MemBarReleaseLock); 5879 ins_cost(0); 5880 5881 size(0); 5882 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5883 ins_encode(); 5884 ins_pipe(empty); 5885 %} 5886 5887 instruct membar_volatile(rFlagsReg cr) %{ 5888 match(MemBarVolatile); 5889 effect(KILL cr); 5890 ins_cost(400); 5891 5892 format %{ 5893 $$template 5894 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5895 %} 5896 ins_encode %{ 5897 __ membar(Assembler::StoreLoad); 5898 %} 5899 ins_pipe(pipe_slow); 5900 %} 5901 5902 instruct unnecessary_membar_volatile() 5903 %{ 5904 match(MemBarVolatile); 5905 predicate(Matcher::post_store_load_barrier(n)); 5906 ins_cost(0); 5907 5908 size(0); 5909 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5910 ins_encode(); 5911 ins_pipe(empty); 5912 %} 5913 5914 instruct membar_storestore() %{ 5915 match(MemBarStoreStore); 5916 match(StoreStoreFence); 5917 ins_cost(0); 5918 5919 size(0); 5920 format %{ "MEMBAR-storestore (empty encoding)" %} 5921 ins_encode( ); 5922 ins_pipe(empty); 5923 %} 5924 5925 //----------Move Instructions-------------------------------------------------- 5926 5927 instruct castX2P(rRegP dst, rRegL src) 5928 %{ 5929 match(Set dst (CastX2P src)); 5930 5931 format %{ "movq $dst, $src\t# long->ptr" %} 5932 ins_encode %{ 5933 if ($dst$$reg != $src$$reg) { 5934 __ movptr($dst$$Register, $src$$Register); 5935 } 5936 %} 5937 ins_pipe(ialu_reg_reg); // XXX 5938 %} 5939 5940 instruct castP2X(rRegL dst, rRegP src) 5941 %{ 5942 match(Set dst (CastP2X src)); 5943 5944 format %{ "movq $dst, $src\t# ptr -> long" %} 5945 ins_encode %{ 5946 if ($dst$$reg != $src$$reg) { 5947 __ movptr($dst$$Register, $src$$Register); 5948 } 5949 %} 5950 ins_pipe(ialu_reg_reg); // XXX 5951 %} 5952 5953 // Convert oop into int for vectors alignment masking 5954 instruct convP2I(rRegI dst, rRegP src) 5955 %{ 5956 match(Set dst (ConvL2I (CastP2X src))); 5957 5958 format %{ "movl $dst, $src\t# ptr -> int" %} 5959 ins_encode %{ 5960 __ movl($dst$$Register, $src$$Register); 5961 %} 5962 ins_pipe(ialu_reg_reg); // XXX 5963 %} 5964 5965 // Convert compressed oop into int for vectors alignment masking 5966 // in case of 32bit oops (heap < 4Gb). 5967 instruct convN2I(rRegI dst, rRegN src) 5968 %{ 5969 predicate(CompressedOops::shift() == 0); 5970 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5971 5972 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5973 ins_encode %{ 5974 __ movl($dst$$Register, $src$$Register); 5975 %} 5976 ins_pipe(ialu_reg_reg); // XXX 5977 %} 5978 5979 // Convert oop pointer into compressed form 5980 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5981 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5982 match(Set dst (EncodeP src)); 5983 effect(KILL cr); 5984 format %{ "encode_heap_oop $dst,$src" %} 5985 ins_encode %{ 5986 Register s = $src$$Register; 5987 Register d = $dst$$Register; 5988 if (s != d) { 5989 __ movq(d, s); 5990 } 5991 __ encode_heap_oop(d); 5992 %} 5993 ins_pipe(ialu_reg_long); 5994 %} 5995 5996 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5997 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 5998 match(Set dst (EncodeP src)); 5999 effect(KILL cr); 6000 format %{ "encode_heap_oop_not_null $dst,$src" %} 6001 ins_encode %{ 6002 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6003 %} 6004 ins_pipe(ialu_reg_long); 6005 %} 6006 6007 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6008 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6009 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6010 match(Set dst (DecodeN src)); 6011 effect(KILL cr); 6012 format %{ "decode_heap_oop $dst,$src" %} 6013 ins_encode %{ 6014 Register s = $src$$Register; 6015 Register d = $dst$$Register; 6016 if (s != d) { 6017 __ movq(d, s); 6018 } 6019 __ decode_heap_oop(d); 6020 %} 6021 ins_pipe(ialu_reg_long); 6022 %} 6023 6024 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6025 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6026 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6027 match(Set dst (DecodeN src)); 6028 effect(KILL cr); 6029 format %{ "decode_heap_oop_not_null $dst,$src" %} 6030 ins_encode %{ 6031 Register s = $src$$Register; 6032 Register d = $dst$$Register; 6033 if (s != d) { 6034 __ decode_heap_oop_not_null(d, s); 6035 } else { 6036 __ decode_heap_oop_not_null(d); 6037 } 6038 %} 6039 ins_pipe(ialu_reg_long); 6040 %} 6041 6042 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6043 match(Set dst (EncodePKlass src)); 6044 effect(TEMP dst, KILL cr); 6045 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6046 ins_encode %{ 6047 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6048 %} 6049 ins_pipe(ialu_reg_long); 6050 %} 6051 6052 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6053 match(Set dst (DecodeNKlass src)); 6054 effect(TEMP dst, KILL cr); 6055 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6056 ins_encode %{ 6057 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6058 %} 6059 ins_pipe(ialu_reg_long); 6060 %} 6061 6062 //----------Conditional Move--------------------------------------------------- 6063 // Jump 6064 // dummy instruction for generating temp registers 6065 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6066 match(Jump (LShiftL switch_val shift)); 6067 ins_cost(350); 6068 predicate(false); 6069 effect(TEMP dest); 6070 6071 format %{ "leaq $dest, [$constantaddress]\n\t" 6072 "jmp [$dest + $switch_val << $shift]\n\t" %} 6073 ins_encode %{ 6074 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6075 // to do that and the compiler is using that register as one it can allocate. 6076 // So we build it all by hand. 6077 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6078 // ArrayAddress dispatch(table, index); 6079 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6080 __ lea($dest$$Register, $constantaddress); 6081 __ jmp(dispatch); 6082 %} 6083 ins_pipe(pipe_jmp); 6084 %} 6085 6086 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6087 match(Jump (AddL (LShiftL switch_val shift) offset)); 6088 ins_cost(350); 6089 effect(TEMP dest); 6090 6091 format %{ "leaq $dest, [$constantaddress]\n\t" 6092 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6093 ins_encode %{ 6094 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6095 // to do that and the compiler is using that register as one it can allocate. 6096 // So we build it all by hand. 6097 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6098 // ArrayAddress dispatch(table, index); 6099 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6100 __ lea($dest$$Register, $constantaddress); 6101 __ jmp(dispatch); 6102 %} 6103 ins_pipe(pipe_jmp); 6104 %} 6105 6106 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6107 match(Jump switch_val); 6108 ins_cost(350); 6109 effect(TEMP dest); 6110 6111 format %{ "leaq $dest, [$constantaddress]\n\t" 6112 "jmp [$dest + $switch_val]\n\t" %} 6113 ins_encode %{ 6114 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6115 // to do that and the compiler is using that register as one it can allocate. 6116 // So we build it all by hand. 6117 // Address index(noreg, switch_reg, Address::times_1); 6118 // ArrayAddress dispatch(table, index); 6119 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6120 __ lea($dest$$Register, $constantaddress); 6121 __ jmp(dispatch); 6122 %} 6123 ins_pipe(pipe_jmp); 6124 %} 6125 6126 // Conditional move 6127 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6128 %{ 6129 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6130 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6131 6132 ins_cost(100); // XXX 6133 format %{ "setbn$cop $dst\t# signed, int" %} 6134 ins_encode %{ 6135 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6136 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6137 %} 6138 ins_pipe(ialu_reg); 6139 %} 6140 6141 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6142 %{ 6143 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6144 6145 ins_cost(200); // XXX 6146 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6147 ins_encode %{ 6148 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6149 %} 6150 ins_pipe(pipe_cmov_reg); 6151 %} 6152 6153 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6154 %{ 6155 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6156 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6157 6158 ins_cost(100); // XXX 6159 format %{ "setbn$cop $dst\t# unsigned, int" %} 6160 ins_encode %{ 6161 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6162 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6163 %} 6164 ins_pipe(ialu_reg); 6165 %} 6166 6167 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6168 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6169 6170 ins_cost(200); // XXX 6171 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6172 ins_encode %{ 6173 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6174 %} 6175 ins_pipe(pipe_cmov_reg); 6176 %} 6177 6178 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6179 %{ 6180 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6181 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6182 6183 ins_cost(100); // XXX 6184 format %{ "setbn$cop $dst\t# unsigned, int" %} 6185 ins_encode %{ 6186 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6187 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6188 %} 6189 ins_pipe(ialu_reg); 6190 %} 6191 6192 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6193 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6194 ins_cost(200); 6195 expand %{ 6196 cmovI_regU(cop, cr, dst, src); 6197 %} 6198 %} 6199 6200 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6201 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6202 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6203 6204 ins_cost(200); // XXX 6205 format %{ "cmovpl $dst, $src\n\t" 6206 "cmovnel $dst, $src" %} 6207 ins_encode %{ 6208 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6209 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6210 %} 6211 ins_pipe(pipe_cmov_reg); 6212 %} 6213 6214 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6215 // inputs of the CMove 6216 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6217 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6218 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6219 6220 ins_cost(200); // XXX 6221 format %{ "cmovpl $dst, $src\n\t" 6222 "cmovnel $dst, $src" %} 6223 ins_encode %{ 6224 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6225 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6226 %} 6227 ins_pipe(pipe_cmov_reg); 6228 %} 6229 6230 // Conditional move 6231 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6232 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6233 6234 ins_cost(250); // XXX 6235 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6236 ins_encode %{ 6237 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6238 %} 6239 ins_pipe(pipe_cmov_mem); 6240 %} 6241 6242 // Conditional move 6243 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6244 %{ 6245 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6246 6247 ins_cost(250); // XXX 6248 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6249 ins_encode %{ 6250 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6251 %} 6252 ins_pipe(pipe_cmov_mem); 6253 %} 6254 6255 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6256 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6257 ins_cost(250); 6258 expand %{ 6259 cmovI_memU(cop, cr, dst, src); 6260 %} 6261 %} 6262 6263 // Conditional move 6264 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6265 %{ 6266 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6267 6268 ins_cost(200); // XXX 6269 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6270 ins_encode %{ 6271 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6272 %} 6273 ins_pipe(pipe_cmov_reg); 6274 %} 6275 6276 // Conditional move 6277 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6278 %{ 6279 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6280 6281 ins_cost(200); // XXX 6282 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6283 ins_encode %{ 6284 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6285 %} 6286 ins_pipe(pipe_cmov_reg); 6287 %} 6288 6289 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6290 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6291 ins_cost(200); 6292 expand %{ 6293 cmovN_regU(cop, cr, dst, src); 6294 %} 6295 %} 6296 6297 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6298 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6299 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6300 6301 ins_cost(200); // XXX 6302 format %{ "cmovpl $dst, $src\n\t" 6303 "cmovnel $dst, $src" %} 6304 ins_encode %{ 6305 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6306 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6307 %} 6308 ins_pipe(pipe_cmov_reg); 6309 %} 6310 6311 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6312 // inputs of the CMove 6313 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6314 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6315 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6316 6317 ins_cost(200); // XXX 6318 format %{ "cmovpl $dst, $src\n\t" 6319 "cmovnel $dst, $src" %} 6320 ins_encode %{ 6321 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6322 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6323 %} 6324 ins_pipe(pipe_cmov_reg); 6325 %} 6326 6327 // Conditional move 6328 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6329 %{ 6330 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6331 6332 ins_cost(200); // XXX 6333 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6334 ins_encode %{ 6335 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6336 %} 6337 ins_pipe(pipe_cmov_reg); // XXX 6338 %} 6339 6340 // Conditional move 6341 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6342 %{ 6343 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6344 6345 ins_cost(200); // XXX 6346 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6347 ins_encode %{ 6348 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6349 %} 6350 ins_pipe(pipe_cmov_reg); // XXX 6351 %} 6352 6353 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6354 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6355 ins_cost(200); 6356 expand %{ 6357 cmovP_regU(cop, cr, dst, src); 6358 %} 6359 %} 6360 6361 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6362 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6363 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6364 6365 ins_cost(200); // XXX 6366 format %{ "cmovpq $dst, $src\n\t" 6367 "cmovneq $dst, $src" %} 6368 ins_encode %{ 6369 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6370 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6371 %} 6372 ins_pipe(pipe_cmov_reg); 6373 %} 6374 6375 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6376 // inputs of the CMove 6377 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6378 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6379 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6380 6381 ins_cost(200); // XXX 6382 format %{ "cmovpq $dst, $src\n\t" 6383 "cmovneq $dst, $src" %} 6384 ins_encode %{ 6385 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6386 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6387 %} 6388 ins_pipe(pipe_cmov_reg); 6389 %} 6390 6391 instruct cmovL_imm_01(rRegL dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6392 %{ 6393 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6394 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6395 6396 ins_cost(100); // XXX 6397 format %{ "setbn$cop $dst\t# signed, long" %} 6398 ins_encode %{ 6399 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6400 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6401 %} 6402 ins_pipe(ialu_reg); 6403 %} 6404 6405 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6406 %{ 6407 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6408 6409 ins_cost(200); // XXX 6410 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6411 ins_encode %{ 6412 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6413 %} 6414 ins_pipe(pipe_cmov_reg); // XXX 6415 %} 6416 6417 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6418 %{ 6419 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6420 6421 ins_cost(200); // XXX 6422 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6423 ins_encode %{ 6424 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6425 %} 6426 ins_pipe(pipe_cmov_mem); // XXX 6427 %} 6428 6429 instruct cmovL_imm_01U(rRegL dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6430 %{ 6431 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6432 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6433 6434 ins_cost(100); // XXX 6435 format %{ "setbn$cop $dst\t# unsigned, long" %} 6436 ins_encode %{ 6437 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6438 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6439 %} 6440 ins_pipe(ialu_reg); 6441 %} 6442 6443 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6444 %{ 6445 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6446 6447 ins_cost(200); // XXX 6448 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6449 ins_encode %{ 6450 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6451 %} 6452 ins_pipe(pipe_cmov_reg); // XXX 6453 %} 6454 6455 instruct cmovL_imm_01UCF(rRegL dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6456 %{ 6457 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6458 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6459 6460 ins_cost(100); // XXX 6461 format %{ "setbn$cop $dst\t# unsigned, long" %} 6462 ins_encode %{ 6463 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6464 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6465 %} 6466 ins_pipe(ialu_reg); 6467 %} 6468 6469 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6470 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6471 ins_cost(200); 6472 expand %{ 6473 cmovL_regU(cop, cr, dst, src); 6474 %} 6475 %} 6476 6477 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6478 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6479 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6480 6481 ins_cost(200); // XXX 6482 format %{ "cmovpq $dst, $src\n\t" 6483 "cmovneq $dst, $src" %} 6484 ins_encode %{ 6485 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6486 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6487 %} 6488 ins_pipe(pipe_cmov_reg); 6489 %} 6490 6491 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6492 // inputs of the CMove 6493 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6494 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6495 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6496 6497 ins_cost(200); // XXX 6498 format %{ "cmovpq $dst, $src\n\t" 6499 "cmovneq $dst, $src" %} 6500 ins_encode %{ 6501 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6502 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6503 %} 6504 ins_pipe(pipe_cmov_reg); 6505 %} 6506 6507 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6508 %{ 6509 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6510 6511 ins_cost(200); // XXX 6512 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6513 ins_encode %{ 6514 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6515 %} 6516 ins_pipe(pipe_cmov_mem); // XXX 6517 %} 6518 6519 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6520 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6521 ins_cost(200); 6522 expand %{ 6523 cmovL_memU(cop, cr, dst, src); 6524 %} 6525 %} 6526 6527 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6528 %{ 6529 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6530 6531 ins_cost(200); // XXX 6532 format %{ "jn$cop skip\t# signed cmove float\n\t" 6533 "movss $dst, $src\n" 6534 "skip:" %} 6535 ins_encode %{ 6536 Label Lskip; 6537 // Invert sense of branch from sense of CMOV 6538 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6539 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6540 __ bind(Lskip); 6541 %} 6542 ins_pipe(pipe_slow); 6543 %} 6544 6545 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6546 %{ 6547 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6548 6549 ins_cost(200); // XXX 6550 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6551 "movss $dst, $src\n" 6552 "skip:" %} 6553 ins_encode %{ 6554 Label Lskip; 6555 // Invert sense of branch from sense of CMOV 6556 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6557 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6558 __ bind(Lskip); 6559 %} 6560 ins_pipe(pipe_slow); 6561 %} 6562 6563 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6564 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6565 ins_cost(200); 6566 expand %{ 6567 cmovF_regU(cop, cr, dst, src); 6568 %} 6569 %} 6570 6571 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6572 %{ 6573 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6574 6575 ins_cost(200); // XXX 6576 format %{ "jn$cop skip\t# signed cmove double\n\t" 6577 "movsd $dst, $src\n" 6578 "skip:" %} 6579 ins_encode %{ 6580 Label Lskip; 6581 // Invert sense of branch from sense of CMOV 6582 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6583 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6584 __ bind(Lskip); 6585 %} 6586 ins_pipe(pipe_slow); 6587 %} 6588 6589 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6590 %{ 6591 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6592 6593 ins_cost(200); // XXX 6594 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6595 "movsd $dst, $src\n" 6596 "skip:" %} 6597 ins_encode %{ 6598 Label Lskip; 6599 // Invert sense of branch from sense of CMOV 6600 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6601 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6602 __ bind(Lskip); 6603 %} 6604 ins_pipe(pipe_slow); 6605 %} 6606 6607 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6608 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6609 ins_cost(200); 6610 expand %{ 6611 cmovD_regU(cop, cr, dst, src); 6612 %} 6613 %} 6614 6615 //----------Arithmetic Instructions-------------------------------------------- 6616 //----------Addition Instructions---------------------------------------------- 6617 6618 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6619 %{ 6620 match(Set dst (AddI dst src)); 6621 effect(KILL cr); 6622 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); 6623 format %{ "addl $dst, $src\t# int" %} 6624 ins_encode %{ 6625 __ addl($dst$$Register, $src$$Register); 6626 %} 6627 ins_pipe(ialu_reg_reg); 6628 %} 6629 6630 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6631 %{ 6632 match(Set dst (AddI dst src)); 6633 effect(KILL cr); 6634 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); 6635 6636 format %{ "addl $dst, $src\t# int" %} 6637 ins_encode %{ 6638 __ addl($dst$$Register, $src$$constant); 6639 %} 6640 ins_pipe( ialu_reg ); 6641 %} 6642 6643 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6644 %{ 6645 match(Set dst (AddI dst (LoadI src))); 6646 effect(KILL cr); 6647 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); 6648 6649 ins_cost(150); // XXX 6650 format %{ "addl $dst, $src\t# int" %} 6651 ins_encode %{ 6652 __ addl($dst$$Register, $src$$Address); 6653 %} 6654 ins_pipe(ialu_reg_mem); 6655 %} 6656 6657 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6658 %{ 6659 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6660 effect(KILL cr); 6661 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); 6662 6663 ins_cost(150); // XXX 6664 format %{ "addl $dst, $src\t# int" %} 6665 ins_encode %{ 6666 __ addl($dst$$Address, $src$$Register); 6667 %} 6668 ins_pipe(ialu_mem_reg); 6669 %} 6670 6671 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6672 %{ 6673 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6674 effect(KILL cr); 6675 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); 6676 6677 6678 ins_cost(125); // XXX 6679 format %{ "addl $dst, $src\t# int" %} 6680 ins_encode %{ 6681 __ addl($dst$$Address, $src$$constant); 6682 %} 6683 ins_pipe(ialu_mem_imm); 6684 %} 6685 6686 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6687 %{ 6688 predicate(UseIncDec); 6689 match(Set dst (AddI dst src)); 6690 effect(KILL cr); 6691 6692 format %{ "incl $dst\t# int" %} 6693 ins_encode %{ 6694 __ incrementl($dst$$Register); 6695 %} 6696 ins_pipe(ialu_reg); 6697 %} 6698 6699 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6700 %{ 6701 predicate(UseIncDec); 6702 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6703 effect(KILL cr); 6704 6705 ins_cost(125); // XXX 6706 format %{ "incl $dst\t# int" %} 6707 ins_encode %{ 6708 __ incrementl($dst$$Address); 6709 %} 6710 ins_pipe(ialu_mem_imm); 6711 %} 6712 6713 // XXX why does that use AddI 6714 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6715 %{ 6716 predicate(UseIncDec); 6717 match(Set dst (AddI dst src)); 6718 effect(KILL cr); 6719 6720 format %{ "decl $dst\t# int" %} 6721 ins_encode %{ 6722 __ decrementl($dst$$Register); 6723 %} 6724 ins_pipe(ialu_reg); 6725 %} 6726 6727 // XXX why does that use AddI 6728 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6729 %{ 6730 predicate(UseIncDec); 6731 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6732 effect(KILL cr); 6733 6734 ins_cost(125); // XXX 6735 format %{ "decl $dst\t# int" %} 6736 ins_encode %{ 6737 __ decrementl($dst$$Address); 6738 %} 6739 ins_pipe(ialu_mem_imm); 6740 %} 6741 6742 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6743 %{ 6744 predicate(VM_Version::supports_fast_2op_lea()); 6745 match(Set dst (AddI (LShiftI index scale) disp)); 6746 6747 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6748 ins_encode %{ 6749 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6750 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6751 %} 6752 ins_pipe(ialu_reg_reg); 6753 %} 6754 6755 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6756 %{ 6757 predicate(VM_Version::supports_fast_3op_lea()); 6758 match(Set dst (AddI (AddI base index) disp)); 6759 6760 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6761 ins_encode %{ 6762 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6763 %} 6764 ins_pipe(ialu_reg_reg); 6765 %} 6766 6767 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6768 %{ 6769 predicate(VM_Version::supports_fast_2op_lea()); 6770 match(Set dst (AddI base (LShiftI index scale))); 6771 6772 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6773 ins_encode %{ 6774 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6775 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6776 %} 6777 ins_pipe(ialu_reg_reg); 6778 %} 6779 6780 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6781 %{ 6782 predicate(VM_Version::supports_fast_3op_lea()); 6783 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6784 6785 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6786 ins_encode %{ 6787 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6788 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6789 %} 6790 ins_pipe(ialu_reg_reg); 6791 %} 6792 6793 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6794 %{ 6795 match(Set dst (AddL dst src)); 6796 effect(KILL cr); 6797 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); 6798 6799 format %{ "addq $dst, $src\t# long" %} 6800 ins_encode %{ 6801 __ addq($dst$$Register, $src$$Register); 6802 %} 6803 ins_pipe(ialu_reg_reg); 6804 %} 6805 6806 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6807 %{ 6808 match(Set dst (AddL dst src)); 6809 effect(KILL cr); 6810 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); 6811 6812 format %{ "addq $dst, $src\t# long" %} 6813 ins_encode %{ 6814 __ addq($dst$$Register, $src$$constant); 6815 %} 6816 ins_pipe( ialu_reg ); 6817 %} 6818 6819 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6820 %{ 6821 match(Set dst (AddL dst (LoadL src))); 6822 effect(KILL cr); 6823 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); 6824 6825 ins_cost(150); // XXX 6826 format %{ "addq $dst, $src\t# long" %} 6827 ins_encode %{ 6828 __ addq($dst$$Register, $src$$Address); 6829 %} 6830 ins_pipe(ialu_reg_mem); 6831 %} 6832 6833 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6834 %{ 6835 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6836 effect(KILL cr); 6837 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); 6838 6839 ins_cost(150); // XXX 6840 format %{ "addq $dst, $src\t# long" %} 6841 ins_encode %{ 6842 __ addq($dst$$Address, $src$$Register); 6843 %} 6844 ins_pipe(ialu_mem_reg); 6845 %} 6846 6847 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6848 %{ 6849 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6850 effect(KILL cr); 6851 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); 6852 6853 ins_cost(125); // XXX 6854 format %{ "addq $dst, $src\t# long" %} 6855 ins_encode %{ 6856 __ addq($dst$$Address, $src$$constant); 6857 %} 6858 ins_pipe(ialu_mem_imm); 6859 %} 6860 6861 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6862 %{ 6863 predicate(UseIncDec); 6864 match(Set dst (AddL dst src)); 6865 effect(KILL cr); 6866 6867 format %{ "incq $dst\t# long" %} 6868 ins_encode %{ 6869 __ incrementq($dst$$Register); 6870 %} 6871 ins_pipe(ialu_reg); 6872 %} 6873 6874 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6875 %{ 6876 predicate(UseIncDec); 6877 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6878 effect(KILL cr); 6879 6880 ins_cost(125); // XXX 6881 format %{ "incq $dst\t# long" %} 6882 ins_encode %{ 6883 __ incrementq($dst$$Address); 6884 %} 6885 ins_pipe(ialu_mem_imm); 6886 %} 6887 6888 // XXX why does that use AddL 6889 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6890 %{ 6891 predicate(UseIncDec); 6892 match(Set dst (AddL dst src)); 6893 effect(KILL cr); 6894 6895 format %{ "decq $dst\t# long" %} 6896 ins_encode %{ 6897 __ decrementq($dst$$Register); 6898 %} 6899 ins_pipe(ialu_reg); 6900 %} 6901 6902 // XXX why does that use AddL 6903 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6904 %{ 6905 predicate(UseIncDec); 6906 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6907 effect(KILL cr); 6908 6909 ins_cost(125); // XXX 6910 format %{ "decq $dst\t# long" %} 6911 ins_encode %{ 6912 __ decrementq($dst$$Address); 6913 %} 6914 ins_pipe(ialu_mem_imm); 6915 %} 6916 6917 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6918 %{ 6919 predicate(VM_Version::supports_fast_2op_lea()); 6920 match(Set dst (AddL (LShiftL index scale) disp)); 6921 6922 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6923 ins_encode %{ 6924 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6925 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6926 %} 6927 ins_pipe(ialu_reg_reg); 6928 %} 6929 6930 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6931 %{ 6932 predicate(VM_Version::supports_fast_3op_lea()); 6933 match(Set dst (AddL (AddL base index) disp)); 6934 6935 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6936 ins_encode %{ 6937 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6938 %} 6939 ins_pipe(ialu_reg_reg); 6940 %} 6941 6942 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6943 %{ 6944 predicate(VM_Version::supports_fast_2op_lea()); 6945 match(Set dst (AddL base (LShiftL index scale))); 6946 6947 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6948 ins_encode %{ 6949 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6950 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6951 %} 6952 ins_pipe(ialu_reg_reg); 6953 %} 6954 6955 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6956 %{ 6957 predicate(VM_Version::supports_fast_3op_lea()); 6958 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6959 6960 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6961 ins_encode %{ 6962 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6963 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6964 %} 6965 ins_pipe(ialu_reg_reg); 6966 %} 6967 6968 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6969 %{ 6970 match(Set dst (AddP dst src)); 6971 effect(KILL cr); 6972 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); 6973 6974 format %{ "addq $dst, $src\t# ptr" %} 6975 ins_encode %{ 6976 __ addq($dst$$Register, $src$$Register); 6977 %} 6978 ins_pipe(ialu_reg_reg); 6979 %} 6980 6981 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6982 %{ 6983 match(Set dst (AddP dst src)); 6984 effect(KILL cr); 6985 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); 6986 6987 format %{ "addq $dst, $src\t# ptr" %} 6988 ins_encode %{ 6989 __ addq($dst$$Register, $src$$constant); 6990 %} 6991 ins_pipe( ialu_reg ); 6992 %} 6993 6994 // XXX addP mem ops ???? 6995 6996 instruct checkCastPP(rRegP dst) 6997 %{ 6998 match(Set dst (CheckCastPP dst)); 6999 7000 size(0); 7001 format %{ "# checkcastPP of $dst" %} 7002 ins_encode(/* empty encoding */); 7003 ins_pipe(empty); 7004 %} 7005 7006 instruct castPP(rRegP dst) 7007 %{ 7008 match(Set dst (CastPP dst)); 7009 7010 size(0); 7011 format %{ "# castPP of $dst" %} 7012 ins_encode(/* empty encoding */); 7013 ins_pipe(empty); 7014 %} 7015 7016 instruct castII(rRegI dst) 7017 %{ 7018 match(Set dst (CastII dst)); 7019 7020 size(0); 7021 format %{ "# castII of $dst" %} 7022 ins_encode(/* empty encoding */); 7023 ins_cost(0); 7024 ins_pipe(empty); 7025 %} 7026 7027 instruct castLL(rRegL dst) 7028 %{ 7029 match(Set dst (CastLL dst)); 7030 7031 size(0); 7032 format %{ "# castLL of $dst" %} 7033 ins_encode(/* empty encoding */); 7034 ins_cost(0); 7035 ins_pipe(empty); 7036 %} 7037 7038 instruct castFF(regF dst) 7039 %{ 7040 match(Set dst (CastFF dst)); 7041 7042 size(0); 7043 format %{ "# castFF of $dst" %} 7044 ins_encode(/* empty encoding */); 7045 ins_cost(0); 7046 ins_pipe(empty); 7047 %} 7048 7049 instruct castDD(regD dst) 7050 %{ 7051 match(Set dst (CastDD dst)); 7052 7053 size(0); 7054 format %{ "# castDD of $dst" %} 7055 ins_encode(/* empty encoding */); 7056 ins_cost(0); 7057 ins_pipe(empty); 7058 %} 7059 7060 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7061 instruct compareAndSwapP(rRegI res, 7062 memory mem_ptr, 7063 rax_RegP oldval, rRegP newval, 7064 rFlagsReg cr) 7065 %{ 7066 predicate(n->as_LoadStore()->barrier_data() == 0); 7067 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7068 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7069 effect(KILL cr, KILL oldval); 7070 7071 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7072 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7073 "sete $res\n\t" 7074 "movzbl $res, $res" %} 7075 ins_encode %{ 7076 __ lock(); 7077 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7078 __ setb(Assembler::equal, $res$$Register); 7079 __ movzbl($res$$Register, $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 "sete $res\n\t" 7096 "movzbl $res, $res" %} 7097 ins_encode %{ 7098 __ lock(); 7099 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7100 __ setb(Assembler::equal, $res$$Register); 7101 __ movzbl($res$$Register, $res$$Register); 7102 %} 7103 ins_pipe( pipe_cmpxchg ); 7104 %} 7105 7106 instruct compareAndSwapI(rRegI res, 7107 memory mem_ptr, 7108 rax_RegI oldval, rRegI newval, 7109 rFlagsReg cr) 7110 %{ 7111 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7112 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7113 effect(KILL cr, KILL oldval); 7114 7115 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7116 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7117 "sete $res\n\t" 7118 "movzbl $res, $res" %} 7119 ins_encode %{ 7120 __ lock(); 7121 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7122 __ setb(Assembler::equal, $res$$Register); 7123 __ movzbl($res$$Register, $res$$Register); 7124 %} 7125 ins_pipe( pipe_cmpxchg ); 7126 %} 7127 7128 instruct compareAndSwapB(rRegI res, 7129 memory mem_ptr, 7130 rax_RegI oldval, rRegI newval, 7131 rFlagsReg cr) 7132 %{ 7133 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7134 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7135 effect(KILL cr, KILL oldval); 7136 7137 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7138 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7139 "sete $res\n\t" 7140 "movzbl $res, $res" %} 7141 ins_encode %{ 7142 __ lock(); 7143 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7144 __ setb(Assembler::equal, $res$$Register); 7145 __ movzbl($res$$Register, $res$$Register); 7146 %} 7147 ins_pipe( pipe_cmpxchg ); 7148 %} 7149 7150 instruct compareAndSwapS(rRegI res, 7151 memory mem_ptr, 7152 rax_RegI oldval, rRegI newval, 7153 rFlagsReg cr) 7154 %{ 7155 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7156 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7157 effect(KILL cr, KILL oldval); 7158 7159 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7160 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7161 "sete $res\n\t" 7162 "movzbl $res, $res" %} 7163 ins_encode %{ 7164 __ lock(); 7165 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7166 __ setb(Assembler::equal, $res$$Register); 7167 __ movzbl($res$$Register, $res$$Register); 7168 %} 7169 ins_pipe( pipe_cmpxchg ); 7170 %} 7171 7172 instruct compareAndSwapN(rRegI res, 7173 memory mem_ptr, 7174 rax_RegN oldval, rRegN newval, 7175 rFlagsReg cr) %{ 7176 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7177 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7178 effect(KILL cr, KILL oldval); 7179 7180 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7181 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7182 "sete $res\n\t" 7183 "movzbl $res, $res" %} 7184 ins_encode %{ 7185 __ lock(); 7186 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7187 __ setb(Assembler::equal, $res$$Register); 7188 __ movzbl($res$$Register, $res$$Register); 7189 %} 7190 ins_pipe( pipe_cmpxchg ); 7191 %} 7192 7193 instruct compareAndExchangeB( 7194 memory mem_ptr, 7195 rax_RegI oldval, rRegI newval, 7196 rFlagsReg cr) 7197 %{ 7198 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7199 effect(KILL cr); 7200 7201 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7202 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7203 ins_encode %{ 7204 __ lock(); 7205 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7206 %} 7207 ins_pipe( pipe_cmpxchg ); 7208 %} 7209 7210 instruct compareAndExchangeS( 7211 memory mem_ptr, 7212 rax_RegI oldval, rRegI newval, 7213 rFlagsReg cr) 7214 %{ 7215 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7216 effect(KILL cr); 7217 7218 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7219 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7220 ins_encode %{ 7221 __ lock(); 7222 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7223 %} 7224 ins_pipe( pipe_cmpxchg ); 7225 %} 7226 7227 instruct compareAndExchangeI( 7228 memory mem_ptr, 7229 rax_RegI oldval, rRegI newval, 7230 rFlagsReg cr) 7231 %{ 7232 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7233 effect(KILL cr); 7234 7235 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7236 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7237 ins_encode %{ 7238 __ lock(); 7239 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7240 %} 7241 ins_pipe( pipe_cmpxchg ); 7242 %} 7243 7244 instruct compareAndExchangeL( 7245 memory mem_ptr, 7246 rax_RegL oldval, rRegL newval, 7247 rFlagsReg cr) 7248 %{ 7249 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7250 effect(KILL cr); 7251 7252 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7253 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7254 ins_encode %{ 7255 __ lock(); 7256 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7257 %} 7258 ins_pipe( pipe_cmpxchg ); 7259 %} 7260 7261 instruct compareAndExchangeN( 7262 memory mem_ptr, 7263 rax_RegN oldval, rRegN newval, 7264 rFlagsReg cr) %{ 7265 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7266 effect(KILL cr); 7267 7268 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7269 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7270 ins_encode %{ 7271 __ lock(); 7272 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7273 %} 7274 ins_pipe( pipe_cmpxchg ); 7275 %} 7276 7277 instruct compareAndExchangeP( 7278 memory mem_ptr, 7279 rax_RegP oldval, rRegP newval, 7280 rFlagsReg cr) 7281 %{ 7282 predicate(n->as_LoadStore()->barrier_data() == 0); 7283 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7284 effect(KILL cr); 7285 7286 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7287 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7288 ins_encode %{ 7289 __ lock(); 7290 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7291 %} 7292 ins_pipe( pipe_cmpxchg ); 7293 %} 7294 7295 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7296 predicate(n->as_LoadStore()->result_not_used()); 7297 match(Set dummy (GetAndAddB mem add)); 7298 effect(KILL cr); 7299 format %{ "addb_lock $mem, $add" %} 7300 ins_encode %{ 7301 __ lock(); 7302 __ addb($mem$$Address, $add$$Register); 7303 %} 7304 ins_pipe(pipe_cmpxchg); 7305 %} 7306 7307 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7308 predicate(n->as_LoadStore()->result_not_used()); 7309 match(Set dummy (GetAndAddB mem add)); 7310 effect(KILL cr); 7311 format %{ "addb_lock $mem, $add" %} 7312 ins_encode %{ 7313 __ lock(); 7314 __ addb($mem$$Address, $add$$constant); 7315 %} 7316 ins_pipe(pipe_cmpxchg); 7317 %} 7318 7319 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7320 predicate(!n->as_LoadStore()->result_not_used()); 7321 match(Set newval (GetAndAddB mem newval)); 7322 effect(KILL cr); 7323 format %{ "xaddb_lock $mem, $newval" %} 7324 ins_encode %{ 7325 __ lock(); 7326 __ xaddb($mem$$Address, $newval$$Register); 7327 %} 7328 ins_pipe(pipe_cmpxchg); 7329 %} 7330 7331 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7332 predicate(n->as_LoadStore()->result_not_used()); 7333 match(Set dummy (GetAndAddS mem add)); 7334 effect(KILL cr); 7335 format %{ "addw_lock $mem, $add" %} 7336 ins_encode %{ 7337 __ lock(); 7338 __ addw($mem$$Address, $add$$Register); 7339 %} 7340 ins_pipe(pipe_cmpxchg); 7341 %} 7342 7343 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7344 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7345 match(Set dummy (GetAndAddS mem add)); 7346 effect(KILL cr); 7347 format %{ "addw_lock $mem, $add" %} 7348 ins_encode %{ 7349 __ lock(); 7350 __ addw($mem$$Address, $add$$constant); 7351 %} 7352 ins_pipe(pipe_cmpxchg); 7353 %} 7354 7355 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7356 predicate(!n->as_LoadStore()->result_not_used()); 7357 match(Set newval (GetAndAddS mem newval)); 7358 effect(KILL cr); 7359 format %{ "xaddw_lock $mem, $newval" %} 7360 ins_encode %{ 7361 __ lock(); 7362 __ xaddw($mem$$Address, $newval$$Register); 7363 %} 7364 ins_pipe(pipe_cmpxchg); 7365 %} 7366 7367 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7368 predicate(n->as_LoadStore()->result_not_used()); 7369 match(Set dummy (GetAndAddI mem add)); 7370 effect(KILL cr); 7371 format %{ "addl_lock $mem, $add" %} 7372 ins_encode %{ 7373 __ lock(); 7374 __ addl($mem$$Address, $add$$Register); 7375 %} 7376 ins_pipe(pipe_cmpxchg); 7377 %} 7378 7379 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7380 predicate(n->as_LoadStore()->result_not_used()); 7381 match(Set dummy (GetAndAddI mem add)); 7382 effect(KILL cr); 7383 format %{ "addl_lock $mem, $add" %} 7384 ins_encode %{ 7385 __ lock(); 7386 __ addl($mem$$Address, $add$$constant); 7387 %} 7388 ins_pipe(pipe_cmpxchg); 7389 %} 7390 7391 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7392 predicate(!n->as_LoadStore()->result_not_used()); 7393 match(Set newval (GetAndAddI mem newval)); 7394 effect(KILL cr); 7395 format %{ "xaddl_lock $mem, $newval" %} 7396 ins_encode %{ 7397 __ lock(); 7398 __ xaddl($mem$$Address, $newval$$Register); 7399 %} 7400 ins_pipe(pipe_cmpxchg); 7401 %} 7402 7403 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7404 predicate(n->as_LoadStore()->result_not_used()); 7405 match(Set dummy (GetAndAddL mem add)); 7406 effect(KILL cr); 7407 format %{ "addq_lock $mem, $add" %} 7408 ins_encode %{ 7409 __ lock(); 7410 __ addq($mem$$Address, $add$$Register); 7411 %} 7412 ins_pipe(pipe_cmpxchg); 7413 %} 7414 7415 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7416 predicate(n->as_LoadStore()->result_not_used()); 7417 match(Set dummy (GetAndAddL mem add)); 7418 effect(KILL cr); 7419 format %{ "addq_lock $mem, $add" %} 7420 ins_encode %{ 7421 __ lock(); 7422 __ addq($mem$$Address, $add$$constant); 7423 %} 7424 ins_pipe(pipe_cmpxchg); 7425 %} 7426 7427 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7428 predicate(!n->as_LoadStore()->result_not_used()); 7429 match(Set newval (GetAndAddL mem newval)); 7430 effect(KILL cr); 7431 format %{ "xaddq_lock $mem, $newval" %} 7432 ins_encode %{ 7433 __ lock(); 7434 __ xaddq($mem$$Address, $newval$$Register); 7435 %} 7436 ins_pipe(pipe_cmpxchg); 7437 %} 7438 7439 instruct xchgB( memory mem, rRegI newval) %{ 7440 match(Set newval (GetAndSetB mem newval)); 7441 format %{ "XCHGB $newval,[$mem]" %} 7442 ins_encode %{ 7443 __ xchgb($newval$$Register, $mem$$Address); 7444 %} 7445 ins_pipe( pipe_cmpxchg ); 7446 %} 7447 7448 instruct xchgS( memory mem, rRegI newval) %{ 7449 match(Set newval (GetAndSetS mem newval)); 7450 format %{ "XCHGW $newval,[$mem]" %} 7451 ins_encode %{ 7452 __ xchgw($newval$$Register, $mem$$Address); 7453 %} 7454 ins_pipe( pipe_cmpxchg ); 7455 %} 7456 7457 instruct xchgI( memory mem, rRegI newval) %{ 7458 match(Set newval (GetAndSetI mem newval)); 7459 format %{ "XCHGL $newval,[$mem]" %} 7460 ins_encode %{ 7461 __ xchgl($newval$$Register, $mem$$Address); 7462 %} 7463 ins_pipe( pipe_cmpxchg ); 7464 %} 7465 7466 instruct xchgL( memory mem, rRegL newval) %{ 7467 match(Set newval (GetAndSetL mem newval)); 7468 format %{ "XCHGL $newval,[$mem]" %} 7469 ins_encode %{ 7470 __ xchgq($newval$$Register, $mem$$Address); 7471 %} 7472 ins_pipe( pipe_cmpxchg ); 7473 %} 7474 7475 instruct xchgP( memory mem, rRegP newval) %{ 7476 match(Set newval (GetAndSetP mem newval)); 7477 predicate(n->as_LoadStore()->barrier_data() == 0); 7478 format %{ "XCHGQ $newval,[$mem]" %} 7479 ins_encode %{ 7480 __ xchgq($newval$$Register, $mem$$Address); 7481 %} 7482 ins_pipe( pipe_cmpxchg ); 7483 %} 7484 7485 instruct xchgN( memory mem, rRegN newval) %{ 7486 match(Set newval (GetAndSetN mem newval)); 7487 format %{ "XCHGL $newval,$mem]" %} 7488 ins_encode %{ 7489 __ xchgl($newval$$Register, $mem$$Address); 7490 %} 7491 ins_pipe( pipe_cmpxchg ); 7492 %} 7493 7494 //----------Abs Instructions------------------------------------------- 7495 7496 // Integer Absolute Instructions 7497 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7498 %{ 7499 match(Set dst (AbsI src)); 7500 effect(TEMP dst, KILL cr); 7501 format %{ "xorl $dst, $dst\t# abs int\n\t" 7502 "subl $dst, $src\n\t" 7503 "cmovll $dst, $src" %} 7504 ins_encode %{ 7505 __ xorl($dst$$Register, $dst$$Register); 7506 __ subl($dst$$Register, $src$$Register); 7507 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7508 %} 7509 7510 ins_pipe(ialu_reg_reg); 7511 %} 7512 7513 // Long Absolute Instructions 7514 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7515 %{ 7516 match(Set dst (AbsL src)); 7517 effect(TEMP dst, KILL cr); 7518 format %{ "xorl $dst, $dst\t# abs long\n\t" 7519 "subq $dst, $src\n\t" 7520 "cmovlq $dst, $src" %} 7521 ins_encode %{ 7522 __ xorl($dst$$Register, $dst$$Register); 7523 __ subq($dst$$Register, $src$$Register); 7524 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7525 %} 7526 7527 ins_pipe(ialu_reg_reg); 7528 %} 7529 7530 //----------Subtraction Instructions------------------------------------------- 7531 7532 // Integer Subtraction Instructions 7533 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7534 %{ 7535 match(Set dst (SubI dst src)); 7536 effect(KILL cr); 7537 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7538 7539 format %{ "subl $dst, $src\t# int" %} 7540 ins_encode %{ 7541 __ subl($dst$$Register, $src$$Register); 7542 %} 7543 ins_pipe(ialu_reg_reg); 7544 %} 7545 7546 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7547 %{ 7548 match(Set dst (SubI dst (LoadI src))); 7549 effect(KILL cr); 7550 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); 7551 7552 ins_cost(150); 7553 format %{ "subl $dst, $src\t# int" %} 7554 ins_encode %{ 7555 __ subl($dst$$Register, $src$$Address); 7556 %} 7557 ins_pipe(ialu_reg_mem); 7558 %} 7559 7560 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7561 %{ 7562 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7563 effect(KILL cr); 7564 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); 7565 7566 ins_cost(150); 7567 format %{ "subl $dst, $src\t# int" %} 7568 ins_encode %{ 7569 __ subl($dst$$Address, $src$$Register); 7570 %} 7571 ins_pipe(ialu_mem_reg); 7572 %} 7573 7574 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7575 %{ 7576 match(Set dst (SubL dst src)); 7577 effect(KILL cr); 7578 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7579 7580 format %{ "subq $dst, $src\t# long" %} 7581 ins_encode %{ 7582 __ subq($dst$$Register, $src$$Register); 7583 %} 7584 ins_pipe(ialu_reg_reg); 7585 %} 7586 7587 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7588 %{ 7589 match(Set dst (SubL dst (LoadL src))); 7590 effect(KILL cr); 7591 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); 7592 7593 ins_cost(150); 7594 format %{ "subq $dst, $src\t# long" %} 7595 ins_encode %{ 7596 __ subq($dst$$Register, $src$$Address); 7597 %} 7598 ins_pipe(ialu_reg_mem); 7599 %} 7600 7601 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7602 %{ 7603 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7604 effect(KILL cr); 7605 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); 7606 7607 ins_cost(150); 7608 format %{ "subq $dst, $src\t# long" %} 7609 ins_encode %{ 7610 __ subq($dst$$Address, $src$$Register); 7611 %} 7612 ins_pipe(ialu_mem_reg); 7613 %} 7614 7615 // Subtract from a pointer 7616 // XXX hmpf??? 7617 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7618 %{ 7619 match(Set dst (AddP dst (SubI zero src))); 7620 effect(KILL cr); 7621 7622 format %{ "subq $dst, $src\t# ptr - int" %} 7623 ins_encode %{ 7624 __ subq($dst$$Register, $src$$Register); 7625 %} 7626 ins_pipe(ialu_reg_reg); 7627 %} 7628 7629 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7630 %{ 7631 match(Set dst (SubI zero dst)); 7632 effect(KILL cr); 7633 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7634 7635 format %{ "negl $dst\t# int" %} 7636 ins_encode %{ 7637 __ negl($dst$$Register); 7638 %} 7639 ins_pipe(ialu_reg); 7640 %} 7641 7642 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7643 %{ 7644 match(Set dst (NegI dst)); 7645 effect(KILL cr); 7646 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7647 7648 format %{ "negl $dst\t# int" %} 7649 ins_encode %{ 7650 __ negl($dst$$Register); 7651 %} 7652 ins_pipe(ialu_reg); 7653 %} 7654 7655 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7656 %{ 7657 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7658 effect(KILL cr); 7659 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7660 7661 format %{ "negl $dst\t# int" %} 7662 ins_encode %{ 7663 __ negl($dst$$Address); 7664 %} 7665 ins_pipe(ialu_reg); 7666 %} 7667 7668 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7669 %{ 7670 match(Set dst (SubL zero dst)); 7671 effect(KILL cr); 7672 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7673 7674 format %{ "negq $dst\t# long" %} 7675 ins_encode %{ 7676 __ negq($dst$$Register); 7677 %} 7678 ins_pipe(ialu_reg); 7679 %} 7680 7681 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7682 %{ 7683 match(Set dst (NegL dst)); 7684 effect(KILL cr); 7685 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7686 7687 format %{ "negq $dst\t# int" %} 7688 ins_encode %{ 7689 __ negq($dst$$Register); 7690 %} 7691 ins_pipe(ialu_reg); 7692 %} 7693 7694 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7695 %{ 7696 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7697 effect(KILL cr); 7698 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7699 7700 format %{ "negq $dst\t# long" %} 7701 ins_encode %{ 7702 __ negq($dst$$Address); 7703 %} 7704 ins_pipe(ialu_reg); 7705 %} 7706 7707 //----------Multiplication/Division Instructions------------------------------- 7708 // Integer Multiplication Instructions 7709 // Multiply Register 7710 7711 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7712 %{ 7713 match(Set dst (MulI dst src)); 7714 effect(KILL cr); 7715 7716 ins_cost(300); 7717 format %{ "imull $dst, $src\t# int" %} 7718 ins_encode %{ 7719 __ imull($dst$$Register, $src$$Register); 7720 %} 7721 ins_pipe(ialu_reg_reg_alu0); 7722 %} 7723 7724 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7725 %{ 7726 match(Set dst (MulI src imm)); 7727 effect(KILL cr); 7728 7729 ins_cost(300); 7730 format %{ "imull $dst, $src, $imm\t# int" %} 7731 ins_encode %{ 7732 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7733 %} 7734 ins_pipe(ialu_reg_reg_alu0); 7735 %} 7736 7737 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7738 %{ 7739 match(Set dst (MulI dst (LoadI src))); 7740 effect(KILL cr); 7741 7742 ins_cost(350); 7743 format %{ "imull $dst, $src\t# int" %} 7744 ins_encode %{ 7745 __ imull($dst$$Register, $src$$Address); 7746 %} 7747 ins_pipe(ialu_reg_mem_alu0); 7748 %} 7749 7750 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7751 %{ 7752 match(Set dst (MulI (LoadI src) imm)); 7753 effect(KILL cr); 7754 7755 ins_cost(300); 7756 format %{ "imull $dst, $src, $imm\t# int" %} 7757 ins_encode %{ 7758 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7759 %} 7760 ins_pipe(ialu_reg_mem_alu0); 7761 %} 7762 7763 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7764 %{ 7765 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7766 effect(KILL cr, KILL src2); 7767 7768 expand %{ mulI_rReg(dst, src1, cr); 7769 mulI_rReg(src2, src3, cr); 7770 addI_rReg(dst, src2, cr); %} 7771 %} 7772 7773 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7774 %{ 7775 match(Set dst (MulL dst src)); 7776 effect(KILL cr); 7777 7778 ins_cost(300); 7779 format %{ "imulq $dst, $src\t# long" %} 7780 ins_encode %{ 7781 __ imulq($dst$$Register, $src$$Register); 7782 %} 7783 ins_pipe(ialu_reg_reg_alu0); 7784 %} 7785 7786 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7787 %{ 7788 match(Set dst (MulL src imm)); 7789 effect(KILL cr); 7790 7791 ins_cost(300); 7792 format %{ "imulq $dst, $src, $imm\t# long" %} 7793 ins_encode %{ 7794 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7795 %} 7796 ins_pipe(ialu_reg_reg_alu0); 7797 %} 7798 7799 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7800 %{ 7801 match(Set dst (MulL dst (LoadL src))); 7802 effect(KILL cr); 7803 7804 ins_cost(350); 7805 format %{ "imulq $dst, $src\t# long" %} 7806 ins_encode %{ 7807 __ imulq($dst$$Register, $src$$Address); 7808 %} 7809 ins_pipe(ialu_reg_mem_alu0); 7810 %} 7811 7812 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7813 %{ 7814 match(Set dst (MulL (LoadL src) imm)); 7815 effect(KILL cr); 7816 7817 ins_cost(300); 7818 format %{ "imulq $dst, $src, $imm\t# long" %} 7819 ins_encode %{ 7820 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7821 %} 7822 ins_pipe(ialu_reg_mem_alu0); 7823 %} 7824 7825 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7826 %{ 7827 match(Set dst (MulHiL src rax)); 7828 effect(USE_KILL rax, KILL cr); 7829 7830 ins_cost(300); 7831 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7832 ins_encode %{ 7833 __ imulq($src$$Register); 7834 %} 7835 ins_pipe(ialu_reg_reg_alu0); 7836 %} 7837 7838 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7839 %{ 7840 match(Set dst (UMulHiL src rax)); 7841 effect(USE_KILL rax, KILL cr); 7842 7843 ins_cost(300); 7844 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7845 ins_encode %{ 7846 __ mulq($src$$Register); 7847 %} 7848 ins_pipe(ialu_reg_reg_alu0); 7849 %} 7850 7851 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7852 rFlagsReg cr) 7853 %{ 7854 match(Set rax (DivI rax div)); 7855 effect(KILL rdx, KILL cr); 7856 7857 ins_cost(30*100+10*100); // XXX 7858 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7859 "jne,s normal\n\t" 7860 "xorl rdx, rdx\n\t" 7861 "cmpl $div, -1\n\t" 7862 "je,s done\n" 7863 "normal: cdql\n\t" 7864 "idivl $div\n" 7865 "done:" %} 7866 ins_encode(cdql_enc(div)); 7867 ins_pipe(ialu_reg_reg_alu0); 7868 %} 7869 7870 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7871 rFlagsReg cr) 7872 %{ 7873 match(Set rax (DivL rax div)); 7874 effect(KILL rdx, KILL cr); 7875 7876 ins_cost(30*100+10*100); // XXX 7877 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7878 "cmpq rax, rdx\n\t" 7879 "jne,s normal\n\t" 7880 "xorl rdx, rdx\n\t" 7881 "cmpq $div, -1\n\t" 7882 "je,s done\n" 7883 "normal: cdqq\n\t" 7884 "idivq $div\n" 7885 "done:" %} 7886 ins_encode(cdqq_enc(div)); 7887 ins_pipe(ialu_reg_reg_alu0); 7888 %} 7889 7890 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7891 %{ 7892 match(Set rax (UDivI rax div)); 7893 effect(KILL rdx, KILL cr); 7894 7895 ins_cost(300); 7896 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7897 ins_encode %{ 7898 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7899 %} 7900 ins_pipe(ialu_reg_reg_alu0); 7901 %} 7902 7903 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7904 %{ 7905 match(Set rax (UDivL rax div)); 7906 effect(KILL rdx, KILL cr); 7907 7908 ins_cost(300); 7909 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7910 ins_encode %{ 7911 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7912 %} 7913 ins_pipe(ialu_reg_reg_alu0); 7914 %} 7915 7916 // Integer DIVMOD with Register, both quotient and mod results 7917 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7918 rFlagsReg cr) 7919 %{ 7920 match(DivModI rax div); 7921 effect(KILL cr); 7922 7923 ins_cost(30*100+10*100); // XXX 7924 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7925 "jne,s normal\n\t" 7926 "xorl rdx, rdx\n\t" 7927 "cmpl $div, -1\n\t" 7928 "je,s done\n" 7929 "normal: cdql\n\t" 7930 "idivl $div\n" 7931 "done:" %} 7932 ins_encode(cdql_enc(div)); 7933 ins_pipe(pipe_slow); 7934 %} 7935 7936 // Long DIVMOD with Register, both quotient and mod results 7937 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7938 rFlagsReg cr) 7939 %{ 7940 match(DivModL rax div); 7941 effect(KILL cr); 7942 7943 ins_cost(30*100+10*100); // XXX 7944 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7945 "cmpq rax, rdx\n\t" 7946 "jne,s normal\n\t" 7947 "xorl rdx, rdx\n\t" 7948 "cmpq $div, -1\n\t" 7949 "je,s done\n" 7950 "normal: cdqq\n\t" 7951 "idivq $div\n" 7952 "done:" %} 7953 ins_encode(cdqq_enc(div)); 7954 ins_pipe(pipe_slow); 7955 %} 7956 7957 // Unsigned integer DIVMOD with Register, both quotient and mod results 7958 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7959 no_rax_rdx_RegI div, rFlagsReg cr) 7960 %{ 7961 match(UDivModI rax div); 7962 effect(TEMP tmp, KILL cr); 7963 7964 ins_cost(300); 7965 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7966 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7967 %} 7968 ins_encode %{ 7969 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7970 %} 7971 ins_pipe(pipe_slow); 7972 %} 7973 7974 // Unsigned long DIVMOD with Register, both quotient and mod results 7975 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7976 no_rax_rdx_RegL div, rFlagsReg cr) 7977 %{ 7978 match(UDivModL rax div); 7979 effect(TEMP tmp, KILL cr); 7980 7981 ins_cost(300); 7982 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7983 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7984 %} 7985 ins_encode %{ 7986 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7987 %} 7988 ins_pipe(pipe_slow); 7989 %} 7990 7991 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7992 rFlagsReg cr) 7993 %{ 7994 match(Set rdx (ModI rax div)); 7995 effect(KILL rax, KILL cr); 7996 7997 ins_cost(300); // XXX 7998 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7999 "jne,s normal\n\t" 8000 "xorl rdx, rdx\n\t" 8001 "cmpl $div, -1\n\t" 8002 "je,s done\n" 8003 "normal: cdql\n\t" 8004 "idivl $div\n" 8005 "done:" %} 8006 ins_encode(cdql_enc(div)); 8007 ins_pipe(ialu_reg_reg_alu0); 8008 %} 8009 8010 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8011 rFlagsReg cr) 8012 %{ 8013 match(Set rdx (ModL rax div)); 8014 effect(KILL rax, KILL cr); 8015 8016 ins_cost(300); // XXX 8017 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8018 "cmpq rax, rdx\n\t" 8019 "jne,s normal\n\t" 8020 "xorl rdx, rdx\n\t" 8021 "cmpq $div, -1\n\t" 8022 "je,s done\n" 8023 "normal: cdqq\n\t" 8024 "idivq $div\n" 8025 "done:" %} 8026 ins_encode(cdqq_enc(div)); 8027 ins_pipe(ialu_reg_reg_alu0); 8028 %} 8029 8030 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8031 %{ 8032 match(Set rdx (UModI rax div)); 8033 effect(KILL rax, KILL cr); 8034 8035 ins_cost(300); 8036 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8037 ins_encode %{ 8038 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8039 %} 8040 ins_pipe(ialu_reg_reg_alu0); 8041 %} 8042 8043 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8044 %{ 8045 match(Set rdx (UModL rax div)); 8046 effect(KILL rax, KILL cr); 8047 8048 ins_cost(300); 8049 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8050 ins_encode %{ 8051 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8052 %} 8053 ins_pipe(ialu_reg_reg_alu0); 8054 %} 8055 8056 // Integer Shift Instructions 8057 // Shift Left by one, two, three 8058 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8059 %{ 8060 match(Set dst (LShiftI dst shift)); 8061 effect(KILL cr); 8062 8063 format %{ "sall $dst, $shift" %} 8064 ins_encode %{ 8065 __ sall($dst$$Register, $shift$$constant); 8066 %} 8067 ins_pipe(ialu_reg); 8068 %} 8069 8070 // Shift Left by 8-bit immediate 8071 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8072 %{ 8073 match(Set dst (LShiftI dst shift)); 8074 effect(KILL cr); 8075 8076 format %{ "sall $dst, $shift" %} 8077 ins_encode %{ 8078 __ sall($dst$$Register, $shift$$constant); 8079 %} 8080 ins_pipe(ialu_reg); 8081 %} 8082 8083 // Shift Left by 8-bit immediate 8084 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8085 %{ 8086 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8087 effect(KILL cr); 8088 8089 format %{ "sall $dst, $shift" %} 8090 ins_encode %{ 8091 __ sall($dst$$Address, $shift$$constant); 8092 %} 8093 ins_pipe(ialu_mem_imm); 8094 %} 8095 8096 // Shift Left by variable 8097 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8098 %{ 8099 predicate(!VM_Version::supports_bmi2()); 8100 match(Set dst (LShiftI dst shift)); 8101 effect(KILL cr); 8102 8103 format %{ "sall $dst, $shift" %} 8104 ins_encode %{ 8105 __ sall($dst$$Register); 8106 %} 8107 ins_pipe(ialu_reg_reg); 8108 %} 8109 8110 // Shift Left by variable 8111 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8112 %{ 8113 predicate(!VM_Version::supports_bmi2()); 8114 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8115 effect(KILL cr); 8116 8117 format %{ "sall $dst, $shift" %} 8118 ins_encode %{ 8119 __ sall($dst$$Address); 8120 %} 8121 ins_pipe(ialu_mem_reg); 8122 %} 8123 8124 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8125 %{ 8126 predicate(VM_Version::supports_bmi2()); 8127 match(Set dst (LShiftI src shift)); 8128 8129 format %{ "shlxl $dst, $src, $shift" %} 8130 ins_encode %{ 8131 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8132 %} 8133 ins_pipe(ialu_reg_reg); 8134 %} 8135 8136 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8137 %{ 8138 predicate(VM_Version::supports_bmi2()); 8139 match(Set dst (LShiftI (LoadI src) shift)); 8140 ins_cost(175); 8141 format %{ "shlxl $dst, $src, $shift" %} 8142 ins_encode %{ 8143 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8144 %} 8145 ins_pipe(ialu_reg_mem); 8146 %} 8147 8148 // Arithmetic Shift Right by 8-bit immediate 8149 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8150 %{ 8151 match(Set dst (RShiftI dst shift)); 8152 effect(KILL cr); 8153 8154 format %{ "sarl $dst, $shift" %} 8155 ins_encode %{ 8156 __ sarl($dst$$Register, $shift$$constant); 8157 %} 8158 ins_pipe(ialu_mem_imm); 8159 %} 8160 8161 // Arithmetic Shift Right by 8-bit immediate 8162 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8163 %{ 8164 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8165 effect(KILL cr); 8166 8167 format %{ "sarl $dst, $shift" %} 8168 ins_encode %{ 8169 __ sarl($dst$$Address, $shift$$constant); 8170 %} 8171 ins_pipe(ialu_mem_imm); 8172 %} 8173 8174 // Arithmetic Shift Right by variable 8175 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8176 %{ 8177 predicate(!VM_Version::supports_bmi2()); 8178 match(Set dst (RShiftI dst shift)); 8179 effect(KILL cr); 8180 8181 format %{ "sarl $dst, $shift" %} 8182 ins_encode %{ 8183 __ sarl($dst$$Register); 8184 %} 8185 ins_pipe(ialu_reg_reg); 8186 %} 8187 8188 // Arithmetic Shift Right by variable 8189 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8190 %{ 8191 predicate(!VM_Version::supports_bmi2()); 8192 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8193 effect(KILL cr); 8194 8195 format %{ "sarl $dst, $shift" %} 8196 ins_encode %{ 8197 __ sarl($dst$$Address); 8198 %} 8199 ins_pipe(ialu_mem_reg); 8200 %} 8201 8202 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8203 %{ 8204 predicate(VM_Version::supports_bmi2()); 8205 match(Set dst (RShiftI src shift)); 8206 8207 format %{ "sarxl $dst, $src, $shift" %} 8208 ins_encode %{ 8209 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8210 %} 8211 ins_pipe(ialu_reg_reg); 8212 %} 8213 8214 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8215 %{ 8216 predicate(VM_Version::supports_bmi2()); 8217 match(Set dst (RShiftI (LoadI src) shift)); 8218 ins_cost(175); 8219 format %{ "sarxl $dst, $src, $shift" %} 8220 ins_encode %{ 8221 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8222 %} 8223 ins_pipe(ialu_reg_mem); 8224 %} 8225 8226 // Logical Shift Right by 8-bit immediate 8227 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8228 %{ 8229 match(Set dst (URShiftI dst shift)); 8230 effect(KILL cr); 8231 8232 format %{ "shrl $dst, $shift" %} 8233 ins_encode %{ 8234 __ shrl($dst$$Register, $shift$$constant); 8235 %} 8236 ins_pipe(ialu_reg); 8237 %} 8238 8239 // Logical Shift Right by 8-bit immediate 8240 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8241 %{ 8242 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8243 effect(KILL cr); 8244 8245 format %{ "shrl $dst, $shift" %} 8246 ins_encode %{ 8247 __ shrl($dst$$Address, $shift$$constant); 8248 %} 8249 ins_pipe(ialu_mem_imm); 8250 %} 8251 8252 // Logical Shift Right by variable 8253 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8254 %{ 8255 predicate(!VM_Version::supports_bmi2()); 8256 match(Set dst (URShiftI dst shift)); 8257 effect(KILL cr); 8258 8259 format %{ "shrl $dst, $shift" %} 8260 ins_encode %{ 8261 __ shrl($dst$$Register); 8262 %} 8263 ins_pipe(ialu_reg_reg); 8264 %} 8265 8266 // Logical Shift Right by variable 8267 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8268 %{ 8269 predicate(!VM_Version::supports_bmi2()); 8270 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8271 effect(KILL cr); 8272 8273 format %{ "shrl $dst, $shift" %} 8274 ins_encode %{ 8275 __ shrl($dst$$Address); 8276 %} 8277 ins_pipe(ialu_mem_reg); 8278 %} 8279 8280 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8281 %{ 8282 predicate(VM_Version::supports_bmi2()); 8283 match(Set dst (URShiftI src shift)); 8284 8285 format %{ "shrxl $dst, $src, $shift" %} 8286 ins_encode %{ 8287 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8288 %} 8289 ins_pipe(ialu_reg_reg); 8290 %} 8291 8292 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8293 %{ 8294 predicate(VM_Version::supports_bmi2()); 8295 match(Set dst (URShiftI (LoadI src) shift)); 8296 ins_cost(175); 8297 format %{ "shrxl $dst, $src, $shift" %} 8298 ins_encode %{ 8299 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8300 %} 8301 ins_pipe(ialu_reg_mem); 8302 %} 8303 8304 // Long Shift Instructions 8305 // Shift Left by one, two, three 8306 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8307 %{ 8308 match(Set dst (LShiftL dst shift)); 8309 effect(KILL cr); 8310 8311 format %{ "salq $dst, $shift" %} 8312 ins_encode %{ 8313 __ salq($dst$$Register, $shift$$constant); 8314 %} 8315 ins_pipe(ialu_reg); 8316 %} 8317 8318 // Shift Left by 8-bit immediate 8319 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8320 %{ 8321 match(Set dst (LShiftL dst shift)); 8322 effect(KILL cr); 8323 8324 format %{ "salq $dst, $shift" %} 8325 ins_encode %{ 8326 __ salq($dst$$Register, $shift$$constant); 8327 %} 8328 ins_pipe(ialu_reg); 8329 %} 8330 8331 // Shift Left by 8-bit immediate 8332 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8333 %{ 8334 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8335 effect(KILL cr); 8336 8337 format %{ "salq $dst, $shift" %} 8338 ins_encode %{ 8339 __ salq($dst$$Address, $shift$$constant); 8340 %} 8341 ins_pipe(ialu_mem_imm); 8342 %} 8343 8344 // Shift Left by variable 8345 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8346 %{ 8347 predicate(!VM_Version::supports_bmi2()); 8348 match(Set dst (LShiftL dst shift)); 8349 effect(KILL cr); 8350 8351 format %{ "salq $dst, $shift" %} 8352 ins_encode %{ 8353 __ salq($dst$$Register); 8354 %} 8355 ins_pipe(ialu_reg_reg); 8356 %} 8357 8358 // Shift Left by variable 8359 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8360 %{ 8361 predicate(!VM_Version::supports_bmi2()); 8362 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8363 effect(KILL cr); 8364 8365 format %{ "salq $dst, $shift" %} 8366 ins_encode %{ 8367 __ salq($dst$$Address); 8368 %} 8369 ins_pipe(ialu_mem_reg); 8370 %} 8371 8372 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8373 %{ 8374 predicate(VM_Version::supports_bmi2()); 8375 match(Set dst (LShiftL src shift)); 8376 8377 format %{ "shlxq $dst, $src, $shift" %} 8378 ins_encode %{ 8379 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8380 %} 8381 ins_pipe(ialu_reg_reg); 8382 %} 8383 8384 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8385 %{ 8386 predicate(VM_Version::supports_bmi2()); 8387 match(Set dst (LShiftL (LoadL src) shift)); 8388 ins_cost(175); 8389 format %{ "shlxq $dst, $src, $shift" %} 8390 ins_encode %{ 8391 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8392 %} 8393 ins_pipe(ialu_reg_mem); 8394 %} 8395 8396 // Arithmetic Shift Right by 8-bit immediate 8397 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8398 %{ 8399 match(Set dst (RShiftL dst shift)); 8400 effect(KILL cr); 8401 8402 format %{ "sarq $dst, $shift" %} 8403 ins_encode %{ 8404 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8405 %} 8406 ins_pipe(ialu_mem_imm); 8407 %} 8408 8409 // Arithmetic Shift Right by 8-bit immediate 8410 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8411 %{ 8412 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8413 effect(KILL cr); 8414 8415 format %{ "sarq $dst, $shift" %} 8416 ins_encode %{ 8417 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8418 %} 8419 ins_pipe(ialu_mem_imm); 8420 %} 8421 8422 // Arithmetic Shift Right by variable 8423 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8424 %{ 8425 predicate(!VM_Version::supports_bmi2()); 8426 match(Set dst (RShiftL dst shift)); 8427 effect(KILL cr); 8428 8429 format %{ "sarq $dst, $shift" %} 8430 ins_encode %{ 8431 __ sarq($dst$$Register); 8432 %} 8433 ins_pipe(ialu_reg_reg); 8434 %} 8435 8436 // Arithmetic Shift Right by variable 8437 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8438 %{ 8439 predicate(!VM_Version::supports_bmi2()); 8440 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8441 effect(KILL cr); 8442 8443 format %{ "sarq $dst, $shift" %} 8444 ins_encode %{ 8445 __ sarq($dst$$Address); 8446 %} 8447 ins_pipe(ialu_mem_reg); 8448 %} 8449 8450 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8451 %{ 8452 predicate(VM_Version::supports_bmi2()); 8453 match(Set dst (RShiftL src shift)); 8454 8455 format %{ "sarxq $dst, $src, $shift" %} 8456 ins_encode %{ 8457 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8458 %} 8459 ins_pipe(ialu_reg_reg); 8460 %} 8461 8462 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8463 %{ 8464 predicate(VM_Version::supports_bmi2()); 8465 match(Set dst (RShiftL (LoadL src) shift)); 8466 ins_cost(175); 8467 format %{ "sarxq $dst, $src, $shift" %} 8468 ins_encode %{ 8469 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8470 %} 8471 ins_pipe(ialu_reg_mem); 8472 %} 8473 8474 // Logical Shift Right by 8-bit immediate 8475 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8476 %{ 8477 match(Set dst (URShiftL dst shift)); 8478 effect(KILL cr); 8479 8480 format %{ "shrq $dst, $shift" %} 8481 ins_encode %{ 8482 __ shrq($dst$$Register, $shift$$constant); 8483 %} 8484 ins_pipe(ialu_reg); 8485 %} 8486 8487 // Logical Shift Right by 8-bit immediate 8488 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8489 %{ 8490 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8491 effect(KILL cr); 8492 8493 format %{ "shrq $dst, $shift" %} 8494 ins_encode %{ 8495 __ shrq($dst$$Address, $shift$$constant); 8496 %} 8497 ins_pipe(ialu_mem_imm); 8498 %} 8499 8500 // Logical Shift Right by variable 8501 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8502 %{ 8503 predicate(!VM_Version::supports_bmi2()); 8504 match(Set dst (URShiftL dst shift)); 8505 effect(KILL cr); 8506 8507 format %{ "shrq $dst, $shift" %} 8508 ins_encode %{ 8509 __ shrq($dst$$Register); 8510 %} 8511 ins_pipe(ialu_reg_reg); 8512 %} 8513 8514 // Logical Shift Right by variable 8515 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8516 %{ 8517 predicate(!VM_Version::supports_bmi2()); 8518 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8519 effect(KILL cr); 8520 8521 format %{ "shrq $dst, $shift" %} 8522 ins_encode %{ 8523 __ shrq($dst$$Address); 8524 %} 8525 ins_pipe(ialu_mem_reg); 8526 %} 8527 8528 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8529 %{ 8530 predicate(VM_Version::supports_bmi2()); 8531 match(Set dst (URShiftL src shift)); 8532 8533 format %{ "shrxq $dst, $src, $shift" %} 8534 ins_encode %{ 8535 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8536 %} 8537 ins_pipe(ialu_reg_reg); 8538 %} 8539 8540 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8541 %{ 8542 predicate(VM_Version::supports_bmi2()); 8543 match(Set dst (URShiftL (LoadL src) shift)); 8544 ins_cost(175); 8545 format %{ "shrxq $dst, $src, $shift" %} 8546 ins_encode %{ 8547 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8548 %} 8549 ins_pipe(ialu_reg_mem); 8550 %} 8551 8552 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8553 // This idiom is used by the compiler for the i2b bytecode. 8554 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8555 %{ 8556 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8557 8558 format %{ "movsbl $dst, $src\t# i2b" %} 8559 ins_encode %{ 8560 __ movsbl($dst$$Register, $src$$Register); 8561 %} 8562 ins_pipe(ialu_reg_reg); 8563 %} 8564 8565 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8566 // This idiom is used by the compiler the i2s bytecode. 8567 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8568 %{ 8569 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8570 8571 format %{ "movswl $dst, $src\t# i2s" %} 8572 ins_encode %{ 8573 __ movswl($dst$$Register, $src$$Register); 8574 %} 8575 ins_pipe(ialu_reg_reg); 8576 %} 8577 8578 // ROL/ROR instructions 8579 8580 // Rotate left by constant. 8581 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8582 %{ 8583 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8584 match(Set dst (RotateLeft dst shift)); 8585 effect(KILL cr); 8586 format %{ "roll $dst, $shift" %} 8587 ins_encode %{ 8588 __ roll($dst$$Register, $shift$$constant); 8589 %} 8590 ins_pipe(ialu_reg); 8591 %} 8592 8593 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8594 %{ 8595 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8596 match(Set dst (RotateLeft src shift)); 8597 format %{ "rolxl $dst, $src, $shift" %} 8598 ins_encode %{ 8599 int shift = 32 - ($shift$$constant & 31); 8600 __ rorxl($dst$$Register, $src$$Register, shift); 8601 %} 8602 ins_pipe(ialu_reg_reg); 8603 %} 8604 8605 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8606 %{ 8607 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8608 match(Set dst (RotateLeft (LoadI src) shift)); 8609 ins_cost(175); 8610 format %{ "rolxl $dst, $src, $shift" %} 8611 ins_encode %{ 8612 int shift = 32 - ($shift$$constant & 31); 8613 __ rorxl($dst$$Register, $src$$Address, shift); 8614 %} 8615 ins_pipe(ialu_reg_mem); 8616 %} 8617 8618 // Rotate Left by variable 8619 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8620 %{ 8621 predicate(n->bottom_type()->basic_type() == T_INT); 8622 match(Set dst (RotateLeft dst shift)); 8623 effect(KILL cr); 8624 format %{ "roll $dst, $shift" %} 8625 ins_encode %{ 8626 __ roll($dst$$Register); 8627 %} 8628 ins_pipe(ialu_reg_reg); 8629 %} 8630 8631 // Rotate Right by constant. 8632 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8633 %{ 8634 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8635 match(Set dst (RotateRight dst shift)); 8636 effect(KILL cr); 8637 format %{ "rorl $dst, $shift" %} 8638 ins_encode %{ 8639 __ rorl($dst$$Register, $shift$$constant); 8640 %} 8641 ins_pipe(ialu_reg); 8642 %} 8643 8644 // Rotate Right by constant. 8645 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8646 %{ 8647 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8648 match(Set dst (RotateRight src shift)); 8649 format %{ "rorxl $dst, $src, $shift" %} 8650 ins_encode %{ 8651 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8652 %} 8653 ins_pipe(ialu_reg_reg); 8654 %} 8655 8656 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8657 %{ 8658 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8659 match(Set dst (RotateRight (LoadI src) shift)); 8660 ins_cost(175); 8661 format %{ "rorxl $dst, $src, $shift" %} 8662 ins_encode %{ 8663 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8664 %} 8665 ins_pipe(ialu_reg_mem); 8666 %} 8667 8668 // Rotate Right by variable 8669 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8670 %{ 8671 predicate(n->bottom_type()->basic_type() == T_INT); 8672 match(Set dst (RotateRight dst shift)); 8673 effect(KILL cr); 8674 format %{ "rorl $dst, $shift" %} 8675 ins_encode %{ 8676 __ rorl($dst$$Register); 8677 %} 8678 ins_pipe(ialu_reg_reg); 8679 %} 8680 8681 // Rotate Left by constant. 8682 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8683 %{ 8684 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8685 match(Set dst (RotateLeft dst shift)); 8686 effect(KILL cr); 8687 format %{ "rolq $dst, $shift" %} 8688 ins_encode %{ 8689 __ rolq($dst$$Register, $shift$$constant); 8690 %} 8691 ins_pipe(ialu_reg); 8692 %} 8693 8694 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8695 %{ 8696 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8697 match(Set dst (RotateLeft src shift)); 8698 format %{ "rolxq $dst, $src, $shift" %} 8699 ins_encode %{ 8700 int shift = 64 - ($shift$$constant & 63); 8701 __ rorxq($dst$$Register, $src$$Register, shift); 8702 %} 8703 ins_pipe(ialu_reg_reg); 8704 %} 8705 8706 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8707 %{ 8708 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8709 match(Set dst (RotateLeft (LoadL src) shift)); 8710 ins_cost(175); 8711 format %{ "rolxq $dst, $src, $shift" %} 8712 ins_encode %{ 8713 int shift = 64 - ($shift$$constant & 63); 8714 __ rorxq($dst$$Register, $src$$Address, shift); 8715 %} 8716 ins_pipe(ialu_reg_mem); 8717 %} 8718 8719 // Rotate Left by variable 8720 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8721 %{ 8722 predicate(n->bottom_type()->basic_type() == T_LONG); 8723 match(Set dst (RotateLeft dst shift)); 8724 effect(KILL cr); 8725 format %{ "rolq $dst, $shift" %} 8726 ins_encode %{ 8727 __ rolq($dst$$Register); 8728 %} 8729 ins_pipe(ialu_reg_reg); 8730 %} 8731 8732 // Rotate Right by constant. 8733 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8734 %{ 8735 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8736 match(Set dst (RotateRight dst shift)); 8737 effect(KILL cr); 8738 format %{ "rorq $dst, $shift" %} 8739 ins_encode %{ 8740 __ rorq($dst$$Register, $shift$$constant); 8741 %} 8742 ins_pipe(ialu_reg); 8743 %} 8744 8745 // Rotate Right by constant 8746 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8747 %{ 8748 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8749 match(Set dst (RotateRight src shift)); 8750 format %{ "rorxq $dst, $src, $shift" %} 8751 ins_encode %{ 8752 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8753 %} 8754 ins_pipe(ialu_reg_reg); 8755 %} 8756 8757 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8758 %{ 8759 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8760 match(Set dst (RotateRight (LoadL src) shift)); 8761 ins_cost(175); 8762 format %{ "rorxq $dst, $src, $shift" %} 8763 ins_encode %{ 8764 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8765 %} 8766 ins_pipe(ialu_reg_mem); 8767 %} 8768 8769 // Rotate Right by variable 8770 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8771 %{ 8772 predicate(n->bottom_type()->basic_type() == T_LONG); 8773 match(Set dst (RotateRight dst shift)); 8774 effect(KILL cr); 8775 format %{ "rorq $dst, $shift" %} 8776 ins_encode %{ 8777 __ rorq($dst$$Register); 8778 %} 8779 ins_pipe(ialu_reg_reg); 8780 %} 8781 8782 //----------------------------- CompressBits/ExpandBits ------------------------ 8783 8784 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8785 predicate(n->bottom_type()->isa_long()); 8786 match(Set dst (CompressBits src mask)); 8787 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8788 ins_encode %{ 8789 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8790 %} 8791 ins_pipe( pipe_slow ); 8792 %} 8793 8794 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8795 predicate(n->bottom_type()->isa_long()); 8796 match(Set dst (ExpandBits src mask)); 8797 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8798 ins_encode %{ 8799 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8800 %} 8801 ins_pipe( pipe_slow ); 8802 %} 8803 8804 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8805 predicate(n->bottom_type()->isa_long()); 8806 match(Set dst (CompressBits src (LoadL mask))); 8807 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8808 ins_encode %{ 8809 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8810 %} 8811 ins_pipe( pipe_slow ); 8812 %} 8813 8814 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8815 predicate(n->bottom_type()->isa_long()); 8816 match(Set dst (ExpandBits src (LoadL mask))); 8817 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8818 ins_encode %{ 8819 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8820 %} 8821 ins_pipe( pipe_slow ); 8822 %} 8823 8824 8825 // Logical Instructions 8826 8827 // Integer Logical Instructions 8828 8829 // And Instructions 8830 // And Register with Register 8831 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8832 %{ 8833 match(Set dst (AndI dst src)); 8834 effect(KILL cr); 8835 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); 8836 8837 format %{ "andl $dst, $src\t# int" %} 8838 ins_encode %{ 8839 __ andl($dst$$Register, $src$$Register); 8840 %} 8841 ins_pipe(ialu_reg_reg); 8842 %} 8843 8844 // And Register with Immediate 255 8845 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8846 %{ 8847 match(Set dst (AndI src mask)); 8848 8849 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8850 ins_encode %{ 8851 __ movzbl($dst$$Register, $src$$Register); 8852 %} 8853 ins_pipe(ialu_reg); 8854 %} 8855 8856 // And Register with Immediate 255 and promote to long 8857 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8858 %{ 8859 match(Set dst (ConvI2L (AndI src mask))); 8860 8861 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8862 ins_encode %{ 8863 __ movzbl($dst$$Register, $src$$Register); 8864 %} 8865 ins_pipe(ialu_reg); 8866 %} 8867 8868 // And Register with Immediate 65535 8869 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8870 %{ 8871 match(Set dst (AndI src mask)); 8872 8873 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8874 ins_encode %{ 8875 __ movzwl($dst$$Register, $src$$Register); 8876 %} 8877 ins_pipe(ialu_reg); 8878 %} 8879 8880 // And Register with Immediate 65535 and promote to long 8881 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8882 %{ 8883 match(Set dst (ConvI2L (AndI src mask))); 8884 8885 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8886 ins_encode %{ 8887 __ movzwl($dst$$Register, $src$$Register); 8888 %} 8889 ins_pipe(ialu_reg); 8890 %} 8891 8892 // Can skip int2long conversions after AND with small bitmask 8893 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8894 %{ 8895 predicate(VM_Version::supports_bmi2()); 8896 ins_cost(125); 8897 effect(TEMP tmp, KILL cr); 8898 match(Set dst (ConvI2L (AndI src mask))); 8899 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8900 ins_encode %{ 8901 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8902 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8903 %} 8904 ins_pipe(ialu_reg_reg); 8905 %} 8906 8907 // And Register with Immediate 8908 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8909 %{ 8910 match(Set dst (AndI dst src)); 8911 effect(KILL cr); 8912 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); 8913 8914 format %{ "andl $dst, $src\t# int" %} 8915 ins_encode %{ 8916 __ andl($dst$$Register, $src$$constant); 8917 %} 8918 ins_pipe(ialu_reg); 8919 %} 8920 8921 // And Register with Memory 8922 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8923 %{ 8924 match(Set dst (AndI dst (LoadI src))); 8925 effect(KILL cr); 8926 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); 8927 8928 ins_cost(150); 8929 format %{ "andl $dst, $src\t# int" %} 8930 ins_encode %{ 8931 __ andl($dst$$Register, $src$$Address); 8932 %} 8933 ins_pipe(ialu_reg_mem); 8934 %} 8935 8936 // And Memory with Register 8937 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8938 %{ 8939 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8940 effect(KILL cr); 8941 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); 8942 8943 ins_cost(150); 8944 format %{ "andb $dst, $src\t# byte" %} 8945 ins_encode %{ 8946 __ andb($dst$$Address, $src$$Register); 8947 %} 8948 ins_pipe(ialu_mem_reg); 8949 %} 8950 8951 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8952 %{ 8953 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8954 effect(KILL cr); 8955 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); 8956 8957 ins_cost(150); 8958 format %{ "andl $dst, $src\t# int" %} 8959 ins_encode %{ 8960 __ andl($dst$$Address, $src$$Register); 8961 %} 8962 ins_pipe(ialu_mem_reg); 8963 %} 8964 8965 // And Memory with Immediate 8966 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8967 %{ 8968 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8969 effect(KILL cr); 8970 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); 8971 8972 ins_cost(125); 8973 format %{ "andl $dst, $src\t# int" %} 8974 ins_encode %{ 8975 __ andl($dst$$Address, $src$$constant); 8976 %} 8977 ins_pipe(ialu_mem_imm); 8978 %} 8979 8980 // BMI1 instructions 8981 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8982 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8983 predicate(UseBMI1Instructions); 8984 effect(KILL cr); 8985 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8986 8987 ins_cost(125); 8988 format %{ "andnl $dst, $src1, $src2" %} 8989 8990 ins_encode %{ 8991 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8992 %} 8993 ins_pipe(ialu_reg_mem); 8994 %} 8995 8996 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8997 match(Set dst (AndI (XorI src1 minus_1) src2)); 8998 predicate(UseBMI1Instructions); 8999 effect(KILL cr); 9000 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9001 9002 format %{ "andnl $dst, $src1, $src2" %} 9003 9004 ins_encode %{ 9005 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9006 %} 9007 ins_pipe(ialu_reg); 9008 %} 9009 9010 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 9011 match(Set dst (AndI (SubI imm_zero src) src)); 9012 predicate(UseBMI1Instructions); 9013 effect(KILL cr); 9014 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9015 9016 format %{ "blsil $dst, $src" %} 9017 9018 ins_encode %{ 9019 __ blsil($dst$$Register, $src$$Register); 9020 %} 9021 ins_pipe(ialu_reg); 9022 %} 9023 9024 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 9025 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9026 predicate(UseBMI1Instructions); 9027 effect(KILL cr); 9028 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9029 9030 ins_cost(125); 9031 format %{ "blsil $dst, $src" %} 9032 9033 ins_encode %{ 9034 __ blsil($dst$$Register, $src$$Address); 9035 %} 9036 ins_pipe(ialu_reg_mem); 9037 %} 9038 9039 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9040 %{ 9041 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9042 predicate(UseBMI1Instructions); 9043 effect(KILL cr); 9044 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9045 9046 ins_cost(125); 9047 format %{ "blsmskl $dst, $src" %} 9048 9049 ins_encode %{ 9050 __ blsmskl($dst$$Register, $src$$Address); 9051 %} 9052 ins_pipe(ialu_reg_mem); 9053 %} 9054 9055 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9056 %{ 9057 match(Set dst (XorI (AddI src minus_1) src)); 9058 predicate(UseBMI1Instructions); 9059 effect(KILL cr); 9060 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9061 9062 format %{ "blsmskl $dst, $src" %} 9063 9064 ins_encode %{ 9065 __ blsmskl($dst$$Register, $src$$Register); 9066 %} 9067 9068 ins_pipe(ialu_reg); 9069 %} 9070 9071 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9072 %{ 9073 match(Set dst (AndI (AddI src minus_1) src) ); 9074 predicate(UseBMI1Instructions); 9075 effect(KILL cr); 9076 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9077 9078 format %{ "blsrl $dst, $src" %} 9079 9080 ins_encode %{ 9081 __ blsrl($dst$$Register, $src$$Register); 9082 %} 9083 9084 ins_pipe(ialu_reg_mem); 9085 %} 9086 9087 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9088 %{ 9089 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9090 predicate(UseBMI1Instructions); 9091 effect(KILL cr); 9092 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9093 9094 ins_cost(125); 9095 format %{ "blsrl $dst, $src" %} 9096 9097 ins_encode %{ 9098 __ blsrl($dst$$Register, $src$$Address); 9099 %} 9100 9101 ins_pipe(ialu_reg); 9102 %} 9103 9104 // Or Instructions 9105 // Or Register with Register 9106 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9107 %{ 9108 match(Set dst (OrI dst src)); 9109 effect(KILL cr); 9110 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); 9111 9112 format %{ "orl $dst, $src\t# int" %} 9113 ins_encode %{ 9114 __ orl($dst$$Register, $src$$Register); 9115 %} 9116 ins_pipe(ialu_reg_reg); 9117 %} 9118 9119 // Or Register with Immediate 9120 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9121 %{ 9122 match(Set dst (OrI dst src)); 9123 effect(KILL cr); 9124 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); 9125 9126 format %{ "orl $dst, $src\t# int" %} 9127 ins_encode %{ 9128 __ orl($dst$$Register, $src$$constant); 9129 %} 9130 ins_pipe(ialu_reg); 9131 %} 9132 9133 // Or Register with Memory 9134 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9135 %{ 9136 match(Set dst (OrI dst (LoadI src))); 9137 effect(KILL cr); 9138 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); 9139 9140 ins_cost(150); 9141 format %{ "orl $dst, $src\t# int" %} 9142 ins_encode %{ 9143 __ orl($dst$$Register, $src$$Address); 9144 %} 9145 ins_pipe(ialu_reg_mem); 9146 %} 9147 9148 // Or Memory with Register 9149 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9150 %{ 9151 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9152 effect(KILL cr); 9153 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); 9154 9155 ins_cost(150); 9156 format %{ "orb $dst, $src\t# byte" %} 9157 ins_encode %{ 9158 __ orb($dst$$Address, $src$$Register); 9159 %} 9160 ins_pipe(ialu_mem_reg); 9161 %} 9162 9163 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9164 %{ 9165 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9166 effect(KILL cr); 9167 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); 9168 9169 ins_cost(150); 9170 format %{ "orl $dst, $src\t# int" %} 9171 ins_encode %{ 9172 __ orl($dst$$Address, $src$$Register); 9173 %} 9174 ins_pipe(ialu_mem_reg); 9175 %} 9176 9177 // Or Memory with Immediate 9178 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9179 %{ 9180 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9181 effect(KILL cr); 9182 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); 9183 9184 ins_cost(125); 9185 format %{ "orl $dst, $src\t# int" %} 9186 ins_encode %{ 9187 __ orl($dst$$Address, $src$$constant); 9188 %} 9189 ins_pipe(ialu_mem_imm); 9190 %} 9191 9192 // Xor Instructions 9193 // Xor Register with Register 9194 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9195 %{ 9196 match(Set dst (XorI dst src)); 9197 effect(KILL cr); 9198 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); 9199 9200 format %{ "xorl $dst, $src\t# int" %} 9201 ins_encode %{ 9202 __ xorl($dst$$Register, $src$$Register); 9203 %} 9204 ins_pipe(ialu_reg_reg); 9205 %} 9206 9207 // Xor Register with Immediate -1 9208 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9209 match(Set dst (XorI dst imm)); 9210 9211 format %{ "not $dst" %} 9212 ins_encode %{ 9213 __ notl($dst$$Register); 9214 %} 9215 ins_pipe(ialu_reg); 9216 %} 9217 9218 // Xor Register with Immediate 9219 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9220 %{ 9221 match(Set dst (XorI dst src)); 9222 effect(KILL cr); 9223 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); 9224 9225 format %{ "xorl $dst, $src\t# int" %} 9226 ins_encode %{ 9227 __ xorl($dst$$Register, $src$$constant); 9228 %} 9229 ins_pipe(ialu_reg); 9230 %} 9231 9232 // Xor Register with Memory 9233 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9234 %{ 9235 match(Set dst (XorI dst (LoadI src))); 9236 effect(KILL cr); 9237 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); 9238 9239 ins_cost(150); 9240 format %{ "xorl $dst, $src\t# int" %} 9241 ins_encode %{ 9242 __ xorl($dst$$Register, $src$$Address); 9243 %} 9244 ins_pipe(ialu_reg_mem); 9245 %} 9246 9247 // Xor Memory with Register 9248 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9249 %{ 9250 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9251 effect(KILL cr); 9252 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); 9253 9254 ins_cost(150); 9255 format %{ "xorb $dst, $src\t# byte" %} 9256 ins_encode %{ 9257 __ xorb($dst$$Address, $src$$Register); 9258 %} 9259 ins_pipe(ialu_mem_reg); 9260 %} 9261 9262 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9263 %{ 9264 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9265 effect(KILL cr); 9266 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); 9267 9268 ins_cost(150); 9269 format %{ "xorl $dst, $src\t# int" %} 9270 ins_encode %{ 9271 __ xorl($dst$$Address, $src$$Register); 9272 %} 9273 ins_pipe(ialu_mem_reg); 9274 %} 9275 9276 // Xor Memory with Immediate 9277 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9278 %{ 9279 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9280 effect(KILL cr); 9281 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); 9282 9283 ins_cost(125); 9284 format %{ "xorl $dst, $src\t# int" %} 9285 ins_encode %{ 9286 __ xorl($dst$$Address, $src$$constant); 9287 %} 9288 ins_pipe(ialu_mem_imm); 9289 %} 9290 9291 9292 // Long Logical Instructions 9293 9294 // And Instructions 9295 // And Register with Register 9296 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9297 %{ 9298 match(Set dst (AndL dst src)); 9299 effect(KILL cr); 9300 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); 9301 9302 format %{ "andq $dst, $src\t# long" %} 9303 ins_encode %{ 9304 __ andq($dst$$Register, $src$$Register); 9305 %} 9306 ins_pipe(ialu_reg_reg); 9307 %} 9308 9309 // And Register with Immediate 255 9310 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9311 %{ 9312 match(Set dst (AndL src mask)); 9313 9314 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9315 ins_encode %{ 9316 // movzbl zeroes out the upper 32-bit and does not need REX.W 9317 __ movzbl($dst$$Register, $src$$Register); 9318 %} 9319 ins_pipe(ialu_reg); 9320 %} 9321 9322 // And Register with Immediate 65535 9323 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9324 %{ 9325 match(Set dst (AndL src mask)); 9326 9327 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9328 ins_encode %{ 9329 // movzwl zeroes out the upper 32-bit and does not need REX.W 9330 __ movzwl($dst$$Register, $src$$Register); 9331 %} 9332 ins_pipe(ialu_reg); 9333 %} 9334 9335 // And Register with Immediate 9336 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9337 %{ 9338 match(Set dst (AndL dst src)); 9339 effect(KILL cr); 9340 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); 9341 9342 format %{ "andq $dst, $src\t# long" %} 9343 ins_encode %{ 9344 __ andq($dst$$Register, $src$$constant); 9345 %} 9346 ins_pipe(ialu_reg); 9347 %} 9348 9349 // And Register with Memory 9350 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9351 %{ 9352 match(Set dst (AndL dst (LoadL src))); 9353 effect(KILL cr); 9354 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); 9355 9356 ins_cost(150); 9357 format %{ "andq $dst, $src\t# long" %} 9358 ins_encode %{ 9359 __ andq($dst$$Register, $src$$Address); 9360 %} 9361 ins_pipe(ialu_reg_mem); 9362 %} 9363 9364 // And Memory with Register 9365 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9366 %{ 9367 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9368 effect(KILL cr); 9369 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); 9370 9371 ins_cost(150); 9372 format %{ "andq $dst, $src\t# long" %} 9373 ins_encode %{ 9374 __ andq($dst$$Address, $src$$Register); 9375 %} 9376 ins_pipe(ialu_mem_reg); 9377 %} 9378 9379 // And Memory with Immediate 9380 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9381 %{ 9382 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9383 effect(KILL cr); 9384 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); 9385 9386 ins_cost(125); 9387 format %{ "andq $dst, $src\t# long" %} 9388 ins_encode %{ 9389 __ andq($dst$$Address, $src$$constant); 9390 %} 9391 ins_pipe(ialu_mem_imm); 9392 %} 9393 9394 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9395 %{ 9396 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9397 // because AND/OR works well enough for 8/32-bit values. 9398 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9399 9400 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9401 effect(KILL cr); 9402 9403 ins_cost(125); 9404 format %{ "btrq $dst, log2(not($con))\t# long" %} 9405 ins_encode %{ 9406 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9407 %} 9408 ins_pipe(ialu_mem_imm); 9409 %} 9410 9411 // BMI1 instructions 9412 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9413 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9414 predicate(UseBMI1Instructions); 9415 effect(KILL cr); 9416 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9417 9418 ins_cost(125); 9419 format %{ "andnq $dst, $src1, $src2" %} 9420 9421 ins_encode %{ 9422 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9423 %} 9424 ins_pipe(ialu_reg_mem); 9425 %} 9426 9427 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9428 match(Set dst (AndL (XorL src1 minus_1) src2)); 9429 predicate(UseBMI1Instructions); 9430 effect(KILL cr); 9431 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9432 9433 format %{ "andnq $dst, $src1, $src2" %} 9434 9435 ins_encode %{ 9436 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9437 %} 9438 ins_pipe(ialu_reg_mem); 9439 %} 9440 9441 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9442 match(Set dst (AndL (SubL imm_zero src) src)); 9443 predicate(UseBMI1Instructions); 9444 effect(KILL cr); 9445 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9446 9447 format %{ "blsiq $dst, $src" %} 9448 9449 ins_encode %{ 9450 __ blsiq($dst$$Register, $src$$Register); 9451 %} 9452 ins_pipe(ialu_reg); 9453 %} 9454 9455 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9456 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9457 predicate(UseBMI1Instructions); 9458 effect(KILL cr); 9459 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9460 9461 ins_cost(125); 9462 format %{ "blsiq $dst, $src" %} 9463 9464 ins_encode %{ 9465 __ blsiq($dst$$Register, $src$$Address); 9466 %} 9467 ins_pipe(ialu_reg_mem); 9468 %} 9469 9470 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9471 %{ 9472 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9473 predicate(UseBMI1Instructions); 9474 effect(KILL cr); 9475 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9476 9477 ins_cost(125); 9478 format %{ "blsmskq $dst, $src" %} 9479 9480 ins_encode %{ 9481 __ blsmskq($dst$$Register, $src$$Address); 9482 %} 9483 ins_pipe(ialu_reg_mem); 9484 %} 9485 9486 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9487 %{ 9488 match(Set dst (XorL (AddL src minus_1) src)); 9489 predicate(UseBMI1Instructions); 9490 effect(KILL cr); 9491 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9492 9493 format %{ "blsmskq $dst, $src" %} 9494 9495 ins_encode %{ 9496 __ blsmskq($dst$$Register, $src$$Register); 9497 %} 9498 9499 ins_pipe(ialu_reg); 9500 %} 9501 9502 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9503 %{ 9504 match(Set dst (AndL (AddL src minus_1) src) ); 9505 predicate(UseBMI1Instructions); 9506 effect(KILL cr); 9507 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9508 9509 format %{ "blsrq $dst, $src" %} 9510 9511 ins_encode %{ 9512 __ blsrq($dst$$Register, $src$$Register); 9513 %} 9514 9515 ins_pipe(ialu_reg); 9516 %} 9517 9518 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9519 %{ 9520 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9521 predicate(UseBMI1Instructions); 9522 effect(KILL cr); 9523 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9524 9525 ins_cost(125); 9526 format %{ "blsrq $dst, $src" %} 9527 9528 ins_encode %{ 9529 __ blsrq($dst$$Register, $src$$Address); 9530 %} 9531 9532 ins_pipe(ialu_reg); 9533 %} 9534 9535 // Or Instructions 9536 // Or Register with Register 9537 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9538 %{ 9539 match(Set dst (OrL dst src)); 9540 effect(KILL cr); 9541 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9542 9543 format %{ "orq $dst, $src\t# long" %} 9544 ins_encode %{ 9545 __ orq($dst$$Register, $src$$Register); 9546 %} 9547 ins_pipe(ialu_reg_reg); 9548 %} 9549 9550 // Use any_RegP to match R15 (TLS register) without spilling. 9551 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9552 match(Set dst (OrL dst (CastP2X src))); 9553 effect(KILL cr); 9554 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); 9555 9556 format %{ "orq $dst, $src\t# long" %} 9557 ins_encode %{ 9558 __ orq($dst$$Register, $src$$Register); 9559 %} 9560 ins_pipe(ialu_reg_reg); 9561 %} 9562 9563 9564 // Or Register with Immediate 9565 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9566 %{ 9567 match(Set dst (OrL dst src)); 9568 effect(KILL cr); 9569 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); 9570 9571 format %{ "orq $dst, $src\t# long" %} 9572 ins_encode %{ 9573 __ orq($dst$$Register, $src$$constant); 9574 %} 9575 ins_pipe(ialu_reg); 9576 %} 9577 9578 // Or Register with Memory 9579 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9580 %{ 9581 match(Set dst (OrL dst (LoadL src))); 9582 effect(KILL cr); 9583 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); 9584 9585 ins_cost(150); 9586 format %{ "orq $dst, $src\t# long" %} 9587 ins_encode %{ 9588 __ orq($dst$$Register, $src$$Address); 9589 %} 9590 ins_pipe(ialu_reg_mem); 9591 %} 9592 9593 // Or Memory with Register 9594 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9595 %{ 9596 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9597 effect(KILL cr); 9598 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); 9599 9600 ins_cost(150); 9601 format %{ "orq $dst, $src\t# long" %} 9602 ins_encode %{ 9603 __ orq($dst$$Address, $src$$Register); 9604 %} 9605 ins_pipe(ialu_mem_reg); 9606 %} 9607 9608 // Or Memory with Immediate 9609 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9610 %{ 9611 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9612 effect(KILL cr); 9613 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9614 9615 ins_cost(125); 9616 format %{ "orq $dst, $src\t# long" %} 9617 ins_encode %{ 9618 __ orq($dst$$Address, $src$$constant); 9619 %} 9620 ins_pipe(ialu_mem_imm); 9621 %} 9622 9623 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9624 %{ 9625 // con should be a pure 64-bit power of 2 immediate 9626 // because AND/OR works well enough for 8/32-bit values. 9627 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9628 9629 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9630 effect(KILL cr); 9631 9632 ins_cost(125); 9633 format %{ "btsq $dst, log2($con)\t# long" %} 9634 ins_encode %{ 9635 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9636 %} 9637 ins_pipe(ialu_mem_imm); 9638 %} 9639 9640 // Xor Instructions 9641 // Xor Register with Register 9642 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9643 %{ 9644 match(Set dst (XorL dst src)); 9645 effect(KILL cr); 9646 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); 9647 9648 format %{ "xorq $dst, $src\t# long" %} 9649 ins_encode %{ 9650 __ xorq($dst$$Register, $src$$Register); 9651 %} 9652 ins_pipe(ialu_reg_reg); 9653 %} 9654 9655 // Xor Register with Immediate -1 9656 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9657 match(Set dst (XorL dst imm)); 9658 9659 format %{ "notq $dst" %} 9660 ins_encode %{ 9661 __ notq($dst$$Register); 9662 %} 9663 ins_pipe(ialu_reg); 9664 %} 9665 9666 // Xor Register with Immediate 9667 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9668 %{ 9669 match(Set dst (XorL dst src)); 9670 effect(KILL cr); 9671 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); 9672 9673 format %{ "xorq $dst, $src\t# long" %} 9674 ins_encode %{ 9675 __ xorq($dst$$Register, $src$$constant); 9676 %} 9677 ins_pipe(ialu_reg); 9678 %} 9679 9680 // Xor Register with Memory 9681 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9682 %{ 9683 match(Set dst (XorL dst (LoadL src))); 9684 effect(KILL cr); 9685 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); 9686 9687 ins_cost(150); 9688 format %{ "xorq $dst, $src\t# long" %} 9689 ins_encode %{ 9690 __ xorq($dst$$Register, $src$$Address); 9691 %} 9692 ins_pipe(ialu_reg_mem); 9693 %} 9694 9695 // Xor Memory with Register 9696 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9697 %{ 9698 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9699 effect(KILL cr); 9700 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); 9701 9702 ins_cost(150); 9703 format %{ "xorq $dst, $src\t# long" %} 9704 ins_encode %{ 9705 __ xorq($dst$$Address, $src$$Register); 9706 %} 9707 ins_pipe(ialu_mem_reg); 9708 %} 9709 9710 // Xor Memory with Immediate 9711 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9712 %{ 9713 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9714 effect(KILL cr); 9715 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); 9716 9717 ins_cost(125); 9718 format %{ "xorq $dst, $src\t# long" %} 9719 ins_encode %{ 9720 __ xorq($dst$$Address, $src$$constant); 9721 %} 9722 ins_pipe(ialu_mem_imm); 9723 %} 9724 9725 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9726 %{ 9727 match(Set dst (CmpLTMask p q)); 9728 effect(KILL cr); 9729 9730 ins_cost(400); 9731 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9732 "setlt $dst\n\t" 9733 "movzbl $dst, $dst\n\t" 9734 "negl $dst" %} 9735 ins_encode %{ 9736 __ cmpl($p$$Register, $q$$Register); 9737 __ setb(Assembler::less, $dst$$Register); 9738 __ movzbl($dst$$Register, $dst$$Register); 9739 __ negl($dst$$Register); 9740 %} 9741 ins_pipe(pipe_slow); 9742 %} 9743 9744 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9745 %{ 9746 match(Set dst (CmpLTMask dst zero)); 9747 effect(KILL cr); 9748 9749 ins_cost(100); 9750 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9751 ins_encode %{ 9752 __ sarl($dst$$Register, 31); 9753 %} 9754 ins_pipe(ialu_reg); 9755 %} 9756 9757 /* Better to save a register than avoid a branch */ 9758 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9759 %{ 9760 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9761 effect(KILL cr); 9762 ins_cost(300); 9763 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9764 "jge done\n\t" 9765 "addl $p,$y\n" 9766 "done: " %} 9767 ins_encode %{ 9768 Register Rp = $p$$Register; 9769 Register Rq = $q$$Register; 9770 Register Ry = $y$$Register; 9771 Label done; 9772 __ subl(Rp, Rq); 9773 __ jccb(Assembler::greaterEqual, done); 9774 __ addl(Rp, Ry); 9775 __ bind(done); 9776 %} 9777 ins_pipe(pipe_cmplt); 9778 %} 9779 9780 /* Better to save a register than avoid a branch */ 9781 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9782 %{ 9783 match(Set y (AndI (CmpLTMask p q) y)); 9784 effect(KILL cr); 9785 9786 ins_cost(300); 9787 9788 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9789 "jlt done\n\t" 9790 "xorl $y, $y\n" 9791 "done: " %} 9792 ins_encode %{ 9793 Register Rp = $p$$Register; 9794 Register Rq = $q$$Register; 9795 Register Ry = $y$$Register; 9796 Label done; 9797 __ cmpl(Rp, Rq); 9798 __ jccb(Assembler::less, done); 9799 __ xorl(Ry, Ry); 9800 __ bind(done); 9801 %} 9802 ins_pipe(pipe_cmplt); 9803 %} 9804 9805 9806 //---------- FP Instructions------------------------------------------------ 9807 9808 // Really expensive, avoid 9809 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9810 %{ 9811 match(Set cr (CmpF src1 src2)); 9812 9813 ins_cost(500); 9814 format %{ "ucomiss $src1, $src2\n\t" 9815 "jnp,s exit\n\t" 9816 "pushfq\t# saw NaN, set CF\n\t" 9817 "andq [rsp], #0xffffff2b\n\t" 9818 "popfq\n" 9819 "exit:" %} 9820 ins_encode %{ 9821 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9822 emit_cmpfp_fixup(masm); 9823 %} 9824 ins_pipe(pipe_slow); 9825 %} 9826 9827 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9828 match(Set cr (CmpF src1 src2)); 9829 9830 ins_cost(100); 9831 format %{ "ucomiss $src1, $src2" %} 9832 ins_encode %{ 9833 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9834 %} 9835 ins_pipe(pipe_slow); 9836 %} 9837 9838 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9839 match(Set cr (CmpF src1 (LoadF src2))); 9840 9841 ins_cost(100); 9842 format %{ "ucomiss $src1, $src2" %} 9843 ins_encode %{ 9844 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9845 %} 9846 ins_pipe(pipe_slow); 9847 %} 9848 9849 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9850 match(Set cr (CmpF src con)); 9851 ins_cost(100); 9852 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9853 ins_encode %{ 9854 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9855 %} 9856 ins_pipe(pipe_slow); 9857 %} 9858 9859 // Really expensive, avoid 9860 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9861 %{ 9862 match(Set cr (CmpD src1 src2)); 9863 9864 ins_cost(500); 9865 format %{ "ucomisd $src1, $src2\n\t" 9866 "jnp,s exit\n\t" 9867 "pushfq\t# saw NaN, set CF\n\t" 9868 "andq [rsp], #0xffffff2b\n\t" 9869 "popfq\n" 9870 "exit:" %} 9871 ins_encode %{ 9872 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9873 emit_cmpfp_fixup(masm); 9874 %} 9875 ins_pipe(pipe_slow); 9876 %} 9877 9878 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9879 match(Set cr (CmpD src1 src2)); 9880 9881 ins_cost(100); 9882 format %{ "ucomisd $src1, $src2 test" %} 9883 ins_encode %{ 9884 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9885 %} 9886 ins_pipe(pipe_slow); 9887 %} 9888 9889 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9890 match(Set cr (CmpD src1 (LoadD src2))); 9891 9892 ins_cost(100); 9893 format %{ "ucomisd $src1, $src2" %} 9894 ins_encode %{ 9895 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9896 %} 9897 ins_pipe(pipe_slow); 9898 %} 9899 9900 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9901 match(Set cr (CmpD src con)); 9902 ins_cost(100); 9903 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9904 ins_encode %{ 9905 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9906 %} 9907 ins_pipe(pipe_slow); 9908 %} 9909 9910 // Compare into -1,0,1 9911 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9912 %{ 9913 match(Set dst (CmpF3 src1 src2)); 9914 effect(KILL cr); 9915 9916 ins_cost(275); 9917 format %{ "ucomiss $src1, $src2\n\t" 9918 "movl $dst, #-1\n\t" 9919 "jp,s done\n\t" 9920 "jb,s done\n\t" 9921 "setne $dst\n\t" 9922 "movzbl $dst, $dst\n" 9923 "done:" %} 9924 ins_encode %{ 9925 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9926 emit_cmpfp3(masm, $dst$$Register); 9927 %} 9928 ins_pipe(pipe_slow); 9929 %} 9930 9931 // Compare into -1,0,1 9932 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9933 %{ 9934 match(Set dst (CmpF3 src1 (LoadF src2))); 9935 effect(KILL cr); 9936 9937 ins_cost(275); 9938 format %{ "ucomiss $src1, $src2\n\t" 9939 "movl $dst, #-1\n\t" 9940 "jp,s done\n\t" 9941 "jb,s done\n\t" 9942 "setne $dst\n\t" 9943 "movzbl $dst, $dst\n" 9944 "done:" %} 9945 ins_encode %{ 9946 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9947 emit_cmpfp3(masm, $dst$$Register); 9948 %} 9949 ins_pipe(pipe_slow); 9950 %} 9951 9952 // Compare into -1,0,1 9953 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9954 match(Set dst (CmpF3 src con)); 9955 effect(KILL cr); 9956 9957 ins_cost(275); 9958 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9959 "movl $dst, #-1\n\t" 9960 "jp,s done\n\t" 9961 "jb,s done\n\t" 9962 "setne $dst\n\t" 9963 "movzbl $dst, $dst\n" 9964 "done:" %} 9965 ins_encode %{ 9966 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9967 emit_cmpfp3(masm, $dst$$Register); 9968 %} 9969 ins_pipe(pipe_slow); 9970 %} 9971 9972 // Compare into -1,0,1 9973 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9974 %{ 9975 match(Set dst (CmpD3 src1 src2)); 9976 effect(KILL cr); 9977 9978 ins_cost(275); 9979 format %{ "ucomisd $src1, $src2\n\t" 9980 "movl $dst, #-1\n\t" 9981 "jp,s done\n\t" 9982 "jb,s done\n\t" 9983 "setne $dst\n\t" 9984 "movzbl $dst, $dst\n" 9985 "done:" %} 9986 ins_encode %{ 9987 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9988 emit_cmpfp3(masm, $dst$$Register); 9989 %} 9990 ins_pipe(pipe_slow); 9991 %} 9992 9993 // Compare into -1,0,1 9994 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9995 %{ 9996 match(Set dst (CmpD3 src1 (LoadD src2))); 9997 effect(KILL cr); 9998 9999 ins_cost(275); 10000 format %{ "ucomisd $src1, $src2\n\t" 10001 "movl $dst, #-1\n\t" 10002 "jp,s done\n\t" 10003 "jb,s done\n\t" 10004 "setne $dst\n\t" 10005 "movzbl $dst, $dst\n" 10006 "done:" %} 10007 ins_encode %{ 10008 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10009 emit_cmpfp3(masm, $dst$$Register); 10010 %} 10011 ins_pipe(pipe_slow); 10012 %} 10013 10014 // Compare into -1,0,1 10015 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10016 match(Set dst (CmpD3 src con)); 10017 effect(KILL cr); 10018 10019 ins_cost(275); 10020 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10021 "movl $dst, #-1\n\t" 10022 "jp,s done\n\t" 10023 "jb,s done\n\t" 10024 "setne $dst\n\t" 10025 "movzbl $dst, $dst\n" 10026 "done:" %} 10027 ins_encode %{ 10028 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10029 emit_cmpfp3(masm, $dst$$Register); 10030 %} 10031 ins_pipe(pipe_slow); 10032 %} 10033 10034 //----------Arithmetic Conversion Instructions--------------------------------- 10035 10036 instruct convF2D_reg_reg(regD dst, regF src) 10037 %{ 10038 match(Set dst (ConvF2D src)); 10039 10040 format %{ "cvtss2sd $dst, $src" %} 10041 ins_encode %{ 10042 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10043 %} 10044 ins_pipe(pipe_slow); // XXX 10045 %} 10046 10047 instruct convF2D_reg_mem(regD dst, memory src) 10048 %{ 10049 predicate(UseAVX == 0); 10050 match(Set dst (ConvF2D (LoadF src))); 10051 10052 format %{ "cvtss2sd $dst, $src" %} 10053 ins_encode %{ 10054 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10055 %} 10056 ins_pipe(pipe_slow); // XXX 10057 %} 10058 10059 instruct convD2F_reg_reg(regF dst, regD src) 10060 %{ 10061 match(Set dst (ConvD2F src)); 10062 10063 format %{ "cvtsd2ss $dst, $src" %} 10064 ins_encode %{ 10065 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10066 %} 10067 ins_pipe(pipe_slow); // XXX 10068 %} 10069 10070 instruct convD2F_reg_mem(regF dst, memory src) 10071 %{ 10072 predicate(UseAVX == 0); 10073 match(Set dst (ConvD2F (LoadD src))); 10074 10075 format %{ "cvtsd2ss $dst, $src" %} 10076 ins_encode %{ 10077 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10078 %} 10079 ins_pipe(pipe_slow); // XXX 10080 %} 10081 10082 // XXX do mem variants 10083 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10084 %{ 10085 match(Set dst (ConvF2I src)); 10086 effect(KILL cr); 10087 format %{ "convert_f2i $dst, $src" %} 10088 ins_encode %{ 10089 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10090 %} 10091 ins_pipe(pipe_slow); 10092 %} 10093 10094 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10095 %{ 10096 match(Set dst (ConvF2L src)); 10097 effect(KILL cr); 10098 format %{ "convert_f2l $dst, $src"%} 10099 ins_encode %{ 10100 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10101 %} 10102 ins_pipe(pipe_slow); 10103 %} 10104 10105 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10106 %{ 10107 match(Set dst (ConvD2I src)); 10108 effect(KILL cr); 10109 format %{ "convert_d2i $dst, $src"%} 10110 ins_encode %{ 10111 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10112 %} 10113 ins_pipe(pipe_slow); 10114 %} 10115 10116 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10117 %{ 10118 match(Set dst (ConvD2L src)); 10119 effect(KILL cr); 10120 format %{ "convert_d2l $dst, $src"%} 10121 ins_encode %{ 10122 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10123 %} 10124 ins_pipe(pipe_slow); 10125 %} 10126 10127 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10128 %{ 10129 match(Set dst (RoundD src)); 10130 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10131 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10132 ins_encode %{ 10133 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10134 %} 10135 ins_pipe(pipe_slow); 10136 %} 10137 10138 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10139 %{ 10140 match(Set dst (RoundF src)); 10141 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10142 format %{ "round_float $dst,$src" %} 10143 ins_encode %{ 10144 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10145 %} 10146 ins_pipe(pipe_slow); 10147 %} 10148 10149 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10150 %{ 10151 predicate(!UseXmmI2F); 10152 match(Set dst (ConvI2F src)); 10153 10154 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10155 ins_encode %{ 10156 if (UseAVX > 0) { 10157 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10158 } 10159 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10160 %} 10161 ins_pipe(pipe_slow); // XXX 10162 %} 10163 10164 instruct convI2F_reg_mem(regF dst, memory src) 10165 %{ 10166 predicate(UseAVX == 0); 10167 match(Set dst (ConvI2F (LoadI src))); 10168 10169 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10170 ins_encode %{ 10171 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10172 %} 10173 ins_pipe(pipe_slow); // XXX 10174 %} 10175 10176 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10177 %{ 10178 predicate(!UseXmmI2D); 10179 match(Set dst (ConvI2D src)); 10180 10181 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10182 ins_encode %{ 10183 if (UseAVX > 0) { 10184 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10185 } 10186 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10187 %} 10188 ins_pipe(pipe_slow); // XXX 10189 %} 10190 10191 instruct convI2D_reg_mem(regD dst, memory src) 10192 %{ 10193 predicate(UseAVX == 0); 10194 match(Set dst (ConvI2D (LoadI src))); 10195 10196 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10197 ins_encode %{ 10198 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10199 %} 10200 ins_pipe(pipe_slow); // XXX 10201 %} 10202 10203 instruct convXI2F_reg(regF dst, rRegI src) 10204 %{ 10205 predicate(UseXmmI2F); 10206 match(Set dst (ConvI2F src)); 10207 10208 format %{ "movdl $dst, $src\n\t" 10209 "cvtdq2psl $dst, $dst\t# i2f" %} 10210 ins_encode %{ 10211 __ movdl($dst$$XMMRegister, $src$$Register); 10212 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10213 %} 10214 ins_pipe(pipe_slow); // XXX 10215 %} 10216 10217 instruct convXI2D_reg(regD dst, rRegI src) 10218 %{ 10219 predicate(UseXmmI2D); 10220 match(Set dst (ConvI2D src)); 10221 10222 format %{ "movdl $dst, $src\n\t" 10223 "cvtdq2pdl $dst, $dst\t# i2d" %} 10224 ins_encode %{ 10225 __ movdl($dst$$XMMRegister, $src$$Register); 10226 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10227 %} 10228 ins_pipe(pipe_slow); // XXX 10229 %} 10230 10231 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10232 %{ 10233 match(Set dst (ConvL2F src)); 10234 10235 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10236 ins_encode %{ 10237 if (UseAVX > 0) { 10238 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10239 } 10240 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10241 %} 10242 ins_pipe(pipe_slow); // XXX 10243 %} 10244 10245 instruct convL2F_reg_mem(regF dst, memory src) 10246 %{ 10247 predicate(UseAVX == 0); 10248 match(Set dst (ConvL2F (LoadL src))); 10249 10250 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10251 ins_encode %{ 10252 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10253 %} 10254 ins_pipe(pipe_slow); // XXX 10255 %} 10256 10257 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10258 %{ 10259 match(Set dst (ConvL2D src)); 10260 10261 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10262 ins_encode %{ 10263 if (UseAVX > 0) { 10264 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10265 } 10266 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10267 %} 10268 ins_pipe(pipe_slow); // XXX 10269 %} 10270 10271 instruct convL2D_reg_mem(regD dst, memory src) 10272 %{ 10273 predicate(UseAVX == 0); 10274 match(Set dst (ConvL2D (LoadL src))); 10275 10276 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10277 ins_encode %{ 10278 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10279 %} 10280 ins_pipe(pipe_slow); // XXX 10281 %} 10282 10283 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10284 %{ 10285 match(Set dst (ConvI2L src)); 10286 10287 ins_cost(125); 10288 format %{ "movslq $dst, $src\t# i2l" %} 10289 ins_encode %{ 10290 __ movslq($dst$$Register, $src$$Register); 10291 %} 10292 ins_pipe(ialu_reg_reg); 10293 %} 10294 10295 // Zero-extend convert int to long 10296 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10297 %{ 10298 match(Set dst (AndL (ConvI2L src) mask)); 10299 10300 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10301 ins_encode %{ 10302 if ($dst$$reg != $src$$reg) { 10303 __ movl($dst$$Register, $src$$Register); 10304 } 10305 %} 10306 ins_pipe(ialu_reg_reg); 10307 %} 10308 10309 // Zero-extend convert int to long 10310 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10311 %{ 10312 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10313 10314 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10315 ins_encode %{ 10316 __ movl($dst$$Register, $src$$Address); 10317 %} 10318 ins_pipe(ialu_reg_mem); 10319 %} 10320 10321 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10322 %{ 10323 match(Set dst (AndL src mask)); 10324 10325 format %{ "movl $dst, $src\t# zero-extend long" %} 10326 ins_encode %{ 10327 __ movl($dst$$Register, $src$$Register); 10328 %} 10329 ins_pipe(ialu_reg_reg); 10330 %} 10331 10332 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10333 %{ 10334 match(Set dst (ConvL2I src)); 10335 10336 format %{ "movl $dst, $src\t# l2i" %} 10337 ins_encode %{ 10338 __ movl($dst$$Register, $src$$Register); 10339 %} 10340 ins_pipe(ialu_reg_reg); 10341 %} 10342 10343 10344 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10345 match(Set dst (MoveF2I src)); 10346 effect(DEF dst, USE src); 10347 10348 ins_cost(125); 10349 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10350 ins_encode %{ 10351 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10352 %} 10353 ins_pipe(ialu_reg_mem); 10354 %} 10355 10356 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10357 match(Set dst (MoveI2F src)); 10358 effect(DEF dst, USE src); 10359 10360 ins_cost(125); 10361 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10362 ins_encode %{ 10363 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10364 %} 10365 ins_pipe(pipe_slow); 10366 %} 10367 10368 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10369 match(Set dst (MoveD2L src)); 10370 effect(DEF dst, USE src); 10371 10372 ins_cost(125); 10373 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10374 ins_encode %{ 10375 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10376 %} 10377 ins_pipe(ialu_reg_mem); 10378 %} 10379 10380 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10381 predicate(!UseXmmLoadAndClearUpper); 10382 match(Set dst (MoveL2D src)); 10383 effect(DEF dst, USE src); 10384 10385 ins_cost(125); 10386 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10387 ins_encode %{ 10388 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10389 %} 10390 ins_pipe(pipe_slow); 10391 %} 10392 10393 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10394 predicate(UseXmmLoadAndClearUpper); 10395 match(Set dst (MoveL2D src)); 10396 effect(DEF dst, USE src); 10397 10398 ins_cost(125); 10399 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10400 ins_encode %{ 10401 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10402 %} 10403 ins_pipe(pipe_slow); 10404 %} 10405 10406 10407 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10408 match(Set dst (MoveF2I src)); 10409 effect(DEF dst, USE src); 10410 10411 ins_cost(95); // XXX 10412 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10413 ins_encode %{ 10414 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10415 %} 10416 ins_pipe(pipe_slow); 10417 %} 10418 10419 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10420 match(Set dst (MoveI2F src)); 10421 effect(DEF dst, USE src); 10422 10423 ins_cost(100); 10424 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10425 ins_encode %{ 10426 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10427 %} 10428 ins_pipe( ialu_mem_reg ); 10429 %} 10430 10431 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10432 match(Set dst (MoveD2L src)); 10433 effect(DEF dst, USE src); 10434 10435 ins_cost(95); // XXX 10436 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10437 ins_encode %{ 10438 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10439 %} 10440 ins_pipe(pipe_slow); 10441 %} 10442 10443 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10444 match(Set dst (MoveL2D src)); 10445 effect(DEF dst, USE src); 10446 10447 ins_cost(100); 10448 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10449 ins_encode %{ 10450 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10451 %} 10452 ins_pipe(ialu_mem_reg); 10453 %} 10454 10455 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10456 match(Set dst (MoveF2I src)); 10457 effect(DEF dst, USE src); 10458 ins_cost(85); 10459 format %{ "movd $dst,$src\t# MoveF2I" %} 10460 ins_encode %{ 10461 __ movdl($dst$$Register, $src$$XMMRegister); 10462 %} 10463 ins_pipe( pipe_slow ); 10464 %} 10465 10466 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10467 match(Set dst (MoveD2L src)); 10468 effect(DEF dst, USE src); 10469 ins_cost(85); 10470 format %{ "movd $dst,$src\t# MoveD2L" %} 10471 ins_encode %{ 10472 __ movdq($dst$$Register, $src$$XMMRegister); 10473 %} 10474 ins_pipe( pipe_slow ); 10475 %} 10476 10477 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10478 match(Set dst (MoveI2F src)); 10479 effect(DEF dst, USE src); 10480 ins_cost(100); 10481 format %{ "movd $dst,$src\t# MoveI2F" %} 10482 ins_encode %{ 10483 __ movdl($dst$$XMMRegister, $src$$Register); 10484 %} 10485 ins_pipe( pipe_slow ); 10486 %} 10487 10488 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10489 match(Set dst (MoveL2D src)); 10490 effect(DEF dst, USE src); 10491 ins_cost(100); 10492 format %{ "movd $dst,$src\t# MoveL2D" %} 10493 ins_encode %{ 10494 __ movdq($dst$$XMMRegister, $src$$Register); 10495 %} 10496 ins_pipe( pipe_slow ); 10497 %} 10498 10499 // Fast clearing of an array 10500 // Small non-constant lenght ClearArray for non-AVX512 targets. 10501 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10502 Universe dummy, rFlagsReg cr) 10503 %{ 10504 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 10505 match(Set dummy (ClearArray cnt base)); 10506 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10507 10508 format %{ $$template 10509 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10510 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10511 $$emit$$"jg LARGE\n\t" 10512 $$emit$$"dec rcx\n\t" 10513 $$emit$$"js DONE\t# Zero length\n\t" 10514 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10515 $$emit$$"dec rcx\n\t" 10516 $$emit$$"jge LOOP\n\t" 10517 $$emit$$"jmp DONE\n\t" 10518 $$emit$$"# LARGE:\n\t" 10519 if (UseFastStosb) { 10520 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10521 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10522 } else if (UseXMMForObjInit) { 10523 $$emit$$"mov rdi,rax\n\t" 10524 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10525 $$emit$$"jmpq L_zero_64_bytes\n\t" 10526 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10527 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10528 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10529 $$emit$$"add 0x40,rax\n\t" 10530 $$emit$$"# L_zero_64_bytes:\n\t" 10531 $$emit$$"sub 0x8,rcx\n\t" 10532 $$emit$$"jge L_loop\n\t" 10533 $$emit$$"add 0x4,rcx\n\t" 10534 $$emit$$"jl L_tail\n\t" 10535 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10536 $$emit$$"add 0x20,rax\n\t" 10537 $$emit$$"sub 0x4,rcx\n\t" 10538 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10539 $$emit$$"add 0x4,rcx\n\t" 10540 $$emit$$"jle L_end\n\t" 10541 $$emit$$"dec rcx\n\t" 10542 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10543 $$emit$$"vmovq xmm0,(rax)\n\t" 10544 $$emit$$"add 0x8,rax\n\t" 10545 $$emit$$"dec rcx\n\t" 10546 $$emit$$"jge L_sloop\n\t" 10547 $$emit$$"# L_end:\n\t" 10548 } else { 10549 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10550 } 10551 $$emit$$"# DONE" 10552 %} 10553 ins_encode %{ 10554 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10555 $tmp$$XMMRegister, false, knoreg); 10556 %} 10557 ins_pipe(pipe_slow); 10558 %} 10559 10560 // Small non-constant length ClearArray for AVX512 targets. 10561 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10562 Universe dummy, rFlagsReg cr) 10563 %{ 10564 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 10565 match(Set dummy (ClearArray cnt base)); 10566 ins_cost(125); 10567 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10568 10569 format %{ $$template 10570 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10571 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10572 $$emit$$"jg LARGE\n\t" 10573 $$emit$$"dec rcx\n\t" 10574 $$emit$$"js DONE\t# Zero length\n\t" 10575 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10576 $$emit$$"dec rcx\n\t" 10577 $$emit$$"jge LOOP\n\t" 10578 $$emit$$"jmp DONE\n\t" 10579 $$emit$$"# LARGE:\n\t" 10580 if (UseFastStosb) { 10581 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10582 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10583 } else if (UseXMMForObjInit) { 10584 $$emit$$"mov rdi,rax\n\t" 10585 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10586 $$emit$$"jmpq L_zero_64_bytes\n\t" 10587 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10588 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10589 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10590 $$emit$$"add 0x40,rax\n\t" 10591 $$emit$$"# L_zero_64_bytes:\n\t" 10592 $$emit$$"sub 0x8,rcx\n\t" 10593 $$emit$$"jge L_loop\n\t" 10594 $$emit$$"add 0x4,rcx\n\t" 10595 $$emit$$"jl L_tail\n\t" 10596 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10597 $$emit$$"add 0x20,rax\n\t" 10598 $$emit$$"sub 0x4,rcx\n\t" 10599 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10600 $$emit$$"add 0x4,rcx\n\t" 10601 $$emit$$"jle L_end\n\t" 10602 $$emit$$"dec rcx\n\t" 10603 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10604 $$emit$$"vmovq xmm0,(rax)\n\t" 10605 $$emit$$"add 0x8,rax\n\t" 10606 $$emit$$"dec rcx\n\t" 10607 $$emit$$"jge L_sloop\n\t" 10608 $$emit$$"# L_end:\n\t" 10609 } else { 10610 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10611 } 10612 $$emit$$"# DONE" 10613 %} 10614 ins_encode %{ 10615 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10616 $tmp$$XMMRegister, false, $ktmp$$KRegister); 10617 %} 10618 ins_pipe(pipe_slow); 10619 %} 10620 10621 // Large non-constant length ClearArray for non-AVX512 targets. 10622 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10623 Universe dummy, rFlagsReg cr) 10624 %{ 10625 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 10626 match(Set dummy (ClearArray cnt base)); 10627 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10628 10629 format %{ $$template 10630 if (UseFastStosb) { 10631 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10632 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10633 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10634 } else if (UseXMMForObjInit) { 10635 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10636 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10637 $$emit$$"jmpq L_zero_64_bytes\n\t" 10638 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10639 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10640 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10641 $$emit$$"add 0x40,rax\n\t" 10642 $$emit$$"# L_zero_64_bytes:\n\t" 10643 $$emit$$"sub 0x8,rcx\n\t" 10644 $$emit$$"jge L_loop\n\t" 10645 $$emit$$"add 0x4,rcx\n\t" 10646 $$emit$$"jl L_tail\n\t" 10647 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10648 $$emit$$"add 0x20,rax\n\t" 10649 $$emit$$"sub 0x4,rcx\n\t" 10650 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10651 $$emit$$"add 0x4,rcx\n\t" 10652 $$emit$$"jle L_end\n\t" 10653 $$emit$$"dec rcx\n\t" 10654 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10655 $$emit$$"vmovq xmm0,(rax)\n\t" 10656 $$emit$$"add 0x8,rax\n\t" 10657 $$emit$$"dec rcx\n\t" 10658 $$emit$$"jge L_sloop\n\t" 10659 $$emit$$"# L_end:\n\t" 10660 } else { 10661 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10662 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10663 } 10664 %} 10665 ins_encode %{ 10666 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10667 $tmp$$XMMRegister, true, knoreg); 10668 %} 10669 ins_pipe(pipe_slow); 10670 %} 10671 10672 // Large non-constant length ClearArray for AVX512 targets. 10673 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10674 Universe dummy, rFlagsReg cr) 10675 %{ 10676 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 10677 match(Set dummy (ClearArray cnt base)); 10678 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10679 10680 format %{ $$template 10681 if (UseFastStosb) { 10682 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10683 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10684 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10685 } else if (UseXMMForObjInit) { 10686 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10687 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10688 $$emit$$"jmpq L_zero_64_bytes\n\t" 10689 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10690 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10691 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10692 $$emit$$"add 0x40,rax\n\t" 10693 $$emit$$"# L_zero_64_bytes:\n\t" 10694 $$emit$$"sub 0x8,rcx\n\t" 10695 $$emit$$"jge L_loop\n\t" 10696 $$emit$$"add 0x4,rcx\n\t" 10697 $$emit$$"jl L_tail\n\t" 10698 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10699 $$emit$$"add 0x20,rax\n\t" 10700 $$emit$$"sub 0x4,rcx\n\t" 10701 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10702 $$emit$$"add 0x4,rcx\n\t" 10703 $$emit$$"jle L_end\n\t" 10704 $$emit$$"dec rcx\n\t" 10705 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10706 $$emit$$"vmovq xmm0,(rax)\n\t" 10707 $$emit$$"add 0x8,rax\n\t" 10708 $$emit$$"dec rcx\n\t" 10709 $$emit$$"jge L_sloop\n\t" 10710 $$emit$$"# L_end:\n\t" 10711 } else { 10712 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10713 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10714 } 10715 %} 10716 ins_encode %{ 10717 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10718 $tmp$$XMMRegister, true, $ktmp$$KRegister); 10719 %} 10720 ins_pipe(pipe_slow); 10721 %} 10722 10723 // Small constant length ClearArray for AVX512 targets. 10724 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 10725 %{ 10726 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 10727 match(Set dummy (ClearArray cnt base)); 10728 ins_cost(100); 10729 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 10730 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10731 ins_encode %{ 10732 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10733 %} 10734 ins_pipe(pipe_slow); 10735 %} 10736 10737 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10738 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10739 %{ 10740 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10741 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10742 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10743 10744 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10745 ins_encode %{ 10746 __ string_compare($str1$$Register, $str2$$Register, 10747 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10748 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10749 %} 10750 ins_pipe( pipe_slow ); 10751 %} 10752 10753 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10754 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10755 %{ 10756 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10757 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10758 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10759 10760 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10761 ins_encode %{ 10762 __ string_compare($str1$$Register, $str2$$Register, 10763 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10764 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10765 %} 10766 ins_pipe( pipe_slow ); 10767 %} 10768 10769 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10770 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10771 %{ 10772 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10773 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10774 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10775 10776 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10777 ins_encode %{ 10778 __ string_compare($str1$$Register, $str2$$Register, 10779 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10780 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10781 %} 10782 ins_pipe( pipe_slow ); 10783 %} 10784 10785 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10786 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10787 %{ 10788 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10789 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10790 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10791 10792 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10793 ins_encode %{ 10794 __ string_compare($str1$$Register, $str2$$Register, 10795 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10796 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10797 %} 10798 ins_pipe( pipe_slow ); 10799 %} 10800 10801 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10802 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10803 %{ 10804 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10805 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10806 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10807 10808 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10809 ins_encode %{ 10810 __ string_compare($str1$$Register, $str2$$Register, 10811 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10812 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 10813 %} 10814 ins_pipe( pipe_slow ); 10815 %} 10816 10817 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10818 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10819 %{ 10820 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10821 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10822 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10823 10824 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10825 ins_encode %{ 10826 __ string_compare($str1$$Register, $str2$$Register, 10827 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10828 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 10829 %} 10830 ins_pipe( pipe_slow ); 10831 %} 10832 10833 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10834 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10835 %{ 10836 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10837 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10838 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10839 10840 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10841 ins_encode %{ 10842 __ string_compare($str2$$Register, $str1$$Register, 10843 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10844 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 10845 %} 10846 ins_pipe( pipe_slow ); 10847 %} 10848 10849 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10850 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10851 %{ 10852 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10853 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10854 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10855 10856 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10857 ins_encode %{ 10858 __ string_compare($str2$$Register, $str1$$Register, 10859 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10860 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 10861 %} 10862 ins_pipe( pipe_slow ); 10863 %} 10864 10865 // fast search of substring with known size. 10866 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10867 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10868 %{ 10869 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10870 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10871 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10872 10873 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10874 ins_encode %{ 10875 int icnt2 = (int)$int_cnt2$$constant; 10876 if (icnt2 >= 16) { 10877 // IndexOf for constant substrings with size >= 16 elements 10878 // which don't need to be loaded through stack. 10879 __ string_indexofC8($str1$$Register, $str2$$Register, 10880 $cnt1$$Register, $cnt2$$Register, 10881 icnt2, $result$$Register, 10882 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10883 } else { 10884 // Small strings are loaded through stack if they cross page boundary. 10885 __ string_indexof($str1$$Register, $str2$$Register, 10886 $cnt1$$Register, $cnt2$$Register, 10887 icnt2, $result$$Register, 10888 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10889 } 10890 %} 10891 ins_pipe( pipe_slow ); 10892 %} 10893 10894 // fast search of substring with known size. 10895 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10896 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10897 %{ 10898 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10899 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10900 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10901 10902 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10903 ins_encode %{ 10904 int icnt2 = (int)$int_cnt2$$constant; 10905 if (icnt2 >= 8) { 10906 // IndexOf for constant substrings with size >= 8 elements 10907 // which don't need to be loaded through stack. 10908 __ string_indexofC8($str1$$Register, $str2$$Register, 10909 $cnt1$$Register, $cnt2$$Register, 10910 icnt2, $result$$Register, 10911 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10912 } else { 10913 // Small strings are loaded through stack if they cross page boundary. 10914 __ string_indexof($str1$$Register, $str2$$Register, 10915 $cnt1$$Register, $cnt2$$Register, 10916 icnt2, $result$$Register, 10917 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10918 } 10919 %} 10920 ins_pipe( pipe_slow ); 10921 %} 10922 10923 // fast search of substring with known size. 10924 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10925 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10926 %{ 10927 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10928 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10929 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10930 10931 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10932 ins_encode %{ 10933 int icnt2 = (int)$int_cnt2$$constant; 10934 if (icnt2 >= 8) { 10935 // IndexOf for constant substrings with size >= 8 elements 10936 // which don't need to be loaded through stack. 10937 __ string_indexofC8($str1$$Register, $str2$$Register, 10938 $cnt1$$Register, $cnt2$$Register, 10939 icnt2, $result$$Register, 10940 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10941 } else { 10942 // Small strings are loaded through stack if they cross page boundary. 10943 __ string_indexof($str1$$Register, $str2$$Register, 10944 $cnt1$$Register, $cnt2$$Register, 10945 icnt2, $result$$Register, 10946 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10947 } 10948 %} 10949 ins_pipe( pipe_slow ); 10950 %} 10951 10952 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10953 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10954 %{ 10955 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10956 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10957 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10958 10959 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10960 ins_encode %{ 10961 __ string_indexof($str1$$Register, $str2$$Register, 10962 $cnt1$$Register, $cnt2$$Register, 10963 (-1), $result$$Register, 10964 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10965 %} 10966 ins_pipe( pipe_slow ); 10967 %} 10968 10969 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10970 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10971 %{ 10972 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10973 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10974 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10975 10976 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10977 ins_encode %{ 10978 __ string_indexof($str1$$Register, $str2$$Register, 10979 $cnt1$$Register, $cnt2$$Register, 10980 (-1), $result$$Register, 10981 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10982 %} 10983 ins_pipe( pipe_slow ); 10984 %} 10985 10986 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10987 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10988 %{ 10989 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10990 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10991 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10992 10993 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10994 ins_encode %{ 10995 __ string_indexof($str1$$Register, $str2$$Register, 10996 $cnt1$$Register, $cnt2$$Register, 10997 (-1), $result$$Register, 10998 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10999 %} 11000 ins_pipe( pipe_slow ); 11001 %} 11002 11003 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11004 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11005 %{ 11006 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 11007 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11008 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11009 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11010 ins_encode %{ 11011 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11012 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11013 %} 11014 ins_pipe( pipe_slow ); 11015 %} 11016 11017 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11018 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11019 %{ 11020 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 11021 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11022 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11023 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11024 ins_encode %{ 11025 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11026 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11027 %} 11028 ins_pipe( pipe_slow ); 11029 %} 11030 11031 // fast string equals 11032 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11033 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11034 %{ 11035 predicate(!VM_Version::supports_avx512vlbw()); 11036 match(Set result (StrEquals (Binary str1 str2) cnt)); 11037 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11038 11039 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11040 ins_encode %{ 11041 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11042 $cnt$$Register, $result$$Register, $tmp3$$Register, 11043 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11044 %} 11045 ins_pipe( pipe_slow ); 11046 %} 11047 11048 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11049 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11050 %{ 11051 predicate(VM_Version::supports_avx512vlbw()); 11052 match(Set result (StrEquals (Binary str1 str2) cnt)); 11053 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11054 11055 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11056 ins_encode %{ 11057 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11058 $cnt$$Register, $result$$Register, $tmp3$$Register, 11059 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11060 %} 11061 ins_pipe( pipe_slow ); 11062 %} 11063 11064 // fast array equals 11065 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11066 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11067 %{ 11068 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11069 match(Set result (AryEq ary1 ary2)); 11070 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11071 11072 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11073 ins_encode %{ 11074 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11075 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11076 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11077 %} 11078 ins_pipe( pipe_slow ); 11079 %} 11080 11081 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11082 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11083 %{ 11084 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11085 match(Set result (AryEq ary1 ary2)); 11086 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11087 11088 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11089 ins_encode %{ 11090 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11091 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11092 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11093 %} 11094 ins_pipe( pipe_slow ); 11095 %} 11096 11097 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11098 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11099 %{ 11100 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11101 match(Set result (AryEq ary1 ary2)); 11102 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11103 11104 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11105 ins_encode %{ 11106 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11107 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11108 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11109 %} 11110 ins_pipe( pipe_slow ); 11111 %} 11112 11113 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11114 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11115 %{ 11116 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11117 match(Set result (AryEq ary1 ary2)); 11118 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11119 11120 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11121 ins_encode %{ 11122 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11123 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11124 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11125 %} 11126 ins_pipe( pipe_slow ); 11127 %} 11128 11129 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11130 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11131 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11132 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11133 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11134 %{ 11135 predicate(UseAVX >= 2); 11136 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11137 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11138 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11139 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11140 USE basic_type, KILL cr); 11141 11142 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11143 ins_encode %{ 11144 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11145 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11146 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11147 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11148 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11149 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11150 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11151 %} 11152 ins_pipe( pipe_slow ); 11153 %} 11154 11155 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11156 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11157 %{ 11158 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11159 match(Set result (CountPositives ary1 len)); 11160 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11161 11162 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11163 ins_encode %{ 11164 __ count_positives($ary1$$Register, $len$$Register, 11165 $result$$Register, $tmp3$$Register, 11166 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11167 %} 11168 ins_pipe( pipe_slow ); 11169 %} 11170 11171 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11172 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11173 %{ 11174 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11175 match(Set result (CountPositives ary1 len)); 11176 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11177 11178 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11179 ins_encode %{ 11180 __ count_positives($ary1$$Register, $len$$Register, 11181 $result$$Register, $tmp3$$Register, 11182 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11183 %} 11184 ins_pipe( pipe_slow ); 11185 %} 11186 11187 // fast char[] to byte[] compression 11188 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11189 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11190 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11191 match(Set result (StrCompressedCopy src (Binary dst len))); 11192 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11193 USE_KILL len, KILL tmp5, KILL cr); 11194 11195 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11196 ins_encode %{ 11197 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11198 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11199 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11200 knoreg, knoreg); 11201 %} 11202 ins_pipe( pipe_slow ); 11203 %} 11204 11205 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11206 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11207 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11208 match(Set result (StrCompressedCopy src (Binary dst len))); 11209 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11210 USE_KILL len, KILL tmp5, KILL cr); 11211 11212 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11213 ins_encode %{ 11214 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11215 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11216 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11217 $ktmp1$$KRegister, $ktmp2$$KRegister); 11218 %} 11219 ins_pipe( pipe_slow ); 11220 %} 11221 // fast byte[] to char[] inflation 11222 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11223 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11224 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11225 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11226 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11227 11228 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11229 ins_encode %{ 11230 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11231 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11232 %} 11233 ins_pipe( pipe_slow ); 11234 %} 11235 11236 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11237 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11238 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11239 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11240 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11241 11242 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11243 ins_encode %{ 11244 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11245 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11246 %} 11247 ins_pipe( pipe_slow ); 11248 %} 11249 11250 // encode char[] to byte[] in ISO_8859_1 11251 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11252 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11253 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11254 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11255 match(Set result (EncodeISOArray src (Binary dst len))); 11256 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11257 11258 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11259 ins_encode %{ 11260 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11261 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11262 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11263 %} 11264 ins_pipe( pipe_slow ); 11265 %} 11266 11267 // encode char[] to byte[] in ASCII 11268 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11269 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11270 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11271 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11272 match(Set result (EncodeISOArray src (Binary dst len))); 11273 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11274 11275 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11276 ins_encode %{ 11277 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11278 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11279 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11280 %} 11281 ins_pipe( pipe_slow ); 11282 %} 11283 11284 //----------Overflow Math Instructions----------------------------------------- 11285 11286 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11287 %{ 11288 match(Set cr (OverflowAddI op1 op2)); 11289 effect(DEF cr, USE_KILL op1, USE op2); 11290 11291 format %{ "addl $op1, $op2\t# overflow check int" %} 11292 11293 ins_encode %{ 11294 __ addl($op1$$Register, $op2$$Register); 11295 %} 11296 ins_pipe(ialu_reg_reg); 11297 %} 11298 11299 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11300 %{ 11301 match(Set cr (OverflowAddI op1 op2)); 11302 effect(DEF cr, USE_KILL op1, USE op2); 11303 11304 format %{ "addl $op1, $op2\t# overflow check int" %} 11305 11306 ins_encode %{ 11307 __ addl($op1$$Register, $op2$$constant); 11308 %} 11309 ins_pipe(ialu_reg_reg); 11310 %} 11311 11312 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11313 %{ 11314 match(Set cr (OverflowAddL op1 op2)); 11315 effect(DEF cr, USE_KILL op1, USE op2); 11316 11317 format %{ "addq $op1, $op2\t# overflow check long" %} 11318 ins_encode %{ 11319 __ addq($op1$$Register, $op2$$Register); 11320 %} 11321 ins_pipe(ialu_reg_reg); 11322 %} 11323 11324 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11325 %{ 11326 match(Set cr (OverflowAddL op1 op2)); 11327 effect(DEF cr, USE_KILL op1, USE op2); 11328 11329 format %{ "addq $op1, $op2\t# overflow check long" %} 11330 ins_encode %{ 11331 __ addq($op1$$Register, $op2$$constant); 11332 %} 11333 ins_pipe(ialu_reg_reg); 11334 %} 11335 11336 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11337 %{ 11338 match(Set cr (OverflowSubI op1 op2)); 11339 11340 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11341 ins_encode %{ 11342 __ cmpl($op1$$Register, $op2$$Register); 11343 %} 11344 ins_pipe(ialu_reg_reg); 11345 %} 11346 11347 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11348 %{ 11349 match(Set cr (OverflowSubI op1 op2)); 11350 11351 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11352 ins_encode %{ 11353 __ cmpl($op1$$Register, $op2$$constant); 11354 %} 11355 ins_pipe(ialu_reg_reg); 11356 %} 11357 11358 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11359 %{ 11360 match(Set cr (OverflowSubL op1 op2)); 11361 11362 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11363 ins_encode %{ 11364 __ cmpq($op1$$Register, $op2$$Register); 11365 %} 11366 ins_pipe(ialu_reg_reg); 11367 %} 11368 11369 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11370 %{ 11371 match(Set cr (OverflowSubL op1 op2)); 11372 11373 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11374 ins_encode %{ 11375 __ cmpq($op1$$Register, $op2$$constant); 11376 %} 11377 ins_pipe(ialu_reg_reg); 11378 %} 11379 11380 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11381 %{ 11382 match(Set cr (OverflowSubI zero op2)); 11383 effect(DEF cr, USE_KILL op2); 11384 11385 format %{ "negl $op2\t# overflow check int" %} 11386 ins_encode %{ 11387 __ negl($op2$$Register); 11388 %} 11389 ins_pipe(ialu_reg_reg); 11390 %} 11391 11392 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11393 %{ 11394 match(Set cr (OverflowSubL zero op2)); 11395 effect(DEF cr, USE_KILL op2); 11396 11397 format %{ "negq $op2\t# overflow check long" %} 11398 ins_encode %{ 11399 __ negq($op2$$Register); 11400 %} 11401 ins_pipe(ialu_reg_reg); 11402 %} 11403 11404 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11405 %{ 11406 match(Set cr (OverflowMulI op1 op2)); 11407 effect(DEF cr, USE_KILL op1, USE op2); 11408 11409 format %{ "imull $op1, $op2\t# overflow check int" %} 11410 ins_encode %{ 11411 __ imull($op1$$Register, $op2$$Register); 11412 %} 11413 ins_pipe(ialu_reg_reg_alu0); 11414 %} 11415 11416 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11417 %{ 11418 match(Set cr (OverflowMulI op1 op2)); 11419 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11420 11421 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11422 ins_encode %{ 11423 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11424 %} 11425 ins_pipe(ialu_reg_reg_alu0); 11426 %} 11427 11428 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11429 %{ 11430 match(Set cr (OverflowMulL op1 op2)); 11431 effect(DEF cr, USE_KILL op1, USE op2); 11432 11433 format %{ "imulq $op1, $op2\t# overflow check long" %} 11434 ins_encode %{ 11435 __ imulq($op1$$Register, $op2$$Register); 11436 %} 11437 ins_pipe(ialu_reg_reg_alu0); 11438 %} 11439 11440 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11441 %{ 11442 match(Set cr (OverflowMulL op1 op2)); 11443 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11444 11445 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11446 ins_encode %{ 11447 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11448 %} 11449 ins_pipe(ialu_reg_reg_alu0); 11450 %} 11451 11452 11453 //----------Control Flow Instructions------------------------------------------ 11454 // Signed compare Instructions 11455 11456 // XXX more variants!! 11457 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11458 %{ 11459 match(Set cr (CmpI op1 op2)); 11460 effect(DEF cr, USE op1, USE op2); 11461 11462 format %{ "cmpl $op1, $op2" %} 11463 ins_encode %{ 11464 __ cmpl($op1$$Register, $op2$$Register); 11465 %} 11466 ins_pipe(ialu_cr_reg_reg); 11467 %} 11468 11469 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11470 %{ 11471 match(Set cr (CmpI op1 op2)); 11472 11473 format %{ "cmpl $op1, $op2" %} 11474 ins_encode %{ 11475 __ cmpl($op1$$Register, $op2$$constant); 11476 %} 11477 ins_pipe(ialu_cr_reg_imm); 11478 %} 11479 11480 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11481 %{ 11482 match(Set cr (CmpI op1 (LoadI op2))); 11483 11484 ins_cost(500); // XXX 11485 format %{ "cmpl $op1, $op2" %} 11486 ins_encode %{ 11487 __ cmpl($op1$$Register, $op2$$Address); 11488 %} 11489 ins_pipe(ialu_cr_reg_mem); 11490 %} 11491 11492 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11493 %{ 11494 match(Set cr (CmpI src zero)); 11495 11496 format %{ "testl $src, $src" %} 11497 ins_encode %{ 11498 __ testl($src$$Register, $src$$Register); 11499 %} 11500 ins_pipe(ialu_cr_reg_imm); 11501 %} 11502 11503 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11504 %{ 11505 match(Set cr (CmpI (AndI src con) zero)); 11506 11507 format %{ "testl $src, $con" %} 11508 ins_encode %{ 11509 __ testl($src$$Register, $con$$constant); 11510 %} 11511 ins_pipe(ialu_cr_reg_imm); 11512 %} 11513 11514 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11515 %{ 11516 match(Set cr (CmpI (AndI src1 src2) zero)); 11517 11518 format %{ "testl $src1, $src2" %} 11519 ins_encode %{ 11520 __ testl($src1$$Register, $src2$$Register); 11521 %} 11522 ins_pipe(ialu_cr_reg_imm); 11523 %} 11524 11525 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11526 %{ 11527 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11528 11529 format %{ "testl $src, $mem" %} 11530 ins_encode %{ 11531 __ testl($src$$Register, $mem$$Address); 11532 %} 11533 ins_pipe(ialu_cr_reg_mem); 11534 %} 11535 11536 // Unsigned compare Instructions; really, same as signed except they 11537 // produce an rFlagsRegU instead of rFlagsReg. 11538 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11539 %{ 11540 match(Set cr (CmpU op1 op2)); 11541 11542 format %{ "cmpl $op1, $op2\t# unsigned" %} 11543 ins_encode %{ 11544 __ cmpl($op1$$Register, $op2$$Register); 11545 %} 11546 ins_pipe(ialu_cr_reg_reg); 11547 %} 11548 11549 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11550 %{ 11551 match(Set cr (CmpU op1 op2)); 11552 11553 format %{ "cmpl $op1, $op2\t# unsigned" %} 11554 ins_encode %{ 11555 __ cmpl($op1$$Register, $op2$$constant); 11556 %} 11557 ins_pipe(ialu_cr_reg_imm); 11558 %} 11559 11560 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11561 %{ 11562 match(Set cr (CmpU op1 (LoadI op2))); 11563 11564 ins_cost(500); // XXX 11565 format %{ "cmpl $op1, $op2\t# unsigned" %} 11566 ins_encode %{ 11567 __ cmpl($op1$$Register, $op2$$Address); 11568 %} 11569 ins_pipe(ialu_cr_reg_mem); 11570 %} 11571 11572 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11573 %{ 11574 match(Set cr (CmpU src zero)); 11575 11576 format %{ "testl $src, $src\t# unsigned" %} 11577 ins_encode %{ 11578 __ testl($src$$Register, $src$$Register); 11579 %} 11580 ins_pipe(ialu_cr_reg_imm); 11581 %} 11582 11583 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11584 %{ 11585 match(Set cr (CmpP op1 op2)); 11586 11587 format %{ "cmpq $op1, $op2\t# ptr" %} 11588 ins_encode %{ 11589 __ cmpq($op1$$Register, $op2$$Register); 11590 %} 11591 ins_pipe(ialu_cr_reg_reg); 11592 %} 11593 11594 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11595 %{ 11596 match(Set cr (CmpP op1 (LoadP op2))); 11597 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11598 11599 ins_cost(500); // XXX 11600 format %{ "cmpq $op1, $op2\t# ptr" %} 11601 ins_encode %{ 11602 __ cmpq($op1$$Register, $op2$$Address); 11603 %} 11604 ins_pipe(ialu_cr_reg_mem); 11605 %} 11606 11607 // XXX this is generalized by compP_rReg_mem??? 11608 // Compare raw pointer (used in out-of-heap check). 11609 // Only works because non-oop pointers must be raw pointers 11610 // and raw pointers have no anti-dependencies. 11611 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11612 %{ 11613 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11614 n->in(2)->as_Load()->barrier_data() == 0); 11615 match(Set cr (CmpP op1 (LoadP op2))); 11616 11617 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11618 ins_encode %{ 11619 __ cmpq($op1$$Register, $op2$$Address); 11620 %} 11621 ins_pipe(ialu_cr_reg_mem); 11622 %} 11623 11624 // This will generate a signed flags result. This should be OK since 11625 // any compare to a zero should be eq/neq. 11626 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11627 %{ 11628 match(Set cr (CmpP src zero)); 11629 11630 format %{ "testq $src, $src\t# ptr" %} 11631 ins_encode %{ 11632 __ testq($src$$Register, $src$$Register); 11633 %} 11634 ins_pipe(ialu_cr_reg_imm); 11635 %} 11636 11637 // This will generate a signed flags result. This should be OK since 11638 // any compare to a zero should be eq/neq. 11639 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11640 %{ 11641 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11642 n->in(1)->as_Load()->barrier_data() == 0); 11643 match(Set cr (CmpP (LoadP op) zero)); 11644 11645 ins_cost(500); // XXX 11646 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11647 ins_encode %{ 11648 __ testq($op$$Address, 0xFFFFFFFF); 11649 %} 11650 ins_pipe(ialu_cr_reg_imm); 11651 %} 11652 11653 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11654 %{ 11655 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11656 n->in(1)->as_Load()->barrier_data() == 0); 11657 match(Set cr (CmpP (LoadP mem) zero)); 11658 11659 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11660 ins_encode %{ 11661 __ cmpq(r12, $mem$$Address); 11662 %} 11663 ins_pipe(ialu_cr_reg_mem); 11664 %} 11665 11666 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11667 %{ 11668 match(Set cr (CmpN op1 op2)); 11669 11670 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11671 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11672 ins_pipe(ialu_cr_reg_reg); 11673 %} 11674 11675 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11676 %{ 11677 match(Set cr (CmpN src (LoadN mem))); 11678 11679 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11680 ins_encode %{ 11681 __ cmpl($src$$Register, $mem$$Address); 11682 %} 11683 ins_pipe(ialu_cr_reg_mem); 11684 %} 11685 11686 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11687 match(Set cr (CmpN op1 op2)); 11688 11689 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11690 ins_encode %{ 11691 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11692 %} 11693 ins_pipe(ialu_cr_reg_imm); 11694 %} 11695 11696 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11697 %{ 11698 match(Set cr (CmpN src (LoadN mem))); 11699 11700 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11701 ins_encode %{ 11702 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11703 %} 11704 ins_pipe(ialu_cr_reg_mem); 11705 %} 11706 11707 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11708 match(Set cr (CmpN op1 op2)); 11709 11710 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11711 ins_encode %{ 11712 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11713 %} 11714 ins_pipe(ialu_cr_reg_imm); 11715 %} 11716 11717 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11718 %{ 11719 match(Set cr (CmpN src (LoadNKlass mem))); 11720 11721 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11722 ins_encode %{ 11723 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11724 %} 11725 ins_pipe(ialu_cr_reg_mem); 11726 %} 11727 11728 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11729 match(Set cr (CmpN src zero)); 11730 11731 format %{ "testl $src, $src\t# compressed ptr" %} 11732 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11733 ins_pipe(ialu_cr_reg_imm); 11734 %} 11735 11736 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11737 %{ 11738 predicate(CompressedOops::base() != nullptr); 11739 match(Set cr (CmpN (LoadN mem) zero)); 11740 11741 ins_cost(500); // XXX 11742 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11743 ins_encode %{ 11744 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11745 %} 11746 ins_pipe(ialu_cr_reg_mem); 11747 %} 11748 11749 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11750 %{ 11751 predicate(CompressedOops::base() == nullptr); 11752 match(Set cr (CmpN (LoadN mem) zero)); 11753 11754 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11755 ins_encode %{ 11756 __ cmpl(r12, $mem$$Address); 11757 %} 11758 ins_pipe(ialu_cr_reg_mem); 11759 %} 11760 11761 // Yanked all unsigned pointer compare operations. 11762 // Pointer compares are done with CmpP which is already unsigned. 11763 11764 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11765 %{ 11766 match(Set cr (CmpL op1 op2)); 11767 11768 format %{ "cmpq $op1, $op2" %} 11769 ins_encode %{ 11770 __ cmpq($op1$$Register, $op2$$Register); 11771 %} 11772 ins_pipe(ialu_cr_reg_reg); 11773 %} 11774 11775 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11776 %{ 11777 match(Set cr (CmpL op1 op2)); 11778 11779 format %{ "cmpq $op1, $op2" %} 11780 ins_encode %{ 11781 __ cmpq($op1$$Register, $op2$$constant); 11782 %} 11783 ins_pipe(ialu_cr_reg_imm); 11784 %} 11785 11786 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11787 %{ 11788 match(Set cr (CmpL op1 (LoadL op2))); 11789 11790 format %{ "cmpq $op1, $op2" %} 11791 ins_encode %{ 11792 __ cmpq($op1$$Register, $op2$$Address); 11793 %} 11794 ins_pipe(ialu_cr_reg_mem); 11795 %} 11796 11797 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11798 %{ 11799 match(Set cr (CmpL src zero)); 11800 11801 format %{ "testq $src, $src" %} 11802 ins_encode %{ 11803 __ testq($src$$Register, $src$$Register); 11804 %} 11805 ins_pipe(ialu_cr_reg_imm); 11806 %} 11807 11808 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11809 %{ 11810 match(Set cr (CmpL (AndL src con) zero)); 11811 11812 format %{ "testq $src, $con\t# long" %} 11813 ins_encode %{ 11814 __ testq($src$$Register, $con$$constant); 11815 %} 11816 ins_pipe(ialu_cr_reg_imm); 11817 %} 11818 11819 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 11820 %{ 11821 match(Set cr (CmpL (AndL src1 src2) zero)); 11822 11823 format %{ "testq $src1, $src2\t# long" %} 11824 ins_encode %{ 11825 __ testq($src1$$Register, $src2$$Register); 11826 %} 11827 ins_pipe(ialu_cr_reg_imm); 11828 %} 11829 11830 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11831 %{ 11832 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11833 11834 format %{ "testq $src, $mem" %} 11835 ins_encode %{ 11836 __ testq($src$$Register, $mem$$Address); 11837 %} 11838 ins_pipe(ialu_cr_reg_mem); 11839 %} 11840 11841 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11842 %{ 11843 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11844 11845 format %{ "testq $src, $mem" %} 11846 ins_encode %{ 11847 __ testq($src$$Register, $mem$$Address); 11848 %} 11849 ins_pipe(ialu_cr_reg_mem); 11850 %} 11851 11852 // Manifest a CmpU result in an integer register. Very painful. 11853 // This is the test to avoid. 11854 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 11855 %{ 11856 match(Set dst (CmpU3 src1 src2)); 11857 effect(KILL flags); 11858 11859 ins_cost(275); // XXX 11860 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 11861 "movl $dst, -1\n\t" 11862 "jb,u done\n\t" 11863 "setne $dst\n\t" 11864 "movzbl $dst, $dst\n\t" 11865 "done:" %} 11866 ins_encode %{ 11867 Label done; 11868 __ cmpl($src1$$Register, $src2$$Register); 11869 __ movl($dst$$Register, -1); 11870 __ jccb(Assembler::below, done); 11871 __ setb(Assembler::notZero, $dst$$Register); 11872 __ movzbl($dst$$Register, $dst$$Register); 11873 __ bind(done); 11874 %} 11875 ins_pipe(pipe_slow); 11876 %} 11877 11878 // Manifest a CmpL result in an integer register. Very painful. 11879 // This is the test to avoid. 11880 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11881 %{ 11882 match(Set dst (CmpL3 src1 src2)); 11883 effect(KILL flags); 11884 11885 ins_cost(275); // XXX 11886 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11887 "movl $dst, -1\n\t" 11888 "jl,s done\n\t" 11889 "setne $dst\n\t" 11890 "movzbl $dst, $dst\n\t" 11891 "done:" %} 11892 ins_encode %{ 11893 Label done; 11894 __ cmpq($src1$$Register, $src2$$Register); 11895 __ movl($dst$$Register, -1); 11896 __ jccb(Assembler::less, done); 11897 __ setb(Assembler::notZero, $dst$$Register); 11898 __ movzbl($dst$$Register, $dst$$Register); 11899 __ bind(done); 11900 %} 11901 ins_pipe(pipe_slow); 11902 %} 11903 11904 // Manifest a CmpUL result in an integer register. Very painful. 11905 // This is the test to avoid. 11906 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11907 %{ 11908 match(Set dst (CmpUL3 src1 src2)); 11909 effect(KILL flags); 11910 11911 ins_cost(275); // XXX 11912 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11913 "movl $dst, -1\n\t" 11914 "jb,u done\n\t" 11915 "setne $dst\n\t" 11916 "movzbl $dst, $dst\n\t" 11917 "done:" %} 11918 ins_encode %{ 11919 Label done; 11920 __ cmpq($src1$$Register, $src2$$Register); 11921 __ movl($dst$$Register, -1); 11922 __ jccb(Assembler::below, done); 11923 __ setb(Assembler::notZero, $dst$$Register); 11924 __ movzbl($dst$$Register, $dst$$Register); 11925 __ bind(done); 11926 %} 11927 ins_pipe(pipe_slow); 11928 %} 11929 11930 // Unsigned long compare Instructions; really, same as signed long except they 11931 // produce an rFlagsRegU instead of rFlagsReg. 11932 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL 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$$Register); 11939 %} 11940 ins_pipe(ialu_cr_reg_reg); 11941 %} 11942 11943 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11944 %{ 11945 match(Set cr (CmpUL op1 op2)); 11946 11947 format %{ "cmpq $op1, $op2\t# unsigned" %} 11948 ins_encode %{ 11949 __ cmpq($op1$$Register, $op2$$constant); 11950 %} 11951 ins_pipe(ialu_cr_reg_imm); 11952 %} 11953 11954 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11955 %{ 11956 match(Set cr (CmpUL op1 (LoadL op2))); 11957 11958 format %{ "cmpq $op1, $op2\t# unsigned" %} 11959 ins_encode %{ 11960 __ cmpq($op1$$Register, $op2$$Address); 11961 %} 11962 ins_pipe(ialu_cr_reg_mem); 11963 %} 11964 11965 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11966 %{ 11967 match(Set cr (CmpUL src zero)); 11968 11969 format %{ "testq $src, $src\t# unsigned" %} 11970 ins_encode %{ 11971 __ testq($src$$Register, $src$$Register); 11972 %} 11973 ins_pipe(ialu_cr_reg_imm); 11974 %} 11975 11976 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11977 %{ 11978 match(Set cr (CmpI (LoadB mem) imm)); 11979 11980 ins_cost(125); 11981 format %{ "cmpb $mem, $imm" %} 11982 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11983 ins_pipe(ialu_cr_reg_mem); 11984 %} 11985 11986 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 11987 %{ 11988 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11989 11990 ins_cost(125); 11991 format %{ "testb $mem, $imm\t# ubyte" %} 11992 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11993 ins_pipe(ialu_cr_reg_mem); 11994 %} 11995 11996 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 11997 %{ 11998 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11999 12000 ins_cost(125); 12001 format %{ "testb $mem, $imm\t# byte" %} 12002 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12003 ins_pipe(ialu_cr_reg_mem); 12004 %} 12005 12006 //----------Max and Min-------------------------------------------------------- 12007 // Min Instructions 12008 12009 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12010 %{ 12011 effect(USE_DEF dst, USE src, USE cr); 12012 12013 format %{ "cmovlgt $dst, $src\t# min" %} 12014 ins_encode %{ 12015 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 12016 %} 12017 ins_pipe(pipe_cmov_reg); 12018 %} 12019 12020 12021 instruct minI_rReg(rRegI dst, rRegI src) 12022 %{ 12023 match(Set dst (MinI dst src)); 12024 12025 ins_cost(200); 12026 expand %{ 12027 rFlagsReg cr; 12028 compI_rReg(cr, dst, src); 12029 cmovI_reg_g(dst, src, cr); 12030 %} 12031 %} 12032 12033 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12034 %{ 12035 effect(USE_DEF dst, USE src, USE cr); 12036 12037 format %{ "cmovllt $dst, $src\t# max" %} 12038 ins_encode %{ 12039 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12040 %} 12041 ins_pipe(pipe_cmov_reg); 12042 %} 12043 12044 12045 instruct maxI_rReg(rRegI dst, rRegI src) 12046 %{ 12047 match(Set dst (MaxI dst src)); 12048 12049 ins_cost(200); 12050 expand %{ 12051 rFlagsReg cr; 12052 compI_rReg(cr, dst, src); 12053 cmovI_reg_l(dst, src, cr); 12054 %} 12055 %} 12056 12057 // ============================================================================ 12058 // Branch Instructions 12059 12060 // Jump Direct - Label defines a relative address from JMP+1 12061 instruct jmpDir(label labl) 12062 %{ 12063 match(Goto); 12064 effect(USE labl); 12065 12066 ins_cost(300); 12067 format %{ "jmp $labl" %} 12068 size(5); 12069 ins_encode %{ 12070 Label* L = $labl$$label; 12071 __ jmp(*L, false); // Always long jump 12072 %} 12073 ins_pipe(pipe_jmp); 12074 %} 12075 12076 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12077 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12078 %{ 12079 match(If cop cr); 12080 effect(USE labl); 12081 12082 ins_cost(300); 12083 format %{ "j$cop $labl" %} 12084 size(6); 12085 ins_encode %{ 12086 Label* L = $labl$$label; 12087 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12088 %} 12089 ins_pipe(pipe_jcc); 12090 %} 12091 12092 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12093 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12094 %{ 12095 match(CountedLoopEnd cop cr); 12096 effect(USE labl); 12097 12098 ins_cost(300); 12099 format %{ "j$cop $labl\t# loop end" %} 12100 size(6); 12101 ins_encode %{ 12102 Label* L = $labl$$label; 12103 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12104 %} 12105 ins_pipe(pipe_jcc); 12106 %} 12107 12108 // Jump Direct Conditional - using unsigned comparison 12109 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12110 match(If cop cmp); 12111 effect(USE labl); 12112 12113 ins_cost(300); 12114 format %{ "j$cop,u $labl" %} 12115 size(6); 12116 ins_encode %{ 12117 Label* L = $labl$$label; 12118 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12119 %} 12120 ins_pipe(pipe_jcc); 12121 %} 12122 12123 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12124 match(If cop cmp); 12125 effect(USE labl); 12126 12127 ins_cost(200); 12128 format %{ "j$cop,u $labl" %} 12129 size(6); 12130 ins_encode %{ 12131 Label* L = $labl$$label; 12132 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12133 %} 12134 ins_pipe(pipe_jcc); 12135 %} 12136 12137 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12138 match(If cop cmp); 12139 effect(USE labl); 12140 12141 ins_cost(200); 12142 format %{ $$template 12143 if ($cop$$cmpcode == Assembler::notEqual) { 12144 $$emit$$"jp,u $labl\n\t" 12145 $$emit$$"j$cop,u $labl" 12146 } else { 12147 $$emit$$"jp,u done\n\t" 12148 $$emit$$"j$cop,u $labl\n\t" 12149 $$emit$$"done:" 12150 } 12151 %} 12152 ins_encode %{ 12153 Label* l = $labl$$label; 12154 if ($cop$$cmpcode == Assembler::notEqual) { 12155 __ jcc(Assembler::parity, *l, false); 12156 __ jcc(Assembler::notEqual, *l, false); 12157 } else if ($cop$$cmpcode == Assembler::equal) { 12158 Label done; 12159 __ jccb(Assembler::parity, done); 12160 __ jcc(Assembler::equal, *l, false); 12161 __ bind(done); 12162 } else { 12163 ShouldNotReachHere(); 12164 } 12165 %} 12166 ins_pipe(pipe_jcc); 12167 %} 12168 12169 // ============================================================================ 12170 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12171 // superklass array for an instance of the superklass. Set a hidden 12172 // internal cache on a hit (cache is checked with exposed code in 12173 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12174 // encoding ALSO sets flags. 12175 12176 instruct partialSubtypeCheck(rdi_RegP result, 12177 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12178 rFlagsReg cr) 12179 %{ 12180 match(Set result (PartialSubtypeCheck sub super)); 12181 effect(KILL rcx, KILL cr); 12182 12183 ins_cost(1100); // slightly larger than the next version 12184 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12185 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12186 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12187 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12188 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12189 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12190 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12191 "miss:\t" %} 12192 12193 opcode(0x1); // Force a XOR of RDI 12194 ins_encode(enc_PartialSubtypeCheck()); 12195 ins_pipe(pipe_slow); 12196 %} 12197 12198 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12199 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12200 rFlagsReg cr) 12201 %{ 12202 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12203 predicate(UseSecondarySupersTable); 12204 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12205 12206 ins_cost(700); // smaller than the next version 12207 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12208 12209 ins_encode %{ 12210 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12211 if (InlineSecondarySupersTest) { 12212 __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12213 $temp3$$Register, $temp4$$Register, $result$$Register, 12214 super_klass_slot); 12215 } else { 12216 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12217 } 12218 %} 12219 12220 ins_pipe(pipe_slow); 12221 %} 12222 12223 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12224 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12225 immP0 zero, 12226 rdi_RegP result) 12227 %{ 12228 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12229 effect(KILL rcx, KILL result); 12230 12231 ins_cost(1000); 12232 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12233 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12234 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12235 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12236 "jne,s miss\t\t# Missed: flags nz\n\t" 12237 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12238 "miss:\t" %} 12239 12240 opcode(0x0); // No need to XOR RDI 12241 ins_encode(enc_PartialSubtypeCheck()); 12242 ins_pipe(pipe_slow); 12243 %} 12244 12245 // ============================================================================ 12246 // Branch Instructions -- short offset versions 12247 // 12248 // These instructions are used to replace jumps of a long offset (the default 12249 // match) with jumps of a shorter offset. These instructions are all tagged 12250 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12251 // match rules in general matching. Instead, the ADLC generates a conversion 12252 // method in the MachNode which can be used to do in-place replacement of the 12253 // long variant with the shorter variant. The compiler will determine if a 12254 // branch can be taken by the is_short_branch_offset() predicate in the machine 12255 // specific code section of the file. 12256 12257 // Jump Direct - Label defines a relative address from JMP+1 12258 instruct jmpDir_short(label labl) %{ 12259 match(Goto); 12260 effect(USE labl); 12261 12262 ins_cost(300); 12263 format %{ "jmp,s $labl" %} 12264 size(2); 12265 ins_encode %{ 12266 Label* L = $labl$$label; 12267 __ jmpb(*L); 12268 %} 12269 ins_pipe(pipe_jmp); 12270 ins_short_branch(1); 12271 %} 12272 12273 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12274 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12275 match(If cop cr); 12276 effect(USE labl); 12277 12278 ins_cost(300); 12279 format %{ "j$cop,s $labl" %} 12280 size(2); 12281 ins_encode %{ 12282 Label* L = $labl$$label; 12283 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12284 %} 12285 ins_pipe(pipe_jcc); 12286 ins_short_branch(1); 12287 %} 12288 12289 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12290 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12291 match(CountedLoopEnd cop cr); 12292 effect(USE labl); 12293 12294 ins_cost(300); 12295 format %{ "j$cop,s $labl\t# loop end" %} 12296 size(2); 12297 ins_encode %{ 12298 Label* L = $labl$$label; 12299 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12300 %} 12301 ins_pipe(pipe_jcc); 12302 ins_short_branch(1); 12303 %} 12304 12305 // Jump Direct Conditional - using unsigned comparison 12306 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12307 match(If cop cmp); 12308 effect(USE labl); 12309 12310 ins_cost(300); 12311 format %{ "j$cop,us $labl" %} 12312 size(2); 12313 ins_encode %{ 12314 Label* L = $labl$$label; 12315 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12316 %} 12317 ins_pipe(pipe_jcc); 12318 ins_short_branch(1); 12319 %} 12320 12321 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12322 match(If cop cmp); 12323 effect(USE labl); 12324 12325 ins_cost(300); 12326 format %{ "j$cop,us $labl" %} 12327 size(2); 12328 ins_encode %{ 12329 Label* L = $labl$$label; 12330 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12331 %} 12332 ins_pipe(pipe_jcc); 12333 ins_short_branch(1); 12334 %} 12335 12336 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12337 match(If cop cmp); 12338 effect(USE labl); 12339 12340 ins_cost(300); 12341 format %{ $$template 12342 if ($cop$$cmpcode == Assembler::notEqual) { 12343 $$emit$$"jp,u,s $labl\n\t" 12344 $$emit$$"j$cop,u,s $labl" 12345 } else { 12346 $$emit$$"jp,u,s done\n\t" 12347 $$emit$$"j$cop,u,s $labl\n\t" 12348 $$emit$$"done:" 12349 } 12350 %} 12351 size(4); 12352 ins_encode %{ 12353 Label* l = $labl$$label; 12354 if ($cop$$cmpcode == Assembler::notEqual) { 12355 __ jccb(Assembler::parity, *l); 12356 __ jccb(Assembler::notEqual, *l); 12357 } else if ($cop$$cmpcode == Assembler::equal) { 12358 Label done; 12359 __ jccb(Assembler::parity, done); 12360 __ jccb(Assembler::equal, *l); 12361 __ bind(done); 12362 } else { 12363 ShouldNotReachHere(); 12364 } 12365 %} 12366 ins_pipe(pipe_jcc); 12367 ins_short_branch(1); 12368 %} 12369 12370 // ============================================================================ 12371 // inlined locking and unlocking 12372 12373 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12374 predicate(LockingMode != LM_LIGHTWEIGHT); 12375 match(Set cr (FastLock object box)); 12376 effect(TEMP tmp, TEMP scr, USE_KILL box); 12377 ins_cost(300); 12378 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12379 ins_encode %{ 12380 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12381 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12382 %} 12383 ins_pipe(pipe_slow); 12384 %} 12385 12386 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12387 predicate(LockingMode != LM_LIGHTWEIGHT); 12388 match(Set cr (FastUnlock object box)); 12389 effect(TEMP tmp, USE_KILL box); 12390 ins_cost(300); 12391 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12392 ins_encode %{ 12393 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12394 %} 12395 ins_pipe(pipe_slow); 12396 %} 12397 12398 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12399 predicate(LockingMode == LM_LIGHTWEIGHT); 12400 match(Set cr (FastLock object box)); 12401 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12402 ins_cost(300); 12403 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12404 ins_encode %{ 12405 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12406 %} 12407 ins_pipe(pipe_slow); 12408 %} 12409 12410 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12411 predicate(LockingMode == LM_LIGHTWEIGHT); 12412 match(Set cr (FastUnlock object rax_reg)); 12413 effect(TEMP tmp, USE_KILL rax_reg); 12414 ins_cost(300); 12415 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12416 ins_encode %{ 12417 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12418 %} 12419 ins_pipe(pipe_slow); 12420 %} 12421 12422 12423 // ============================================================================ 12424 // Safepoint Instructions 12425 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12426 %{ 12427 match(SafePoint poll); 12428 effect(KILL cr, USE poll); 12429 12430 format %{ "testl rax, [$poll]\t" 12431 "# Safepoint: poll for GC" %} 12432 ins_cost(125); 12433 ins_encode %{ 12434 __ relocate(relocInfo::poll_type); 12435 address pre_pc = __ pc(); 12436 __ testl(rax, Address($poll$$Register, 0)); 12437 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12438 %} 12439 ins_pipe(ialu_reg_mem); 12440 %} 12441 12442 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12443 match(Set dst (MaskAll src)); 12444 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12445 ins_encode %{ 12446 int mask_len = Matcher::vector_length(this); 12447 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12448 %} 12449 ins_pipe( pipe_slow ); 12450 %} 12451 12452 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12453 predicate(Matcher::vector_length(n) > 32); 12454 match(Set dst (MaskAll src)); 12455 effect(TEMP tmp); 12456 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12457 ins_encode %{ 12458 int mask_len = Matcher::vector_length(this); 12459 __ movslq($tmp$$Register, $src$$Register); 12460 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12461 %} 12462 ins_pipe( pipe_slow ); 12463 %} 12464 12465 // ============================================================================ 12466 // Procedure Call/Return Instructions 12467 // Call Java Static Instruction 12468 // Note: If this code changes, the corresponding ret_addr_offset() and 12469 // compute_padding() functions will have to be adjusted. 12470 instruct CallStaticJavaDirect(method meth) %{ 12471 match(CallStaticJava); 12472 effect(USE meth); 12473 12474 ins_cost(300); 12475 format %{ "call,static " %} 12476 opcode(0xE8); /* E8 cd */ 12477 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12478 ins_pipe(pipe_slow); 12479 ins_alignment(4); 12480 %} 12481 12482 // Call Java Dynamic Instruction 12483 // Note: If this code changes, the corresponding ret_addr_offset() and 12484 // compute_padding() functions will have to be adjusted. 12485 instruct CallDynamicJavaDirect(method meth) 12486 %{ 12487 match(CallDynamicJava); 12488 effect(USE meth); 12489 12490 ins_cost(300); 12491 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12492 "call,dynamic " %} 12493 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12494 ins_pipe(pipe_slow); 12495 ins_alignment(4); 12496 %} 12497 12498 // Call Runtime Instruction 12499 instruct CallRuntimeDirect(method meth) 12500 %{ 12501 match(CallRuntime); 12502 effect(USE meth); 12503 12504 ins_cost(300); 12505 format %{ "call,runtime " %} 12506 ins_encode(clear_avx, Java_To_Runtime(meth)); 12507 ins_pipe(pipe_slow); 12508 %} 12509 12510 // Call runtime without safepoint 12511 instruct CallLeafDirect(method meth) 12512 %{ 12513 match(CallLeaf); 12514 effect(USE meth); 12515 12516 ins_cost(300); 12517 format %{ "call_leaf,runtime " %} 12518 ins_encode(clear_avx, Java_To_Runtime(meth)); 12519 ins_pipe(pipe_slow); 12520 %} 12521 12522 // Call runtime without safepoint and with vector arguments 12523 instruct CallLeafDirectVector(method meth) 12524 %{ 12525 match(CallLeafVector); 12526 effect(USE meth); 12527 12528 ins_cost(300); 12529 format %{ "call_leaf,vector " %} 12530 ins_encode(Java_To_Runtime(meth)); 12531 ins_pipe(pipe_slow); 12532 %} 12533 12534 // Call runtime without safepoint 12535 instruct CallLeafNoFPDirect(method meth) 12536 %{ 12537 match(CallLeafNoFP); 12538 effect(USE meth); 12539 12540 ins_cost(300); 12541 format %{ "call_leaf_nofp,runtime " %} 12542 ins_encode(clear_avx, Java_To_Runtime(meth)); 12543 ins_pipe(pipe_slow); 12544 %} 12545 12546 // Return Instruction 12547 // Remove the return address & jump to it. 12548 // Notice: We always emit a nop after a ret to make sure there is room 12549 // for safepoint patching 12550 instruct Ret() 12551 %{ 12552 match(Return); 12553 12554 format %{ "ret" %} 12555 ins_encode %{ 12556 __ ret(0); 12557 %} 12558 ins_pipe(pipe_jmp); 12559 %} 12560 12561 // Tail Call; Jump from runtime stub to Java code. 12562 // Also known as an 'interprocedural jump'. 12563 // Target of jump will eventually return to caller. 12564 // TailJump below removes the return address. 12565 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12566 // emitted just above the TailCall which has reset rbp to the caller state. 12567 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12568 %{ 12569 match(TailCall jump_target method_ptr); 12570 12571 ins_cost(300); 12572 format %{ "jmp $jump_target\t# rbx holds method" %} 12573 ins_encode %{ 12574 __ jmp($jump_target$$Register); 12575 %} 12576 ins_pipe(pipe_jmp); 12577 %} 12578 12579 // Tail Jump; remove the return address; jump to target. 12580 // TailCall above leaves the return address around. 12581 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12582 %{ 12583 match(TailJump jump_target ex_oop); 12584 12585 ins_cost(300); 12586 format %{ "popq rdx\t# pop return address\n\t" 12587 "jmp $jump_target" %} 12588 ins_encode %{ 12589 __ popq(as_Register(RDX_enc)); 12590 __ jmp($jump_target$$Register); 12591 %} 12592 ins_pipe(pipe_jmp); 12593 %} 12594 12595 // Create exception oop: created by stack-crawling runtime code. 12596 // Created exception is now available to this handler, and is setup 12597 // just prior to jumping to this handler. No code emitted. 12598 instruct CreateException(rax_RegP ex_oop) 12599 %{ 12600 match(Set ex_oop (CreateEx)); 12601 12602 size(0); 12603 // use the following format syntax 12604 format %{ "# exception oop is in rax; no code emitted" %} 12605 ins_encode(); 12606 ins_pipe(empty); 12607 %} 12608 12609 // Rethrow exception: 12610 // The exception oop will come in the first argument position. 12611 // Then JUMP (not call) to the rethrow stub code. 12612 instruct RethrowException() 12613 %{ 12614 match(Rethrow); 12615 12616 // use the following format syntax 12617 format %{ "jmp rethrow_stub" %} 12618 ins_encode %{ 12619 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12620 %} 12621 ins_pipe(pipe_jmp); 12622 %} 12623 12624 // ============================================================================ 12625 // This name is KNOWN by the ADLC and cannot be changed. 12626 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12627 // for this guy. 12628 instruct tlsLoadP(r15_RegP dst) %{ 12629 match(Set dst (ThreadLocal)); 12630 effect(DEF dst); 12631 12632 size(0); 12633 format %{ "# TLS is in R15" %} 12634 ins_encode( /*empty encoding*/ ); 12635 ins_pipe(ialu_reg_reg); 12636 %} 12637 12638 12639 //----------PEEPHOLE RULES----------------------------------------------------- 12640 // These must follow all instruction definitions as they use the names 12641 // defined in the instructions definitions. 12642 // 12643 // peeppredicate ( rule_predicate ); 12644 // // the predicate unless which the peephole rule will be ignored 12645 // 12646 // peepmatch ( root_instr_name [preceding_instruction]* ); 12647 // 12648 // peepprocedure ( procedure_name ); 12649 // // provide a procedure name to perform the optimization, the procedure should 12650 // // reside in the architecture dependent peephole file, the method has the 12651 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12652 // // with the arguments being the basic block, the current node index inside the 12653 // // block, the register allocator, the functions upon invoked return a new node 12654 // // defined in peepreplace, and the rules of the nodes appearing in the 12655 // // corresponding peepmatch, the function return true if successful, else 12656 // // return false 12657 // 12658 // peepconstraint %{ 12659 // (instruction_number.operand_name relational_op instruction_number.operand_name 12660 // [, ...] ); 12661 // // instruction numbers are zero-based using left to right order in peepmatch 12662 // 12663 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12664 // // provide an instruction_number.operand_name for each operand that appears 12665 // // in the replacement instruction's match rule 12666 // 12667 // ---------VM FLAGS--------------------------------------------------------- 12668 // 12669 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12670 // 12671 // Each peephole rule is given an identifying number starting with zero and 12672 // increasing by one in the order seen by the parser. An individual peephole 12673 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12674 // on the command-line. 12675 // 12676 // ---------CURRENT LIMITATIONS---------------------------------------------- 12677 // 12678 // Only transformations inside a basic block (do we need more for peephole) 12679 // 12680 // ---------EXAMPLE---------------------------------------------------------- 12681 // 12682 // // pertinent parts of existing instructions in architecture description 12683 // instruct movI(rRegI dst, rRegI src) 12684 // %{ 12685 // match(Set dst (CopyI src)); 12686 // %} 12687 // 12688 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12689 // %{ 12690 // match(Set dst (AddI dst src)); 12691 // effect(KILL cr); 12692 // %} 12693 // 12694 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12695 // %{ 12696 // match(Set dst (AddI dst src)); 12697 // %} 12698 // 12699 // 1. Simple replacement 12700 // - Only match adjacent instructions in same basic block 12701 // - Only equality constraints 12702 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12703 // - Only one replacement instruction 12704 // 12705 // // Change (inc mov) to lea 12706 // peephole %{ 12707 // // lea should only be emitted when beneficial 12708 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12709 // // increment preceded by register-register move 12710 // peepmatch ( incI_rReg movI ); 12711 // // require that the destination register of the increment 12712 // // match the destination register of the move 12713 // peepconstraint ( 0.dst == 1.dst ); 12714 // // construct a replacement instruction that sets 12715 // // the destination to ( move's source register + one ) 12716 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12717 // %} 12718 // 12719 // 2. Procedural replacement 12720 // - More flexible finding relevent nodes 12721 // - More flexible constraints 12722 // - More flexible transformations 12723 // - May utilise architecture-dependent API more effectively 12724 // - Currently only one replacement instruction due to adlc parsing capabilities 12725 // 12726 // // Change (inc mov) to lea 12727 // peephole %{ 12728 // // lea should only be emitted when beneficial 12729 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12730 // // the rule numbers of these nodes inside are passed into the function below 12731 // peepmatch ( incI_rReg movI ); 12732 // // the method that takes the responsibility of transformation 12733 // peepprocedure ( inc_mov_to_lea ); 12734 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12735 // // node is passed into the function above 12736 // peepreplace ( leaI_rReg_immI() ); 12737 // %} 12738 12739 // These instructions is not matched by the matcher but used by the peephole 12740 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12741 %{ 12742 predicate(false); 12743 match(Set dst (AddI src1 src2)); 12744 format %{ "leal $dst, [$src1 + $src2]" %} 12745 ins_encode %{ 12746 Register dst = $dst$$Register; 12747 Register src1 = $src1$$Register; 12748 Register src2 = $src2$$Register; 12749 if (src1 != rbp && src1 != r13) { 12750 __ leal(dst, Address(src1, src2, Address::times_1)); 12751 } else { 12752 assert(src2 != rbp && src2 != r13, ""); 12753 __ leal(dst, Address(src2, src1, Address::times_1)); 12754 } 12755 %} 12756 ins_pipe(ialu_reg_reg); 12757 %} 12758 12759 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 12760 %{ 12761 predicate(false); 12762 match(Set dst (AddI src1 src2)); 12763 format %{ "leal $dst, [$src1 + $src2]" %} 12764 ins_encode %{ 12765 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 12766 %} 12767 ins_pipe(ialu_reg_reg); 12768 %} 12769 12770 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 12771 %{ 12772 predicate(false); 12773 match(Set dst (LShiftI src shift)); 12774 format %{ "leal $dst, [$src << $shift]" %} 12775 ins_encode %{ 12776 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12777 Register src = $src$$Register; 12778 if (scale == Address::times_2 && src != rbp && src != r13) { 12779 __ leal($dst$$Register, Address(src, src, Address::times_1)); 12780 } else { 12781 __ leal($dst$$Register, Address(noreg, src, scale)); 12782 } 12783 %} 12784 ins_pipe(ialu_reg_reg); 12785 %} 12786 12787 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 12788 %{ 12789 predicate(false); 12790 match(Set dst (AddL src1 src2)); 12791 format %{ "leaq $dst, [$src1 + $src2]" %} 12792 ins_encode %{ 12793 Register dst = $dst$$Register; 12794 Register src1 = $src1$$Register; 12795 Register src2 = $src2$$Register; 12796 if (src1 != rbp && src1 != r13) { 12797 __ leaq(dst, Address(src1, src2, Address::times_1)); 12798 } else { 12799 assert(src2 != rbp && src2 != r13, ""); 12800 __ leaq(dst, Address(src2, src1, Address::times_1)); 12801 } 12802 %} 12803 ins_pipe(ialu_reg_reg); 12804 %} 12805 12806 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 12807 %{ 12808 predicate(false); 12809 match(Set dst (AddL src1 src2)); 12810 format %{ "leaq $dst, [$src1 + $src2]" %} 12811 ins_encode %{ 12812 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 12813 %} 12814 ins_pipe(ialu_reg_reg); 12815 %} 12816 12817 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 12818 %{ 12819 predicate(false); 12820 match(Set dst (LShiftL src shift)); 12821 format %{ "leaq $dst, [$src << $shift]" %} 12822 ins_encode %{ 12823 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12824 Register src = $src$$Register; 12825 if (scale == Address::times_2 && src != rbp && src != r13) { 12826 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 12827 } else { 12828 __ leaq($dst$$Register, Address(noreg, src, scale)); 12829 } 12830 %} 12831 ins_pipe(ialu_reg_reg); 12832 %} 12833 12834 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 12835 // sal}) with lea instructions. The {add, sal} rules are beneficial in 12836 // processors with at least partial ALU support for lea 12837 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 12838 // beneficial for processors with full ALU support 12839 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 12840 12841 peephole 12842 %{ 12843 peeppredicate(VM_Version::supports_fast_2op_lea()); 12844 peepmatch (addI_rReg); 12845 peepprocedure (lea_coalesce_reg); 12846 peepreplace (leaI_rReg_rReg_peep()); 12847 %} 12848 12849 peephole 12850 %{ 12851 peeppredicate(VM_Version::supports_fast_2op_lea()); 12852 peepmatch (addI_rReg_imm); 12853 peepprocedure (lea_coalesce_imm); 12854 peepreplace (leaI_rReg_immI_peep()); 12855 %} 12856 12857 peephole 12858 %{ 12859 peeppredicate(VM_Version::supports_fast_3op_lea() || 12860 VM_Version::is_intel_cascade_lake()); 12861 peepmatch (incI_rReg); 12862 peepprocedure (lea_coalesce_imm); 12863 peepreplace (leaI_rReg_immI_peep()); 12864 %} 12865 12866 peephole 12867 %{ 12868 peeppredicate(VM_Version::supports_fast_3op_lea() || 12869 VM_Version::is_intel_cascade_lake()); 12870 peepmatch (decI_rReg); 12871 peepprocedure (lea_coalesce_imm); 12872 peepreplace (leaI_rReg_immI_peep()); 12873 %} 12874 12875 peephole 12876 %{ 12877 peeppredicate(VM_Version::supports_fast_2op_lea()); 12878 peepmatch (salI_rReg_immI2); 12879 peepprocedure (lea_coalesce_imm); 12880 peepreplace (leaI_rReg_immI2_peep()); 12881 %} 12882 12883 peephole 12884 %{ 12885 peeppredicate(VM_Version::supports_fast_2op_lea()); 12886 peepmatch (addL_rReg); 12887 peepprocedure (lea_coalesce_reg); 12888 peepreplace (leaL_rReg_rReg_peep()); 12889 %} 12890 12891 peephole 12892 %{ 12893 peeppredicate(VM_Version::supports_fast_2op_lea()); 12894 peepmatch (addL_rReg_imm); 12895 peepprocedure (lea_coalesce_imm); 12896 peepreplace (leaL_rReg_immL32_peep()); 12897 %} 12898 12899 peephole 12900 %{ 12901 peeppredicate(VM_Version::supports_fast_3op_lea() || 12902 VM_Version::is_intel_cascade_lake()); 12903 peepmatch (incL_rReg); 12904 peepprocedure (lea_coalesce_imm); 12905 peepreplace (leaL_rReg_immL32_peep()); 12906 %} 12907 12908 peephole 12909 %{ 12910 peeppredicate(VM_Version::supports_fast_3op_lea() || 12911 VM_Version::is_intel_cascade_lake()); 12912 peepmatch (decL_rReg); 12913 peepprocedure (lea_coalesce_imm); 12914 peepreplace (leaL_rReg_immL32_peep()); 12915 %} 12916 12917 peephole 12918 %{ 12919 peeppredicate(VM_Version::supports_fast_2op_lea()); 12920 peepmatch (salL_rReg_immI2); 12921 peepprocedure (lea_coalesce_imm); 12922 peepreplace (leaL_rReg_immI2_peep()); 12923 %} 12924 12925 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 12926 // 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 12927 12928 //int variant 12929 peephole 12930 %{ 12931 peepmatch (testI_reg); 12932 peepprocedure (test_may_remove); 12933 %} 12934 12935 //long variant 12936 peephole 12937 %{ 12938 peepmatch (testL_reg); 12939 peepprocedure (test_may_remove); 12940 %} 12941 12942 12943 //----------SMARTSPILL RULES--------------------------------------------------- 12944 // These must follow all instruction definitions as they use the names 12945 // defined in the instructions definitions.