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