1 // 2 // Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // architecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 reg_def R16 (SOC, SOC, Op_RegI, 16, r16->as_VMReg()); 132 reg_def R16_H(SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 133 134 reg_def R17 (SOC, SOC, Op_RegI, 17, r17->as_VMReg()); 135 reg_def R17_H(SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 136 137 reg_def R18 (SOC, SOC, Op_RegI, 18, r18->as_VMReg()); 138 reg_def R18_H(SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 139 140 reg_def R19 (SOC, SOC, Op_RegI, 19, r19->as_VMReg()); 141 reg_def R19_H(SOC, SOC, Op_RegI, 19, r19->as_VMReg()->next()); 142 143 reg_def R20 (SOC, SOC, Op_RegI, 20, r20->as_VMReg()); 144 reg_def R20_H(SOC, SOC, Op_RegI, 20, r20->as_VMReg()->next()); 145 146 reg_def R21 (SOC, SOC, Op_RegI, 21, r21->as_VMReg()); 147 reg_def R21_H(SOC, SOC, Op_RegI, 21, r21->as_VMReg()->next()); 148 149 reg_def R22 (SOC, SOC, Op_RegI, 22, r22->as_VMReg()); 150 reg_def R22_H(SOC, SOC, Op_RegI, 22, r22->as_VMReg()->next()); 151 152 reg_def R23 (SOC, SOC, Op_RegI, 23, r23->as_VMReg()); 153 reg_def R23_H(SOC, SOC, Op_RegI, 23, r23->as_VMReg()->next()); 154 155 reg_def R24 (SOC, SOC, Op_RegI, 24, r24->as_VMReg()); 156 reg_def R24_H(SOC, SOC, Op_RegI, 24, r24->as_VMReg()->next()); 157 158 reg_def R25 (SOC, SOC, Op_RegI, 25, r25->as_VMReg()); 159 reg_def R25_H(SOC, SOC, Op_RegI, 25, r25->as_VMReg()->next()); 160 161 reg_def R26 (SOC, SOC, Op_RegI, 26, r26->as_VMReg()); 162 reg_def R26_H(SOC, SOC, Op_RegI, 26, r26->as_VMReg()->next()); 163 164 reg_def R27 (SOC, SOC, Op_RegI, 27, r27->as_VMReg()); 165 reg_def R27_H(SOC, SOC, Op_RegI, 27, r27->as_VMReg()->next()); 166 167 reg_def R28 (SOC, SOC, Op_RegI, 28, r28->as_VMReg()); 168 reg_def R28_H(SOC, SOC, Op_RegI, 28, r28->as_VMReg()->next()); 169 170 reg_def R29 (SOC, SOC, Op_RegI, 29, r29->as_VMReg()); 171 reg_def R29_H(SOC, SOC, Op_RegI, 29, r29->as_VMReg()->next()); 172 173 reg_def R30 (SOC, SOC, Op_RegI, 30, r30->as_VMReg()); 174 reg_def R30_H(SOC, SOC, Op_RegI, 30, r30->as_VMReg()->next()); 175 176 reg_def R31 (SOC, SOC, Op_RegI, 31, r31->as_VMReg()); 177 reg_def R31_H(SOC, SOC, Op_RegI, 31, r31->as_VMReg()->next()); 178 179 // Floating Point Registers 180 181 // Specify priority of register selection within phases of register 182 // allocation. Highest priority is first. A useful heuristic is to 183 // give registers a low priority when they are required by machine 184 // instructions, like EAX and EDX on I486, and choose no-save registers 185 // before save-on-call, & save-on-call before save-on-entry. Registers 186 // which participate in fixed calling sequences should come last. 187 // Registers which are used as pairs must fall on an even boundary. 188 189 alloc_class chunk0(R10, R10_H, 190 R11, R11_H, 191 R8, R8_H, 192 R9, R9_H, 193 R12, R12_H, 194 RCX, RCX_H, 195 RBX, RBX_H, 196 RDI, RDI_H, 197 RDX, RDX_H, 198 RSI, RSI_H, 199 RAX, RAX_H, 200 RBP, RBP_H, 201 R13, R13_H, 202 R14, R14_H, 203 R15, R15_H, 204 R16, R16_H, 205 R17, R17_H, 206 R18, R18_H, 207 R19, R19_H, 208 R20, R20_H, 209 R21, R21_H, 210 R22, R22_H, 211 R23, R23_H, 212 R24, R24_H, 213 R25, R25_H, 214 R26, R26_H, 215 R27, R27_H, 216 R28, R28_H, 217 R29, R29_H, 218 R30, R30_H, 219 R31, R31_H, 220 RSP, RSP_H); 221 222 223 //----------Architecture Description Register Classes-------------------------- 224 // Several register classes are automatically defined based upon information in 225 // this architecture description. 226 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 227 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 228 // 229 230 // Empty register class. 231 reg_class no_reg(); 232 233 // Class for all pointer/long registers including APX extended GPRs. 234 reg_class all_reg(RAX, RAX_H, 235 RDX, RDX_H, 236 RBP, RBP_H, 237 RDI, RDI_H, 238 RSI, RSI_H, 239 RCX, RCX_H, 240 RBX, RBX_H, 241 RSP, RSP_H, 242 R8, R8_H, 243 R9, R9_H, 244 R10, R10_H, 245 R11, R11_H, 246 R12, R12_H, 247 R13, R13_H, 248 R14, R14_H, 249 R15, R15_H, 250 R16, R16_H, 251 R17, R17_H, 252 R18, R18_H, 253 R19, R19_H, 254 R20, R20_H, 255 R21, R21_H, 256 R22, R22_H, 257 R23, R23_H, 258 R24, R24_H, 259 R25, R25_H, 260 R26, R26_H, 261 R27, R27_H, 262 R28, R28_H, 263 R29, R29_H, 264 R30, R30_H, 265 R31, R31_H); 266 267 // Class for all int registers including APX extended GPRs. 268 reg_class all_int_reg(RAX 269 RDX, 270 RBP, 271 RDI, 272 RSI, 273 RCX, 274 RBX, 275 R8, 276 R9, 277 R10, 278 R11, 279 R12, 280 R13, 281 R14, 282 R16, 283 R17, 284 R18, 285 R19, 286 R20, 287 R21, 288 R22, 289 R23, 290 R24, 291 R25, 292 R26, 293 R27, 294 R28, 295 R29, 296 R30, 297 R31); 298 299 // Class for all pointer registers 300 reg_class any_reg %{ 301 return _ANY_REG_mask; 302 %} 303 304 // Class for all pointer registers (excluding RSP) 305 reg_class ptr_reg %{ 306 return _PTR_REG_mask; 307 %} 308 309 // Class for all pointer registers (excluding RSP and RBP) 310 reg_class ptr_reg_no_rbp %{ 311 return _PTR_REG_NO_RBP_mask; 312 %} 313 314 // Class for all pointer registers (excluding RAX and RSP) 315 reg_class ptr_no_rax_reg %{ 316 return _PTR_NO_RAX_REG_mask; 317 %} 318 319 // Class for all pointer registers (excluding RAX, RBX, and RSP) 320 reg_class ptr_no_rax_rbx_reg %{ 321 return _PTR_NO_RAX_RBX_REG_mask; 322 %} 323 324 // Class for all long registers (excluding RSP) 325 reg_class long_reg %{ 326 return _LONG_REG_mask; 327 %} 328 329 // Class for all long registers (excluding RAX, RDX and RSP) 330 reg_class long_no_rax_rdx_reg %{ 331 return _LONG_NO_RAX_RDX_REG_mask; 332 %} 333 334 // Class for all long registers (excluding RCX and RSP) 335 reg_class long_no_rcx_reg %{ 336 return _LONG_NO_RCX_REG_mask; 337 %} 338 339 // Class for all long registers (excluding RBP and R13) 340 reg_class long_no_rbp_r13_reg %{ 341 return _LONG_NO_RBP_R13_REG_mask; 342 %} 343 344 // Class for all int registers (excluding RSP) 345 reg_class int_reg %{ 346 return _INT_REG_mask; 347 %} 348 349 // Class for all int registers (excluding RAX, RDX, and RSP) 350 reg_class int_no_rax_rdx_reg %{ 351 return _INT_NO_RAX_RDX_REG_mask; 352 %} 353 354 // Class for all int registers (excluding RCX and RSP) 355 reg_class int_no_rcx_reg %{ 356 return _INT_NO_RCX_REG_mask; 357 %} 358 359 // Class for all int registers (excluding RBP and R13) 360 reg_class int_no_rbp_r13_reg %{ 361 return _INT_NO_RBP_R13_REG_mask; 362 %} 363 364 // Singleton class for RAX pointer register 365 reg_class ptr_rax_reg(RAX, RAX_H); 366 367 // Singleton class for RBX pointer register 368 reg_class ptr_rbx_reg(RBX, RBX_H); 369 370 // Singleton class for RSI pointer register 371 reg_class ptr_rsi_reg(RSI, RSI_H); 372 373 // Singleton class for RBP pointer register 374 reg_class ptr_rbp_reg(RBP, RBP_H); 375 376 // Singleton class for RDI pointer register 377 reg_class ptr_rdi_reg(RDI, RDI_H); 378 379 // Singleton class for stack pointer 380 reg_class ptr_rsp_reg(RSP, RSP_H); 381 382 // Singleton class for TLS pointer 383 reg_class ptr_r15_reg(R15, R15_H); 384 385 // Singleton class for RAX long register 386 reg_class long_rax_reg(RAX, RAX_H); 387 388 // Singleton class for RCX long register 389 reg_class long_rcx_reg(RCX, RCX_H); 390 391 // Singleton class for RDX long register 392 reg_class long_rdx_reg(RDX, RDX_H); 393 394 // Singleton class for R11 long register 395 reg_class long_r11_reg(R11, R11_H); 396 397 // Singleton class for RAX int register 398 reg_class int_rax_reg(RAX); 399 400 // Singleton class for RBX int register 401 reg_class int_rbx_reg(RBX); 402 403 // Singleton class for RCX int register 404 reg_class int_rcx_reg(RCX); 405 406 // Singleton class for RDX int register 407 reg_class int_rdx_reg(RDX); 408 409 // Singleton class for RDI int register 410 reg_class int_rdi_reg(RDI); 411 412 // Singleton class for instruction pointer 413 // reg_class ip_reg(RIP); 414 415 %} 416 417 //----------SOURCE BLOCK------------------------------------------------------- 418 // This is a block of C++ code which provides values, functions, and 419 // definitions necessary in the rest of the architecture description 420 421 source_hpp %{ 422 423 #include "peephole_x86_64.hpp" 424 425 %} 426 427 // Register masks 428 source_hpp %{ 429 430 extern RegMask _ANY_REG_mask; 431 extern RegMask _PTR_REG_mask; 432 extern RegMask _PTR_REG_NO_RBP_mask; 433 extern RegMask _PTR_NO_RAX_REG_mask; 434 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 435 extern RegMask _LONG_REG_mask; 436 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 437 extern RegMask _LONG_NO_RCX_REG_mask; 438 extern RegMask _LONG_NO_RBP_R13_REG_mask; 439 extern RegMask _INT_REG_mask; 440 extern RegMask _INT_NO_RAX_RDX_REG_mask; 441 extern RegMask _INT_NO_RCX_REG_mask; 442 extern RegMask _INT_NO_RBP_R13_REG_mask; 443 extern RegMask _FLOAT_REG_mask; 444 445 extern RegMask _STACK_OR_PTR_REG_mask; 446 extern RegMask _STACK_OR_LONG_REG_mask; 447 extern RegMask _STACK_OR_INT_REG_mask; 448 449 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 450 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 451 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 452 453 %} 454 455 source %{ 456 #define RELOC_IMM64 Assembler::imm_operand 457 #define RELOC_DISP32 Assembler::disp32_operand 458 459 #define __ masm-> 460 461 RegMask _ANY_REG_mask; 462 RegMask _PTR_REG_mask; 463 RegMask _PTR_REG_NO_RBP_mask; 464 RegMask _PTR_NO_RAX_REG_mask; 465 RegMask _PTR_NO_RAX_RBX_REG_mask; 466 RegMask _LONG_REG_mask; 467 RegMask _LONG_NO_RAX_RDX_REG_mask; 468 RegMask _LONG_NO_RCX_REG_mask; 469 RegMask _LONG_NO_RBP_R13_REG_mask; 470 RegMask _INT_REG_mask; 471 RegMask _INT_NO_RAX_RDX_REG_mask; 472 RegMask _INT_NO_RCX_REG_mask; 473 RegMask _INT_NO_RBP_R13_REG_mask; 474 RegMask _FLOAT_REG_mask; 475 RegMask _STACK_OR_PTR_REG_mask; 476 RegMask _STACK_OR_LONG_REG_mask; 477 RegMask _STACK_OR_INT_REG_mask; 478 479 static bool need_r12_heapbase() { 480 return UseCompressedOops; 481 } 482 483 void reg_mask_init() { 484 constexpr Register egprs[] = {r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31}; 485 486 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 487 // We derive a number of subsets from it. 488 _ANY_REG_mask = _ALL_REG_mask; 489 490 if (PreserveFramePointer) { 491 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 492 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 493 } 494 if (need_r12_heapbase()) { 495 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 496 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 497 } 498 499 _PTR_REG_mask = _ANY_REG_mask; 500 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 501 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 502 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 503 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 504 if (!UseAPX) { 505 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 506 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 507 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg()->next())); 508 } 509 } 510 511 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 512 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 513 514 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 515 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 516 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 517 518 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 519 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 520 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 521 522 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 523 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 524 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 525 526 527 _LONG_REG_mask = _PTR_REG_mask; 528 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 529 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 530 531 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 532 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 533 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 534 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 535 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 536 537 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 538 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 539 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 540 541 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 542 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 543 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 544 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 545 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 546 547 _INT_REG_mask = _ALL_INT_REG_mask; 548 if (!UseAPX) { 549 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 550 _INT_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 551 } 552 } 553 554 if (PreserveFramePointer) { 555 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 556 } 557 if (need_r12_heapbase()) { 558 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 559 } 560 561 _STACK_OR_INT_REG_mask = _INT_REG_mask; 562 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 563 564 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 565 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 566 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 567 568 _INT_NO_RCX_REG_mask = _INT_REG_mask; 569 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 570 571 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 572 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 573 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 574 575 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 576 // from the float_reg_legacy/float_reg_evex register class. 577 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 578 } 579 580 static bool generate_vzeroupper(Compile* C) { 581 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 582 } 583 584 static int clear_avx_size() { 585 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 586 } 587 588 // !!!!! Special hack to get all types of calls to specify the byte offset 589 // from the start of the call to the point where the return address 590 // will point. 591 int MachCallStaticJavaNode::ret_addr_offset() 592 { 593 int offset = 5; // 5 bytes from start of call to where return address points 594 offset += clear_avx_size(); 595 return offset; 596 } 597 598 int MachCallDynamicJavaNode::ret_addr_offset() 599 { 600 int offset = 15; // 15 bytes from start of call to where return address points 601 offset += clear_avx_size(); 602 return offset; 603 } 604 605 int MachCallRuntimeNode::ret_addr_offset() { 606 int offset = 13; // movq r10,#addr; callq (r10) 607 if (this->ideal_Opcode() != Op_CallLeafVector) { 608 offset += clear_avx_size(); 609 } 610 return offset; 611 } 612 // 613 // Compute padding required for nodes which need alignment 614 // 615 616 // The address of the call instruction needs to be 4-byte aligned to 617 // ensure that it does not span a cache line so that it can be patched. 618 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 619 { 620 current_offset += clear_avx_size(); // skip vzeroupper 621 current_offset += 1; // skip call opcode byte 622 return align_up(current_offset, alignment_required()) - current_offset; 623 } 624 625 // The address of the call instruction needs to be 4-byte aligned to 626 // ensure that it does not span a cache line so that it can be patched. 627 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 628 { 629 current_offset += clear_avx_size(); // skip vzeroupper 630 current_offset += 11; // skip movq instruction + call opcode byte 631 return align_up(current_offset, alignment_required()) - current_offset; 632 } 633 634 // This could be in MacroAssembler but it's fairly C2 specific 635 static void emit_cmpfp_fixup(MacroAssembler* masm) { 636 Label exit; 637 __ jccb(Assembler::noParity, exit); 638 __ pushf(); 639 // 640 // comiss/ucomiss instructions set ZF,PF,CF flags and 641 // zero OF,AF,SF for NaN values. 642 // Fixup flags by zeroing ZF,PF so that compare of NaN 643 // values returns 'less than' result (CF is set). 644 // Leave the rest of flags unchanged. 645 // 646 // 7 6 5 4 3 2 1 0 647 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 648 // 0 0 1 0 1 0 1 1 (0x2B) 649 // 650 __ andq(Address(rsp, 0), 0xffffff2b); 651 __ popf(); 652 __ bind(exit); 653 } 654 655 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 656 Label done; 657 __ movl(dst, -1); 658 __ jcc(Assembler::parity, done); 659 __ jcc(Assembler::below, done); 660 __ setcc(Assembler::notEqual, dst); 661 __ bind(done); 662 } 663 664 // Math.min() # Math.max() 665 // -------------------------- 666 // ucomis[s/d] # 667 // ja -> b # a 668 // jp -> NaN # NaN 669 // jb -> a # b 670 // je # 671 // |-jz -> a | b # a & b 672 // | -> a # 673 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 674 XMMRegister a, XMMRegister b, 675 XMMRegister xmmt, Register rt, 676 bool min, bool single) { 677 678 Label nan, zero, below, above, done; 679 680 if (single) 681 __ ucomiss(a, b); 682 else 683 __ ucomisd(a, b); 684 685 if (dst->encoding() != (min ? b : a)->encoding()) 686 __ jccb(Assembler::above, above); // CF=0 & ZF=0 687 else 688 __ jccb(Assembler::above, done); 689 690 __ jccb(Assembler::parity, nan); // PF=1 691 __ jccb(Assembler::below, below); // CF=1 692 693 // equal 694 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 695 if (single) { 696 __ ucomiss(a, xmmt); 697 __ jccb(Assembler::equal, zero); 698 699 __ movflt(dst, a); 700 __ jmp(done); 701 } 702 else { 703 __ ucomisd(a, xmmt); 704 __ jccb(Assembler::equal, zero); 705 706 __ movdbl(dst, a); 707 __ jmp(done); 708 } 709 710 __ bind(zero); 711 if (min) 712 __ vpor(dst, a, b, Assembler::AVX_128bit); 713 else 714 __ vpand(dst, a, b, Assembler::AVX_128bit); 715 716 __ jmp(done); 717 718 __ bind(above); 719 if (single) 720 __ movflt(dst, min ? b : a); 721 else 722 __ movdbl(dst, min ? b : a); 723 724 __ jmp(done); 725 726 __ bind(nan); 727 if (single) { 728 __ movl(rt, 0x7fc00000); // Float.NaN 729 __ movdl(dst, rt); 730 } 731 else { 732 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 733 __ movdq(dst, rt); 734 } 735 __ jmp(done); 736 737 __ bind(below); 738 if (single) 739 __ movflt(dst, min ? a : b); 740 else 741 __ movdbl(dst, min ? a : b); 742 743 __ bind(done); 744 } 745 746 //============================================================================= 747 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 748 749 int ConstantTable::calculate_table_base_offset() const { 750 return 0; // absolute addressing, no offset 751 } 752 753 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 754 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 755 ShouldNotReachHere(); 756 } 757 758 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 759 // Empty encoding 760 } 761 762 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 763 return 0; 764 } 765 766 #ifndef PRODUCT 767 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 768 st->print("# MachConstantBaseNode (empty encoding)"); 769 } 770 #endif 771 772 773 //============================================================================= 774 #ifndef PRODUCT 775 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 776 Compile* C = ra_->C; 777 778 int framesize = C->output()->frame_size_in_bytes(); 779 int bangsize = C->output()->bang_size_in_bytes(); 780 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 781 // Remove wordSize for return addr which is already pushed. 782 framesize -= wordSize; 783 784 if (C->output()->need_stack_bang(bangsize)) { 785 framesize -= wordSize; 786 st->print("# stack bang (%d bytes)", bangsize); 787 st->print("\n\t"); 788 st->print("pushq rbp\t# Save rbp"); 789 if (PreserveFramePointer) { 790 st->print("\n\t"); 791 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 792 } 793 if (framesize) { 794 st->print("\n\t"); 795 st->print("subq rsp, #%d\t# Create frame",framesize); 796 } 797 } else { 798 st->print("subq rsp, #%d\t# Create frame",framesize); 799 st->print("\n\t"); 800 framesize -= wordSize; 801 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 802 if (PreserveFramePointer) { 803 st->print("\n\t"); 804 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 805 if (framesize > 0) { 806 st->print("\n\t"); 807 st->print("addq rbp, #%d", framesize); 808 } 809 } 810 } 811 812 if (VerifyStackAtCalls) { 813 st->print("\n\t"); 814 framesize -= wordSize; 815 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 816 #ifdef ASSERT 817 st->print("\n\t"); 818 st->print("# stack alignment check"); 819 #endif 820 } 821 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 822 st->print("\n\t"); 823 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 824 st->print("\n\t"); 825 st->print("je fast_entry\t"); 826 st->print("\n\t"); 827 st->print("call #nmethod_entry_barrier_stub\t"); 828 st->print("\n\tfast_entry:"); 829 } 830 st->cr(); 831 } 832 #endif 833 834 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 835 Compile* C = ra_->C; 836 837 int framesize = C->output()->frame_size_in_bytes(); 838 int bangsize = C->output()->bang_size_in_bytes(); 839 840 if (C->clinit_barrier_on_entry()) { 841 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 842 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 843 844 Label L_skip_barrier; 845 Register klass = rscratch1; 846 847 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 848 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 849 850 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 851 852 __ bind(L_skip_barrier); 853 } 854 855 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 856 857 C->output()->set_frame_complete(__ offset()); 858 859 if (C->has_mach_constant_base_node()) { 860 // NOTE: We set the table base offset here because users might be 861 // emitted before MachConstantBaseNode. 862 ConstantTable& constant_table = C->output()->constant_table(); 863 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 864 } 865 } 866 867 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 868 { 869 return MachNode::size(ra_); // too many variables; just compute it 870 // the hard way 871 } 872 873 int MachPrologNode::reloc() const 874 { 875 return 0; // a large enough number 876 } 877 878 //============================================================================= 879 #ifndef PRODUCT 880 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 881 { 882 Compile* C = ra_->C; 883 if (generate_vzeroupper(C)) { 884 st->print("vzeroupper"); 885 st->cr(); st->print("\t"); 886 } 887 888 int framesize = C->output()->frame_size_in_bytes(); 889 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 890 // Remove word for return adr already pushed 891 // and RBP 892 framesize -= 2*wordSize; 893 894 if (framesize) { 895 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 896 st->print("\t"); 897 } 898 899 st->print_cr("popq rbp"); 900 if (do_polling() && C->is_method_compilation()) { 901 st->print("\t"); 902 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 903 "ja #safepoint_stub\t" 904 "# Safepoint: poll for GC"); 905 } 906 } 907 #endif 908 909 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 910 { 911 Compile* C = ra_->C; 912 913 if (generate_vzeroupper(C)) { 914 // Clear upper bits of YMM registers when current compiled code uses 915 // wide vectors to avoid AVX <-> SSE transition penalty during call. 916 __ vzeroupper(); 917 } 918 919 int framesize = C->output()->frame_size_in_bytes(); 920 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 921 // Remove word for return adr already pushed 922 // and RBP 923 framesize -= 2*wordSize; 924 925 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 926 927 if (framesize) { 928 __ addq(rsp, framesize); 929 } 930 931 __ popq(rbp); 932 933 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 934 __ reserved_stack_check(); 935 } 936 937 if (do_polling() && C->is_method_compilation()) { 938 Label dummy_label; 939 Label* code_stub = &dummy_label; 940 if (!C->output()->in_scratch_emit_size()) { 941 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 942 C->output()->add_stub(stub); 943 code_stub = &stub->entry(); 944 } 945 __ relocate(relocInfo::poll_return_type); 946 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 947 } 948 } 949 950 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 951 { 952 return MachNode::size(ra_); // too many variables; just compute it 953 // the hard way 954 } 955 956 int MachEpilogNode::reloc() const 957 { 958 return 2; // a large enough number 959 } 960 961 const Pipeline* MachEpilogNode::pipeline() const 962 { 963 return MachNode::pipeline_class(); 964 } 965 966 //============================================================================= 967 968 enum RC { 969 rc_bad, 970 rc_int, 971 rc_kreg, 972 rc_float, 973 rc_stack 974 }; 975 976 static enum RC rc_class(OptoReg::Name reg) 977 { 978 if( !OptoReg::is_valid(reg) ) return rc_bad; 979 980 if (OptoReg::is_stack(reg)) return rc_stack; 981 982 VMReg r = OptoReg::as_VMReg(reg); 983 984 if (r->is_Register()) return rc_int; 985 986 if (r->is_KRegister()) return rc_kreg; 987 988 assert(r->is_XMMRegister(), "must be"); 989 return rc_float; 990 } 991 992 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 993 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 994 int src_hi, int dst_hi, uint ireg, outputStream* st); 995 996 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 997 int stack_offset, int reg, uint ireg, outputStream* st); 998 999 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 1000 int dst_offset, uint ireg, outputStream* st) { 1001 if (masm) { 1002 switch (ireg) { 1003 case Op_VecS: 1004 __ movq(Address(rsp, -8), rax); 1005 __ movl(rax, Address(rsp, src_offset)); 1006 __ movl(Address(rsp, dst_offset), rax); 1007 __ movq(rax, Address(rsp, -8)); 1008 break; 1009 case Op_VecD: 1010 __ pushq(Address(rsp, src_offset)); 1011 __ popq (Address(rsp, dst_offset)); 1012 break; 1013 case Op_VecX: 1014 __ pushq(Address(rsp, src_offset)); 1015 __ popq (Address(rsp, dst_offset)); 1016 __ pushq(Address(rsp, src_offset+8)); 1017 __ popq (Address(rsp, dst_offset+8)); 1018 break; 1019 case Op_VecY: 1020 __ vmovdqu(Address(rsp, -32), xmm0); 1021 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1022 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1023 __ vmovdqu(xmm0, Address(rsp, -32)); 1024 break; 1025 case Op_VecZ: 1026 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1027 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1028 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1029 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1030 break; 1031 default: 1032 ShouldNotReachHere(); 1033 } 1034 #ifndef PRODUCT 1035 } else { 1036 switch (ireg) { 1037 case Op_VecS: 1038 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1039 "movl rax, [rsp + #%d]\n\t" 1040 "movl [rsp + #%d], rax\n\t" 1041 "movq rax, [rsp - #8]", 1042 src_offset, dst_offset); 1043 break; 1044 case Op_VecD: 1045 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1046 "popq [rsp + #%d]", 1047 src_offset, dst_offset); 1048 break; 1049 case Op_VecX: 1050 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1051 "popq [rsp + #%d]\n\t" 1052 "pushq [rsp + #%d]\n\t" 1053 "popq [rsp + #%d]", 1054 src_offset, dst_offset, src_offset+8, dst_offset+8); 1055 break; 1056 case Op_VecY: 1057 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1058 "vmovdqu xmm0, [rsp + #%d]\n\t" 1059 "vmovdqu [rsp + #%d], xmm0\n\t" 1060 "vmovdqu xmm0, [rsp - #32]", 1061 src_offset, dst_offset); 1062 break; 1063 case Op_VecZ: 1064 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1065 "vmovdqu xmm0, [rsp + #%d]\n\t" 1066 "vmovdqu [rsp + #%d], xmm0\n\t" 1067 "vmovdqu xmm0, [rsp - #64]", 1068 src_offset, dst_offset); 1069 break; 1070 default: 1071 ShouldNotReachHere(); 1072 } 1073 #endif 1074 } 1075 } 1076 1077 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1078 PhaseRegAlloc* ra_, 1079 bool do_size, 1080 outputStream* st) const { 1081 assert(masm != nullptr || st != nullptr, "sanity"); 1082 // Get registers to move 1083 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1084 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1085 OptoReg::Name dst_second = ra_->get_reg_second(this); 1086 OptoReg::Name dst_first = ra_->get_reg_first(this); 1087 1088 enum RC src_second_rc = rc_class(src_second); 1089 enum RC src_first_rc = rc_class(src_first); 1090 enum RC dst_second_rc = rc_class(dst_second); 1091 enum RC dst_first_rc = rc_class(dst_first); 1092 1093 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1094 "must move at least 1 register" ); 1095 1096 if (src_first == dst_first && src_second == dst_second) { 1097 // Self copy, no move 1098 return 0; 1099 } 1100 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1101 uint ireg = ideal_reg(); 1102 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1103 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1104 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1105 // mem -> mem 1106 int src_offset = ra_->reg2offset(src_first); 1107 int dst_offset = ra_->reg2offset(dst_first); 1108 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1109 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1110 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1111 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1112 int stack_offset = ra_->reg2offset(dst_first); 1113 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1114 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1115 int stack_offset = ra_->reg2offset(src_first); 1116 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1117 } else { 1118 ShouldNotReachHere(); 1119 } 1120 return 0; 1121 } 1122 if (src_first_rc == rc_stack) { 1123 // mem -> 1124 if (dst_first_rc == rc_stack) { 1125 // mem -> mem 1126 assert(src_second != dst_first, "overlap"); 1127 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1128 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1129 // 64-bit 1130 int src_offset = ra_->reg2offset(src_first); 1131 int dst_offset = ra_->reg2offset(dst_first); 1132 if (masm) { 1133 __ pushq(Address(rsp, src_offset)); 1134 __ popq (Address(rsp, dst_offset)); 1135 #ifndef PRODUCT 1136 } else { 1137 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1138 "popq [rsp + #%d]", 1139 src_offset, dst_offset); 1140 #endif 1141 } 1142 } else { 1143 // 32-bit 1144 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1145 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1146 // No pushl/popl, so: 1147 int src_offset = ra_->reg2offset(src_first); 1148 int dst_offset = ra_->reg2offset(dst_first); 1149 if (masm) { 1150 __ movq(Address(rsp, -8), rax); 1151 __ movl(rax, Address(rsp, src_offset)); 1152 __ movl(Address(rsp, dst_offset), rax); 1153 __ movq(rax, Address(rsp, -8)); 1154 #ifndef PRODUCT 1155 } else { 1156 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1157 "movl rax, [rsp + #%d]\n\t" 1158 "movl [rsp + #%d], rax\n\t" 1159 "movq rax, [rsp - #8]", 1160 src_offset, dst_offset); 1161 #endif 1162 } 1163 } 1164 return 0; 1165 } else if (dst_first_rc == rc_int) { 1166 // mem -> gpr 1167 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1168 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1169 // 64-bit 1170 int offset = ra_->reg2offset(src_first); 1171 if (masm) { 1172 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1173 #ifndef PRODUCT 1174 } else { 1175 st->print("movq %s, [rsp + #%d]\t# spill", 1176 Matcher::regName[dst_first], 1177 offset); 1178 #endif 1179 } 1180 } else { 1181 // 32-bit 1182 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1183 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1184 int offset = ra_->reg2offset(src_first); 1185 if (masm) { 1186 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1187 #ifndef PRODUCT 1188 } else { 1189 st->print("movl %s, [rsp + #%d]\t# spill", 1190 Matcher::regName[dst_first], 1191 offset); 1192 #endif 1193 } 1194 } 1195 return 0; 1196 } else if (dst_first_rc == rc_float) { 1197 // mem-> xmm 1198 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1199 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1200 // 64-bit 1201 int offset = ra_->reg2offset(src_first); 1202 if (masm) { 1203 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1204 #ifndef PRODUCT 1205 } else { 1206 st->print("%s %s, [rsp + #%d]\t# spill", 1207 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1208 Matcher::regName[dst_first], 1209 offset); 1210 #endif 1211 } 1212 } else { 1213 // 32-bit 1214 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1215 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1216 int offset = ra_->reg2offset(src_first); 1217 if (masm) { 1218 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1219 #ifndef PRODUCT 1220 } else { 1221 st->print("movss %s, [rsp + #%d]\t# spill", 1222 Matcher::regName[dst_first], 1223 offset); 1224 #endif 1225 } 1226 } 1227 return 0; 1228 } else if (dst_first_rc == rc_kreg) { 1229 // mem -> kreg 1230 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1231 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1232 // 64-bit 1233 int offset = ra_->reg2offset(src_first); 1234 if (masm) { 1235 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1236 #ifndef PRODUCT 1237 } else { 1238 st->print("kmovq %s, [rsp + #%d]\t# spill", 1239 Matcher::regName[dst_first], 1240 offset); 1241 #endif 1242 } 1243 } 1244 return 0; 1245 } 1246 } else if (src_first_rc == rc_int) { 1247 // gpr -> 1248 if (dst_first_rc == rc_stack) { 1249 // gpr -> mem 1250 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1251 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1252 // 64-bit 1253 int offset = ra_->reg2offset(dst_first); 1254 if (masm) { 1255 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1256 #ifndef PRODUCT 1257 } else { 1258 st->print("movq [rsp + #%d], %s\t# spill", 1259 offset, 1260 Matcher::regName[src_first]); 1261 #endif 1262 } 1263 } else { 1264 // 32-bit 1265 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1266 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1267 int offset = ra_->reg2offset(dst_first); 1268 if (masm) { 1269 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1270 #ifndef PRODUCT 1271 } else { 1272 st->print("movl [rsp + #%d], %s\t# spill", 1273 offset, 1274 Matcher::regName[src_first]); 1275 #endif 1276 } 1277 } 1278 return 0; 1279 } else if (dst_first_rc == rc_int) { 1280 // gpr -> gpr 1281 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1282 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1283 // 64-bit 1284 if (masm) { 1285 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1286 as_Register(Matcher::_regEncode[src_first])); 1287 #ifndef PRODUCT 1288 } else { 1289 st->print("movq %s, %s\t# spill", 1290 Matcher::regName[dst_first], 1291 Matcher::regName[src_first]); 1292 #endif 1293 } 1294 return 0; 1295 } else { 1296 // 32-bit 1297 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1298 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1299 if (masm) { 1300 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1301 as_Register(Matcher::_regEncode[src_first])); 1302 #ifndef PRODUCT 1303 } else { 1304 st->print("movl %s, %s\t# spill", 1305 Matcher::regName[dst_first], 1306 Matcher::regName[src_first]); 1307 #endif 1308 } 1309 return 0; 1310 } 1311 } else if (dst_first_rc == rc_float) { 1312 // gpr -> xmm 1313 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1314 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1315 // 64-bit 1316 if (masm) { 1317 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1318 #ifndef PRODUCT 1319 } else { 1320 st->print("movdq %s, %s\t# spill", 1321 Matcher::regName[dst_first], 1322 Matcher::regName[src_first]); 1323 #endif 1324 } 1325 } else { 1326 // 32-bit 1327 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1328 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1329 if (masm) { 1330 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1331 #ifndef PRODUCT 1332 } else { 1333 st->print("movdl %s, %s\t# spill", 1334 Matcher::regName[dst_first], 1335 Matcher::regName[src_first]); 1336 #endif 1337 } 1338 } 1339 return 0; 1340 } else if (dst_first_rc == rc_kreg) { 1341 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1342 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1343 // 64-bit 1344 if (masm) { 1345 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1346 #ifndef PRODUCT 1347 } else { 1348 st->print("kmovq %s, %s\t# spill", 1349 Matcher::regName[dst_first], 1350 Matcher::regName[src_first]); 1351 #endif 1352 } 1353 } 1354 Unimplemented(); 1355 return 0; 1356 } 1357 } else if (src_first_rc == rc_float) { 1358 // xmm -> 1359 if (dst_first_rc == rc_stack) { 1360 // xmm -> mem 1361 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1362 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1363 // 64-bit 1364 int offset = ra_->reg2offset(dst_first); 1365 if (masm) { 1366 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1367 #ifndef PRODUCT 1368 } else { 1369 st->print("movsd [rsp + #%d], %s\t# spill", 1370 offset, 1371 Matcher::regName[src_first]); 1372 #endif 1373 } 1374 } else { 1375 // 32-bit 1376 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1377 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1378 int offset = ra_->reg2offset(dst_first); 1379 if (masm) { 1380 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1381 #ifndef PRODUCT 1382 } else { 1383 st->print("movss [rsp + #%d], %s\t# spill", 1384 offset, 1385 Matcher::regName[src_first]); 1386 #endif 1387 } 1388 } 1389 return 0; 1390 } else if (dst_first_rc == rc_int) { 1391 // xmm -> gpr 1392 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1393 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1394 // 64-bit 1395 if (masm) { 1396 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1397 #ifndef PRODUCT 1398 } else { 1399 st->print("movdq %s, %s\t# spill", 1400 Matcher::regName[dst_first], 1401 Matcher::regName[src_first]); 1402 #endif 1403 } 1404 } else { 1405 // 32-bit 1406 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1407 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1408 if (masm) { 1409 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1410 #ifndef PRODUCT 1411 } else { 1412 st->print("movdl %s, %s\t# spill", 1413 Matcher::regName[dst_first], 1414 Matcher::regName[src_first]); 1415 #endif 1416 } 1417 } 1418 return 0; 1419 } else if (dst_first_rc == rc_float) { 1420 // xmm -> xmm 1421 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1422 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1423 // 64-bit 1424 if (masm) { 1425 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1426 #ifndef PRODUCT 1427 } else { 1428 st->print("%s %s, %s\t# spill", 1429 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1430 Matcher::regName[dst_first], 1431 Matcher::regName[src_first]); 1432 #endif 1433 } 1434 } else { 1435 // 32-bit 1436 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1437 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1438 if (masm) { 1439 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1440 #ifndef PRODUCT 1441 } else { 1442 st->print("%s %s, %s\t# spill", 1443 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1444 Matcher::regName[dst_first], 1445 Matcher::regName[src_first]); 1446 #endif 1447 } 1448 } 1449 return 0; 1450 } else if (dst_first_rc == rc_kreg) { 1451 assert(false, "Illegal spilling"); 1452 return 0; 1453 } 1454 } else if (src_first_rc == rc_kreg) { 1455 if (dst_first_rc == rc_stack) { 1456 // mem -> kreg 1457 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1458 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1459 // 64-bit 1460 int offset = ra_->reg2offset(dst_first); 1461 if (masm) { 1462 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1463 #ifndef PRODUCT 1464 } else { 1465 st->print("kmovq [rsp + #%d] , %s\t# spill", 1466 offset, 1467 Matcher::regName[src_first]); 1468 #endif 1469 } 1470 } 1471 return 0; 1472 } else if (dst_first_rc == rc_int) { 1473 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1474 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1475 // 64-bit 1476 if (masm) { 1477 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1478 #ifndef PRODUCT 1479 } else { 1480 st->print("kmovq %s, %s\t# spill", 1481 Matcher::regName[dst_first], 1482 Matcher::regName[src_first]); 1483 #endif 1484 } 1485 } 1486 Unimplemented(); 1487 return 0; 1488 } else if (dst_first_rc == rc_kreg) { 1489 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1490 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1491 // 64-bit 1492 if (masm) { 1493 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1494 #ifndef PRODUCT 1495 } else { 1496 st->print("kmovq %s, %s\t# spill", 1497 Matcher::regName[dst_first], 1498 Matcher::regName[src_first]); 1499 #endif 1500 } 1501 } 1502 return 0; 1503 } else if (dst_first_rc == rc_float) { 1504 assert(false, "Illegal spill"); 1505 return 0; 1506 } 1507 } 1508 1509 assert(0," foo "); 1510 Unimplemented(); 1511 return 0; 1512 } 1513 1514 #ifndef PRODUCT 1515 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1516 implementation(nullptr, ra_, false, st); 1517 } 1518 #endif 1519 1520 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1521 implementation(masm, ra_, false, nullptr); 1522 } 1523 1524 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1525 return MachNode::size(ra_); 1526 } 1527 1528 //============================================================================= 1529 #ifndef PRODUCT 1530 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1531 { 1532 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1533 int reg = ra_->get_reg_first(this); 1534 st->print("leaq %s, [rsp + #%d]\t# box lock", 1535 Matcher::regName[reg], offset); 1536 } 1537 #endif 1538 1539 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1540 { 1541 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1542 int reg = ra_->get_encode(this); 1543 1544 __ lea(as_Register(reg), Address(rsp, offset)); 1545 } 1546 1547 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1548 { 1549 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1550 return (offset < 0x80) ? 5 : 8; // REX 1551 } 1552 1553 //============================================================================= 1554 #ifndef PRODUCT 1555 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1556 { 1557 if (UseCompressedClassPointers) { 1558 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1559 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1560 } else { 1561 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1562 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1563 } 1564 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1565 } 1566 #endif 1567 1568 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1569 { 1570 __ ic_check(InteriorEntryAlignment); 1571 } 1572 1573 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1574 { 1575 return MachNode::size(ra_); // too many variables; just compute it 1576 // the hard way 1577 } 1578 1579 1580 //============================================================================= 1581 1582 bool Matcher::supports_vector_calling_convention(void) { 1583 if (EnableVectorSupport && UseVectorStubs) { 1584 return true; 1585 } 1586 return false; 1587 } 1588 1589 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1590 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1591 int lo = XMM0_num; 1592 int hi = XMM0b_num; 1593 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1594 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1595 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1596 return OptoRegPair(hi, lo); 1597 } 1598 1599 // Is this branch offset short enough that a short branch can be used? 1600 // 1601 // NOTE: If the platform does not provide any short branch variants, then 1602 // this method should return false for offset 0. 1603 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1604 // The passed offset is relative to address of the branch. 1605 // On 86 a branch displacement is calculated relative to address 1606 // of a next instruction. 1607 offset -= br_size; 1608 1609 // the short version of jmpConUCF2 contains multiple branches, 1610 // making the reach slightly less 1611 if (rule == jmpConUCF2_rule) 1612 return (-126 <= offset && offset <= 125); 1613 return (-128 <= offset && offset <= 127); 1614 } 1615 1616 // Return whether or not this register is ever used as an argument. 1617 // This function is used on startup to build the trampoline stubs in 1618 // generateOptoStub. Registers not mentioned will be killed by the VM 1619 // call in the trampoline, and arguments in those registers not be 1620 // available to the callee. 1621 bool Matcher::can_be_java_arg(int reg) 1622 { 1623 return 1624 reg == RDI_num || reg == RDI_H_num || 1625 reg == RSI_num || reg == RSI_H_num || 1626 reg == RDX_num || reg == RDX_H_num || 1627 reg == RCX_num || reg == RCX_H_num || 1628 reg == R8_num || reg == R8_H_num || 1629 reg == R9_num || reg == R9_H_num || 1630 reg == R12_num || reg == R12_H_num || 1631 reg == XMM0_num || reg == XMM0b_num || 1632 reg == XMM1_num || reg == XMM1b_num || 1633 reg == XMM2_num || reg == XMM2b_num || 1634 reg == XMM3_num || reg == XMM3b_num || 1635 reg == XMM4_num || reg == XMM4b_num || 1636 reg == XMM5_num || reg == XMM5b_num || 1637 reg == XMM6_num || reg == XMM6b_num || 1638 reg == XMM7_num || reg == XMM7b_num; 1639 } 1640 1641 bool Matcher::is_spillable_arg(int reg) 1642 { 1643 return can_be_java_arg(reg); 1644 } 1645 1646 uint Matcher::int_pressure_limit() 1647 { 1648 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1649 } 1650 1651 uint Matcher::float_pressure_limit() 1652 { 1653 // After experiment around with different values, the following default threshold 1654 // works best for LCM's register pressure scheduling on x64. 1655 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1656 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1657 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1658 } 1659 1660 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1661 // In 64 bit mode a code which use multiply when 1662 // devisor is constant is faster than hardware 1663 // DIV instruction (it uses MulHiL). 1664 return false; 1665 } 1666 1667 // Register for DIVI projection of divmodI 1668 RegMask Matcher::divI_proj_mask() { 1669 return INT_RAX_REG_mask(); 1670 } 1671 1672 // Register for MODI projection of divmodI 1673 RegMask Matcher::modI_proj_mask() { 1674 return INT_RDX_REG_mask(); 1675 } 1676 1677 // Register for DIVL projection of divmodL 1678 RegMask Matcher::divL_proj_mask() { 1679 return LONG_RAX_REG_mask(); 1680 } 1681 1682 // Register for MODL projection of divmodL 1683 RegMask Matcher::modL_proj_mask() { 1684 return LONG_RDX_REG_mask(); 1685 } 1686 1687 // Register for saving SP into on method handle invokes. Not used on x86_64. 1688 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1689 return NO_REG_mask(); 1690 } 1691 1692 %} 1693 1694 //----------ENCODING BLOCK----------------------------------------------------- 1695 // This block specifies the encoding classes used by the compiler to 1696 // output byte streams. Encoding classes are parameterized macros 1697 // used by Machine Instruction Nodes in order to generate the bit 1698 // encoding of the instruction. Operands specify their base encoding 1699 // interface with the interface keyword. There are currently 1700 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1701 // COND_INTER. REG_INTER causes an operand to generate a function 1702 // which returns its register number when queried. CONST_INTER causes 1703 // an operand to generate a function which returns the value of the 1704 // constant when queried. MEMORY_INTER causes an operand to generate 1705 // four functions which return the Base Register, the Index Register, 1706 // the Scale Value, and the Offset Value of the operand when queried. 1707 // COND_INTER causes an operand to generate six functions which return 1708 // the encoding code (ie - encoding bits for the instruction) 1709 // associated with each basic boolean condition for a conditional 1710 // instruction. 1711 // 1712 // Instructions specify two basic values for encoding. Again, a 1713 // function is available to check if the constant displacement is an 1714 // oop. They use the ins_encode keyword to specify their encoding 1715 // classes (which must be a sequence of enc_class names, and their 1716 // parameters, specified in the encoding block), and they use the 1717 // opcode keyword to specify, in order, their primary, secondary, and 1718 // tertiary opcode. Only the opcode sections which a particular 1719 // instruction needs for encoding need to be specified. 1720 encode %{ 1721 enc_class cdql_enc(no_rax_rdx_RegI div) 1722 %{ 1723 // Full implementation of Java idiv and irem; checks for 1724 // special case as described in JVM spec., p.243 & p.271. 1725 // 1726 // normal case special case 1727 // 1728 // input : rax: dividend min_int 1729 // reg: divisor -1 1730 // 1731 // output: rax: quotient (= rax idiv reg) min_int 1732 // rdx: remainder (= rax irem reg) 0 1733 // 1734 // Code sequnce: 1735 // 1736 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1737 // 5: 75 07/08 jne e <normal> 1738 // 7: 33 d2 xor %edx,%edx 1739 // [div >= 8 -> offset + 1] 1740 // [REX_B] 1741 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1742 // c: 74 03/04 je 11 <done> 1743 // 000000000000000e <normal>: 1744 // e: 99 cltd 1745 // [div >= 8 -> offset + 1] 1746 // [REX_B] 1747 // f: f7 f9 idiv $div 1748 // 0000000000000011 <done>: 1749 Label normal; 1750 Label done; 1751 1752 // cmp $0x80000000,%eax 1753 __ cmpl(as_Register(RAX_enc), 0x80000000); 1754 1755 // jne e <normal> 1756 __ jccb(Assembler::notEqual, normal); 1757 1758 // xor %edx,%edx 1759 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1760 1761 // cmp $0xffffffffffffffff,%ecx 1762 __ cmpl($div$$Register, -1); 1763 1764 // je 11 <done> 1765 __ jccb(Assembler::equal, done); 1766 1767 // <normal> 1768 // cltd 1769 __ bind(normal); 1770 __ cdql(); 1771 1772 // idivl 1773 // <done> 1774 __ idivl($div$$Register); 1775 __ bind(done); 1776 %} 1777 1778 enc_class cdqq_enc(no_rax_rdx_RegL div) 1779 %{ 1780 // Full implementation of Java ldiv and lrem; checks for 1781 // special case as described in JVM spec., p.243 & p.271. 1782 // 1783 // normal case special case 1784 // 1785 // input : rax: dividend min_long 1786 // reg: divisor -1 1787 // 1788 // output: rax: quotient (= rax idiv reg) min_long 1789 // rdx: remainder (= rax irem reg) 0 1790 // 1791 // Code sequnce: 1792 // 1793 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1794 // 7: 00 00 80 1795 // a: 48 39 d0 cmp %rdx,%rax 1796 // d: 75 08 jne 17 <normal> 1797 // f: 33 d2 xor %edx,%edx 1798 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1799 // 15: 74 05 je 1c <done> 1800 // 0000000000000017 <normal>: 1801 // 17: 48 99 cqto 1802 // 19: 48 f7 f9 idiv $div 1803 // 000000000000001c <done>: 1804 Label normal; 1805 Label done; 1806 1807 // mov $0x8000000000000000,%rdx 1808 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1809 1810 // cmp %rdx,%rax 1811 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1812 1813 // jne 17 <normal> 1814 __ jccb(Assembler::notEqual, normal); 1815 1816 // xor %edx,%edx 1817 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1818 1819 // cmp $0xffffffffffffffff,$div 1820 __ cmpq($div$$Register, -1); 1821 1822 // je 1e <done> 1823 __ jccb(Assembler::equal, done); 1824 1825 // <normal> 1826 // cqto 1827 __ bind(normal); 1828 __ cdqq(); 1829 1830 // idivq (note: must be emitted by the user of this rule) 1831 // <done> 1832 __ idivq($div$$Register); 1833 __ bind(done); 1834 %} 1835 1836 enc_class clear_avx %{ 1837 debug_only(int off0 = __ offset()); 1838 if (generate_vzeroupper(Compile::current())) { 1839 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1840 // Clear upper bits of YMM registers when current compiled code uses 1841 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1842 __ vzeroupper(); 1843 } 1844 debug_only(int off1 = __ offset()); 1845 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1846 %} 1847 1848 enc_class Java_To_Runtime(method meth) %{ 1849 // No relocation needed 1850 __ mov64(r10, (int64_t) $meth$$method); 1851 __ call(r10); 1852 __ post_call_nop(); 1853 %} 1854 1855 enc_class Java_Static_Call(method meth) 1856 %{ 1857 // JAVA STATIC CALL 1858 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1859 // determine who we intended to call. 1860 if (!_method) { 1861 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1862 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1863 // The NOP here is purely to ensure that eliding a call to 1864 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1865 __ addr_nop_5(); 1866 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1867 } else { 1868 int method_index = resolved_method_index(masm); 1869 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1870 : static_call_Relocation::spec(method_index); 1871 address mark = __ pc(); 1872 int call_offset = __ offset(); 1873 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1874 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1875 // Calls of the same statically bound method can share 1876 // a stub to the interpreter. 1877 __ code()->shared_stub_to_interp_for(_method, call_offset); 1878 } else { 1879 // Emit stubs for static call. 1880 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1881 __ clear_inst_mark(); 1882 if (stub == nullptr) { 1883 ciEnv::current()->record_failure("CodeCache is full"); 1884 return; 1885 } 1886 } 1887 } 1888 __ post_call_nop(); 1889 %} 1890 1891 enc_class Java_Dynamic_Call(method meth) %{ 1892 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1893 __ post_call_nop(); 1894 %} 1895 1896 %} 1897 1898 1899 1900 //----------FRAME-------------------------------------------------------------- 1901 // Definition of frame structure and management information. 1902 // 1903 // S T A C K L A Y O U T Allocators stack-slot number 1904 // | (to get allocators register number 1905 // G Owned by | | v add OptoReg::stack0()) 1906 // r CALLER | | 1907 // o | +--------+ pad to even-align allocators stack-slot 1908 // w V | pad0 | numbers; owned by CALLER 1909 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1910 // h ^ | in | 5 1911 // | | args | 4 Holes in incoming args owned by SELF 1912 // | | | | 3 1913 // | | +--------+ 1914 // V | | old out| Empty on Intel, window on Sparc 1915 // | old |preserve| Must be even aligned. 1916 // | SP-+--------+----> Matcher::_old_SP, even aligned 1917 // | | in | 3 area for Intel ret address 1918 // Owned by |preserve| Empty on Sparc. 1919 // SELF +--------+ 1920 // | | pad2 | 2 pad to align old SP 1921 // | +--------+ 1 1922 // | | locks | 0 1923 // | +--------+----> OptoReg::stack0(), even aligned 1924 // | | pad1 | 11 pad to align new SP 1925 // | +--------+ 1926 // | | | 10 1927 // | | spills | 9 spills 1928 // V | | 8 (pad0 slot for callee) 1929 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1930 // ^ | out | 7 1931 // | | args | 6 Holes in outgoing args owned by CALLEE 1932 // Owned by +--------+ 1933 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1934 // | new |preserve| Must be even-aligned. 1935 // | SP-+--------+----> Matcher::_new_SP, even aligned 1936 // | | | 1937 // 1938 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1939 // known from SELF's arguments and the Java calling convention. 1940 // Region 6-7 is determined per call site. 1941 // Note 2: If the calling convention leaves holes in the incoming argument 1942 // area, those holes are owned by SELF. Holes in the outgoing area 1943 // are owned by the CALLEE. Holes should not be necessary in the 1944 // incoming area, as the Java calling convention is completely under 1945 // the control of the AD file. Doubles can be sorted and packed to 1946 // avoid holes. Holes in the outgoing arguments may be necessary for 1947 // varargs C calling conventions. 1948 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1949 // even aligned with pad0 as needed. 1950 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1951 // region 6-11 is even aligned; it may be padded out more so that 1952 // the region from SP to FP meets the minimum stack alignment. 1953 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1954 // alignment. Region 11, pad1, may be dynamically extended so that 1955 // SP meets the minimum alignment. 1956 1957 frame 1958 %{ 1959 // These three registers define part of the calling convention 1960 // between compiled code and the interpreter. 1961 inline_cache_reg(RAX); // Inline Cache Register 1962 1963 // Optional: name the operand used by cisc-spilling to access 1964 // [stack_pointer + offset] 1965 cisc_spilling_operand_name(indOffset32); 1966 1967 // Number of stack slots consumed by locking an object 1968 sync_stack_slots(2); 1969 1970 // Compiled code's Frame Pointer 1971 frame_pointer(RSP); 1972 1973 // Interpreter stores its frame pointer in a register which is 1974 // stored to the stack by I2CAdaptors. 1975 // I2CAdaptors convert from interpreted java to compiled java. 1976 interpreter_frame_pointer(RBP); 1977 1978 // Stack alignment requirement 1979 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1980 1981 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1982 // for calls to C. Supports the var-args backing area for register parms. 1983 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1984 1985 // The after-PROLOG location of the return address. Location of 1986 // return address specifies a type (REG or STACK) and a number 1987 // representing the register number (i.e. - use a register name) or 1988 // stack slot. 1989 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 1990 // Otherwise, it is above the locks and verification slot and alignment word 1991 return_addr(STACK - 2 + 1992 align_up((Compile::current()->in_preserve_stack_slots() + 1993 Compile::current()->fixed_slots()), 1994 stack_alignment_in_slots())); 1995 1996 // Location of compiled Java return values. Same as C for now. 1997 return_value 1998 %{ 1999 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2000 "only return normal values"); 2001 2002 static const int lo[Op_RegL + 1] = { 2003 0, 2004 0, 2005 RAX_num, // Op_RegN 2006 RAX_num, // Op_RegI 2007 RAX_num, // Op_RegP 2008 XMM0_num, // Op_RegF 2009 XMM0_num, // Op_RegD 2010 RAX_num // Op_RegL 2011 }; 2012 static const int hi[Op_RegL + 1] = { 2013 0, 2014 0, 2015 OptoReg::Bad, // Op_RegN 2016 OptoReg::Bad, // Op_RegI 2017 RAX_H_num, // Op_RegP 2018 OptoReg::Bad, // Op_RegF 2019 XMM0b_num, // Op_RegD 2020 RAX_H_num // Op_RegL 2021 }; 2022 // Excluded flags and vector registers. 2023 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2024 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2025 %} 2026 %} 2027 2028 //----------ATTRIBUTES--------------------------------------------------------- 2029 //----------Operand Attributes------------------------------------------------- 2030 op_attrib op_cost(0); // Required cost attribute 2031 2032 //----------Instruction Attributes--------------------------------------------- 2033 ins_attrib ins_cost(100); // Required cost attribute 2034 ins_attrib ins_size(8); // Required size attribute (in bits) 2035 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2036 // a non-matching short branch variant 2037 // of some long branch? 2038 ins_attrib ins_alignment(1); // Required alignment attribute (must 2039 // be a power of 2) specifies the 2040 // alignment that some part of the 2041 // instruction (not necessarily the 2042 // start) requires. If > 1, a 2043 // compute_padding() function must be 2044 // provided for the instruction 2045 2046 //----------OPERANDS----------------------------------------------------------- 2047 // Operand definitions must precede instruction definitions for correct parsing 2048 // in the ADLC because operands constitute user defined types which are used in 2049 // instruction definitions. 2050 2051 //----------Simple Operands---------------------------------------------------- 2052 // Immediate Operands 2053 // Integer Immediate 2054 operand immI() 2055 %{ 2056 match(ConI); 2057 2058 op_cost(10); 2059 format %{ %} 2060 interface(CONST_INTER); 2061 %} 2062 2063 // Constant for test vs zero 2064 operand immI_0() 2065 %{ 2066 predicate(n->get_int() == 0); 2067 match(ConI); 2068 2069 op_cost(0); 2070 format %{ %} 2071 interface(CONST_INTER); 2072 %} 2073 2074 // Constant for increment 2075 operand immI_1() 2076 %{ 2077 predicate(n->get_int() == 1); 2078 match(ConI); 2079 2080 op_cost(0); 2081 format %{ %} 2082 interface(CONST_INTER); 2083 %} 2084 2085 // Constant for decrement 2086 operand immI_M1() 2087 %{ 2088 predicate(n->get_int() == -1); 2089 match(ConI); 2090 2091 op_cost(0); 2092 format %{ %} 2093 interface(CONST_INTER); 2094 %} 2095 2096 operand immI_2() 2097 %{ 2098 predicate(n->get_int() == 2); 2099 match(ConI); 2100 2101 op_cost(0); 2102 format %{ %} 2103 interface(CONST_INTER); 2104 %} 2105 2106 operand immI_4() 2107 %{ 2108 predicate(n->get_int() == 4); 2109 match(ConI); 2110 2111 op_cost(0); 2112 format %{ %} 2113 interface(CONST_INTER); 2114 %} 2115 2116 operand immI_8() 2117 %{ 2118 predicate(n->get_int() == 8); 2119 match(ConI); 2120 2121 op_cost(0); 2122 format %{ %} 2123 interface(CONST_INTER); 2124 %} 2125 2126 // Valid scale values for addressing modes 2127 operand immI2() 2128 %{ 2129 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2130 match(ConI); 2131 2132 format %{ %} 2133 interface(CONST_INTER); 2134 %} 2135 2136 operand immU7() 2137 %{ 2138 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2139 match(ConI); 2140 2141 op_cost(5); 2142 format %{ %} 2143 interface(CONST_INTER); 2144 %} 2145 2146 operand immI8() 2147 %{ 2148 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2149 match(ConI); 2150 2151 op_cost(5); 2152 format %{ %} 2153 interface(CONST_INTER); 2154 %} 2155 2156 operand immU8() 2157 %{ 2158 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2159 match(ConI); 2160 2161 op_cost(5); 2162 format %{ %} 2163 interface(CONST_INTER); 2164 %} 2165 2166 operand immI16() 2167 %{ 2168 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2169 match(ConI); 2170 2171 op_cost(10); 2172 format %{ %} 2173 interface(CONST_INTER); 2174 %} 2175 2176 // Int Immediate non-negative 2177 operand immU31() 2178 %{ 2179 predicate(n->get_int() >= 0); 2180 match(ConI); 2181 2182 op_cost(0); 2183 format %{ %} 2184 interface(CONST_INTER); 2185 %} 2186 2187 // Pointer Immediate 2188 operand immP() 2189 %{ 2190 match(ConP); 2191 2192 op_cost(10); 2193 format %{ %} 2194 interface(CONST_INTER); 2195 %} 2196 2197 // Null Pointer Immediate 2198 operand immP0() 2199 %{ 2200 predicate(n->get_ptr() == 0); 2201 match(ConP); 2202 2203 op_cost(5); 2204 format %{ %} 2205 interface(CONST_INTER); 2206 %} 2207 2208 // Pointer Immediate 2209 operand immN() %{ 2210 match(ConN); 2211 2212 op_cost(10); 2213 format %{ %} 2214 interface(CONST_INTER); 2215 %} 2216 2217 operand immNKlass() %{ 2218 match(ConNKlass); 2219 2220 op_cost(10); 2221 format %{ %} 2222 interface(CONST_INTER); 2223 %} 2224 2225 // Null Pointer Immediate 2226 operand immN0() %{ 2227 predicate(n->get_narrowcon() == 0); 2228 match(ConN); 2229 2230 op_cost(5); 2231 format %{ %} 2232 interface(CONST_INTER); 2233 %} 2234 2235 operand immP31() 2236 %{ 2237 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2238 && (n->get_ptr() >> 31) == 0); 2239 match(ConP); 2240 2241 op_cost(5); 2242 format %{ %} 2243 interface(CONST_INTER); 2244 %} 2245 2246 2247 // Long Immediate 2248 operand immL() 2249 %{ 2250 match(ConL); 2251 2252 op_cost(20); 2253 format %{ %} 2254 interface(CONST_INTER); 2255 %} 2256 2257 // Long Immediate 8-bit 2258 operand immL8() 2259 %{ 2260 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2261 match(ConL); 2262 2263 op_cost(5); 2264 format %{ %} 2265 interface(CONST_INTER); 2266 %} 2267 2268 // Long Immediate 32-bit unsigned 2269 operand immUL32() 2270 %{ 2271 predicate(n->get_long() == (unsigned int) (n->get_long())); 2272 match(ConL); 2273 2274 op_cost(10); 2275 format %{ %} 2276 interface(CONST_INTER); 2277 %} 2278 2279 // Long Immediate 32-bit signed 2280 operand immL32() 2281 %{ 2282 predicate(n->get_long() == (int) (n->get_long())); 2283 match(ConL); 2284 2285 op_cost(15); 2286 format %{ %} 2287 interface(CONST_INTER); 2288 %} 2289 2290 operand immL_Pow2() 2291 %{ 2292 predicate(is_power_of_2((julong)n->get_long())); 2293 match(ConL); 2294 2295 op_cost(15); 2296 format %{ %} 2297 interface(CONST_INTER); 2298 %} 2299 2300 operand immL_NotPow2() 2301 %{ 2302 predicate(is_power_of_2((julong)~n->get_long())); 2303 match(ConL); 2304 2305 op_cost(15); 2306 format %{ %} 2307 interface(CONST_INTER); 2308 %} 2309 2310 // Long Immediate zero 2311 operand immL0() 2312 %{ 2313 predicate(n->get_long() == 0L); 2314 match(ConL); 2315 2316 op_cost(10); 2317 format %{ %} 2318 interface(CONST_INTER); 2319 %} 2320 2321 // Constant for increment 2322 operand immL1() 2323 %{ 2324 predicate(n->get_long() == 1); 2325 match(ConL); 2326 2327 format %{ %} 2328 interface(CONST_INTER); 2329 %} 2330 2331 // Constant for decrement 2332 operand immL_M1() 2333 %{ 2334 predicate(n->get_long() == -1); 2335 match(ConL); 2336 2337 format %{ %} 2338 interface(CONST_INTER); 2339 %} 2340 2341 // Long Immediate: low 32-bit mask 2342 operand immL_32bits() 2343 %{ 2344 predicate(n->get_long() == 0xFFFFFFFFL); 2345 match(ConL); 2346 op_cost(20); 2347 2348 format %{ %} 2349 interface(CONST_INTER); 2350 %} 2351 2352 // Int Immediate: 2^n-1, positive 2353 operand immI_Pow2M1() 2354 %{ 2355 predicate((n->get_int() > 0) 2356 && is_power_of_2((juint)n->get_int() + 1)); 2357 match(ConI); 2358 2359 op_cost(20); 2360 format %{ %} 2361 interface(CONST_INTER); 2362 %} 2363 2364 // Float Immediate zero 2365 operand immF0() 2366 %{ 2367 predicate(jint_cast(n->getf()) == 0); 2368 match(ConF); 2369 2370 op_cost(5); 2371 format %{ %} 2372 interface(CONST_INTER); 2373 %} 2374 2375 // Float Immediate 2376 operand immF() 2377 %{ 2378 match(ConF); 2379 2380 op_cost(15); 2381 format %{ %} 2382 interface(CONST_INTER); 2383 %} 2384 2385 // Double Immediate zero 2386 operand immD0() 2387 %{ 2388 predicate(jlong_cast(n->getd()) == 0); 2389 match(ConD); 2390 2391 op_cost(5); 2392 format %{ %} 2393 interface(CONST_INTER); 2394 %} 2395 2396 // Double Immediate 2397 operand immD() 2398 %{ 2399 match(ConD); 2400 2401 op_cost(15); 2402 format %{ %} 2403 interface(CONST_INTER); 2404 %} 2405 2406 // Immediates for special shifts (sign extend) 2407 2408 // Constants for increment 2409 operand immI_16() 2410 %{ 2411 predicate(n->get_int() == 16); 2412 match(ConI); 2413 2414 format %{ %} 2415 interface(CONST_INTER); 2416 %} 2417 2418 operand immI_24() 2419 %{ 2420 predicate(n->get_int() == 24); 2421 match(ConI); 2422 2423 format %{ %} 2424 interface(CONST_INTER); 2425 %} 2426 2427 // Constant for byte-wide masking 2428 operand immI_255() 2429 %{ 2430 predicate(n->get_int() == 255); 2431 match(ConI); 2432 2433 format %{ %} 2434 interface(CONST_INTER); 2435 %} 2436 2437 // Constant for short-wide masking 2438 operand immI_65535() 2439 %{ 2440 predicate(n->get_int() == 65535); 2441 match(ConI); 2442 2443 format %{ %} 2444 interface(CONST_INTER); 2445 %} 2446 2447 // Constant for byte-wide masking 2448 operand immL_255() 2449 %{ 2450 predicate(n->get_long() == 255); 2451 match(ConL); 2452 2453 format %{ %} 2454 interface(CONST_INTER); 2455 %} 2456 2457 // Constant for short-wide masking 2458 operand immL_65535() 2459 %{ 2460 predicate(n->get_long() == 65535); 2461 match(ConL); 2462 2463 format %{ %} 2464 interface(CONST_INTER); 2465 %} 2466 2467 operand kReg() 2468 %{ 2469 constraint(ALLOC_IN_RC(vectmask_reg)); 2470 match(RegVectMask); 2471 format %{%} 2472 interface(REG_INTER); 2473 %} 2474 2475 // Register Operands 2476 // Integer Register 2477 operand rRegI() 2478 %{ 2479 constraint(ALLOC_IN_RC(int_reg)); 2480 match(RegI); 2481 2482 match(rax_RegI); 2483 match(rbx_RegI); 2484 match(rcx_RegI); 2485 match(rdx_RegI); 2486 match(rdi_RegI); 2487 2488 format %{ %} 2489 interface(REG_INTER); 2490 %} 2491 2492 // Special Registers 2493 operand rax_RegI() 2494 %{ 2495 constraint(ALLOC_IN_RC(int_rax_reg)); 2496 match(RegI); 2497 match(rRegI); 2498 2499 format %{ "RAX" %} 2500 interface(REG_INTER); 2501 %} 2502 2503 // Special Registers 2504 operand rbx_RegI() 2505 %{ 2506 constraint(ALLOC_IN_RC(int_rbx_reg)); 2507 match(RegI); 2508 match(rRegI); 2509 2510 format %{ "RBX" %} 2511 interface(REG_INTER); 2512 %} 2513 2514 operand rcx_RegI() 2515 %{ 2516 constraint(ALLOC_IN_RC(int_rcx_reg)); 2517 match(RegI); 2518 match(rRegI); 2519 2520 format %{ "RCX" %} 2521 interface(REG_INTER); 2522 %} 2523 2524 operand rdx_RegI() 2525 %{ 2526 constraint(ALLOC_IN_RC(int_rdx_reg)); 2527 match(RegI); 2528 match(rRegI); 2529 2530 format %{ "RDX" %} 2531 interface(REG_INTER); 2532 %} 2533 2534 operand rdi_RegI() 2535 %{ 2536 constraint(ALLOC_IN_RC(int_rdi_reg)); 2537 match(RegI); 2538 match(rRegI); 2539 2540 format %{ "RDI" %} 2541 interface(REG_INTER); 2542 %} 2543 2544 operand no_rax_rdx_RegI() 2545 %{ 2546 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2547 match(RegI); 2548 match(rbx_RegI); 2549 match(rcx_RegI); 2550 match(rdi_RegI); 2551 2552 format %{ %} 2553 interface(REG_INTER); 2554 %} 2555 2556 operand no_rbp_r13_RegI() 2557 %{ 2558 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2559 match(RegI); 2560 match(rRegI); 2561 match(rax_RegI); 2562 match(rbx_RegI); 2563 match(rcx_RegI); 2564 match(rdx_RegI); 2565 match(rdi_RegI); 2566 2567 format %{ %} 2568 interface(REG_INTER); 2569 %} 2570 2571 // Pointer Register 2572 operand any_RegP() 2573 %{ 2574 constraint(ALLOC_IN_RC(any_reg)); 2575 match(RegP); 2576 match(rax_RegP); 2577 match(rbx_RegP); 2578 match(rdi_RegP); 2579 match(rsi_RegP); 2580 match(rbp_RegP); 2581 match(r15_RegP); 2582 match(rRegP); 2583 2584 format %{ %} 2585 interface(REG_INTER); 2586 %} 2587 2588 operand rRegP() 2589 %{ 2590 constraint(ALLOC_IN_RC(ptr_reg)); 2591 match(RegP); 2592 match(rax_RegP); 2593 match(rbx_RegP); 2594 match(rdi_RegP); 2595 match(rsi_RegP); 2596 match(rbp_RegP); // See Q&A below about 2597 match(r15_RegP); // r15_RegP and rbp_RegP. 2598 2599 format %{ %} 2600 interface(REG_INTER); 2601 %} 2602 2603 operand rRegN() %{ 2604 constraint(ALLOC_IN_RC(int_reg)); 2605 match(RegN); 2606 2607 format %{ %} 2608 interface(REG_INTER); 2609 %} 2610 2611 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2612 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2613 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2614 // The output of an instruction is controlled by the allocator, which respects 2615 // register class masks, not match rules. Unless an instruction mentions 2616 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2617 // by the allocator as an input. 2618 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2619 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2620 // result, RBP is not included in the output of the instruction either. 2621 2622 // This operand is not allowed to use RBP even if 2623 // RBP is not used to hold the frame pointer. 2624 operand no_rbp_RegP() 2625 %{ 2626 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2627 match(RegP); 2628 match(rbx_RegP); 2629 match(rsi_RegP); 2630 match(rdi_RegP); 2631 2632 format %{ %} 2633 interface(REG_INTER); 2634 %} 2635 2636 // Special Registers 2637 // Return a pointer value 2638 operand rax_RegP() 2639 %{ 2640 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2641 match(RegP); 2642 match(rRegP); 2643 2644 format %{ %} 2645 interface(REG_INTER); 2646 %} 2647 2648 // Special Registers 2649 // Return a compressed pointer value 2650 operand rax_RegN() 2651 %{ 2652 constraint(ALLOC_IN_RC(int_rax_reg)); 2653 match(RegN); 2654 match(rRegN); 2655 2656 format %{ %} 2657 interface(REG_INTER); 2658 %} 2659 2660 // Used in AtomicAdd 2661 operand rbx_RegP() 2662 %{ 2663 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2664 match(RegP); 2665 match(rRegP); 2666 2667 format %{ %} 2668 interface(REG_INTER); 2669 %} 2670 2671 operand rsi_RegP() 2672 %{ 2673 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2674 match(RegP); 2675 match(rRegP); 2676 2677 format %{ %} 2678 interface(REG_INTER); 2679 %} 2680 2681 operand rbp_RegP() 2682 %{ 2683 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2684 match(RegP); 2685 match(rRegP); 2686 2687 format %{ %} 2688 interface(REG_INTER); 2689 %} 2690 2691 // Used in rep stosq 2692 operand rdi_RegP() 2693 %{ 2694 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2695 match(RegP); 2696 match(rRegP); 2697 2698 format %{ %} 2699 interface(REG_INTER); 2700 %} 2701 2702 operand r15_RegP() 2703 %{ 2704 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2705 match(RegP); 2706 match(rRegP); 2707 2708 format %{ %} 2709 interface(REG_INTER); 2710 %} 2711 2712 operand rRegL() 2713 %{ 2714 constraint(ALLOC_IN_RC(long_reg)); 2715 match(RegL); 2716 match(rax_RegL); 2717 match(rdx_RegL); 2718 2719 format %{ %} 2720 interface(REG_INTER); 2721 %} 2722 2723 // Special Registers 2724 operand no_rax_rdx_RegL() 2725 %{ 2726 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2727 match(RegL); 2728 match(rRegL); 2729 2730 format %{ %} 2731 interface(REG_INTER); 2732 %} 2733 2734 operand rax_RegL() 2735 %{ 2736 constraint(ALLOC_IN_RC(long_rax_reg)); 2737 match(RegL); 2738 match(rRegL); 2739 2740 format %{ "RAX" %} 2741 interface(REG_INTER); 2742 %} 2743 2744 operand rcx_RegL() 2745 %{ 2746 constraint(ALLOC_IN_RC(long_rcx_reg)); 2747 match(RegL); 2748 match(rRegL); 2749 2750 format %{ %} 2751 interface(REG_INTER); 2752 %} 2753 2754 operand rdx_RegL() 2755 %{ 2756 constraint(ALLOC_IN_RC(long_rdx_reg)); 2757 match(RegL); 2758 match(rRegL); 2759 2760 format %{ %} 2761 interface(REG_INTER); 2762 %} 2763 2764 operand r11_RegL() 2765 %{ 2766 constraint(ALLOC_IN_RC(long_r11_reg)); 2767 match(RegL); 2768 match(rRegL); 2769 2770 format %{ %} 2771 interface(REG_INTER); 2772 %} 2773 2774 operand no_rbp_r13_RegL() 2775 %{ 2776 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2777 match(RegL); 2778 match(rRegL); 2779 match(rax_RegL); 2780 match(rcx_RegL); 2781 match(rdx_RegL); 2782 2783 format %{ %} 2784 interface(REG_INTER); 2785 %} 2786 2787 // Flags register, used as output of compare instructions 2788 operand rFlagsReg() 2789 %{ 2790 constraint(ALLOC_IN_RC(int_flags)); 2791 match(RegFlags); 2792 2793 format %{ "RFLAGS" %} 2794 interface(REG_INTER); 2795 %} 2796 2797 // Flags register, used as output of FLOATING POINT compare instructions 2798 operand rFlagsRegU() 2799 %{ 2800 constraint(ALLOC_IN_RC(int_flags)); 2801 match(RegFlags); 2802 2803 format %{ "RFLAGS_U" %} 2804 interface(REG_INTER); 2805 %} 2806 2807 operand rFlagsRegUCF() %{ 2808 constraint(ALLOC_IN_RC(int_flags)); 2809 match(RegFlags); 2810 predicate(false); 2811 2812 format %{ "RFLAGS_U_CF" %} 2813 interface(REG_INTER); 2814 %} 2815 2816 // Float register operands 2817 operand regF() %{ 2818 constraint(ALLOC_IN_RC(float_reg)); 2819 match(RegF); 2820 2821 format %{ %} 2822 interface(REG_INTER); 2823 %} 2824 2825 // Float register operands 2826 operand legRegF() %{ 2827 constraint(ALLOC_IN_RC(float_reg_legacy)); 2828 match(RegF); 2829 2830 format %{ %} 2831 interface(REG_INTER); 2832 %} 2833 2834 // Float register operands 2835 operand vlRegF() %{ 2836 constraint(ALLOC_IN_RC(float_reg_vl)); 2837 match(RegF); 2838 2839 format %{ %} 2840 interface(REG_INTER); 2841 %} 2842 2843 // Double register operands 2844 operand regD() %{ 2845 constraint(ALLOC_IN_RC(double_reg)); 2846 match(RegD); 2847 2848 format %{ %} 2849 interface(REG_INTER); 2850 %} 2851 2852 // Double register operands 2853 operand legRegD() %{ 2854 constraint(ALLOC_IN_RC(double_reg_legacy)); 2855 match(RegD); 2856 2857 format %{ %} 2858 interface(REG_INTER); 2859 %} 2860 2861 // Double register operands 2862 operand vlRegD() %{ 2863 constraint(ALLOC_IN_RC(double_reg_vl)); 2864 match(RegD); 2865 2866 format %{ %} 2867 interface(REG_INTER); 2868 %} 2869 2870 //----------Memory Operands---------------------------------------------------- 2871 // Direct Memory Operand 2872 // operand direct(immP addr) 2873 // %{ 2874 // match(addr); 2875 2876 // format %{ "[$addr]" %} 2877 // interface(MEMORY_INTER) %{ 2878 // base(0xFFFFFFFF); 2879 // index(0x4); 2880 // scale(0x0); 2881 // disp($addr); 2882 // %} 2883 // %} 2884 2885 // Indirect Memory Operand 2886 operand indirect(any_RegP reg) 2887 %{ 2888 constraint(ALLOC_IN_RC(ptr_reg)); 2889 match(reg); 2890 2891 format %{ "[$reg]" %} 2892 interface(MEMORY_INTER) %{ 2893 base($reg); 2894 index(0x4); 2895 scale(0x0); 2896 disp(0x0); 2897 %} 2898 %} 2899 2900 // Indirect Memory Plus Short Offset Operand 2901 operand indOffset8(any_RegP reg, immL8 off) 2902 %{ 2903 constraint(ALLOC_IN_RC(ptr_reg)); 2904 match(AddP reg off); 2905 2906 format %{ "[$reg + $off (8-bit)]" %} 2907 interface(MEMORY_INTER) %{ 2908 base($reg); 2909 index(0x4); 2910 scale(0x0); 2911 disp($off); 2912 %} 2913 %} 2914 2915 // Indirect Memory Plus Long Offset Operand 2916 operand indOffset32(any_RegP reg, immL32 off) 2917 %{ 2918 constraint(ALLOC_IN_RC(ptr_reg)); 2919 match(AddP reg off); 2920 2921 format %{ "[$reg + $off (32-bit)]" %} 2922 interface(MEMORY_INTER) %{ 2923 base($reg); 2924 index(0x4); 2925 scale(0x0); 2926 disp($off); 2927 %} 2928 %} 2929 2930 // Indirect Memory Plus Index Register Plus Offset Operand 2931 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2932 %{ 2933 constraint(ALLOC_IN_RC(ptr_reg)); 2934 match(AddP (AddP reg lreg) off); 2935 2936 op_cost(10); 2937 format %{"[$reg + $off + $lreg]" %} 2938 interface(MEMORY_INTER) %{ 2939 base($reg); 2940 index($lreg); 2941 scale(0x0); 2942 disp($off); 2943 %} 2944 %} 2945 2946 // Indirect Memory Plus Index Register Plus Offset Operand 2947 operand indIndex(any_RegP reg, rRegL lreg) 2948 %{ 2949 constraint(ALLOC_IN_RC(ptr_reg)); 2950 match(AddP reg lreg); 2951 2952 op_cost(10); 2953 format %{"[$reg + $lreg]" %} 2954 interface(MEMORY_INTER) %{ 2955 base($reg); 2956 index($lreg); 2957 scale(0x0); 2958 disp(0x0); 2959 %} 2960 %} 2961 2962 // Indirect Memory Times Scale Plus Index Register 2963 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2964 %{ 2965 constraint(ALLOC_IN_RC(ptr_reg)); 2966 match(AddP reg (LShiftL lreg scale)); 2967 2968 op_cost(10); 2969 format %{"[$reg + $lreg << $scale]" %} 2970 interface(MEMORY_INTER) %{ 2971 base($reg); 2972 index($lreg); 2973 scale($scale); 2974 disp(0x0); 2975 %} 2976 %} 2977 2978 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 2979 %{ 2980 constraint(ALLOC_IN_RC(ptr_reg)); 2981 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 2982 match(AddP reg (LShiftL (ConvI2L idx) scale)); 2983 2984 op_cost(10); 2985 format %{"[$reg + pos $idx << $scale]" %} 2986 interface(MEMORY_INTER) %{ 2987 base($reg); 2988 index($idx); 2989 scale($scale); 2990 disp(0x0); 2991 %} 2992 %} 2993 2994 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 2995 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 2996 %{ 2997 constraint(ALLOC_IN_RC(ptr_reg)); 2998 match(AddP (AddP reg (LShiftL lreg scale)) off); 2999 3000 op_cost(10); 3001 format %{"[$reg + $off + $lreg << $scale]" %} 3002 interface(MEMORY_INTER) %{ 3003 base($reg); 3004 index($lreg); 3005 scale($scale); 3006 disp($off); 3007 %} 3008 %} 3009 3010 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3011 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3012 %{ 3013 constraint(ALLOC_IN_RC(ptr_reg)); 3014 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3015 match(AddP (AddP reg (ConvI2L idx)) off); 3016 3017 op_cost(10); 3018 format %{"[$reg + $off + $idx]" %} 3019 interface(MEMORY_INTER) %{ 3020 base($reg); 3021 index($idx); 3022 scale(0x0); 3023 disp($off); 3024 %} 3025 %} 3026 3027 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3028 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3029 %{ 3030 constraint(ALLOC_IN_RC(ptr_reg)); 3031 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3032 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3033 3034 op_cost(10); 3035 format %{"[$reg + $off + $idx << $scale]" %} 3036 interface(MEMORY_INTER) %{ 3037 base($reg); 3038 index($idx); 3039 scale($scale); 3040 disp($off); 3041 %} 3042 %} 3043 3044 // Indirect Narrow Oop Plus Offset Operand 3045 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3046 // we can't free r12 even with CompressedOops::base() == nullptr. 3047 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3048 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3049 constraint(ALLOC_IN_RC(ptr_reg)); 3050 match(AddP (DecodeN reg) off); 3051 3052 op_cost(10); 3053 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3054 interface(MEMORY_INTER) %{ 3055 base(0xc); // R12 3056 index($reg); 3057 scale(0x3); 3058 disp($off); 3059 %} 3060 %} 3061 3062 // Indirect Memory Operand 3063 operand indirectNarrow(rRegN reg) 3064 %{ 3065 predicate(CompressedOops::shift() == 0); 3066 constraint(ALLOC_IN_RC(ptr_reg)); 3067 match(DecodeN reg); 3068 3069 format %{ "[$reg]" %} 3070 interface(MEMORY_INTER) %{ 3071 base($reg); 3072 index(0x4); 3073 scale(0x0); 3074 disp(0x0); 3075 %} 3076 %} 3077 3078 // Indirect Memory Plus Short Offset Operand 3079 operand indOffset8Narrow(rRegN reg, immL8 off) 3080 %{ 3081 predicate(CompressedOops::shift() == 0); 3082 constraint(ALLOC_IN_RC(ptr_reg)); 3083 match(AddP (DecodeN reg) off); 3084 3085 format %{ "[$reg + $off (8-bit)]" %} 3086 interface(MEMORY_INTER) %{ 3087 base($reg); 3088 index(0x4); 3089 scale(0x0); 3090 disp($off); 3091 %} 3092 %} 3093 3094 // Indirect Memory Plus Long Offset Operand 3095 operand indOffset32Narrow(rRegN reg, immL32 off) 3096 %{ 3097 predicate(CompressedOops::shift() == 0); 3098 constraint(ALLOC_IN_RC(ptr_reg)); 3099 match(AddP (DecodeN reg) off); 3100 3101 format %{ "[$reg + $off (32-bit)]" %} 3102 interface(MEMORY_INTER) %{ 3103 base($reg); 3104 index(0x4); 3105 scale(0x0); 3106 disp($off); 3107 %} 3108 %} 3109 3110 // Indirect Memory Plus Index Register Plus Offset Operand 3111 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3112 %{ 3113 predicate(CompressedOops::shift() == 0); 3114 constraint(ALLOC_IN_RC(ptr_reg)); 3115 match(AddP (AddP (DecodeN reg) lreg) off); 3116 3117 op_cost(10); 3118 format %{"[$reg + $off + $lreg]" %} 3119 interface(MEMORY_INTER) %{ 3120 base($reg); 3121 index($lreg); 3122 scale(0x0); 3123 disp($off); 3124 %} 3125 %} 3126 3127 // Indirect Memory Plus Index Register Plus Offset Operand 3128 operand indIndexNarrow(rRegN reg, rRegL lreg) 3129 %{ 3130 predicate(CompressedOops::shift() == 0); 3131 constraint(ALLOC_IN_RC(ptr_reg)); 3132 match(AddP (DecodeN reg) lreg); 3133 3134 op_cost(10); 3135 format %{"[$reg + $lreg]" %} 3136 interface(MEMORY_INTER) %{ 3137 base($reg); 3138 index($lreg); 3139 scale(0x0); 3140 disp(0x0); 3141 %} 3142 %} 3143 3144 // Indirect Memory Times Scale Plus Index Register 3145 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3146 %{ 3147 predicate(CompressedOops::shift() == 0); 3148 constraint(ALLOC_IN_RC(ptr_reg)); 3149 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3150 3151 op_cost(10); 3152 format %{"[$reg + $lreg << $scale]" %} 3153 interface(MEMORY_INTER) %{ 3154 base($reg); 3155 index($lreg); 3156 scale($scale); 3157 disp(0x0); 3158 %} 3159 %} 3160 3161 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3162 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3163 %{ 3164 predicate(CompressedOops::shift() == 0); 3165 constraint(ALLOC_IN_RC(ptr_reg)); 3166 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3167 3168 op_cost(10); 3169 format %{"[$reg + $off + $lreg << $scale]" %} 3170 interface(MEMORY_INTER) %{ 3171 base($reg); 3172 index($lreg); 3173 scale($scale); 3174 disp($off); 3175 %} 3176 %} 3177 3178 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3179 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3180 %{ 3181 constraint(ALLOC_IN_RC(ptr_reg)); 3182 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3183 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3184 3185 op_cost(10); 3186 format %{"[$reg + $off + $idx]" %} 3187 interface(MEMORY_INTER) %{ 3188 base($reg); 3189 index($idx); 3190 scale(0x0); 3191 disp($off); 3192 %} 3193 %} 3194 3195 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3196 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3197 %{ 3198 constraint(ALLOC_IN_RC(ptr_reg)); 3199 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3200 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3201 3202 op_cost(10); 3203 format %{"[$reg + $off + $idx << $scale]" %} 3204 interface(MEMORY_INTER) %{ 3205 base($reg); 3206 index($idx); 3207 scale($scale); 3208 disp($off); 3209 %} 3210 %} 3211 3212 //----------Special Memory Operands-------------------------------------------- 3213 // Stack Slot Operand - This operand is used for loading and storing temporary 3214 // values on the stack where a match requires a value to 3215 // flow through memory. 3216 operand stackSlotP(sRegP reg) 3217 %{ 3218 constraint(ALLOC_IN_RC(stack_slots)); 3219 // No match rule because this operand is only generated in matching 3220 3221 format %{ "[$reg]" %} 3222 interface(MEMORY_INTER) %{ 3223 base(0x4); // RSP 3224 index(0x4); // No Index 3225 scale(0x0); // No Scale 3226 disp($reg); // Stack Offset 3227 %} 3228 %} 3229 3230 operand stackSlotI(sRegI reg) 3231 %{ 3232 constraint(ALLOC_IN_RC(stack_slots)); 3233 // No match rule because this operand is only generated in matching 3234 3235 format %{ "[$reg]" %} 3236 interface(MEMORY_INTER) %{ 3237 base(0x4); // RSP 3238 index(0x4); // No Index 3239 scale(0x0); // No Scale 3240 disp($reg); // Stack Offset 3241 %} 3242 %} 3243 3244 operand stackSlotF(sRegF reg) 3245 %{ 3246 constraint(ALLOC_IN_RC(stack_slots)); 3247 // No match rule because this operand is only generated in matching 3248 3249 format %{ "[$reg]" %} 3250 interface(MEMORY_INTER) %{ 3251 base(0x4); // RSP 3252 index(0x4); // No Index 3253 scale(0x0); // No Scale 3254 disp($reg); // Stack Offset 3255 %} 3256 %} 3257 3258 operand stackSlotD(sRegD reg) 3259 %{ 3260 constraint(ALLOC_IN_RC(stack_slots)); 3261 // No match rule because this operand is only generated in matching 3262 3263 format %{ "[$reg]" %} 3264 interface(MEMORY_INTER) %{ 3265 base(0x4); // RSP 3266 index(0x4); // No Index 3267 scale(0x0); // No Scale 3268 disp($reg); // Stack Offset 3269 %} 3270 %} 3271 operand stackSlotL(sRegL reg) 3272 %{ 3273 constraint(ALLOC_IN_RC(stack_slots)); 3274 // No match rule because this operand is only generated in matching 3275 3276 format %{ "[$reg]" %} 3277 interface(MEMORY_INTER) %{ 3278 base(0x4); // RSP 3279 index(0x4); // No Index 3280 scale(0x0); // No Scale 3281 disp($reg); // Stack Offset 3282 %} 3283 %} 3284 3285 //----------Conditional Branch Operands---------------------------------------- 3286 // Comparison Op - This is the operation of the comparison, and is limited to 3287 // the following set of codes: 3288 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3289 // 3290 // Other attributes of the comparison, such as unsignedness, are specified 3291 // by the comparison instruction that sets a condition code flags register. 3292 // That result is represented by a flags operand whose subtype is appropriate 3293 // to the unsignedness (etc.) of the comparison. 3294 // 3295 // Later, the instruction which matches both the Comparison Op (a Bool) and 3296 // the flags (produced by the Cmp) specifies the coding of the comparison op 3297 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3298 3299 // Comparison Code 3300 operand cmpOp() 3301 %{ 3302 match(Bool); 3303 3304 format %{ "" %} 3305 interface(COND_INTER) %{ 3306 equal(0x4, "e"); 3307 not_equal(0x5, "ne"); 3308 less(0xC, "l"); 3309 greater_equal(0xD, "ge"); 3310 less_equal(0xE, "le"); 3311 greater(0xF, "g"); 3312 overflow(0x0, "o"); 3313 no_overflow(0x1, "no"); 3314 %} 3315 %} 3316 3317 // Comparison Code, unsigned compare. Used by FP also, with 3318 // C2 (unordered) turned into GT or LT already. The other bits 3319 // C0 and C3 are turned into Carry & Zero flags. 3320 operand cmpOpU() 3321 %{ 3322 match(Bool); 3323 3324 format %{ "" %} 3325 interface(COND_INTER) %{ 3326 equal(0x4, "e"); 3327 not_equal(0x5, "ne"); 3328 less(0x2, "b"); 3329 greater_equal(0x3, "ae"); 3330 less_equal(0x6, "be"); 3331 greater(0x7, "a"); 3332 overflow(0x0, "o"); 3333 no_overflow(0x1, "no"); 3334 %} 3335 %} 3336 3337 3338 // Floating comparisons that don't require any fixup for the unordered case, 3339 // If both inputs of the comparison are the same, ZF is always set so we 3340 // don't need to use cmpOpUCF2 for eq/ne 3341 operand cmpOpUCF() %{ 3342 match(Bool); 3343 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3344 n->as_Bool()->_test._test == BoolTest::ge || 3345 n->as_Bool()->_test._test == BoolTest::le || 3346 n->as_Bool()->_test._test == BoolTest::gt || 3347 n->in(1)->in(1) == n->in(1)->in(2)); 3348 format %{ "" %} 3349 interface(COND_INTER) %{ 3350 equal(0xb, "np"); 3351 not_equal(0xa, "p"); 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 can be fixed up with extra conditional jumps 3363 operand cmpOpUCF2() %{ 3364 match(Bool); 3365 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3366 n->as_Bool()->_test._test == BoolTest::eq) && 3367 n->in(1)->in(1) != n->in(1)->in(2)); 3368 format %{ "" %} 3369 interface(COND_INTER) %{ 3370 equal(0x4, "e"); 3371 not_equal(0x5, "ne"); 3372 less(0x2, "b"); 3373 greater_equal(0x3, "ae"); 3374 less_equal(0x6, "be"); 3375 greater(0x7, "a"); 3376 overflow(0x0, "o"); 3377 no_overflow(0x1, "no"); 3378 %} 3379 %} 3380 3381 //----------OPERAND CLASSES---------------------------------------------------- 3382 // Operand Classes are groups of operands that are used as to simplify 3383 // instruction definitions by not requiring the AD writer to specify separate 3384 // instructions for every form of operand when the instruction accepts 3385 // multiple operand types with the same basic encoding and format. The classic 3386 // case of this is memory operands. 3387 3388 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3389 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3390 indCompressedOopOffset, 3391 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3392 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3393 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3394 3395 //----------PIPELINE----------------------------------------------------------- 3396 // Rules which define the behavior of the target architectures pipeline. 3397 pipeline %{ 3398 3399 //----------ATTRIBUTES--------------------------------------------------------- 3400 attributes %{ 3401 variable_size_instructions; // Fixed size instructions 3402 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3403 instruction_unit_size = 1; // An instruction is 1 bytes long 3404 instruction_fetch_unit_size = 16; // The processor fetches one line 3405 instruction_fetch_units = 1; // of 16 bytes 3406 3407 // List of nop instructions 3408 nops( MachNop ); 3409 %} 3410 3411 //----------RESOURCES---------------------------------------------------------- 3412 // Resources are the functional units available to the machine 3413 3414 // Generic P2/P3 pipeline 3415 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3416 // 3 instructions decoded per cycle. 3417 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3418 // 3 ALU op, only ALU0 handles mul instructions. 3419 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3420 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3421 BR, FPU, 3422 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3423 3424 //----------PIPELINE DESCRIPTION----------------------------------------------- 3425 // Pipeline Description specifies the stages in the machine's pipeline 3426 3427 // Generic P2/P3 pipeline 3428 pipe_desc(S0, S1, S2, S3, S4, S5); 3429 3430 //----------PIPELINE CLASSES--------------------------------------------------- 3431 // Pipeline Classes describe the stages in which input and output are 3432 // referenced by the hardware pipeline. 3433 3434 // Naming convention: ialu or fpu 3435 // Then: _reg 3436 // Then: _reg if there is a 2nd register 3437 // Then: _long if it's a pair of instructions implementing a long 3438 // Then: _fat if it requires the big decoder 3439 // Or: _mem if it requires the big decoder and a memory unit. 3440 3441 // Integer ALU reg operation 3442 pipe_class ialu_reg(rRegI dst) 3443 %{ 3444 single_instruction; 3445 dst : S4(write); 3446 dst : S3(read); 3447 DECODE : S0; // any decoder 3448 ALU : S3; // any alu 3449 %} 3450 3451 // Long ALU reg operation 3452 pipe_class ialu_reg_long(rRegL dst) 3453 %{ 3454 instruction_count(2); 3455 dst : S4(write); 3456 dst : S3(read); 3457 DECODE : S0(2); // any 2 decoders 3458 ALU : S3(2); // both alus 3459 %} 3460 3461 // Integer ALU reg operation using big decoder 3462 pipe_class ialu_reg_fat(rRegI dst) 3463 %{ 3464 single_instruction; 3465 dst : S4(write); 3466 dst : S3(read); 3467 D0 : S0; // big decoder only 3468 ALU : S3; // any alu 3469 %} 3470 3471 // Integer ALU reg-reg operation 3472 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3473 %{ 3474 single_instruction; 3475 dst : S4(write); 3476 src : S3(read); 3477 DECODE : S0; // any decoder 3478 ALU : S3; // any alu 3479 %} 3480 3481 // Integer ALU reg-reg operation 3482 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3483 %{ 3484 single_instruction; 3485 dst : S4(write); 3486 src : S3(read); 3487 D0 : S0; // big decoder only 3488 ALU : S3; // any alu 3489 %} 3490 3491 // Integer ALU reg-mem operation 3492 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3493 %{ 3494 single_instruction; 3495 dst : S5(write); 3496 mem : S3(read); 3497 D0 : S0; // big decoder only 3498 ALU : S4; // any alu 3499 MEM : S3; // any mem 3500 %} 3501 3502 // Integer mem operation (prefetch) 3503 pipe_class ialu_mem(memory mem) 3504 %{ 3505 single_instruction; 3506 mem : S3(read); 3507 D0 : S0; // big decoder only 3508 MEM : S3; // any mem 3509 %} 3510 3511 // Integer Store to Memory 3512 pipe_class ialu_mem_reg(memory mem, rRegI src) 3513 %{ 3514 single_instruction; 3515 mem : S3(read); 3516 src : S5(read); 3517 D0 : S0; // big decoder only 3518 ALU : S4; // any alu 3519 MEM : S3; 3520 %} 3521 3522 // // Long Store to Memory 3523 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3524 // %{ 3525 // instruction_count(2); 3526 // mem : S3(read); 3527 // src : S5(read); 3528 // D0 : S0(2); // big decoder only; twice 3529 // ALU : S4(2); // any 2 alus 3530 // MEM : S3(2); // Both mems 3531 // %} 3532 3533 // Integer Store to Memory 3534 pipe_class ialu_mem_imm(memory mem) 3535 %{ 3536 single_instruction; 3537 mem : S3(read); 3538 D0 : S0; // big decoder only 3539 ALU : S4; // any alu 3540 MEM : S3; 3541 %} 3542 3543 // Integer ALU0 reg-reg operation 3544 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3545 %{ 3546 single_instruction; 3547 dst : S4(write); 3548 src : S3(read); 3549 D0 : S0; // Big decoder only 3550 ALU0 : S3; // only alu0 3551 %} 3552 3553 // Integer ALU0 reg-mem operation 3554 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3555 %{ 3556 single_instruction; 3557 dst : S5(write); 3558 mem : S3(read); 3559 D0 : S0; // big decoder only 3560 ALU0 : S4; // ALU0 only 3561 MEM : S3; // any mem 3562 %} 3563 3564 // Integer ALU reg-reg operation 3565 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3566 %{ 3567 single_instruction; 3568 cr : S4(write); 3569 src1 : S3(read); 3570 src2 : S3(read); 3571 DECODE : S0; // any decoder 3572 ALU : S3; // any alu 3573 %} 3574 3575 // Integer ALU reg-imm operation 3576 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3577 %{ 3578 single_instruction; 3579 cr : S4(write); 3580 src1 : S3(read); 3581 DECODE : S0; // any decoder 3582 ALU : S3; // any alu 3583 %} 3584 3585 // Integer ALU reg-mem operation 3586 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3587 %{ 3588 single_instruction; 3589 cr : S4(write); 3590 src1 : S3(read); 3591 src2 : S3(read); 3592 D0 : S0; // big decoder only 3593 ALU : S4; // any alu 3594 MEM : S3; 3595 %} 3596 3597 // Conditional move reg-reg 3598 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3599 %{ 3600 instruction_count(4); 3601 y : S4(read); 3602 q : S3(read); 3603 p : S3(read); 3604 DECODE : S0(4); // any decoder 3605 %} 3606 3607 // Conditional move reg-reg 3608 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3609 %{ 3610 single_instruction; 3611 dst : S4(write); 3612 src : S3(read); 3613 cr : S3(read); 3614 DECODE : S0; // any decoder 3615 %} 3616 3617 // Conditional move reg-mem 3618 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3619 %{ 3620 single_instruction; 3621 dst : S4(write); 3622 src : S3(read); 3623 cr : S3(read); 3624 DECODE : S0; // any decoder 3625 MEM : S3; 3626 %} 3627 3628 // Conditional move reg-reg long 3629 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3630 %{ 3631 single_instruction; 3632 dst : S4(write); 3633 src : S3(read); 3634 cr : S3(read); 3635 DECODE : S0(2); // any 2 decoders 3636 %} 3637 3638 // Float reg-reg operation 3639 pipe_class fpu_reg(regD dst) 3640 %{ 3641 instruction_count(2); 3642 dst : S3(read); 3643 DECODE : S0(2); // any 2 decoders 3644 FPU : S3; 3645 %} 3646 3647 // Float reg-reg operation 3648 pipe_class fpu_reg_reg(regD dst, regD src) 3649 %{ 3650 instruction_count(2); 3651 dst : S4(write); 3652 src : S3(read); 3653 DECODE : S0(2); // any 2 decoders 3654 FPU : S3; 3655 %} 3656 3657 // Float reg-reg operation 3658 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3659 %{ 3660 instruction_count(3); 3661 dst : S4(write); 3662 src1 : S3(read); 3663 src2 : S3(read); 3664 DECODE : S0(3); // any 3 decoders 3665 FPU : S3(2); 3666 %} 3667 3668 // Float reg-reg operation 3669 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3670 %{ 3671 instruction_count(4); 3672 dst : S4(write); 3673 src1 : S3(read); 3674 src2 : S3(read); 3675 src3 : S3(read); 3676 DECODE : S0(4); // any 3 decoders 3677 FPU : S3(2); 3678 %} 3679 3680 // Float reg-reg operation 3681 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3682 %{ 3683 instruction_count(4); 3684 dst : S4(write); 3685 src1 : S3(read); 3686 src2 : S3(read); 3687 src3 : S3(read); 3688 DECODE : S1(3); // any 3 decoders 3689 D0 : S0; // Big decoder only 3690 FPU : S3(2); 3691 MEM : S3; 3692 %} 3693 3694 // Float reg-mem operation 3695 pipe_class fpu_reg_mem(regD dst, memory mem) 3696 %{ 3697 instruction_count(2); 3698 dst : S5(write); 3699 mem : S3(read); 3700 D0 : S0; // big decoder only 3701 DECODE : S1; // any decoder for FPU POP 3702 FPU : S4; 3703 MEM : S3; // any mem 3704 %} 3705 3706 // Float reg-mem operation 3707 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3708 %{ 3709 instruction_count(3); 3710 dst : S5(write); 3711 src1 : S3(read); 3712 mem : S3(read); 3713 D0 : S0; // big decoder only 3714 DECODE : S1(2); // any decoder for FPU POP 3715 FPU : S4; 3716 MEM : S3; // any mem 3717 %} 3718 3719 // Float mem-reg operation 3720 pipe_class fpu_mem_reg(memory mem, regD src) 3721 %{ 3722 instruction_count(2); 3723 src : S5(read); 3724 mem : S3(read); 3725 DECODE : S0; // any decoder for FPU PUSH 3726 D0 : S1; // big decoder only 3727 FPU : S4; 3728 MEM : S3; // any mem 3729 %} 3730 3731 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3732 %{ 3733 instruction_count(3); 3734 src1 : S3(read); 3735 src2 : S3(read); 3736 mem : S3(read); 3737 DECODE : S0(2); // any decoder for FPU PUSH 3738 D0 : S1; // big decoder only 3739 FPU : S4; 3740 MEM : S3; // any mem 3741 %} 3742 3743 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3744 %{ 3745 instruction_count(3); 3746 src1 : S3(read); 3747 src2 : S3(read); 3748 mem : S4(read); 3749 DECODE : S0; // any decoder for FPU PUSH 3750 D0 : S0(2); // big decoder only 3751 FPU : S4; 3752 MEM : S3(2); // any mem 3753 %} 3754 3755 pipe_class fpu_mem_mem(memory dst, memory src1) 3756 %{ 3757 instruction_count(2); 3758 src1 : S3(read); 3759 dst : S4(read); 3760 D0 : S0(2); // big decoder only 3761 MEM : S3(2); // any mem 3762 %} 3763 3764 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3765 %{ 3766 instruction_count(3); 3767 src1 : S3(read); 3768 src2 : S3(read); 3769 dst : S4(read); 3770 D0 : S0(3); // big decoder only 3771 FPU : S4; 3772 MEM : S3(3); // any mem 3773 %} 3774 3775 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3776 %{ 3777 instruction_count(3); 3778 src1 : S4(read); 3779 mem : S4(read); 3780 DECODE : S0; // any decoder for FPU PUSH 3781 D0 : S0(2); // big decoder only 3782 FPU : S4; 3783 MEM : S3(2); // any mem 3784 %} 3785 3786 // Float load constant 3787 pipe_class fpu_reg_con(regD dst) 3788 %{ 3789 instruction_count(2); 3790 dst : S5(write); 3791 D0 : S0; // big decoder only for the load 3792 DECODE : S1; // any decoder for FPU POP 3793 FPU : S4; 3794 MEM : S3; // any mem 3795 %} 3796 3797 // Float load constant 3798 pipe_class fpu_reg_reg_con(regD dst, regD src) 3799 %{ 3800 instruction_count(3); 3801 dst : S5(write); 3802 src : S3(read); 3803 D0 : S0; // big decoder only for the load 3804 DECODE : S1(2); // any decoder for FPU POP 3805 FPU : S4; 3806 MEM : S3; // any mem 3807 %} 3808 3809 // UnConditional branch 3810 pipe_class pipe_jmp(label labl) 3811 %{ 3812 single_instruction; 3813 BR : S3; 3814 %} 3815 3816 // Conditional branch 3817 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3818 %{ 3819 single_instruction; 3820 cr : S1(read); 3821 BR : S3; 3822 %} 3823 3824 // Allocation idiom 3825 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3826 %{ 3827 instruction_count(1); force_serialization; 3828 fixed_latency(6); 3829 heap_ptr : S3(read); 3830 DECODE : S0(3); 3831 D0 : S2; 3832 MEM : S3; 3833 ALU : S3(2); 3834 dst : S5(write); 3835 BR : S5; 3836 %} 3837 3838 // Generic big/slow expanded idiom 3839 pipe_class pipe_slow() 3840 %{ 3841 instruction_count(10); multiple_bundles; force_serialization; 3842 fixed_latency(100); 3843 D0 : S0(2); 3844 MEM : S3(2); 3845 %} 3846 3847 // The real do-nothing guy 3848 pipe_class empty() 3849 %{ 3850 instruction_count(0); 3851 %} 3852 3853 // Define the class for the Nop node 3854 define 3855 %{ 3856 MachNop = empty; 3857 %} 3858 3859 %} 3860 3861 //----------INSTRUCTIONS------------------------------------------------------- 3862 // 3863 // match -- States which machine-independent subtree may be replaced 3864 // by this instruction. 3865 // ins_cost -- The estimated cost of this instruction is used by instruction 3866 // selection to identify a minimum cost tree of machine 3867 // instructions that matches a tree of machine-independent 3868 // instructions. 3869 // format -- A string providing the disassembly for this instruction. 3870 // The value of an instruction's operand may be inserted 3871 // by referring to it with a '$' prefix. 3872 // opcode -- Three instruction opcodes may be provided. These are referred 3873 // to within an encode class as $primary, $secondary, and $tertiary 3874 // rrspectively. The primary opcode is commonly used to 3875 // indicate the type of machine instruction, while secondary 3876 // and tertiary are often used for prefix options or addressing 3877 // modes. 3878 // ins_encode -- A list of encode classes with parameters. The encode class 3879 // name must have been defined in an 'enc_class' specification 3880 // in the encode section of the architecture description. 3881 3882 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3883 // Load Float 3884 instruct MoveF2VL(vlRegF dst, regF src) %{ 3885 match(Set dst src); 3886 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3887 ins_encode %{ 3888 ShouldNotReachHere(); 3889 %} 3890 ins_pipe( fpu_reg_reg ); 3891 %} 3892 3893 // Load Float 3894 instruct MoveF2LEG(legRegF dst, regF src) %{ 3895 match(Set dst src); 3896 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3897 ins_encode %{ 3898 ShouldNotReachHere(); 3899 %} 3900 ins_pipe( fpu_reg_reg ); 3901 %} 3902 3903 // Load Float 3904 instruct MoveVL2F(regF dst, vlRegF src) %{ 3905 match(Set dst src); 3906 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3907 ins_encode %{ 3908 ShouldNotReachHere(); 3909 %} 3910 ins_pipe( fpu_reg_reg ); 3911 %} 3912 3913 // Load Float 3914 instruct MoveLEG2F(regF dst, legRegF src) %{ 3915 match(Set dst src); 3916 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3917 ins_encode %{ 3918 ShouldNotReachHere(); 3919 %} 3920 ins_pipe( fpu_reg_reg ); 3921 %} 3922 3923 // Load Double 3924 instruct MoveD2VL(vlRegD dst, regD src) %{ 3925 match(Set dst src); 3926 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3927 ins_encode %{ 3928 ShouldNotReachHere(); 3929 %} 3930 ins_pipe( fpu_reg_reg ); 3931 %} 3932 3933 // Load Double 3934 instruct MoveD2LEG(legRegD dst, regD src) %{ 3935 match(Set dst src); 3936 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3937 ins_encode %{ 3938 ShouldNotReachHere(); 3939 %} 3940 ins_pipe( fpu_reg_reg ); 3941 %} 3942 3943 // Load Double 3944 instruct MoveVL2D(regD dst, vlRegD src) %{ 3945 match(Set dst src); 3946 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3947 ins_encode %{ 3948 ShouldNotReachHere(); 3949 %} 3950 ins_pipe( fpu_reg_reg ); 3951 %} 3952 3953 // Load Double 3954 instruct MoveLEG2D(regD dst, legRegD src) %{ 3955 match(Set dst src); 3956 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3957 ins_encode %{ 3958 ShouldNotReachHere(); 3959 %} 3960 ins_pipe( fpu_reg_reg ); 3961 %} 3962 3963 //----------Load/Store/Move Instructions--------------------------------------- 3964 //----------Load Instructions-------------------------------------------------- 3965 3966 // Load Byte (8 bit signed) 3967 instruct loadB(rRegI dst, memory mem) 3968 %{ 3969 match(Set dst (LoadB mem)); 3970 3971 ins_cost(125); 3972 format %{ "movsbl $dst, $mem\t# byte" %} 3973 3974 ins_encode %{ 3975 __ movsbl($dst$$Register, $mem$$Address); 3976 %} 3977 3978 ins_pipe(ialu_reg_mem); 3979 %} 3980 3981 // Load Byte (8 bit signed) into Long Register 3982 instruct loadB2L(rRegL dst, memory mem) 3983 %{ 3984 match(Set dst (ConvI2L (LoadB mem))); 3985 3986 ins_cost(125); 3987 format %{ "movsbq $dst, $mem\t# byte -> long" %} 3988 3989 ins_encode %{ 3990 __ movsbq($dst$$Register, $mem$$Address); 3991 %} 3992 3993 ins_pipe(ialu_reg_mem); 3994 %} 3995 3996 // Load Unsigned Byte (8 bit UNsigned) 3997 instruct loadUB(rRegI dst, memory mem) 3998 %{ 3999 match(Set dst (LoadUB mem)); 4000 4001 ins_cost(125); 4002 format %{ "movzbl $dst, $mem\t# ubyte" %} 4003 4004 ins_encode %{ 4005 __ movzbl($dst$$Register, $mem$$Address); 4006 %} 4007 4008 ins_pipe(ialu_reg_mem); 4009 %} 4010 4011 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4012 instruct loadUB2L(rRegL dst, memory mem) 4013 %{ 4014 match(Set dst (ConvI2L (LoadUB mem))); 4015 4016 ins_cost(125); 4017 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4018 4019 ins_encode %{ 4020 __ movzbq($dst$$Register, $mem$$Address); 4021 %} 4022 4023 ins_pipe(ialu_reg_mem); 4024 %} 4025 4026 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4027 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4028 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4029 effect(KILL cr); 4030 4031 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4032 "andl $dst, right_n_bits($mask, 8)" %} 4033 ins_encode %{ 4034 Register Rdst = $dst$$Register; 4035 __ movzbq(Rdst, $mem$$Address); 4036 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4037 %} 4038 ins_pipe(ialu_reg_mem); 4039 %} 4040 4041 // Load Short (16 bit signed) 4042 instruct loadS(rRegI dst, memory mem) 4043 %{ 4044 match(Set dst (LoadS mem)); 4045 4046 ins_cost(125); 4047 format %{ "movswl $dst, $mem\t# short" %} 4048 4049 ins_encode %{ 4050 __ movswl($dst$$Register, $mem$$Address); 4051 %} 4052 4053 ins_pipe(ialu_reg_mem); 4054 %} 4055 4056 // Load Short (16 bit signed) to Byte (8 bit signed) 4057 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4058 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4059 4060 ins_cost(125); 4061 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4062 ins_encode %{ 4063 __ movsbl($dst$$Register, $mem$$Address); 4064 %} 4065 ins_pipe(ialu_reg_mem); 4066 %} 4067 4068 // Load Short (16 bit signed) into Long Register 4069 instruct loadS2L(rRegL dst, memory mem) 4070 %{ 4071 match(Set dst (ConvI2L (LoadS mem))); 4072 4073 ins_cost(125); 4074 format %{ "movswq $dst, $mem\t# short -> long" %} 4075 4076 ins_encode %{ 4077 __ movswq($dst$$Register, $mem$$Address); 4078 %} 4079 4080 ins_pipe(ialu_reg_mem); 4081 %} 4082 4083 // Load Unsigned Short/Char (16 bit UNsigned) 4084 instruct loadUS(rRegI dst, memory mem) 4085 %{ 4086 match(Set dst (LoadUS mem)); 4087 4088 ins_cost(125); 4089 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4090 4091 ins_encode %{ 4092 __ movzwl($dst$$Register, $mem$$Address); 4093 %} 4094 4095 ins_pipe(ialu_reg_mem); 4096 %} 4097 4098 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4099 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4100 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4101 4102 ins_cost(125); 4103 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4104 ins_encode %{ 4105 __ movsbl($dst$$Register, $mem$$Address); 4106 %} 4107 ins_pipe(ialu_reg_mem); 4108 %} 4109 4110 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4111 instruct loadUS2L(rRegL dst, memory mem) 4112 %{ 4113 match(Set dst (ConvI2L (LoadUS mem))); 4114 4115 ins_cost(125); 4116 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4117 4118 ins_encode %{ 4119 __ movzwq($dst$$Register, $mem$$Address); 4120 %} 4121 4122 ins_pipe(ialu_reg_mem); 4123 %} 4124 4125 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4126 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4127 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4128 4129 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4130 ins_encode %{ 4131 __ movzbq($dst$$Register, $mem$$Address); 4132 %} 4133 ins_pipe(ialu_reg_mem); 4134 %} 4135 4136 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4137 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4138 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4139 effect(KILL cr); 4140 4141 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4142 "andl $dst, right_n_bits($mask, 16)" %} 4143 ins_encode %{ 4144 Register Rdst = $dst$$Register; 4145 __ movzwq(Rdst, $mem$$Address); 4146 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4147 %} 4148 ins_pipe(ialu_reg_mem); 4149 %} 4150 4151 // Load Integer 4152 instruct loadI(rRegI dst, memory mem) 4153 %{ 4154 match(Set dst (LoadI mem)); 4155 4156 ins_cost(125); 4157 format %{ "movl $dst, $mem\t# int" %} 4158 4159 ins_encode %{ 4160 __ movl($dst$$Register, $mem$$Address); 4161 %} 4162 4163 ins_pipe(ialu_reg_mem); 4164 %} 4165 4166 // Load Integer (32 bit signed) to Byte (8 bit signed) 4167 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4168 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4169 4170 ins_cost(125); 4171 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4172 ins_encode %{ 4173 __ movsbl($dst$$Register, $mem$$Address); 4174 %} 4175 ins_pipe(ialu_reg_mem); 4176 %} 4177 4178 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4179 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4180 match(Set dst (AndI (LoadI mem) mask)); 4181 4182 ins_cost(125); 4183 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4184 ins_encode %{ 4185 __ movzbl($dst$$Register, $mem$$Address); 4186 %} 4187 ins_pipe(ialu_reg_mem); 4188 %} 4189 4190 // Load Integer (32 bit signed) to Short (16 bit signed) 4191 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4192 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4193 4194 ins_cost(125); 4195 format %{ "movswl $dst, $mem\t# int -> short" %} 4196 ins_encode %{ 4197 __ movswl($dst$$Register, $mem$$Address); 4198 %} 4199 ins_pipe(ialu_reg_mem); 4200 %} 4201 4202 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4203 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4204 match(Set dst (AndI (LoadI mem) mask)); 4205 4206 ins_cost(125); 4207 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4208 ins_encode %{ 4209 __ movzwl($dst$$Register, $mem$$Address); 4210 %} 4211 ins_pipe(ialu_reg_mem); 4212 %} 4213 4214 // Load Integer into Long Register 4215 instruct loadI2L(rRegL dst, memory mem) 4216 %{ 4217 match(Set dst (ConvI2L (LoadI mem))); 4218 4219 ins_cost(125); 4220 format %{ "movslq $dst, $mem\t# int -> long" %} 4221 4222 ins_encode %{ 4223 __ movslq($dst$$Register, $mem$$Address); 4224 %} 4225 4226 ins_pipe(ialu_reg_mem); 4227 %} 4228 4229 // Load Integer with mask 0xFF into Long Register 4230 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4231 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4232 4233 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4234 ins_encode %{ 4235 __ movzbq($dst$$Register, $mem$$Address); 4236 %} 4237 ins_pipe(ialu_reg_mem); 4238 %} 4239 4240 // Load Integer with mask 0xFFFF into Long Register 4241 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4242 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4243 4244 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4245 ins_encode %{ 4246 __ movzwq($dst$$Register, $mem$$Address); 4247 %} 4248 ins_pipe(ialu_reg_mem); 4249 %} 4250 4251 // Load Integer with a 31-bit mask into Long Register 4252 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4253 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4254 effect(KILL cr); 4255 4256 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4257 "andl $dst, $mask" %} 4258 ins_encode %{ 4259 Register Rdst = $dst$$Register; 4260 __ movl(Rdst, $mem$$Address); 4261 __ andl(Rdst, $mask$$constant); 4262 %} 4263 ins_pipe(ialu_reg_mem); 4264 %} 4265 4266 // Load Unsigned Integer into Long Register 4267 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4268 %{ 4269 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4270 4271 ins_cost(125); 4272 format %{ "movl $dst, $mem\t# uint -> long" %} 4273 4274 ins_encode %{ 4275 __ movl($dst$$Register, $mem$$Address); 4276 %} 4277 4278 ins_pipe(ialu_reg_mem); 4279 %} 4280 4281 // Load Long 4282 instruct loadL(rRegL dst, memory mem) 4283 %{ 4284 match(Set dst (LoadL mem)); 4285 4286 ins_cost(125); 4287 format %{ "movq $dst, $mem\t# long" %} 4288 4289 ins_encode %{ 4290 __ movq($dst$$Register, $mem$$Address); 4291 %} 4292 4293 ins_pipe(ialu_reg_mem); // XXX 4294 %} 4295 4296 // Load Range 4297 instruct loadRange(rRegI dst, memory mem) 4298 %{ 4299 match(Set dst (LoadRange mem)); 4300 4301 ins_cost(125); // XXX 4302 format %{ "movl $dst, $mem\t# range" %} 4303 ins_encode %{ 4304 __ movl($dst$$Register, $mem$$Address); 4305 %} 4306 ins_pipe(ialu_reg_mem); 4307 %} 4308 4309 // Load Pointer 4310 instruct loadP(rRegP dst, memory mem) 4311 %{ 4312 match(Set dst (LoadP mem)); 4313 predicate(n->as_Load()->barrier_data() == 0); 4314 4315 ins_cost(125); // XXX 4316 format %{ "movq $dst, $mem\t# ptr" %} 4317 ins_encode %{ 4318 __ movq($dst$$Register, $mem$$Address); 4319 %} 4320 ins_pipe(ialu_reg_mem); // XXX 4321 %} 4322 4323 // Load Compressed Pointer 4324 instruct loadN(rRegN dst, memory mem) 4325 %{ 4326 predicate(n->as_Load()->barrier_data() == 0); 4327 match(Set dst (LoadN mem)); 4328 4329 ins_cost(125); // XXX 4330 format %{ "movl $dst, $mem\t# compressed ptr" %} 4331 ins_encode %{ 4332 __ movl($dst$$Register, $mem$$Address); 4333 %} 4334 ins_pipe(ialu_reg_mem); // XXX 4335 %} 4336 4337 4338 // Load Klass Pointer 4339 instruct loadKlass(rRegP dst, memory mem) 4340 %{ 4341 match(Set dst (LoadKlass mem)); 4342 4343 ins_cost(125); // XXX 4344 format %{ "movq $dst, $mem\t# class" %} 4345 ins_encode %{ 4346 __ movq($dst$$Register, $mem$$Address); 4347 %} 4348 ins_pipe(ialu_reg_mem); // XXX 4349 %} 4350 4351 // Load narrow Klass Pointer 4352 instruct loadNKlass(rRegN dst, memory mem) 4353 %{ 4354 predicate(!UseCompactObjectHeaders); 4355 match(Set dst (LoadNKlass mem)); 4356 4357 ins_cost(125); // XXX 4358 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4359 ins_encode %{ 4360 __ movl($dst$$Register, $mem$$Address); 4361 %} 4362 ins_pipe(ialu_reg_mem); // XXX 4363 %} 4364 4365 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4366 %{ 4367 predicate(UseCompactObjectHeaders); 4368 match(Set dst (LoadNKlass mem)); 4369 effect(KILL cr); 4370 ins_cost(125); // XXX 4371 format %{ 4372 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4373 "shrl $dst, markWord::klass_shift" 4374 %} 4375 ins_encode %{ 4376 // The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract 4377 // obj-start, so that we can load from the object's mark-word instead. Usually the address 4378 // comes as obj-start in obj and klass_offset_in_bytes in disp. 4379 Register d = $dst$$Register; 4380 Address s = $mem$$Address; 4381 __ movl(d, s.plus_disp(-Type::klass_offset())); 4382 __ shrl(d, markWord::klass_shift); 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 xtmp, rRegI rtmp, rFlagsReg cr) %{ 4440 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4441 match(Set dst (MaxF a b)); 4442 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4443 4444 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4445 ins_encode %{ 4446 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$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 xtmp, rRegL rtmp, rFlagsReg cr) %{ 4465 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4466 match(Set dst (MaxD a b)); 4467 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4468 4469 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4470 ins_encode %{ 4471 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$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 xtmp, rRegI rtmp, rFlagsReg cr) %{ 4490 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4491 match(Set dst (MinF a b)); 4492 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4493 4494 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4495 ins_encode %{ 4496 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$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 xtmp, rRegL rtmp, rFlagsReg cr) %{ 4515 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4516 match(Set dst (MinD a b)); 4517 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4518 4519 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4520 ins_encode %{ 4521 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$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 predicate(n->as_Store()->barrier_data() == 0); 5136 match(Set mem (StoreN mem src)); 5137 5138 ins_cost(125); // XXX 5139 format %{ "movl $mem, $src\t# compressed ptr" %} 5140 ins_encode %{ 5141 __ movl($mem$$Address, $src$$Register); 5142 %} 5143 ins_pipe(ialu_mem_reg); 5144 %} 5145 5146 instruct storeNKlass(memory mem, rRegN src) 5147 %{ 5148 match(Set mem (StoreNKlass mem src)); 5149 5150 ins_cost(125); // XXX 5151 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5152 ins_encode %{ 5153 __ movl($mem$$Address, $src$$Register); 5154 %} 5155 ins_pipe(ialu_mem_reg); 5156 %} 5157 5158 instruct storeImmN0(memory mem, immN0 zero) 5159 %{ 5160 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5161 match(Set mem (StoreN mem zero)); 5162 5163 ins_cost(125); // XXX 5164 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5165 ins_encode %{ 5166 __ movl($mem$$Address, r12); 5167 %} 5168 ins_pipe(ialu_mem_reg); 5169 %} 5170 5171 instruct storeImmN(memory mem, immN src) 5172 %{ 5173 predicate(n->as_Store()->barrier_data() == 0); 5174 match(Set mem (StoreN mem src)); 5175 5176 ins_cost(150); // XXX 5177 format %{ "movl $mem, $src\t# compressed ptr" %} 5178 ins_encode %{ 5179 address con = (address)$src$$constant; 5180 if (con == nullptr) { 5181 __ movl($mem$$Address, 0); 5182 } else { 5183 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5184 } 5185 %} 5186 ins_pipe(ialu_mem_imm); 5187 %} 5188 5189 instruct storeImmNKlass(memory mem, immNKlass src) 5190 %{ 5191 match(Set mem (StoreNKlass mem src)); 5192 5193 ins_cost(150); // XXX 5194 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5195 ins_encode %{ 5196 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5197 %} 5198 ins_pipe(ialu_mem_imm); 5199 %} 5200 5201 // Store Integer Immediate 5202 instruct storeImmI0(memory mem, immI_0 zero) 5203 %{ 5204 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5205 match(Set mem (StoreI mem zero)); 5206 5207 ins_cost(125); // XXX 5208 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5209 ins_encode %{ 5210 __ movl($mem$$Address, r12); 5211 %} 5212 ins_pipe(ialu_mem_reg); 5213 %} 5214 5215 instruct storeImmI(memory mem, immI src) 5216 %{ 5217 match(Set mem (StoreI mem src)); 5218 5219 ins_cost(150); 5220 format %{ "movl $mem, $src\t# int" %} 5221 ins_encode %{ 5222 __ movl($mem$$Address, $src$$constant); 5223 %} 5224 ins_pipe(ialu_mem_imm); 5225 %} 5226 5227 // Store Long Immediate 5228 instruct storeImmL0(memory mem, immL0 zero) 5229 %{ 5230 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5231 match(Set mem (StoreL mem zero)); 5232 5233 ins_cost(125); // XXX 5234 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5235 ins_encode %{ 5236 __ movq($mem$$Address, r12); 5237 %} 5238 ins_pipe(ialu_mem_reg); 5239 %} 5240 5241 instruct storeImmL(memory mem, immL32 src) 5242 %{ 5243 match(Set mem (StoreL mem src)); 5244 5245 ins_cost(150); 5246 format %{ "movq $mem, $src\t# long" %} 5247 ins_encode %{ 5248 __ movq($mem$$Address, $src$$constant); 5249 %} 5250 ins_pipe(ialu_mem_imm); 5251 %} 5252 5253 // Store Short/Char Immediate 5254 instruct storeImmC0(memory mem, immI_0 zero) 5255 %{ 5256 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5257 match(Set mem (StoreC mem zero)); 5258 5259 ins_cost(125); // XXX 5260 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5261 ins_encode %{ 5262 __ movw($mem$$Address, r12); 5263 %} 5264 ins_pipe(ialu_mem_reg); 5265 %} 5266 5267 instruct storeImmI16(memory mem, immI16 src) 5268 %{ 5269 predicate(UseStoreImmI16); 5270 match(Set mem (StoreC mem src)); 5271 5272 ins_cost(150); 5273 format %{ "movw $mem, $src\t# short/char" %} 5274 ins_encode %{ 5275 __ movw($mem$$Address, $src$$constant); 5276 %} 5277 ins_pipe(ialu_mem_imm); 5278 %} 5279 5280 // Store Byte Immediate 5281 instruct storeImmB0(memory mem, immI_0 zero) 5282 %{ 5283 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5284 match(Set mem (StoreB mem zero)); 5285 5286 ins_cost(125); // XXX 5287 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5288 ins_encode %{ 5289 __ movb($mem$$Address, r12); 5290 %} 5291 ins_pipe(ialu_mem_reg); 5292 %} 5293 5294 instruct storeImmB(memory mem, immI8 src) 5295 %{ 5296 match(Set mem (StoreB mem src)); 5297 5298 ins_cost(150); // XXX 5299 format %{ "movb $mem, $src\t# byte" %} 5300 ins_encode %{ 5301 __ movb($mem$$Address, $src$$constant); 5302 %} 5303 ins_pipe(ialu_mem_imm); 5304 %} 5305 5306 // Store Float 5307 instruct storeF(memory mem, regF src) 5308 %{ 5309 match(Set mem (StoreF mem src)); 5310 5311 ins_cost(95); // XXX 5312 format %{ "movss $mem, $src\t# float" %} 5313 ins_encode %{ 5314 __ movflt($mem$$Address, $src$$XMMRegister); 5315 %} 5316 ins_pipe(pipe_slow); // XXX 5317 %} 5318 5319 // Store immediate Float value (it is faster than store from XMM register) 5320 instruct storeF0(memory mem, immF0 zero) 5321 %{ 5322 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5323 match(Set mem (StoreF mem zero)); 5324 5325 ins_cost(25); // XXX 5326 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5327 ins_encode %{ 5328 __ movl($mem$$Address, r12); 5329 %} 5330 ins_pipe(ialu_mem_reg); 5331 %} 5332 5333 instruct storeF_imm(memory mem, immF src) 5334 %{ 5335 match(Set mem (StoreF mem src)); 5336 5337 ins_cost(50); 5338 format %{ "movl $mem, $src\t# float" %} 5339 ins_encode %{ 5340 __ movl($mem$$Address, jint_cast($src$$constant)); 5341 %} 5342 ins_pipe(ialu_mem_imm); 5343 %} 5344 5345 // Store Double 5346 instruct storeD(memory mem, regD src) 5347 %{ 5348 match(Set mem (StoreD mem src)); 5349 5350 ins_cost(95); // XXX 5351 format %{ "movsd $mem, $src\t# double" %} 5352 ins_encode %{ 5353 __ movdbl($mem$$Address, $src$$XMMRegister); 5354 %} 5355 ins_pipe(pipe_slow); // XXX 5356 %} 5357 5358 // Store immediate double 0.0 (it is faster than store from XMM register) 5359 instruct storeD0_imm(memory mem, immD0 src) 5360 %{ 5361 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5362 match(Set mem (StoreD mem src)); 5363 5364 ins_cost(50); 5365 format %{ "movq $mem, $src\t# double 0." %} 5366 ins_encode %{ 5367 __ movq($mem$$Address, $src$$constant); 5368 %} 5369 ins_pipe(ialu_mem_imm); 5370 %} 5371 5372 instruct storeD0(memory mem, immD0 zero) 5373 %{ 5374 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5375 match(Set mem (StoreD mem zero)); 5376 5377 ins_cost(25); // XXX 5378 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5379 ins_encode %{ 5380 __ movq($mem$$Address, r12); 5381 %} 5382 ins_pipe(ialu_mem_reg); 5383 %} 5384 5385 instruct storeSSI(stackSlotI dst, rRegI src) 5386 %{ 5387 match(Set dst src); 5388 5389 ins_cost(100); 5390 format %{ "movl $dst, $src\t# int stk" %} 5391 ins_encode %{ 5392 __ movl($dst$$Address, $src$$Register); 5393 %} 5394 ins_pipe( ialu_mem_reg ); 5395 %} 5396 5397 instruct storeSSL(stackSlotL dst, rRegL src) 5398 %{ 5399 match(Set dst src); 5400 5401 ins_cost(100); 5402 format %{ "movq $dst, $src\t# long stk" %} 5403 ins_encode %{ 5404 __ movq($dst$$Address, $src$$Register); 5405 %} 5406 ins_pipe(ialu_mem_reg); 5407 %} 5408 5409 instruct storeSSP(stackSlotP dst, rRegP src) 5410 %{ 5411 match(Set dst src); 5412 5413 ins_cost(100); 5414 format %{ "movq $dst, $src\t# ptr stk" %} 5415 ins_encode %{ 5416 __ movq($dst$$Address, $src$$Register); 5417 %} 5418 ins_pipe(ialu_mem_reg); 5419 %} 5420 5421 instruct storeSSF(stackSlotF dst, regF src) 5422 %{ 5423 match(Set dst src); 5424 5425 ins_cost(95); // XXX 5426 format %{ "movss $dst, $src\t# float stk" %} 5427 ins_encode %{ 5428 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5429 %} 5430 ins_pipe(pipe_slow); // XXX 5431 %} 5432 5433 instruct storeSSD(stackSlotD dst, regD src) 5434 %{ 5435 match(Set dst src); 5436 5437 ins_cost(95); // XXX 5438 format %{ "movsd $dst, $src\t# double stk" %} 5439 ins_encode %{ 5440 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5441 %} 5442 ins_pipe(pipe_slow); // XXX 5443 %} 5444 5445 instruct cacheWB(indirect addr) 5446 %{ 5447 predicate(VM_Version::supports_data_cache_line_flush()); 5448 match(CacheWB addr); 5449 5450 ins_cost(100); 5451 format %{"cache wb $addr" %} 5452 ins_encode %{ 5453 assert($addr->index_position() < 0, "should be"); 5454 assert($addr$$disp == 0, "should be"); 5455 __ cache_wb(Address($addr$$base$$Register, 0)); 5456 %} 5457 ins_pipe(pipe_slow); // XXX 5458 %} 5459 5460 instruct cacheWBPreSync() 5461 %{ 5462 predicate(VM_Version::supports_data_cache_line_flush()); 5463 match(CacheWBPreSync); 5464 5465 ins_cost(100); 5466 format %{"cache wb presync" %} 5467 ins_encode %{ 5468 __ cache_wbsync(true); 5469 %} 5470 ins_pipe(pipe_slow); // XXX 5471 %} 5472 5473 instruct cacheWBPostSync() 5474 %{ 5475 predicate(VM_Version::supports_data_cache_line_flush()); 5476 match(CacheWBPostSync); 5477 5478 ins_cost(100); 5479 format %{"cache wb postsync" %} 5480 ins_encode %{ 5481 __ cache_wbsync(false); 5482 %} 5483 ins_pipe(pipe_slow); // XXX 5484 %} 5485 5486 //----------BSWAP Instructions------------------------------------------------- 5487 instruct bytes_reverse_int(rRegI dst) %{ 5488 match(Set dst (ReverseBytesI dst)); 5489 5490 format %{ "bswapl $dst" %} 5491 ins_encode %{ 5492 __ bswapl($dst$$Register); 5493 %} 5494 ins_pipe( ialu_reg ); 5495 %} 5496 5497 instruct bytes_reverse_long(rRegL dst) %{ 5498 match(Set dst (ReverseBytesL dst)); 5499 5500 format %{ "bswapq $dst" %} 5501 ins_encode %{ 5502 __ bswapq($dst$$Register); 5503 %} 5504 ins_pipe( ialu_reg); 5505 %} 5506 5507 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5508 match(Set dst (ReverseBytesUS dst)); 5509 effect(KILL cr); 5510 5511 format %{ "bswapl $dst\n\t" 5512 "shrl $dst,16\n\t" %} 5513 ins_encode %{ 5514 __ bswapl($dst$$Register); 5515 __ shrl($dst$$Register, 16); 5516 %} 5517 ins_pipe( ialu_reg ); 5518 %} 5519 5520 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5521 match(Set dst (ReverseBytesS dst)); 5522 effect(KILL cr); 5523 5524 format %{ "bswapl $dst\n\t" 5525 "sar $dst,16\n\t" %} 5526 ins_encode %{ 5527 __ bswapl($dst$$Register); 5528 __ sarl($dst$$Register, 16); 5529 %} 5530 ins_pipe( ialu_reg ); 5531 %} 5532 5533 //---------- Zeros Count Instructions ------------------------------------------ 5534 5535 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5536 predicate(UseCountLeadingZerosInstruction); 5537 match(Set dst (CountLeadingZerosI src)); 5538 effect(KILL cr); 5539 5540 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5541 ins_encode %{ 5542 __ lzcntl($dst$$Register, $src$$Register); 5543 %} 5544 ins_pipe(ialu_reg); 5545 %} 5546 5547 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5548 predicate(UseCountLeadingZerosInstruction); 5549 match(Set dst (CountLeadingZerosI (LoadI src))); 5550 effect(KILL cr); 5551 ins_cost(175); 5552 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5553 ins_encode %{ 5554 __ lzcntl($dst$$Register, $src$$Address); 5555 %} 5556 ins_pipe(ialu_reg_mem); 5557 %} 5558 5559 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5560 predicate(!UseCountLeadingZerosInstruction); 5561 match(Set dst (CountLeadingZerosI src)); 5562 effect(KILL cr); 5563 5564 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5565 "jnz skip\n\t" 5566 "movl $dst, -1\n" 5567 "skip:\n\t" 5568 "negl $dst\n\t" 5569 "addl $dst, 31" %} 5570 ins_encode %{ 5571 Register Rdst = $dst$$Register; 5572 Register Rsrc = $src$$Register; 5573 Label skip; 5574 __ bsrl(Rdst, Rsrc); 5575 __ jccb(Assembler::notZero, skip); 5576 __ movl(Rdst, -1); 5577 __ bind(skip); 5578 __ negl(Rdst); 5579 __ addl(Rdst, BitsPerInt - 1); 5580 %} 5581 ins_pipe(ialu_reg); 5582 %} 5583 5584 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5585 predicate(UseCountLeadingZerosInstruction); 5586 match(Set dst (CountLeadingZerosL src)); 5587 effect(KILL cr); 5588 5589 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5590 ins_encode %{ 5591 __ lzcntq($dst$$Register, $src$$Register); 5592 %} 5593 ins_pipe(ialu_reg); 5594 %} 5595 5596 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5597 predicate(UseCountLeadingZerosInstruction); 5598 match(Set dst (CountLeadingZerosL (LoadL src))); 5599 effect(KILL cr); 5600 ins_cost(175); 5601 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5602 ins_encode %{ 5603 __ lzcntq($dst$$Register, $src$$Address); 5604 %} 5605 ins_pipe(ialu_reg_mem); 5606 %} 5607 5608 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5609 predicate(!UseCountLeadingZerosInstruction); 5610 match(Set dst (CountLeadingZerosL src)); 5611 effect(KILL cr); 5612 5613 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5614 "jnz skip\n\t" 5615 "movl $dst, -1\n" 5616 "skip:\n\t" 5617 "negl $dst\n\t" 5618 "addl $dst, 63" %} 5619 ins_encode %{ 5620 Register Rdst = $dst$$Register; 5621 Register Rsrc = $src$$Register; 5622 Label skip; 5623 __ bsrq(Rdst, Rsrc); 5624 __ jccb(Assembler::notZero, skip); 5625 __ movl(Rdst, -1); 5626 __ bind(skip); 5627 __ negl(Rdst); 5628 __ addl(Rdst, BitsPerLong - 1); 5629 %} 5630 ins_pipe(ialu_reg); 5631 %} 5632 5633 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5634 predicate(UseCountTrailingZerosInstruction); 5635 match(Set dst (CountTrailingZerosI src)); 5636 effect(KILL cr); 5637 5638 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5639 ins_encode %{ 5640 __ tzcntl($dst$$Register, $src$$Register); 5641 %} 5642 ins_pipe(ialu_reg); 5643 %} 5644 5645 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5646 predicate(UseCountTrailingZerosInstruction); 5647 match(Set dst (CountTrailingZerosI (LoadI src))); 5648 effect(KILL cr); 5649 ins_cost(175); 5650 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5651 ins_encode %{ 5652 __ tzcntl($dst$$Register, $src$$Address); 5653 %} 5654 ins_pipe(ialu_reg_mem); 5655 %} 5656 5657 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5658 predicate(!UseCountTrailingZerosInstruction); 5659 match(Set dst (CountTrailingZerosI src)); 5660 effect(KILL cr); 5661 5662 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5663 "jnz done\n\t" 5664 "movl $dst, 32\n" 5665 "done:" %} 5666 ins_encode %{ 5667 Register Rdst = $dst$$Register; 5668 Label done; 5669 __ bsfl(Rdst, $src$$Register); 5670 __ jccb(Assembler::notZero, done); 5671 __ movl(Rdst, BitsPerInt); 5672 __ bind(done); 5673 %} 5674 ins_pipe(ialu_reg); 5675 %} 5676 5677 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5678 predicate(UseCountTrailingZerosInstruction); 5679 match(Set dst (CountTrailingZerosL src)); 5680 effect(KILL cr); 5681 5682 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5683 ins_encode %{ 5684 __ tzcntq($dst$$Register, $src$$Register); 5685 %} 5686 ins_pipe(ialu_reg); 5687 %} 5688 5689 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5690 predicate(UseCountTrailingZerosInstruction); 5691 match(Set dst (CountTrailingZerosL (LoadL src))); 5692 effect(KILL cr); 5693 ins_cost(175); 5694 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5695 ins_encode %{ 5696 __ tzcntq($dst$$Register, $src$$Address); 5697 %} 5698 ins_pipe(ialu_reg_mem); 5699 %} 5700 5701 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5702 predicate(!UseCountTrailingZerosInstruction); 5703 match(Set dst (CountTrailingZerosL src)); 5704 effect(KILL cr); 5705 5706 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5707 "jnz done\n\t" 5708 "movl $dst, 64\n" 5709 "done:" %} 5710 ins_encode %{ 5711 Register Rdst = $dst$$Register; 5712 Label done; 5713 __ bsfq(Rdst, $src$$Register); 5714 __ jccb(Assembler::notZero, done); 5715 __ movl(Rdst, BitsPerLong); 5716 __ bind(done); 5717 %} 5718 ins_pipe(ialu_reg); 5719 %} 5720 5721 //--------------- Reverse Operation Instructions ---------------- 5722 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5723 predicate(!VM_Version::supports_gfni()); 5724 match(Set dst (ReverseI src)); 5725 effect(TEMP dst, TEMP rtmp, KILL cr); 5726 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5727 ins_encode %{ 5728 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5729 %} 5730 ins_pipe( ialu_reg ); 5731 %} 5732 5733 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5734 predicate(VM_Version::supports_gfni()); 5735 match(Set dst (ReverseI src)); 5736 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5737 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5738 ins_encode %{ 5739 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5740 %} 5741 ins_pipe( ialu_reg ); 5742 %} 5743 5744 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5745 predicate(!VM_Version::supports_gfni()); 5746 match(Set dst (ReverseL src)); 5747 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5748 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5749 ins_encode %{ 5750 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5751 %} 5752 ins_pipe( ialu_reg ); 5753 %} 5754 5755 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5756 predicate(VM_Version::supports_gfni()); 5757 match(Set dst (ReverseL src)); 5758 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5759 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5760 ins_encode %{ 5761 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5762 %} 5763 ins_pipe( ialu_reg ); 5764 %} 5765 5766 //---------- Population Count Instructions ------------------------------------- 5767 5768 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5769 predicate(UsePopCountInstruction); 5770 match(Set dst (PopCountI src)); 5771 effect(KILL cr); 5772 5773 format %{ "popcnt $dst, $src" %} 5774 ins_encode %{ 5775 __ popcntl($dst$$Register, $src$$Register); 5776 %} 5777 ins_pipe(ialu_reg); 5778 %} 5779 5780 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5781 predicate(UsePopCountInstruction); 5782 match(Set dst (PopCountI (LoadI mem))); 5783 effect(KILL cr); 5784 5785 format %{ "popcnt $dst, $mem" %} 5786 ins_encode %{ 5787 __ popcntl($dst$$Register, $mem$$Address); 5788 %} 5789 ins_pipe(ialu_reg); 5790 %} 5791 5792 // Note: Long.bitCount(long) returns an int. 5793 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5794 predicate(UsePopCountInstruction); 5795 match(Set dst (PopCountL src)); 5796 effect(KILL cr); 5797 5798 format %{ "popcnt $dst, $src" %} 5799 ins_encode %{ 5800 __ popcntq($dst$$Register, $src$$Register); 5801 %} 5802 ins_pipe(ialu_reg); 5803 %} 5804 5805 // Note: Long.bitCount(long) returns an int. 5806 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5807 predicate(UsePopCountInstruction); 5808 match(Set dst (PopCountL (LoadL mem))); 5809 effect(KILL cr); 5810 5811 format %{ "popcnt $dst, $mem" %} 5812 ins_encode %{ 5813 __ popcntq($dst$$Register, $mem$$Address); 5814 %} 5815 ins_pipe(ialu_reg); 5816 %} 5817 5818 5819 //----------MemBar Instructions----------------------------------------------- 5820 // Memory barrier flavors 5821 5822 instruct membar_acquire() 5823 %{ 5824 match(MemBarAcquire); 5825 match(LoadFence); 5826 ins_cost(0); 5827 5828 size(0); 5829 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5830 ins_encode(); 5831 ins_pipe(empty); 5832 %} 5833 5834 instruct membar_acquire_lock() 5835 %{ 5836 match(MemBarAcquireLock); 5837 ins_cost(0); 5838 5839 size(0); 5840 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5841 ins_encode(); 5842 ins_pipe(empty); 5843 %} 5844 5845 instruct membar_release() 5846 %{ 5847 match(MemBarRelease); 5848 match(StoreFence); 5849 ins_cost(0); 5850 5851 size(0); 5852 format %{ "MEMBAR-release ! (empty encoding)" %} 5853 ins_encode(); 5854 ins_pipe(empty); 5855 %} 5856 5857 instruct membar_release_lock() 5858 %{ 5859 match(MemBarReleaseLock); 5860 ins_cost(0); 5861 5862 size(0); 5863 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5864 ins_encode(); 5865 ins_pipe(empty); 5866 %} 5867 5868 instruct membar_volatile(rFlagsReg cr) %{ 5869 match(MemBarVolatile); 5870 effect(KILL cr); 5871 ins_cost(400); 5872 5873 format %{ 5874 $$template 5875 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5876 %} 5877 ins_encode %{ 5878 __ membar(Assembler::StoreLoad); 5879 %} 5880 ins_pipe(pipe_slow); 5881 %} 5882 5883 instruct unnecessary_membar_volatile() 5884 %{ 5885 match(MemBarVolatile); 5886 predicate(Matcher::post_store_load_barrier(n)); 5887 ins_cost(0); 5888 5889 size(0); 5890 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5891 ins_encode(); 5892 ins_pipe(empty); 5893 %} 5894 5895 instruct membar_storestore() %{ 5896 match(MemBarStoreStore); 5897 match(StoreStoreFence); 5898 ins_cost(0); 5899 5900 size(0); 5901 format %{ "MEMBAR-storestore (empty encoding)" %} 5902 ins_encode( ); 5903 ins_pipe(empty); 5904 %} 5905 5906 //----------Move Instructions-------------------------------------------------- 5907 5908 instruct castX2P(rRegP dst, rRegL src) 5909 %{ 5910 match(Set dst (CastX2P src)); 5911 5912 format %{ "movq $dst, $src\t# long->ptr" %} 5913 ins_encode %{ 5914 if ($dst$$reg != $src$$reg) { 5915 __ movptr($dst$$Register, $src$$Register); 5916 } 5917 %} 5918 ins_pipe(ialu_reg_reg); // XXX 5919 %} 5920 5921 instruct castP2X(rRegL dst, rRegP src) 5922 %{ 5923 match(Set dst (CastP2X src)); 5924 5925 format %{ "movq $dst, $src\t# ptr -> long" %} 5926 ins_encode %{ 5927 if ($dst$$reg != $src$$reg) { 5928 __ movptr($dst$$Register, $src$$Register); 5929 } 5930 %} 5931 ins_pipe(ialu_reg_reg); // XXX 5932 %} 5933 5934 // Convert oop into int for vectors alignment masking 5935 instruct convP2I(rRegI dst, rRegP src) 5936 %{ 5937 match(Set dst (ConvL2I (CastP2X src))); 5938 5939 format %{ "movl $dst, $src\t# ptr -> int" %} 5940 ins_encode %{ 5941 __ movl($dst$$Register, $src$$Register); 5942 %} 5943 ins_pipe(ialu_reg_reg); // XXX 5944 %} 5945 5946 // Convert compressed oop into int for vectors alignment masking 5947 // in case of 32bit oops (heap < 4Gb). 5948 instruct convN2I(rRegI dst, rRegN src) 5949 %{ 5950 predicate(CompressedOops::shift() == 0); 5951 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5952 5953 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5954 ins_encode %{ 5955 __ movl($dst$$Register, $src$$Register); 5956 %} 5957 ins_pipe(ialu_reg_reg); // XXX 5958 %} 5959 5960 // Convert oop pointer into compressed form 5961 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5962 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5963 match(Set dst (EncodeP src)); 5964 effect(KILL cr); 5965 format %{ "encode_heap_oop $dst,$src" %} 5966 ins_encode %{ 5967 Register s = $src$$Register; 5968 Register d = $dst$$Register; 5969 if (s != d) { 5970 __ movq(d, s); 5971 } 5972 __ encode_heap_oop(d); 5973 %} 5974 ins_pipe(ialu_reg_long); 5975 %} 5976 5977 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5978 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 5979 match(Set dst (EncodeP src)); 5980 effect(KILL cr); 5981 format %{ "encode_heap_oop_not_null $dst,$src" %} 5982 ins_encode %{ 5983 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 5984 %} 5985 ins_pipe(ialu_reg_long); 5986 %} 5987 5988 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 5989 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 5990 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 5991 match(Set dst (DecodeN src)); 5992 effect(KILL cr); 5993 format %{ "decode_heap_oop $dst,$src" %} 5994 ins_encode %{ 5995 Register s = $src$$Register; 5996 Register d = $dst$$Register; 5997 if (s != d) { 5998 __ movq(d, s); 5999 } 6000 __ decode_heap_oop(d); 6001 %} 6002 ins_pipe(ialu_reg_long); 6003 %} 6004 6005 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6006 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6007 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6008 match(Set dst (DecodeN src)); 6009 effect(KILL cr); 6010 format %{ "decode_heap_oop_not_null $dst,$src" %} 6011 ins_encode %{ 6012 Register s = $src$$Register; 6013 Register d = $dst$$Register; 6014 if (s != d) { 6015 __ decode_heap_oop_not_null(d, s); 6016 } else { 6017 __ decode_heap_oop_not_null(d); 6018 } 6019 %} 6020 ins_pipe(ialu_reg_long); 6021 %} 6022 6023 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6024 match(Set dst (EncodePKlass src)); 6025 effect(TEMP dst, KILL cr); 6026 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6027 ins_encode %{ 6028 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6029 %} 6030 ins_pipe(ialu_reg_long); 6031 %} 6032 6033 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6034 match(Set dst (DecodeNKlass src)); 6035 effect(TEMP dst, KILL cr); 6036 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6037 ins_encode %{ 6038 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6039 %} 6040 ins_pipe(ialu_reg_long); 6041 %} 6042 6043 //----------Conditional Move--------------------------------------------------- 6044 // Jump 6045 // dummy instruction for generating temp registers 6046 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6047 match(Jump (LShiftL switch_val shift)); 6048 ins_cost(350); 6049 predicate(false); 6050 effect(TEMP dest); 6051 6052 format %{ "leaq $dest, [$constantaddress]\n\t" 6053 "jmp [$dest + $switch_val << $shift]\n\t" %} 6054 ins_encode %{ 6055 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6056 // to do that and the compiler is using that register as one it can allocate. 6057 // So we build it all by hand. 6058 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6059 // ArrayAddress dispatch(table, index); 6060 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6061 __ lea($dest$$Register, $constantaddress); 6062 __ jmp(dispatch); 6063 %} 6064 ins_pipe(pipe_jmp); 6065 %} 6066 6067 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6068 match(Jump (AddL (LShiftL switch_val shift) offset)); 6069 ins_cost(350); 6070 effect(TEMP dest); 6071 6072 format %{ "leaq $dest, [$constantaddress]\n\t" 6073 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6074 ins_encode %{ 6075 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6076 // to do that and the compiler is using that register as one it can allocate. 6077 // So we build it all by hand. 6078 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6079 // ArrayAddress dispatch(table, index); 6080 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6081 __ lea($dest$$Register, $constantaddress); 6082 __ jmp(dispatch); 6083 %} 6084 ins_pipe(pipe_jmp); 6085 %} 6086 6087 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6088 match(Jump switch_val); 6089 ins_cost(350); 6090 effect(TEMP dest); 6091 6092 format %{ "leaq $dest, [$constantaddress]\n\t" 6093 "jmp [$dest + $switch_val]\n\t" %} 6094 ins_encode %{ 6095 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6096 // to do that and the compiler is using that register as one it can allocate. 6097 // So we build it all by hand. 6098 // Address index(noreg, switch_reg, Address::times_1); 6099 // ArrayAddress dispatch(table, index); 6100 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6101 __ lea($dest$$Register, $constantaddress); 6102 __ jmp(dispatch); 6103 %} 6104 ins_pipe(pipe_jmp); 6105 %} 6106 6107 // Conditional move 6108 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6109 %{ 6110 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6111 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6112 6113 ins_cost(100); // XXX 6114 format %{ "setbn$cop $dst\t# signed, int" %} 6115 ins_encode %{ 6116 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6117 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6118 %} 6119 ins_pipe(ialu_reg); 6120 %} 6121 6122 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6123 %{ 6124 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6125 6126 ins_cost(200); // XXX 6127 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6128 ins_encode %{ 6129 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6130 %} 6131 ins_pipe(pipe_cmov_reg); 6132 %} 6133 6134 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6135 %{ 6136 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6137 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6138 6139 ins_cost(100); // XXX 6140 format %{ "setbn$cop $dst\t# unsigned, int" %} 6141 ins_encode %{ 6142 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6143 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6144 %} 6145 ins_pipe(ialu_reg); 6146 %} 6147 6148 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6149 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6150 6151 ins_cost(200); // XXX 6152 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6153 ins_encode %{ 6154 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6155 %} 6156 ins_pipe(pipe_cmov_reg); 6157 %} 6158 6159 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6160 %{ 6161 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6162 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6163 6164 ins_cost(100); // XXX 6165 format %{ "setbn$cop $dst\t# unsigned, int" %} 6166 ins_encode %{ 6167 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6168 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6169 %} 6170 ins_pipe(ialu_reg); 6171 %} 6172 6173 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6174 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6175 ins_cost(200); 6176 expand %{ 6177 cmovI_regU(cop, cr, dst, src); 6178 %} 6179 %} 6180 6181 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6182 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6183 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6184 6185 ins_cost(200); // XXX 6186 format %{ "cmovpl $dst, $src\n\t" 6187 "cmovnel $dst, $src" %} 6188 ins_encode %{ 6189 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6190 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6191 %} 6192 ins_pipe(pipe_cmov_reg); 6193 %} 6194 6195 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6196 // inputs of the CMove 6197 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6198 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6199 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6200 6201 ins_cost(200); // XXX 6202 format %{ "cmovpl $dst, $src\n\t" 6203 "cmovnel $dst, $src" %} 6204 ins_encode %{ 6205 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6206 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6207 %} 6208 ins_pipe(pipe_cmov_reg); 6209 %} 6210 6211 // Conditional move 6212 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6213 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6214 6215 ins_cost(250); // XXX 6216 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6217 ins_encode %{ 6218 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6219 %} 6220 ins_pipe(pipe_cmov_mem); 6221 %} 6222 6223 // Conditional move 6224 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6225 %{ 6226 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6227 6228 ins_cost(250); // XXX 6229 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6230 ins_encode %{ 6231 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6232 %} 6233 ins_pipe(pipe_cmov_mem); 6234 %} 6235 6236 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6237 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6238 ins_cost(250); 6239 expand %{ 6240 cmovI_memU(cop, cr, dst, src); 6241 %} 6242 %} 6243 6244 // Conditional move 6245 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6246 %{ 6247 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6248 6249 ins_cost(200); // XXX 6250 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6251 ins_encode %{ 6252 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6253 %} 6254 ins_pipe(pipe_cmov_reg); 6255 %} 6256 6257 // Conditional move 6258 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6259 %{ 6260 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6261 6262 ins_cost(200); // XXX 6263 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6264 ins_encode %{ 6265 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6266 %} 6267 ins_pipe(pipe_cmov_reg); 6268 %} 6269 6270 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6271 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6272 ins_cost(200); 6273 expand %{ 6274 cmovN_regU(cop, cr, dst, src); 6275 %} 6276 %} 6277 6278 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6279 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6280 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6281 6282 ins_cost(200); // XXX 6283 format %{ "cmovpl $dst, $src\n\t" 6284 "cmovnel $dst, $src" %} 6285 ins_encode %{ 6286 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6287 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6288 %} 6289 ins_pipe(pipe_cmov_reg); 6290 %} 6291 6292 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6293 // inputs of the CMove 6294 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6295 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6296 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6297 6298 ins_cost(200); // XXX 6299 format %{ "cmovpl $dst, $src\n\t" 6300 "cmovnel $dst, $src" %} 6301 ins_encode %{ 6302 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6303 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6304 %} 6305 ins_pipe(pipe_cmov_reg); 6306 %} 6307 6308 // Conditional move 6309 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6310 %{ 6311 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6312 6313 ins_cost(200); // XXX 6314 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6315 ins_encode %{ 6316 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6317 %} 6318 ins_pipe(pipe_cmov_reg); // XXX 6319 %} 6320 6321 // Conditional move 6322 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6323 %{ 6324 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6325 6326 ins_cost(200); // XXX 6327 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6328 ins_encode %{ 6329 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6330 %} 6331 ins_pipe(pipe_cmov_reg); // XXX 6332 %} 6333 6334 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6335 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6336 ins_cost(200); 6337 expand %{ 6338 cmovP_regU(cop, cr, dst, src); 6339 %} 6340 %} 6341 6342 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6343 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6344 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6345 6346 ins_cost(200); // XXX 6347 format %{ "cmovpq $dst, $src\n\t" 6348 "cmovneq $dst, $src" %} 6349 ins_encode %{ 6350 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6351 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6352 %} 6353 ins_pipe(pipe_cmov_reg); 6354 %} 6355 6356 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6357 // inputs of the CMove 6358 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6359 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6360 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6361 6362 ins_cost(200); // XXX 6363 format %{ "cmovpq $dst, $src\n\t" 6364 "cmovneq $dst, $src" %} 6365 ins_encode %{ 6366 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6367 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6368 %} 6369 ins_pipe(pipe_cmov_reg); 6370 %} 6371 6372 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6373 %{ 6374 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6375 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6376 6377 ins_cost(100); // XXX 6378 format %{ "setbn$cop $dst\t# signed, long" %} 6379 ins_encode %{ 6380 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6381 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6382 %} 6383 ins_pipe(ialu_reg); 6384 %} 6385 6386 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6387 %{ 6388 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6389 6390 ins_cost(200); // XXX 6391 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6392 ins_encode %{ 6393 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6394 %} 6395 ins_pipe(pipe_cmov_reg); // XXX 6396 %} 6397 6398 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6399 %{ 6400 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6401 6402 ins_cost(200); // XXX 6403 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6404 ins_encode %{ 6405 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6406 %} 6407 ins_pipe(pipe_cmov_mem); // XXX 6408 %} 6409 6410 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6411 %{ 6412 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6413 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6414 6415 ins_cost(100); // XXX 6416 format %{ "setbn$cop $dst\t# unsigned, long" %} 6417 ins_encode %{ 6418 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6419 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6420 %} 6421 ins_pipe(ialu_reg); 6422 %} 6423 6424 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6425 %{ 6426 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6427 6428 ins_cost(200); // XXX 6429 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6430 ins_encode %{ 6431 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6432 %} 6433 ins_pipe(pipe_cmov_reg); // XXX 6434 %} 6435 6436 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6437 %{ 6438 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6439 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6440 6441 ins_cost(100); // XXX 6442 format %{ "setbn$cop $dst\t# unsigned, long" %} 6443 ins_encode %{ 6444 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6445 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6446 %} 6447 ins_pipe(ialu_reg); 6448 %} 6449 6450 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6451 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6452 ins_cost(200); 6453 expand %{ 6454 cmovL_regU(cop, cr, dst, src); 6455 %} 6456 %} 6457 6458 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6459 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6460 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6461 6462 ins_cost(200); // XXX 6463 format %{ "cmovpq $dst, $src\n\t" 6464 "cmovneq $dst, $src" %} 6465 ins_encode %{ 6466 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6467 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6468 %} 6469 ins_pipe(pipe_cmov_reg); 6470 %} 6471 6472 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6473 // inputs of the CMove 6474 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6475 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6476 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6477 6478 ins_cost(200); // XXX 6479 format %{ "cmovpq $dst, $src\n\t" 6480 "cmovneq $dst, $src" %} 6481 ins_encode %{ 6482 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6483 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6484 %} 6485 ins_pipe(pipe_cmov_reg); 6486 %} 6487 6488 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6489 %{ 6490 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6491 6492 ins_cost(200); // XXX 6493 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6494 ins_encode %{ 6495 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6496 %} 6497 ins_pipe(pipe_cmov_mem); // XXX 6498 %} 6499 6500 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6501 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6502 ins_cost(200); 6503 expand %{ 6504 cmovL_memU(cop, cr, dst, src); 6505 %} 6506 %} 6507 6508 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6509 %{ 6510 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6511 6512 ins_cost(200); // XXX 6513 format %{ "jn$cop skip\t# signed cmove float\n\t" 6514 "movss $dst, $src\n" 6515 "skip:" %} 6516 ins_encode %{ 6517 Label Lskip; 6518 // Invert sense of branch from sense of CMOV 6519 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6520 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6521 __ bind(Lskip); 6522 %} 6523 ins_pipe(pipe_slow); 6524 %} 6525 6526 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6527 %{ 6528 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6529 6530 ins_cost(200); // XXX 6531 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6532 "movss $dst, $src\n" 6533 "skip:" %} 6534 ins_encode %{ 6535 Label Lskip; 6536 // Invert sense of branch from sense of CMOV 6537 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6538 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6539 __ bind(Lskip); 6540 %} 6541 ins_pipe(pipe_slow); 6542 %} 6543 6544 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6545 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6546 ins_cost(200); 6547 expand %{ 6548 cmovF_regU(cop, cr, dst, src); 6549 %} 6550 %} 6551 6552 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6553 %{ 6554 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6555 6556 ins_cost(200); // XXX 6557 format %{ "jn$cop skip\t# signed cmove double\n\t" 6558 "movsd $dst, $src\n" 6559 "skip:" %} 6560 ins_encode %{ 6561 Label Lskip; 6562 // Invert sense of branch from sense of CMOV 6563 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6564 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6565 __ bind(Lskip); 6566 %} 6567 ins_pipe(pipe_slow); 6568 %} 6569 6570 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6571 %{ 6572 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6573 6574 ins_cost(200); // XXX 6575 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6576 "movsd $dst, $src\n" 6577 "skip:" %} 6578 ins_encode %{ 6579 Label Lskip; 6580 // Invert sense of branch from sense of CMOV 6581 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6582 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6583 __ bind(Lskip); 6584 %} 6585 ins_pipe(pipe_slow); 6586 %} 6587 6588 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6589 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6590 ins_cost(200); 6591 expand %{ 6592 cmovD_regU(cop, cr, dst, src); 6593 %} 6594 %} 6595 6596 //----------Arithmetic Instructions-------------------------------------------- 6597 //----------Addition Instructions---------------------------------------------- 6598 6599 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6600 %{ 6601 match(Set dst (AddI dst src)); 6602 effect(KILL cr); 6603 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); 6604 format %{ "addl $dst, $src\t# int" %} 6605 ins_encode %{ 6606 __ addl($dst$$Register, $src$$Register); 6607 %} 6608 ins_pipe(ialu_reg_reg); 6609 %} 6610 6611 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6612 %{ 6613 match(Set dst (AddI dst src)); 6614 effect(KILL cr); 6615 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); 6616 6617 format %{ "addl $dst, $src\t# int" %} 6618 ins_encode %{ 6619 __ addl($dst$$Register, $src$$constant); 6620 %} 6621 ins_pipe( ialu_reg ); 6622 %} 6623 6624 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6625 %{ 6626 match(Set dst (AddI dst (LoadI src))); 6627 effect(KILL cr); 6628 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); 6629 6630 ins_cost(150); // XXX 6631 format %{ "addl $dst, $src\t# int" %} 6632 ins_encode %{ 6633 __ addl($dst$$Register, $src$$Address); 6634 %} 6635 ins_pipe(ialu_reg_mem); 6636 %} 6637 6638 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6639 %{ 6640 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6641 effect(KILL cr); 6642 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); 6643 6644 ins_cost(150); // XXX 6645 format %{ "addl $dst, $src\t# int" %} 6646 ins_encode %{ 6647 __ addl($dst$$Address, $src$$Register); 6648 %} 6649 ins_pipe(ialu_mem_reg); 6650 %} 6651 6652 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6653 %{ 6654 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6655 effect(KILL cr); 6656 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); 6657 6658 6659 ins_cost(125); // XXX 6660 format %{ "addl $dst, $src\t# int" %} 6661 ins_encode %{ 6662 __ addl($dst$$Address, $src$$constant); 6663 %} 6664 ins_pipe(ialu_mem_imm); 6665 %} 6666 6667 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6668 %{ 6669 predicate(UseIncDec); 6670 match(Set dst (AddI dst src)); 6671 effect(KILL cr); 6672 6673 format %{ "incl $dst\t# int" %} 6674 ins_encode %{ 6675 __ incrementl($dst$$Register); 6676 %} 6677 ins_pipe(ialu_reg); 6678 %} 6679 6680 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6681 %{ 6682 predicate(UseIncDec); 6683 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6684 effect(KILL cr); 6685 6686 ins_cost(125); // XXX 6687 format %{ "incl $dst\t# int" %} 6688 ins_encode %{ 6689 __ incrementl($dst$$Address); 6690 %} 6691 ins_pipe(ialu_mem_imm); 6692 %} 6693 6694 // XXX why does that use AddI 6695 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6696 %{ 6697 predicate(UseIncDec); 6698 match(Set dst (AddI dst src)); 6699 effect(KILL cr); 6700 6701 format %{ "decl $dst\t# int" %} 6702 ins_encode %{ 6703 __ decrementl($dst$$Register); 6704 %} 6705 ins_pipe(ialu_reg); 6706 %} 6707 6708 // XXX why does that use AddI 6709 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6710 %{ 6711 predicate(UseIncDec); 6712 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6713 effect(KILL cr); 6714 6715 ins_cost(125); // XXX 6716 format %{ "decl $dst\t# int" %} 6717 ins_encode %{ 6718 __ decrementl($dst$$Address); 6719 %} 6720 ins_pipe(ialu_mem_imm); 6721 %} 6722 6723 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6724 %{ 6725 predicate(VM_Version::supports_fast_2op_lea()); 6726 match(Set dst (AddI (LShiftI index scale) disp)); 6727 6728 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6729 ins_encode %{ 6730 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6731 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6732 %} 6733 ins_pipe(ialu_reg_reg); 6734 %} 6735 6736 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6737 %{ 6738 predicate(VM_Version::supports_fast_3op_lea()); 6739 match(Set dst (AddI (AddI base index) disp)); 6740 6741 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6742 ins_encode %{ 6743 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6744 %} 6745 ins_pipe(ialu_reg_reg); 6746 %} 6747 6748 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6749 %{ 6750 predicate(VM_Version::supports_fast_2op_lea()); 6751 match(Set dst (AddI base (LShiftI index scale))); 6752 6753 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6754 ins_encode %{ 6755 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6756 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6757 %} 6758 ins_pipe(ialu_reg_reg); 6759 %} 6760 6761 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6762 %{ 6763 predicate(VM_Version::supports_fast_3op_lea()); 6764 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6765 6766 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6767 ins_encode %{ 6768 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6769 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6770 %} 6771 ins_pipe(ialu_reg_reg); 6772 %} 6773 6774 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6775 %{ 6776 match(Set dst (AddL dst src)); 6777 effect(KILL cr); 6778 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); 6779 6780 format %{ "addq $dst, $src\t# long" %} 6781 ins_encode %{ 6782 __ addq($dst$$Register, $src$$Register); 6783 %} 6784 ins_pipe(ialu_reg_reg); 6785 %} 6786 6787 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6788 %{ 6789 match(Set dst (AddL dst src)); 6790 effect(KILL cr); 6791 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); 6792 6793 format %{ "addq $dst, $src\t# long" %} 6794 ins_encode %{ 6795 __ addq($dst$$Register, $src$$constant); 6796 %} 6797 ins_pipe( ialu_reg ); 6798 %} 6799 6800 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6801 %{ 6802 match(Set dst (AddL dst (LoadL src))); 6803 effect(KILL cr); 6804 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); 6805 6806 ins_cost(150); // XXX 6807 format %{ "addq $dst, $src\t# long" %} 6808 ins_encode %{ 6809 __ addq($dst$$Register, $src$$Address); 6810 %} 6811 ins_pipe(ialu_reg_mem); 6812 %} 6813 6814 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6815 %{ 6816 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6817 effect(KILL cr); 6818 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); 6819 6820 ins_cost(150); // XXX 6821 format %{ "addq $dst, $src\t# long" %} 6822 ins_encode %{ 6823 __ addq($dst$$Address, $src$$Register); 6824 %} 6825 ins_pipe(ialu_mem_reg); 6826 %} 6827 6828 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6829 %{ 6830 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6831 effect(KILL cr); 6832 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); 6833 6834 ins_cost(125); // XXX 6835 format %{ "addq $dst, $src\t# long" %} 6836 ins_encode %{ 6837 __ addq($dst$$Address, $src$$constant); 6838 %} 6839 ins_pipe(ialu_mem_imm); 6840 %} 6841 6842 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6843 %{ 6844 predicate(UseIncDec); 6845 match(Set dst (AddL dst src)); 6846 effect(KILL cr); 6847 6848 format %{ "incq $dst\t# long" %} 6849 ins_encode %{ 6850 __ incrementq($dst$$Register); 6851 %} 6852 ins_pipe(ialu_reg); 6853 %} 6854 6855 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6856 %{ 6857 predicate(UseIncDec); 6858 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6859 effect(KILL cr); 6860 6861 ins_cost(125); // XXX 6862 format %{ "incq $dst\t# long" %} 6863 ins_encode %{ 6864 __ incrementq($dst$$Address); 6865 %} 6866 ins_pipe(ialu_mem_imm); 6867 %} 6868 6869 // XXX why does that use AddL 6870 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6871 %{ 6872 predicate(UseIncDec); 6873 match(Set dst (AddL dst src)); 6874 effect(KILL cr); 6875 6876 format %{ "decq $dst\t# long" %} 6877 ins_encode %{ 6878 __ decrementq($dst$$Register); 6879 %} 6880 ins_pipe(ialu_reg); 6881 %} 6882 6883 // XXX why does that use AddL 6884 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6885 %{ 6886 predicate(UseIncDec); 6887 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6888 effect(KILL cr); 6889 6890 ins_cost(125); // XXX 6891 format %{ "decq $dst\t# long" %} 6892 ins_encode %{ 6893 __ decrementq($dst$$Address); 6894 %} 6895 ins_pipe(ialu_mem_imm); 6896 %} 6897 6898 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6899 %{ 6900 predicate(VM_Version::supports_fast_2op_lea()); 6901 match(Set dst (AddL (LShiftL index scale) disp)); 6902 6903 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6904 ins_encode %{ 6905 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6906 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6907 %} 6908 ins_pipe(ialu_reg_reg); 6909 %} 6910 6911 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6912 %{ 6913 predicate(VM_Version::supports_fast_3op_lea()); 6914 match(Set dst (AddL (AddL base index) disp)); 6915 6916 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6917 ins_encode %{ 6918 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6919 %} 6920 ins_pipe(ialu_reg_reg); 6921 %} 6922 6923 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6924 %{ 6925 predicate(VM_Version::supports_fast_2op_lea()); 6926 match(Set dst (AddL base (LShiftL index scale))); 6927 6928 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6929 ins_encode %{ 6930 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6931 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6932 %} 6933 ins_pipe(ialu_reg_reg); 6934 %} 6935 6936 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6937 %{ 6938 predicate(VM_Version::supports_fast_3op_lea()); 6939 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6940 6941 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6942 ins_encode %{ 6943 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6944 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6945 %} 6946 ins_pipe(ialu_reg_reg); 6947 %} 6948 6949 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6950 %{ 6951 match(Set dst (AddP dst src)); 6952 effect(KILL cr); 6953 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); 6954 6955 format %{ "addq $dst, $src\t# ptr" %} 6956 ins_encode %{ 6957 __ addq($dst$$Register, $src$$Register); 6958 %} 6959 ins_pipe(ialu_reg_reg); 6960 %} 6961 6962 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6963 %{ 6964 match(Set dst (AddP dst src)); 6965 effect(KILL cr); 6966 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); 6967 6968 format %{ "addq $dst, $src\t# ptr" %} 6969 ins_encode %{ 6970 __ addq($dst$$Register, $src$$constant); 6971 %} 6972 ins_pipe( ialu_reg ); 6973 %} 6974 6975 // XXX addP mem ops ???? 6976 6977 instruct checkCastPP(rRegP dst) 6978 %{ 6979 match(Set dst (CheckCastPP dst)); 6980 6981 size(0); 6982 format %{ "# checkcastPP of $dst" %} 6983 ins_encode(/* empty encoding */); 6984 ins_pipe(empty); 6985 %} 6986 6987 instruct castPP(rRegP dst) 6988 %{ 6989 match(Set dst (CastPP dst)); 6990 6991 size(0); 6992 format %{ "# castPP of $dst" %} 6993 ins_encode(/* empty encoding */); 6994 ins_pipe(empty); 6995 %} 6996 6997 instruct castII(rRegI dst) 6998 %{ 6999 match(Set dst (CastII dst)); 7000 7001 size(0); 7002 format %{ "# castII of $dst" %} 7003 ins_encode(/* empty encoding */); 7004 ins_cost(0); 7005 ins_pipe(empty); 7006 %} 7007 7008 instruct castLL(rRegL dst) 7009 %{ 7010 match(Set dst (CastLL dst)); 7011 7012 size(0); 7013 format %{ "# castLL of $dst" %} 7014 ins_encode(/* empty encoding */); 7015 ins_cost(0); 7016 ins_pipe(empty); 7017 %} 7018 7019 instruct castFF(regF dst) 7020 %{ 7021 match(Set dst (CastFF dst)); 7022 7023 size(0); 7024 format %{ "# castFF of $dst" %} 7025 ins_encode(/* empty encoding */); 7026 ins_cost(0); 7027 ins_pipe(empty); 7028 %} 7029 7030 instruct castDD(regD dst) 7031 %{ 7032 match(Set dst (CastDD dst)); 7033 7034 size(0); 7035 format %{ "# castDD of $dst" %} 7036 ins_encode(/* empty encoding */); 7037 ins_cost(0); 7038 ins_pipe(empty); 7039 %} 7040 7041 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7042 instruct compareAndSwapP(rRegI res, 7043 memory mem_ptr, 7044 rax_RegP oldval, rRegP newval, 7045 rFlagsReg cr) 7046 %{ 7047 predicate(n->as_LoadStore()->barrier_data() == 0); 7048 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7049 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7050 effect(KILL cr, KILL oldval); 7051 7052 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7053 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7054 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7055 ins_encode %{ 7056 __ lock(); 7057 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7058 __ setcc(Assembler::equal, $res$$Register); 7059 %} 7060 ins_pipe( pipe_cmpxchg ); 7061 %} 7062 7063 instruct compareAndSwapL(rRegI res, 7064 memory mem_ptr, 7065 rax_RegL oldval, rRegL newval, 7066 rFlagsReg cr) 7067 %{ 7068 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7069 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7070 effect(KILL cr, KILL oldval); 7071 7072 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7073 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7074 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7075 ins_encode %{ 7076 __ lock(); 7077 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7078 __ setcc(Assembler::equal, $res$$Register); 7079 %} 7080 ins_pipe( pipe_cmpxchg ); 7081 %} 7082 7083 instruct compareAndSwapI(rRegI res, 7084 memory mem_ptr, 7085 rax_RegI oldval, rRegI newval, 7086 rFlagsReg cr) 7087 %{ 7088 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7089 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7090 effect(KILL cr, KILL oldval); 7091 7092 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7093 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7094 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7095 ins_encode %{ 7096 __ lock(); 7097 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7098 __ setcc(Assembler::equal, $res$$Register); 7099 %} 7100 ins_pipe( pipe_cmpxchg ); 7101 %} 7102 7103 instruct compareAndSwapB(rRegI res, 7104 memory mem_ptr, 7105 rax_RegI oldval, rRegI newval, 7106 rFlagsReg cr) 7107 %{ 7108 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7109 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7110 effect(KILL cr, KILL oldval); 7111 7112 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7113 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7114 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7115 ins_encode %{ 7116 __ lock(); 7117 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7118 __ setcc(Assembler::equal, $res$$Register); 7119 %} 7120 ins_pipe( pipe_cmpxchg ); 7121 %} 7122 7123 instruct compareAndSwapS(rRegI res, 7124 memory mem_ptr, 7125 rax_RegI oldval, rRegI newval, 7126 rFlagsReg cr) 7127 %{ 7128 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7129 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7130 effect(KILL cr, KILL oldval); 7131 7132 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7133 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7134 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7135 ins_encode %{ 7136 __ lock(); 7137 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7138 __ setcc(Assembler::equal, $res$$Register); 7139 %} 7140 ins_pipe( pipe_cmpxchg ); 7141 %} 7142 7143 instruct compareAndSwapN(rRegI res, 7144 memory mem_ptr, 7145 rax_RegN oldval, rRegN newval, 7146 rFlagsReg cr) %{ 7147 predicate(n->as_LoadStore()->barrier_data() == 0); 7148 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7149 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7150 effect(KILL cr, KILL oldval); 7151 7152 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7153 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7154 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7155 ins_encode %{ 7156 __ lock(); 7157 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7158 __ setcc(Assembler::equal, $res$$Register); 7159 %} 7160 ins_pipe( pipe_cmpxchg ); 7161 %} 7162 7163 instruct compareAndExchangeB( 7164 memory mem_ptr, 7165 rax_RegI oldval, rRegI newval, 7166 rFlagsReg cr) 7167 %{ 7168 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7169 effect(KILL cr); 7170 7171 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7172 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7173 ins_encode %{ 7174 __ lock(); 7175 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7176 %} 7177 ins_pipe( pipe_cmpxchg ); 7178 %} 7179 7180 instruct compareAndExchangeS( 7181 memory mem_ptr, 7182 rax_RegI oldval, rRegI newval, 7183 rFlagsReg cr) 7184 %{ 7185 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7186 effect(KILL cr); 7187 7188 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7189 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7190 ins_encode %{ 7191 __ lock(); 7192 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7193 %} 7194 ins_pipe( pipe_cmpxchg ); 7195 %} 7196 7197 instruct compareAndExchangeI( 7198 memory mem_ptr, 7199 rax_RegI oldval, rRegI newval, 7200 rFlagsReg cr) 7201 %{ 7202 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7203 effect(KILL cr); 7204 7205 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7206 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7207 ins_encode %{ 7208 __ lock(); 7209 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7210 %} 7211 ins_pipe( pipe_cmpxchg ); 7212 %} 7213 7214 instruct compareAndExchangeL( 7215 memory mem_ptr, 7216 rax_RegL oldval, rRegL newval, 7217 rFlagsReg cr) 7218 %{ 7219 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7220 effect(KILL cr); 7221 7222 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7223 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7224 ins_encode %{ 7225 __ lock(); 7226 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7227 %} 7228 ins_pipe( pipe_cmpxchg ); 7229 %} 7230 7231 instruct compareAndExchangeN( 7232 memory mem_ptr, 7233 rax_RegN oldval, rRegN newval, 7234 rFlagsReg cr) %{ 7235 predicate(n->as_LoadStore()->barrier_data() == 0); 7236 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7237 effect(KILL cr); 7238 7239 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7240 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7241 ins_encode %{ 7242 __ lock(); 7243 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7244 %} 7245 ins_pipe( pipe_cmpxchg ); 7246 %} 7247 7248 instruct compareAndExchangeP( 7249 memory mem_ptr, 7250 rax_RegP oldval, rRegP newval, 7251 rFlagsReg cr) 7252 %{ 7253 predicate(n->as_LoadStore()->barrier_data() == 0); 7254 match(Set oldval (CompareAndExchangeP 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 xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7267 predicate(n->as_LoadStore()->result_not_used()); 7268 match(Set dummy (GetAndAddB mem add)); 7269 effect(KILL cr); 7270 format %{ "addb_lock $mem, $add" %} 7271 ins_encode %{ 7272 __ lock(); 7273 __ addb($mem$$Address, $add$$Register); 7274 %} 7275 ins_pipe(pipe_cmpxchg); 7276 %} 7277 7278 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7279 predicate(n->as_LoadStore()->result_not_used()); 7280 match(Set dummy (GetAndAddB mem add)); 7281 effect(KILL cr); 7282 format %{ "addb_lock $mem, $add" %} 7283 ins_encode %{ 7284 __ lock(); 7285 __ addb($mem$$Address, $add$$constant); 7286 %} 7287 ins_pipe(pipe_cmpxchg); 7288 %} 7289 7290 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7291 predicate(!n->as_LoadStore()->result_not_used()); 7292 match(Set newval (GetAndAddB mem newval)); 7293 effect(KILL cr); 7294 format %{ "xaddb_lock $mem, $newval" %} 7295 ins_encode %{ 7296 __ lock(); 7297 __ xaddb($mem$$Address, $newval$$Register); 7298 %} 7299 ins_pipe(pipe_cmpxchg); 7300 %} 7301 7302 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7303 predicate(n->as_LoadStore()->result_not_used()); 7304 match(Set dummy (GetAndAddS mem add)); 7305 effect(KILL cr); 7306 format %{ "addw_lock $mem, $add" %} 7307 ins_encode %{ 7308 __ lock(); 7309 __ addw($mem$$Address, $add$$Register); 7310 %} 7311 ins_pipe(pipe_cmpxchg); 7312 %} 7313 7314 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7315 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7316 match(Set dummy (GetAndAddS mem add)); 7317 effect(KILL cr); 7318 format %{ "addw_lock $mem, $add" %} 7319 ins_encode %{ 7320 __ lock(); 7321 __ addw($mem$$Address, $add$$constant); 7322 %} 7323 ins_pipe(pipe_cmpxchg); 7324 %} 7325 7326 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7327 predicate(!n->as_LoadStore()->result_not_used()); 7328 match(Set newval (GetAndAddS mem newval)); 7329 effect(KILL cr); 7330 format %{ "xaddw_lock $mem, $newval" %} 7331 ins_encode %{ 7332 __ lock(); 7333 __ xaddw($mem$$Address, $newval$$Register); 7334 %} 7335 ins_pipe(pipe_cmpxchg); 7336 %} 7337 7338 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7339 predicate(n->as_LoadStore()->result_not_used()); 7340 match(Set dummy (GetAndAddI mem add)); 7341 effect(KILL cr); 7342 format %{ "addl_lock $mem, $add" %} 7343 ins_encode %{ 7344 __ lock(); 7345 __ addl($mem$$Address, $add$$Register); 7346 %} 7347 ins_pipe(pipe_cmpxchg); 7348 %} 7349 7350 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7351 predicate(n->as_LoadStore()->result_not_used()); 7352 match(Set dummy (GetAndAddI mem add)); 7353 effect(KILL cr); 7354 format %{ "addl_lock $mem, $add" %} 7355 ins_encode %{ 7356 __ lock(); 7357 __ addl($mem$$Address, $add$$constant); 7358 %} 7359 ins_pipe(pipe_cmpxchg); 7360 %} 7361 7362 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7363 predicate(!n->as_LoadStore()->result_not_used()); 7364 match(Set newval (GetAndAddI mem newval)); 7365 effect(KILL cr); 7366 format %{ "xaddl_lock $mem, $newval" %} 7367 ins_encode %{ 7368 __ lock(); 7369 __ xaddl($mem$$Address, $newval$$Register); 7370 %} 7371 ins_pipe(pipe_cmpxchg); 7372 %} 7373 7374 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7375 predicate(n->as_LoadStore()->result_not_used()); 7376 match(Set dummy (GetAndAddL mem add)); 7377 effect(KILL cr); 7378 format %{ "addq_lock $mem, $add" %} 7379 ins_encode %{ 7380 __ lock(); 7381 __ addq($mem$$Address, $add$$Register); 7382 %} 7383 ins_pipe(pipe_cmpxchg); 7384 %} 7385 7386 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7387 predicate(n->as_LoadStore()->result_not_used()); 7388 match(Set dummy (GetAndAddL mem add)); 7389 effect(KILL cr); 7390 format %{ "addq_lock $mem, $add" %} 7391 ins_encode %{ 7392 __ lock(); 7393 __ addq($mem$$Address, $add$$constant); 7394 %} 7395 ins_pipe(pipe_cmpxchg); 7396 %} 7397 7398 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7399 predicate(!n->as_LoadStore()->result_not_used()); 7400 match(Set newval (GetAndAddL mem newval)); 7401 effect(KILL cr); 7402 format %{ "xaddq_lock $mem, $newval" %} 7403 ins_encode %{ 7404 __ lock(); 7405 __ xaddq($mem$$Address, $newval$$Register); 7406 %} 7407 ins_pipe(pipe_cmpxchg); 7408 %} 7409 7410 instruct xchgB( memory mem, rRegI newval) %{ 7411 match(Set newval (GetAndSetB mem newval)); 7412 format %{ "XCHGB $newval,[$mem]" %} 7413 ins_encode %{ 7414 __ xchgb($newval$$Register, $mem$$Address); 7415 %} 7416 ins_pipe( pipe_cmpxchg ); 7417 %} 7418 7419 instruct xchgS( memory mem, rRegI newval) %{ 7420 match(Set newval (GetAndSetS mem newval)); 7421 format %{ "XCHGW $newval,[$mem]" %} 7422 ins_encode %{ 7423 __ xchgw($newval$$Register, $mem$$Address); 7424 %} 7425 ins_pipe( pipe_cmpxchg ); 7426 %} 7427 7428 instruct xchgI( memory mem, rRegI newval) %{ 7429 match(Set newval (GetAndSetI mem newval)); 7430 format %{ "XCHGL $newval,[$mem]" %} 7431 ins_encode %{ 7432 __ xchgl($newval$$Register, $mem$$Address); 7433 %} 7434 ins_pipe( pipe_cmpxchg ); 7435 %} 7436 7437 instruct xchgL( memory mem, rRegL newval) %{ 7438 match(Set newval (GetAndSetL mem newval)); 7439 format %{ "XCHGL $newval,[$mem]" %} 7440 ins_encode %{ 7441 __ xchgq($newval$$Register, $mem$$Address); 7442 %} 7443 ins_pipe( pipe_cmpxchg ); 7444 %} 7445 7446 instruct xchgP( memory mem, rRegP newval) %{ 7447 match(Set newval (GetAndSetP mem newval)); 7448 predicate(n->as_LoadStore()->barrier_data() == 0); 7449 format %{ "XCHGQ $newval,[$mem]" %} 7450 ins_encode %{ 7451 __ xchgq($newval$$Register, $mem$$Address); 7452 %} 7453 ins_pipe( pipe_cmpxchg ); 7454 %} 7455 7456 instruct xchgN( memory mem, rRegN newval) %{ 7457 predicate(n->as_LoadStore()->barrier_data() == 0); 7458 match(Set newval (GetAndSetN mem newval)); 7459 format %{ "XCHGL $newval,$mem]" %} 7460 ins_encode %{ 7461 __ xchgl($newval$$Register, $mem$$Address); 7462 %} 7463 ins_pipe( pipe_cmpxchg ); 7464 %} 7465 7466 //----------Abs Instructions------------------------------------------- 7467 7468 // Integer Absolute Instructions 7469 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7470 %{ 7471 match(Set dst (AbsI src)); 7472 effect(TEMP dst, KILL cr); 7473 format %{ "xorl $dst, $dst\t# abs int\n\t" 7474 "subl $dst, $src\n\t" 7475 "cmovll $dst, $src" %} 7476 ins_encode %{ 7477 __ xorl($dst$$Register, $dst$$Register); 7478 __ subl($dst$$Register, $src$$Register); 7479 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7480 %} 7481 7482 ins_pipe(ialu_reg_reg); 7483 %} 7484 7485 // Long Absolute Instructions 7486 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7487 %{ 7488 match(Set dst (AbsL src)); 7489 effect(TEMP dst, KILL cr); 7490 format %{ "xorl $dst, $dst\t# abs long\n\t" 7491 "subq $dst, $src\n\t" 7492 "cmovlq $dst, $src" %} 7493 ins_encode %{ 7494 __ xorl($dst$$Register, $dst$$Register); 7495 __ subq($dst$$Register, $src$$Register); 7496 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7497 %} 7498 7499 ins_pipe(ialu_reg_reg); 7500 %} 7501 7502 //----------Subtraction Instructions------------------------------------------- 7503 7504 // Integer Subtraction Instructions 7505 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7506 %{ 7507 match(Set dst (SubI dst src)); 7508 effect(KILL cr); 7509 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); 7510 7511 format %{ "subl $dst, $src\t# int" %} 7512 ins_encode %{ 7513 __ subl($dst$$Register, $src$$Register); 7514 %} 7515 ins_pipe(ialu_reg_reg); 7516 %} 7517 7518 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7519 %{ 7520 match(Set dst (SubI dst (LoadI src))); 7521 effect(KILL cr); 7522 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); 7523 7524 ins_cost(150); 7525 format %{ "subl $dst, $src\t# int" %} 7526 ins_encode %{ 7527 __ subl($dst$$Register, $src$$Address); 7528 %} 7529 ins_pipe(ialu_reg_mem); 7530 %} 7531 7532 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7533 %{ 7534 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7535 effect(KILL cr); 7536 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); 7537 7538 ins_cost(150); 7539 format %{ "subl $dst, $src\t# int" %} 7540 ins_encode %{ 7541 __ subl($dst$$Address, $src$$Register); 7542 %} 7543 ins_pipe(ialu_mem_reg); 7544 %} 7545 7546 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7547 %{ 7548 match(Set dst (SubL dst src)); 7549 effect(KILL cr); 7550 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7551 7552 format %{ "subq $dst, $src\t# long" %} 7553 ins_encode %{ 7554 __ subq($dst$$Register, $src$$Register); 7555 %} 7556 ins_pipe(ialu_reg_reg); 7557 %} 7558 7559 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7560 %{ 7561 match(Set dst (SubL dst (LoadL src))); 7562 effect(KILL cr); 7563 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); 7564 7565 ins_cost(150); 7566 format %{ "subq $dst, $src\t# long" %} 7567 ins_encode %{ 7568 __ subq($dst$$Register, $src$$Address); 7569 %} 7570 ins_pipe(ialu_reg_mem); 7571 %} 7572 7573 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7574 %{ 7575 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7576 effect(KILL cr); 7577 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); 7578 7579 ins_cost(150); 7580 format %{ "subq $dst, $src\t# long" %} 7581 ins_encode %{ 7582 __ subq($dst$$Address, $src$$Register); 7583 %} 7584 ins_pipe(ialu_mem_reg); 7585 %} 7586 7587 // Subtract from a pointer 7588 // XXX hmpf??? 7589 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7590 %{ 7591 match(Set dst (AddP dst (SubI zero src))); 7592 effect(KILL cr); 7593 7594 format %{ "subq $dst, $src\t# ptr - int" %} 7595 ins_encode %{ 7596 __ subq($dst$$Register, $src$$Register); 7597 %} 7598 ins_pipe(ialu_reg_reg); 7599 %} 7600 7601 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7602 %{ 7603 match(Set dst (SubI zero dst)); 7604 effect(KILL cr); 7605 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7606 7607 format %{ "negl $dst\t# int" %} 7608 ins_encode %{ 7609 __ negl($dst$$Register); 7610 %} 7611 ins_pipe(ialu_reg); 7612 %} 7613 7614 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7615 %{ 7616 match(Set dst (NegI dst)); 7617 effect(KILL cr); 7618 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7619 7620 format %{ "negl $dst\t# int" %} 7621 ins_encode %{ 7622 __ negl($dst$$Register); 7623 %} 7624 ins_pipe(ialu_reg); 7625 %} 7626 7627 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7628 %{ 7629 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7630 effect(KILL cr); 7631 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7632 7633 format %{ "negl $dst\t# int" %} 7634 ins_encode %{ 7635 __ negl($dst$$Address); 7636 %} 7637 ins_pipe(ialu_reg); 7638 %} 7639 7640 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7641 %{ 7642 match(Set dst (SubL zero dst)); 7643 effect(KILL cr); 7644 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7645 7646 format %{ "negq $dst\t# long" %} 7647 ins_encode %{ 7648 __ negq($dst$$Register); 7649 %} 7650 ins_pipe(ialu_reg); 7651 %} 7652 7653 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7654 %{ 7655 match(Set dst (NegL dst)); 7656 effect(KILL cr); 7657 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7658 7659 format %{ "negq $dst\t# int" %} 7660 ins_encode %{ 7661 __ negq($dst$$Register); 7662 %} 7663 ins_pipe(ialu_reg); 7664 %} 7665 7666 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7667 %{ 7668 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7669 effect(KILL cr); 7670 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7671 7672 format %{ "negq $dst\t# long" %} 7673 ins_encode %{ 7674 __ negq($dst$$Address); 7675 %} 7676 ins_pipe(ialu_reg); 7677 %} 7678 7679 //----------Multiplication/Division Instructions------------------------------- 7680 // Integer Multiplication Instructions 7681 // Multiply Register 7682 7683 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7684 %{ 7685 match(Set dst (MulI dst src)); 7686 effect(KILL cr); 7687 7688 ins_cost(300); 7689 format %{ "imull $dst, $src\t# int" %} 7690 ins_encode %{ 7691 __ imull($dst$$Register, $src$$Register); 7692 %} 7693 ins_pipe(ialu_reg_reg_alu0); 7694 %} 7695 7696 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7697 %{ 7698 match(Set dst (MulI src imm)); 7699 effect(KILL cr); 7700 7701 ins_cost(300); 7702 format %{ "imull $dst, $src, $imm\t# int" %} 7703 ins_encode %{ 7704 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7705 %} 7706 ins_pipe(ialu_reg_reg_alu0); 7707 %} 7708 7709 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7710 %{ 7711 match(Set dst (MulI dst (LoadI src))); 7712 effect(KILL cr); 7713 7714 ins_cost(350); 7715 format %{ "imull $dst, $src\t# int" %} 7716 ins_encode %{ 7717 __ imull($dst$$Register, $src$$Address); 7718 %} 7719 ins_pipe(ialu_reg_mem_alu0); 7720 %} 7721 7722 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7723 %{ 7724 match(Set dst (MulI (LoadI src) imm)); 7725 effect(KILL cr); 7726 7727 ins_cost(300); 7728 format %{ "imull $dst, $src, $imm\t# int" %} 7729 ins_encode %{ 7730 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7731 %} 7732 ins_pipe(ialu_reg_mem_alu0); 7733 %} 7734 7735 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7736 %{ 7737 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7738 effect(KILL cr, KILL src2); 7739 7740 expand %{ mulI_rReg(dst, src1, cr); 7741 mulI_rReg(src2, src3, cr); 7742 addI_rReg(dst, src2, cr); %} 7743 %} 7744 7745 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7746 %{ 7747 match(Set dst (MulL dst src)); 7748 effect(KILL cr); 7749 7750 ins_cost(300); 7751 format %{ "imulq $dst, $src\t# long" %} 7752 ins_encode %{ 7753 __ imulq($dst$$Register, $src$$Register); 7754 %} 7755 ins_pipe(ialu_reg_reg_alu0); 7756 %} 7757 7758 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7759 %{ 7760 match(Set dst (MulL src imm)); 7761 effect(KILL cr); 7762 7763 ins_cost(300); 7764 format %{ "imulq $dst, $src, $imm\t# long" %} 7765 ins_encode %{ 7766 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7767 %} 7768 ins_pipe(ialu_reg_reg_alu0); 7769 %} 7770 7771 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7772 %{ 7773 match(Set dst (MulL dst (LoadL src))); 7774 effect(KILL cr); 7775 7776 ins_cost(350); 7777 format %{ "imulq $dst, $src\t# long" %} 7778 ins_encode %{ 7779 __ imulq($dst$$Register, $src$$Address); 7780 %} 7781 ins_pipe(ialu_reg_mem_alu0); 7782 %} 7783 7784 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7785 %{ 7786 match(Set dst (MulL (LoadL src) imm)); 7787 effect(KILL cr); 7788 7789 ins_cost(300); 7790 format %{ "imulq $dst, $src, $imm\t# long" %} 7791 ins_encode %{ 7792 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7793 %} 7794 ins_pipe(ialu_reg_mem_alu0); 7795 %} 7796 7797 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7798 %{ 7799 match(Set dst (MulHiL src rax)); 7800 effect(USE_KILL rax, KILL cr); 7801 7802 ins_cost(300); 7803 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7804 ins_encode %{ 7805 __ imulq($src$$Register); 7806 %} 7807 ins_pipe(ialu_reg_reg_alu0); 7808 %} 7809 7810 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7811 %{ 7812 match(Set dst (UMulHiL src rax)); 7813 effect(USE_KILL rax, KILL cr); 7814 7815 ins_cost(300); 7816 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7817 ins_encode %{ 7818 __ mulq($src$$Register); 7819 %} 7820 ins_pipe(ialu_reg_reg_alu0); 7821 %} 7822 7823 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7824 rFlagsReg cr) 7825 %{ 7826 match(Set rax (DivI rax div)); 7827 effect(KILL rdx, KILL cr); 7828 7829 ins_cost(30*100+10*100); // XXX 7830 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7831 "jne,s normal\n\t" 7832 "xorl rdx, rdx\n\t" 7833 "cmpl $div, -1\n\t" 7834 "je,s done\n" 7835 "normal: cdql\n\t" 7836 "idivl $div\n" 7837 "done:" %} 7838 ins_encode(cdql_enc(div)); 7839 ins_pipe(ialu_reg_reg_alu0); 7840 %} 7841 7842 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7843 rFlagsReg cr) 7844 %{ 7845 match(Set rax (DivL rax div)); 7846 effect(KILL rdx, KILL cr); 7847 7848 ins_cost(30*100+10*100); // XXX 7849 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7850 "cmpq rax, rdx\n\t" 7851 "jne,s normal\n\t" 7852 "xorl rdx, rdx\n\t" 7853 "cmpq $div, -1\n\t" 7854 "je,s done\n" 7855 "normal: cdqq\n\t" 7856 "idivq $div\n" 7857 "done:" %} 7858 ins_encode(cdqq_enc(div)); 7859 ins_pipe(ialu_reg_reg_alu0); 7860 %} 7861 7862 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7863 %{ 7864 match(Set rax (UDivI rax div)); 7865 effect(KILL rdx, KILL cr); 7866 7867 ins_cost(300); 7868 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7869 ins_encode %{ 7870 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7871 %} 7872 ins_pipe(ialu_reg_reg_alu0); 7873 %} 7874 7875 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7876 %{ 7877 match(Set rax (UDivL rax div)); 7878 effect(KILL rdx, KILL cr); 7879 7880 ins_cost(300); 7881 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7882 ins_encode %{ 7883 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7884 %} 7885 ins_pipe(ialu_reg_reg_alu0); 7886 %} 7887 7888 // Integer DIVMOD with Register, both quotient and mod results 7889 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7890 rFlagsReg cr) 7891 %{ 7892 match(DivModI rax div); 7893 effect(KILL cr); 7894 7895 ins_cost(30*100+10*100); // XXX 7896 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7897 "jne,s normal\n\t" 7898 "xorl rdx, rdx\n\t" 7899 "cmpl $div, -1\n\t" 7900 "je,s done\n" 7901 "normal: cdql\n\t" 7902 "idivl $div\n" 7903 "done:" %} 7904 ins_encode(cdql_enc(div)); 7905 ins_pipe(pipe_slow); 7906 %} 7907 7908 // Long DIVMOD with Register, both quotient and mod results 7909 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7910 rFlagsReg cr) 7911 %{ 7912 match(DivModL rax div); 7913 effect(KILL cr); 7914 7915 ins_cost(30*100+10*100); // XXX 7916 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7917 "cmpq rax, rdx\n\t" 7918 "jne,s normal\n\t" 7919 "xorl rdx, rdx\n\t" 7920 "cmpq $div, -1\n\t" 7921 "je,s done\n" 7922 "normal: cdqq\n\t" 7923 "idivq $div\n" 7924 "done:" %} 7925 ins_encode(cdqq_enc(div)); 7926 ins_pipe(pipe_slow); 7927 %} 7928 7929 // Unsigned integer DIVMOD with Register, both quotient and mod results 7930 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7931 no_rax_rdx_RegI div, rFlagsReg cr) 7932 %{ 7933 match(UDivModI rax div); 7934 effect(TEMP tmp, KILL cr); 7935 7936 ins_cost(300); 7937 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7938 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7939 %} 7940 ins_encode %{ 7941 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7942 %} 7943 ins_pipe(pipe_slow); 7944 %} 7945 7946 // Unsigned long DIVMOD with Register, both quotient and mod results 7947 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7948 no_rax_rdx_RegL div, rFlagsReg cr) 7949 %{ 7950 match(UDivModL rax div); 7951 effect(TEMP tmp, KILL cr); 7952 7953 ins_cost(300); 7954 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7955 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7956 %} 7957 ins_encode %{ 7958 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7959 %} 7960 ins_pipe(pipe_slow); 7961 %} 7962 7963 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7964 rFlagsReg cr) 7965 %{ 7966 match(Set rdx (ModI rax div)); 7967 effect(KILL rax, KILL cr); 7968 7969 ins_cost(300); // XXX 7970 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7971 "jne,s normal\n\t" 7972 "xorl rdx, rdx\n\t" 7973 "cmpl $div, -1\n\t" 7974 "je,s done\n" 7975 "normal: cdql\n\t" 7976 "idivl $div\n" 7977 "done:" %} 7978 ins_encode(cdql_enc(div)); 7979 ins_pipe(ialu_reg_reg_alu0); 7980 %} 7981 7982 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7983 rFlagsReg cr) 7984 %{ 7985 match(Set rdx (ModL rax div)); 7986 effect(KILL rax, KILL cr); 7987 7988 ins_cost(300); // XXX 7989 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7990 "cmpq rax, rdx\n\t" 7991 "jne,s normal\n\t" 7992 "xorl rdx, rdx\n\t" 7993 "cmpq $div, -1\n\t" 7994 "je,s done\n" 7995 "normal: cdqq\n\t" 7996 "idivq $div\n" 7997 "done:" %} 7998 ins_encode(cdqq_enc(div)); 7999 ins_pipe(ialu_reg_reg_alu0); 8000 %} 8001 8002 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8003 %{ 8004 match(Set rdx (UModI rax div)); 8005 effect(KILL rax, KILL cr); 8006 8007 ins_cost(300); 8008 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8009 ins_encode %{ 8010 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8011 %} 8012 ins_pipe(ialu_reg_reg_alu0); 8013 %} 8014 8015 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8016 %{ 8017 match(Set rdx (UModL rax div)); 8018 effect(KILL rax, KILL cr); 8019 8020 ins_cost(300); 8021 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8022 ins_encode %{ 8023 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8024 %} 8025 ins_pipe(ialu_reg_reg_alu0); 8026 %} 8027 8028 // Integer Shift Instructions 8029 // Shift Left by one, two, three 8030 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8031 %{ 8032 match(Set dst (LShiftI dst shift)); 8033 effect(KILL cr); 8034 8035 format %{ "sall $dst, $shift" %} 8036 ins_encode %{ 8037 __ sall($dst$$Register, $shift$$constant); 8038 %} 8039 ins_pipe(ialu_reg); 8040 %} 8041 8042 // Shift Left by 8-bit immediate 8043 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8044 %{ 8045 match(Set dst (LShiftI dst shift)); 8046 effect(KILL cr); 8047 8048 format %{ "sall $dst, $shift" %} 8049 ins_encode %{ 8050 __ sall($dst$$Register, $shift$$constant); 8051 %} 8052 ins_pipe(ialu_reg); 8053 %} 8054 8055 // Shift Left by 8-bit immediate 8056 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8057 %{ 8058 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8059 effect(KILL cr); 8060 8061 format %{ "sall $dst, $shift" %} 8062 ins_encode %{ 8063 __ sall($dst$$Address, $shift$$constant); 8064 %} 8065 ins_pipe(ialu_mem_imm); 8066 %} 8067 8068 // Shift Left by variable 8069 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8070 %{ 8071 predicate(!VM_Version::supports_bmi2()); 8072 match(Set dst (LShiftI dst shift)); 8073 effect(KILL cr); 8074 8075 format %{ "sall $dst, $shift" %} 8076 ins_encode %{ 8077 __ sall($dst$$Register); 8078 %} 8079 ins_pipe(ialu_reg_reg); 8080 %} 8081 8082 // Shift Left by variable 8083 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8084 %{ 8085 predicate(!VM_Version::supports_bmi2()); 8086 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8087 effect(KILL cr); 8088 8089 format %{ "sall $dst, $shift" %} 8090 ins_encode %{ 8091 __ sall($dst$$Address); 8092 %} 8093 ins_pipe(ialu_mem_reg); 8094 %} 8095 8096 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8097 %{ 8098 predicate(VM_Version::supports_bmi2()); 8099 match(Set dst (LShiftI src shift)); 8100 8101 format %{ "shlxl $dst, $src, $shift" %} 8102 ins_encode %{ 8103 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8104 %} 8105 ins_pipe(ialu_reg_reg); 8106 %} 8107 8108 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8109 %{ 8110 predicate(VM_Version::supports_bmi2()); 8111 match(Set dst (LShiftI (LoadI src) shift)); 8112 ins_cost(175); 8113 format %{ "shlxl $dst, $src, $shift" %} 8114 ins_encode %{ 8115 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8116 %} 8117 ins_pipe(ialu_reg_mem); 8118 %} 8119 8120 // Arithmetic Shift Right by 8-bit immediate 8121 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8122 %{ 8123 match(Set dst (RShiftI dst shift)); 8124 effect(KILL cr); 8125 8126 format %{ "sarl $dst, $shift" %} 8127 ins_encode %{ 8128 __ sarl($dst$$Register, $shift$$constant); 8129 %} 8130 ins_pipe(ialu_mem_imm); 8131 %} 8132 8133 // Arithmetic Shift Right by 8-bit immediate 8134 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8135 %{ 8136 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8137 effect(KILL cr); 8138 8139 format %{ "sarl $dst, $shift" %} 8140 ins_encode %{ 8141 __ sarl($dst$$Address, $shift$$constant); 8142 %} 8143 ins_pipe(ialu_mem_imm); 8144 %} 8145 8146 // Arithmetic Shift Right by variable 8147 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8148 %{ 8149 predicate(!VM_Version::supports_bmi2()); 8150 match(Set dst (RShiftI dst shift)); 8151 effect(KILL cr); 8152 8153 format %{ "sarl $dst, $shift" %} 8154 ins_encode %{ 8155 __ sarl($dst$$Register); 8156 %} 8157 ins_pipe(ialu_reg_reg); 8158 %} 8159 8160 // Arithmetic Shift Right by variable 8161 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8162 %{ 8163 predicate(!VM_Version::supports_bmi2()); 8164 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8165 effect(KILL cr); 8166 8167 format %{ "sarl $dst, $shift" %} 8168 ins_encode %{ 8169 __ sarl($dst$$Address); 8170 %} 8171 ins_pipe(ialu_mem_reg); 8172 %} 8173 8174 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8175 %{ 8176 predicate(VM_Version::supports_bmi2()); 8177 match(Set dst (RShiftI src shift)); 8178 8179 format %{ "sarxl $dst, $src, $shift" %} 8180 ins_encode %{ 8181 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8182 %} 8183 ins_pipe(ialu_reg_reg); 8184 %} 8185 8186 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8187 %{ 8188 predicate(VM_Version::supports_bmi2()); 8189 match(Set dst (RShiftI (LoadI src) shift)); 8190 ins_cost(175); 8191 format %{ "sarxl $dst, $src, $shift" %} 8192 ins_encode %{ 8193 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8194 %} 8195 ins_pipe(ialu_reg_mem); 8196 %} 8197 8198 // Logical Shift Right by 8-bit immediate 8199 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8200 %{ 8201 match(Set dst (URShiftI dst shift)); 8202 effect(KILL cr); 8203 8204 format %{ "shrl $dst, $shift" %} 8205 ins_encode %{ 8206 __ shrl($dst$$Register, $shift$$constant); 8207 %} 8208 ins_pipe(ialu_reg); 8209 %} 8210 8211 // Logical Shift Right by 8-bit immediate 8212 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8213 %{ 8214 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8215 effect(KILL cr); 8216 8217 format %{ "shrl $dst, $shift" %} 8218 ins_encode %{ 8219 __ shrl($dst$$Address, $shift$$constant); 8220 %} 8221 ins_pipe(ialu_mem_imm); 8222 %} 8223 8224 // Logical Shift Right by variable 8225 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8226 %{ 8227 predicate(!VM_Version::supports_bmi2()); 8228 match(Set dst (URShiftI dst shift)); 8229 effect(KILL cr); 8230 8231 format %{ "shrl $dst, $shift" %} 8232 ins_encode %{ 8233 __ shrl($dst$$Register); 8234 %} 8235 ins_pipe(ialu_reg_reg); 8236 %} 8237 8238 // Logical Shift Right by variable 8239 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8240 %{ 8241 predicate(!VM_Version::supports_bmi2()); 8242 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8243 effect(KILL cr); 8244 8245 format %{ "shrl $dst, $shift" %} 8246 ins_encode %{ 8247 __ shrl($dst$$Address); 8248 %} 8249 ins_pipe(ialu_mem_reg); 8250 %} 8251 8252 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8253 %{ 8254 predicate(VM_Version::supports_bmi2()); 8255 match(Set dst (URShiftI src shift)); 8256 8257 format %{ "shrxl $dst, $src, $shift" %} 8258 ins_encode %{ 8259 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8260 %} 8261 ins_pipe(ialu_reg_reg); 8262 %} 8263 8264 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8265 %{ 8266 predicate(VM_Version::supports_bmi2()); 8267 match(Set dst (URShiftI (LoadI src) shift)); 8268 ins_cost(175); 8269 format %{ "shrxl $dst, $src, $shift" %} 8270 ins_encode %{ 8271 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8272 %} 8273 ins_pipe(ialu_reg_mem); 8274 %} 8275 8276 // Long Shift Instructions 8277 // Shift Left by one, two, three 8278 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8279 %{ 8280 match(Set dst (LShiftL dst shift)); 8281 effect(KILL cr); 8282 8283 format %{ "salq $dst, $shift" %} 8284 ins_encode %{ 8285 __ salq($dst$$Register, $shift$$constant); 8286 %} 8287 ins_pipe(ialu_reg); 8288 %} 8289 8290 // Shift Left by 8-bit immediate 8291 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8292 %{ 8293 match(Set dst (LShiftL dst shift)); 8294 effect(KILL cr); 8295 8296 format %{ "salq $dst, $shift" %} 8297 ins_encode %{ 8298 __ salq($dst$$Register, $shift$$constant); 8299 %} 8300 ins_pipe(ialu_reg); 8301 %} 8302 8303 // Shift Left by 8-bit immediate 8304 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8305 %{ 8306 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8307 effect(KILL cr); 8308 8309 format %{ "salq $dst, $shift" %} 8310 ins_encode %{ 8311 __ salq($dst$$Address, $shift$$constant); 8312 %} 8313 ins_pipe(ialu_mem_imm); 8314 %} 8315 8316 // Shift Left by variable 8317 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8318 %{ 8319 predicate(!VM_Version::supports_bmi2()); 8320 match(Set dst (LShiftL dst shift)); 8321 effect(KILL cr); 8322 8323 format %{ "salq $dst, $shift" %} 8324 ins_encode %{ 8325 __ salq($dst$$Register); 8326 %} 8327 ins_pipe(ialu_reg_reg); 8328 %} 8329 8330 // Shift Left by variable 8331 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8332 %{ 8333 predicate(!VM_Version::supports_bmi2()); 8334 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8335 effect(KILL cr); 8336 8337 format %{ "salq $dst, $shift" %} 8338 ins_encode %{ 8339 __ salq($dst$$Address); 8340 %} 8341 ins_pipe(ialu_mem_reg); 8342 %} 8343 8344 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8345 %{ 8346 predicate(VM_Version::supports_bmi2()); 8347 match(Set dst (LShiftL src shift)); 8348 8349 format %{ "shlxq $dst, $src, $shift" %} 8350 ins_encode %{ 8351 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8352 %} 8353 ins_pipe(ialu_reg_reg); 8354 %} 8355 8356 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8357 %{ 8358 predicate(VM_Version::supports_bmi2()); 8359 match(Set dst (LShiftL (LoadL src) shift)); 8360 ins_cost(175); 8361 format %{ "shlxq $dst, $src, $shift" %} 8362 ins_encode %{ 8363 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8364 %} 8365 ins_pipe(ialu_reg_mem); 8366 %} 8367 8368 // Arithmetic Shift Right by 8-bit immediate 8369 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8370 %{ 8371 match(Set dst (RShiftL dst shift)); 8372 effect(KILL cr); 8373 8374 format %{ "sarq $dst, $shift" %} 8375 ins_encode %{ 8376 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8377 %} 8378 ins_pipe(ialu_mem_imm); 8379 %} 8380 8381 // Arithmetic Shift Right by 8-bit immediate 8382 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8383 %{ 8384 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8385 effect(KILL cr); 8386 8387 format %{ "sarq $dst, $shift" %} 8388 ins_encode %{ 8389 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8390 %} 8391 ins_pipe(ialu_mem_imm); 8392 %} 8393 8394 // Arithmetic Shift Right by variable 8395 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8396 %{ 8397 predicate(!VM_Version::supports_bmi2()); 8398 match(Set dst (RShiftL dst shift)); 8399 effect(KILL cr); 8400 8401 format %{ "sarq $dst, $shift" %} 8402 ins_encode %{ 8403 __ sarq($dst$$Register); 8404 %} 8405 ins_pipe(ialu_reg_reg); 8406 %} 8407 8408 // Arithmetic Shift Right by variable 8409 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8410 %{ 8411 predicate(!VM_Version::supports_bmi2()); 8412 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8413 effect(KILL cr); 8414 8415 format %{ "sarq $dst, $shift" %} 8416 ins_encode %{ 8417 __ sarq($dst$$Address); 8418 %} 8419 ins_pipe(ialu_mem_reg); 8420 %} 8421 8422 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8423 %{ 8424 predicate(VM_Version::supports_bmi2()); 8425 match(Set dst (RShiftL src shift)); 8426 8427 format %{ "sarxq $dst, $src, $shift" %} 8428 ins_encode %{ 8429 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8430 %} 8431 ins_pipe(ialu_reg_reg); 8432 %} 8433 8434 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8435 %{ 8436 predicate(VM_Version::supports_bmi2()); 8437 match(Set dst (RShiftL (LoadL src) shift)); 8438 ins_cost(175); 8439 format %{ "sarxq $dst, $src, $shift" %} 8440 ins_encode %{ 8441 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8442 %} 8443 ins_pipe(ialu_reg_mem); 8444 %} 8445 8446 // Logical Shift Right by 8-bit immediate 8447 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8448 %{ 8449 match(Set dst (URShiftL dst shift)); 8450 effect(KILL cr); 8451 8452 format %{ "shrq $dst, $shift" %} 8453 ins_encode %{ 8454 __ shrq($dst$$Register, $shift$$constant); 8455 %} 8456 ins_pipe(ialu_reg); 8457 %} 8458 8459 // Logical Shift Right by 8-bit immediate 8460 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8461 %{ 8462 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8463 effect(KILL cr); 8464 8465 format %{ "shrq $dst, $shift" %} 8466 ins_encode %{ 8467 __ shrq($dst$$Address, $shift$$constant); 8468 %} 8469 ins_pipe(ialu_mem_imm); 8470 %} 8471 8472 // Logical Shift Right by variable 8473 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8474 %{ 8475 predicate(!VM_Version::supports_bmi2()); 8476 match(Set dst (URShiftL dst shift)); 8477 effect(KILL cr); 8478 8479 format %{ "shrq $dst, $shift" %} 8480 ins_encode %{ 8481 __ shrq($dst$$Register); 8482 %} 8483 ins_pipe(ialu_reg_reg); 8484 %} 8485 8486 // Logical Shift Right by variable 8487 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8488 %{ 8489 predicate(!VM_Version::supports_bmi2()); 8490 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8491 effect(KILL cr); 8492 8493 format %{ "shrq $dst, $shift" %} 8494 ins_encode %{ 8495 __ shrq($dst$$Address); 8496 %} 8497 ins_pipe(ialu_mem_reg); 8498 %} 8499 8500 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8501 %{ 8502 predicate(VM_Version::supports_bmi2()); 8503 match(Set dst (URShiftL src shift)); 8504 8505 format %{ "shrxq $dst, $src, $shift" %} 8506 ins_encode %{ 8507 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8508 %} 8509 ins_pipe(ialu_reg_reg); 8510 %} 8511 8512 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8513 %{ 8514 predicate(VM_Version::supports_bmi2()); 8515 match(Set dst (URShiftL (LoadL src) shift)); 8516 ins_cost(175); 8517 format %{ "shrxq $dst, $src, $shift" %} 8518 ins_encode %{ 8519 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8520 %} 8521 ins_pipe(ialu_reg_mem); 8522 %} 8523 8524 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8525 // This idiom is used by the compiler for the i2b bytecode. 8526 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8527 %{ 8528 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8529 8530 format %{ "movsbl $dst, $src\t# i2b" %} 8531 ins_encode %{ 8532 __ movsbl($dst$$Register, $src$$Register); 8533 %} 8534 ins_pipe(ialu_reg_reg); 8535 %} 8536 8537 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8538 // This idiom is used by the compiler the i2s bytecode. 8539 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8540 %{ 8541 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8542 8543 format %{ "movswl $dst, $src\t# i2s" %} 8544 ins_encode %{ 8545 __ movswl($dst$$Register, $src$$Register); 8546 %} 8547 ins_pipe(ialu_reg_reg); 8548 %} 8549 8550 // ROL/ROR instructions 8551 8552 // Rotate left by constant. 8553 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8554 %{ 8555 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8556 match(Set dst (RotateLeft dst shift)); 8557 effect(KILL cr); 8558 format %{ "roll $dst, $shift" %} 8559 ins_encode %{ 8560 __ roll($dst$$Register, $shift$$constant); 8561 %} 8562 ins_pipe(ialu_reg); 8563 %} 8564 8565 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8566 %{ 8567 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8568 match(Set dst (RotateLeft src shift)); 8569 format %{ "rolxl $dst, $src, $shift" %} 8570 ins_encode %{ 8571 int shift = 32 - ($shift$$constant & 31); 8572 __ rorxl($dst$$Register, $src$$Register, shift); 8573 %} 8574 ins_pipe(ialu_reg_reg); 8575 %} 8576 8577 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8578 %{ 8579 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8580 match(Set dst (RotateLeft (LoadI src) shift)); 8581 ins_cost(175); 8582 format %{ "rolxl $dst, $src, $shift" %} 8583 ins_encode %{ 8584 int shift = 32 - ($shift$$constant & 31); 8585 __ rorxl($dst$$Register, $src$$Address, shift); 8586 %} 8587 ins_pipe(ialu_reg_mem); 8588 %} 8589 8590 // Rotate Left by variable 8591 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8592 %{ 8593 predicate(n->bottom_type()->basic_type() == T_INT); 8594 match(Set dst (RotateLeft dst shift)); 8595 effect(KILL cr); 8596 format %{ "roll $dst, $shift" %} 8597 ins_encode %{ 8598 __ roll($dst$$Register); 8599 %} 8600 ins_pipe(ialu_reg_reg); 8601 %} 8602 8603 // Rotate Right by constant. 8604 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8605 %{ 8606 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8607 match(Set dst (RotateRight dst shift)); 8608 effect(KILL cr); 8609 format %{ "rorl $dst, $shift" %} 8610 ins_encode %{ 8611 __ rorl($dst$$Register, $shift$$constant); 8612 %} 8613 ins_pipe(ialu_reg); 8614 %} 8615 8616 // Rotate Right by constant. 8617 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8618 %{ 8619 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8620 match(Set dst (RotateRight src shift)); 8621 format %{ "rorxl $dst, $src, $shift" %} 8622 ins_encode %{ 8623 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8624 %} 8625 ins_pipe(ialu_reg_reg); 8626 %} 8627 8628 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8629 %{ 8630 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8631 match(Set dst (RotateRight (LoadI src) shift)); 8632 ins_cost(175); 8633 format %{ "rorxl $dst, $src, $shift" %} 8634 ins_encode %{ 8635 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8636 %} 8637 ins_pipe(ialu_reg_mem); 8638 %} 8639 8640 // Rotate Right by variable 8641 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8642 %{ 8643 predicate(n->bottom_type()->basic_type() == T_INT); 8644 match(Set dst (RotateRight dst shift)); 8645 effect(KILL cr); 8646 format %{ "rorl $dst, $shift" %} 8647 ins_encode %{ 8648 __ rorl($dst$$Register); 8649 %} 8650 ins_pipe(ialu_reg_reg); 8651 %} 8652 8653 // Rotate Left by constant. 8654 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8655 %{ 8656 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8657 match(Set dst (RotateLeft dst shift)); 8658 effect(KILL cr); 8659 format %{ "rolq $dst, $shift" %} 8660 ins_encode %{ 8661 __ rolq($dst$$Register, $shift$$constant); 8662 %} 8663 ins_pipe(ialu_reg); 8664 %} 8665 8666 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8667 %{ 8668 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8669 match(Set dst (RotateLeft src shift)); 8670 format %{ "rolxq $dst, $src, $shift" %} 8671 ins_encode %{ 8672 int shift = 64 - ($shift$$constant & 63); 8673 __ rorxq($dst$$Register, $src$$Register, shift); 8674 %} 8675 ins_pipe(ialu_reg_reg); 8676 %} 8677 8678 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8679 %{ 8680 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8681 match(Set dst (RotateLeft (LoadL src) shift)); 8682 ins_cost(175); 8683 format %{ "rolxq $dst, $src, $shift" %} 8684 ins_encode %{ 8685 int shift = 64 - ($shift$$constant & 63); 8686 __ rorxq($dst$$Register, $src$$Address, shift); 8687 %} 8688 ins_pipe(ialu_reg_mem); 8689 %} 8690 8691 // Rotate Left by variable 8692 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8693 %{ 8694 predicate(n->bottom_type()->basic_type() == T_LONG); 8695 match(Set dst (RotateLeft dst shift)); 8696 effect(KILL cr); 8697 format %{ "rolq $dst, $shift" %} 8698 ins_encode %{ 8699 __ rolq($dst$$Register); 8700 %} 8701 ins_pipe(ialu_reg_reg); 8702 %} 8703 8704 // Rotate Right by constant. 8705 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8706 %{ 8707 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8708 match(Set dst (RotateRight dst shift)); 8709 effect(KILL cr); 8710 format %{ "rorq $dst, $shift" %} 8711 ins_encode %{ 8712 __ rorq($dst$$Register, $shift$$constant); 8713 %} 8714 ins_pipe(ialu_reg); 8715 %} 8716 8717 // Rotate Right by constant 8718 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8719 %{ 8720 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8721 match(Set dst (RotateRight src shift)); 8722 format %{ "rorxq $dst, $src, $shift" %} 8723 ins_encode %{ 8724 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8725 %} 8726 ins_pipe(ialu_reg_reg); 8727 %} 8728 8729 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8730 %{ 8731 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8732 match(Set dst (RotateRight (LoadL src) shift)); 8733 ins_cost(175); 8734 format %{ "rorxq $dst, $src, $shift" %} 8735 ins_encode %{ 8736 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8737 %} 8738 ins_pipe(ialu_reg_mem); 8739 %} 8740 8741 // Rotate Right by variable 8742 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8743 %{ 8744 predicate(n->bottom_type()->basic_type() == T_LONG); 8745 match(Set dst (RotateRight dst shift)); 8746 effect(KILL cr); 8747 format %{ "rorq $dst, $shift" %} 8748 ins_encode %{ 8749 __ rorq($dst$$Register); 8750 %} 8751 ins_pipe(ialu_reg_reg); 8752 %} 8753 8754 //----------------------------- CompressBits/ExpandBits ------------------------ 8755 8756 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8757 predicate(n->bottom_type()->isa_long()); 8758 match(Set dst (CompressBits src mask)); 8759 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8760 ins_encode %{ 8761 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8762 %} 8763 ins_pipe( pipe_slow ); 8764 %} 8765 8766 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8767 predicate(n->bottom_type()->isa_long()); 8768 match(Set dst (ExpandBits src mask)); 8769 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8770 ins_encode %{ 8771 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8772 %} 8773 ins_pipe( pipe_slow ); 8774 %} 8775 8776 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8777 predicate(n->bottom_type()->isa_long()); 8778 match(Set dst (CompressBits src (LoadL mask))); 8779 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8780 ins_encode %{ 8781 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8782 %} 8783 ins_pipe( pipe_slow ); 8784 %} 8785 8786 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8787 predicate(n->bottom_type()->isa_long()); 8788 match(Set dst (ExpandBits src (LoadL mask))); 8789 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8790 ins_encode %{ 8791 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8792 %} 8793 ins_pipe( pipe_slow ); 8794 %} 8795 8796 8797 // Logical Instructions 8798 8799 // Integer Logical Instructions 8800 8801 // And Instructions 8802 // And Register with Register 8803 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8804 %{ 8805 match(Set dst (AndI dst src)); 8806 effect(KILL cr); 8807 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); 8808 8809 format %{ "andl $dst, $src\t# int" %} 8810 ins_encode %{ 8811 __ andl($dst$$Register, $src$$Register); 8812 %} 8813 ins_pipe(ialu_reg_reg); 8814 %} 8815 8816 // And Register with Immediate 255 8817 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8818 %{ 8819 match(Set dst (AndI src mask)); 8820 8821 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8822 ins_encode %{ 8823 __ movzbl($dst$$Register, $src$$Register); 8824 %} 8825 ins_pipe(ialu_reg); 8826 %} 8827 8828 // And Register with Immediate 255 and promote to long 8829 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8830 %{ 8831 match(Set dst (ConvI2L (AndI src mask))); 8832 8833 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8834 ins_encode %{ 8835 __ movzbl($dst$$Register, $src$$Register); 8836 %} 8837 ins_pipe(ialu_reg); 8838 %} 8839 8840 // And Register with Immediate 65535 8841 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8842 %{ 8843 match(Set dst (AndI src mask)); 8844 8845 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8846 ins_encode %{ 8847 __ movzwl($dst$$Register, $src$$Register); 8848 %} 8849 ins_pipe(ialu_reg); 8850 %} 8851 8852 // And Register with Immediate 65535 and promote to long 8853 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8854 %{ 8855 match(Set dst (ConvI2L (AndI src mask))); 8856 8857 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8858 ins_encode %{ 8859 __ movzwl($dst$$Register, $src$$Register); 8860 %} 8861 ins_pipe(ialu_reg); 8862 %} 8863 8864 // Can skip int2long conversions after AND with small bitmask 8865 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8866 %{ 8867 predicate(VM_Version::supports_bmi2()); 8868 ins_cost(125); 8869 effect(TEMP tmp, KILL cr); 8870 match(Set dst (ConvI2L (AndI src mask))); 8871 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8872 ins_encode %{ 8873 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8874 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8875 %} 8876 ins_pipe(ialu_reg_reg); 8877 %} 8878 8879 // And Register with Immediate 8880 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8881 %{ 8882 match(Set dst (AndI dst src)); 8883 effect(KILL cr); 8884 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); 8885 8886 format %{ "andl $dst, $src\t# int" %} 8887 ins_encode %{ 8888 __ andl($dst$$Register, $src$$constant); 8889 %} 8890 ins_pipe(ialu_reg); 8891 %} 8892 8893 // And Register with Memory 8894 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8895 %{ 8896 match(Set dst (AndI dst (LoadI src))); 8897 effect(KILL cr); 8898 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); 8899 8900 ins_cost(150); 8901 format %{ "andl $dst, $src\t# int" %} 8902 ins_encode %{ 8903 __ andl($dst$$Register, $src$$Address); 8904 %} 8905 ins_pipe(ialu_reg_mem); 8906 %} 8907 8908 // And Memory with Register 8909 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8910 %{ 8911 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8912 effect(KILL cr); 8913 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8914 8915 ins_cost(150); 8916 format %{ "andb $dst, $src\t# byte" %} 8917 ins_encode %{ 8918 __ andb($dst$$Address, $src$$Register); 8919 %} 8920 ins_pipe(ialu_mem_reg); 8921 %} 8922 8923 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8924 %{ 8925 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8926 effect(KILL cr); 8927 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); 8928 8929 ins_cost(150); 8930 format %{ "andl $dst, $src\t# int" %} 8931 ins_encode %{ 8932 __ andl($dst$$Address, $src$$Register); 8933 %} 8934 ins_pipe(ialu_mem_reg); 8935 %} 8936 8937 // And Memory with Immediate 8938 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8939 %{ 8940 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8941 effect(KILL cr); 8942 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8943 8944 ins_cost(125); 8945 format %{ "andl $dst, $src\t# int" %} 8946 ins_encode %{ 8947 __ andl($dst$$Address, $src$$constant); 8948 %} 8949 ins_pipe(ialu_mem_imm); 8950 %} 8951 8952 // BMI1 instructions 8953 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8954 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8955 predicate(UseBMI1Instructions); 8956 effect(KILL cr); 8957 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8958 8959 ins_cost(125); 8960 format %{ "andnl $dst, $src1, $src2" %} 8961 8962 ins_encode %{ 8963 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8964 %} 8965 ins_pipe(ialu_reg_mem); 8966 %} 8967 8968 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8969 match(Set dst (AndI (XorI src1 minus_1) src2)); 8970 predicate(UseBMI1Instructions); 8971 effect(KILL cr); 8972 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8973 8974 format %{ "andnl $dst, $src1, $src2" %} 8975 8976 ins_encode %{ 8977 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8978 %} 8979 ins_pipe(ialu_reg); 8980 %} 8981 8982 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 8983 match(Set dst (AndI (SubI imm_zero src) src)); 8984 predicate(UseBMI1Instructions); 8985 effect(KILL cr); 8986 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 8987 8988 format %{ "blsil $dst, $src" %} 8989 8990 ins_encode %{ 8991 __ blsil($dst$$Register, $src$$Register); 8992 %} 8993 ins_pipe(ialu_reg); 8994 %} 8995 8996 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 8997 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8998 predicate(UseBMI1Instructions); 8999 effect(KILL cr); 9000 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9001 9002 ins_cost(125); 9003 format %{ "blsil $dst, $src" %} 9004 9005 ins_encode %{ 9006 __ blsil($dst$$Register, $src$$Address); 9007 %} 9008 ins_pipe(ialu_reg_mem); 9009 %} 9010 9011 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9012 %{ 9013 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9014 predicate(UseBMI1Instructions); 9015 effect(KILL cr); 9016 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9017 9018 ins_cost(125); 9019 format %{ "blsmskl $dst, $src" %} 9020 9021 ins_encode %{ 9022 __ blsmskl($dst$$Register, $src$$Address); 9023 %} 9024 ins_pipe(ialu_reg_mem); 9025 %} 9026 9027 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9028 %{ 9029 match(Set dst (XorI (AddI src minus_1) src)); 9030 predicate(UseBMI1Instructions); 9031 effect(KILL cr); 9032 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9033 9034 format %{ "blsmskl $dst, $src" %} 9035 9036 ins_encode %{ 9037 __ blsmskl($dst$$Register, $src$$Register); 9038 %} 9039 9040 ins_pipe(ialu_reg); 9041 %} 9042 9043 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9044 %{ 9045 match(Set dst (AndI (AddI src minus_1) src) ); 9046 predicate(UseBMI1Instructions); 9047 effect(KILL cr); 9048 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9049 9050 format %{ "blsrl $dst, $src" %} 9051 9052 ins_encode %{ 9053 __ blsrl($dst$$Register, $src$$Register); 9054 %} 9055 9056 ins_pipe(ialu_reg_mem); 9057 %} 9058 9059 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9060 %{ 9061 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9062 predicate(UseBMI1Instructions); 9063 effect(KILL cr); 9064 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9065 9066 ins_cost(125); 9067 format %{ "blsrl $dst, $src" %} 9068 9069 ins_encode %{ 9070 __ blsrl($dst$$Register, $src$$Address); 9071 %} 9072 9073 ins_pipe(ialu_reg); 9074 %} 9075 9076 // Or Instructions 9077 // Or Register with Register 9078 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9079 %{ 9080 match(Set dst (OrI dst src)); 9081 effect(KILL cr); 9082 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); 9083 9084 format %{ "orl $dst, $src\t# int" %} 9085 ins_encode %{ 9086 __ orl($dst$$Register, $src$$Register); 9087 %} 9088 ins_pipe(ialu_reg_reg); 9089 %} 9090 9091 // Or Register with Immediate 9092 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9093 %{ 9094 match(Set dst (OrI dst src)); 9095 effect(KILL cr); 9096 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); 9097 9098 format %{ "orl $dst, $src\t# int" %} 9099 ins_encode %{ 9100 __ orl($dst$$Register, $src$$constant); 9101 %} 9102 ins_pipe(ialu_reg); 9103 %} 9104 9105 // Or Register with Memory 9106 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9107 %{ 9108 match(Set dst (OrI dst (LoadI src))); 9109 effect(KILL cr); 9110 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9111 9112 ins_cost(150); 9113 format %{ "orl $dst, $src\t# int" %} 9114 ins_encode %{ 9115 __ orl($dst$$Register, $src$$Address); 9116 %} 9117 ins_pipe(ialu_reg_mem); 9118 %} 9119 9120 // Or Memory with Register 9121 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9122 %{ 9123 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9124 effect(KILL cr); 9125 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9126 9127 ins_cost(150); 9128 format %{ "orb $dst, $src\t# byte" %} 9129 ins_encode %{ 9130 __ orb($dst$$Address, $src$$Register); 9131 %} 9132 ins_pipe(ialu_mem_reg); 9133 %} 9134 9135 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9136 %{ 9137 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9138 effect(KILL cr); 9139 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); 9140 9141 ins_cost(150); 9142 format %{ "orl $dst, $src\t# int" %} 9143 ins_encode %{ 9144 __ orl($dst$$Address, $src$$Register); 9145 %} 9146 ins_pipe(ialu_mem_reg); 9147 %} 9148 9149 // Or Memory with Immediate 9150 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9151 %{ 9152 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9153 effect(KILL cr); 9154 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9155 9156 ins_cost(125); 9157 format %{ "orl $dst, $src\t# int" %} 9158 ins_encode %{ 9159 __ orl($dst$$Address, $src$$constant); 9160 %} 9161 ins_pipe(ialu_mem_imm); 9162 %} 9163 9164 // Xor Instructions 9165 // Xor Register with Register 9166 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9167 %{ 9168 match(Set dst (XorI dst src)); 9169 effect(KILL cr); 9170 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); 9171 9172 format %{ "xorl $dst, $src\t# int" %} 9173 ins_encode %{ 9174 __ xorl($dst$$Register, $src$$Register); 9175 %} 9176 ins_pipe(ialu_reg_reg); 9177 %} 9178 9179 // Xor Register with Immediate -1 9180 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9181 match(Set dst (XorI dst imm)); 9182 9183 format %{ "not $dst" %} 9184 ins_encode %{ 9185 __ notl($dst$$Register); 9186 %} 9187 ins_pipe(ialu_reg); 9188 %} 9189 9190 // Xor Register with Immediate 9191 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9192 %{ 9193 match(Set dst (XorI dst src)); 9194 effect(KILL cr); 9195 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); 9196 9197 format %{ "xorl $dst, $src\t# int" %} 9198 ins_encode %{ 9199 __ xorl($dst$$Register, $src$$constant); 9200 %} 9201 ins_pipe(ialu_reg); 9202 %} 9203 9204 // Xor Register with Memory 9205 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9206 %{ 9207 match(Set dst (XorI dst (LoadI src))); 9208 effect(KILL cr); 9209 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); 9210 9211 ins_cost(150); 9212 format %{ "xorl $dst, $src\t# int" %} 9213 ins_encode %{ 9214 __ xorl($dst$$Register, $src$$Address); 9215 %} 9216 ins_pipe(ialu_reg_mem); 9217 %} 9218 9219 // Xor Memory with Register 9220 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9221 %{ 9222 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9223 effect(KILL cr); 9224 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9225 9226 ins_cost(150); 9227 format %{ "xorb $dst, $src\t# byte" %} 9228 ins_encode %{ 9229 __ xorb($dst$$Address, $src$$Register); 9230 %} 9231 ins_pipe(ialu_mem_reg); 9232 %} 9233 9234 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9235 %{ 9236 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9237 effect(KILL cr); 9238 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); 9239 9240 ins_cost(150); 9241 format %{ "xorl $dst, $src\t# int" %} 9242 ins_encode %{ 9243 __ xorl($dst$$Address, $src$$Register); 9244 %} 9245 ins_pipe(ialu_mem_reg); 9246 %} 9247 9248 // Xor Memory with Immediate 9249 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9250 %{ 9251 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9252 effect(KILL cr); 9253 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9254 9255 ins_cost(125); 9256 format %{ "xorl $dst, $src\t# int" %} 9257 ins_encode %{ 9258 __ xorl($dst$$Address, $src$$constant); 9259 %} 9260 ins_pipe(ialu_mem_imm); 9261 %} 9262 9263 9264 // Long Logical Instructions 9265 9266 // And Instructions 9267 // And Register with Register 9268 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9269 %{ 9270 match(Set dst (AndL dst src)); 9271 effect(KILL cr); 9272 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); 9273 9274 format %{ "andq $dst, $src\t# long" %} 9275 ins_encode %{ 9276 __ andq($dst$$Register, $src$$Register); 9277 %} 9278 ins_pipe(ialu_reg_reg); 9279 %} 9280 9281 // And Register with Immediate 255 9282 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9283 %{ 9284 match(Set dst (AndL src mask)); 9285 9286 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9287 ins_encode %{ 9288 // movzbl zeroes out the upper 32-bit and does not need REX.W 9289 __ movzbl($dst$$Register, $src$$Register); 9290 %} 9291 ins_pipe(ialu_reg); 9292 %} 9293 9294 // And Register with Immediate 65535 9295 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9296 %{ 9297 match(Set dst (AndL src mask)); 9298 9299 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9300 ins_encode %{ 9301 // movzwl zeroes out the upper 32-bit and does not need REX.W 9302 __ movzwl($dst$$Register, $src$$Register); 9303 %} 9304 ins_pipe(ialu_reg); 9305 %} 9306 9307 // And Register with Immediate 9308 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9309 %{ 9310 match(Set dst (AndL dst src)); 9311 effect(KILL cr); 9312 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); 9313 9314 format %{ "andq $dst, $src\t# long" %} 9315 ins_encode %{ 9316 __ andq($dst$$Register, $src$$constant); 9317 %} 9318 ins_pipe(ialu_reg); 9319 %} 9320 9321 // And Register with Memory 9322 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9323 %{ 9324 match(Set dst (AndL dst (LoadL src))); 9325 effect(KILL cr); 9326 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); 9327 9328 ins_cost(150); 9329 format %{ "andq $dst, $src\t# long" %} 9330 ins_encode %{ 9331 __ andq($dst$$Register, $src$$Address); 9332 %} 9333 ins_pipe(ialu_reg_mem); 9334 %} 9335 9336 // And Memory with Register 9337 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9338 %{ 9339 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9340 effect(KILL cr); 9341 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9342 9343 ins_cost(150); 9344 format %{ "andq $dst, $src\t# long" %} 9345 ins_encode %{ 9346 __ andq($dst$$Address, $src$$Register); 9347 %} 9348 ins_pipe(ialu_mem_reg); 9349 %} 9350 9351 // And Memory with Immediate 9352 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9353 %{ 9354 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9355 effect(KILL cr); 9356 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9357 9358 ins_cost(125); 9359 format %{ "andq $dst, $src\t# long" %} 9360 ins_encode %{ 9361 __ andq($dst$$Address, $src$$constant); 9362 %} 9363 ins_pipe(ialu_mem_imm); 9364 %} 9365 9366 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9367 %{ 9368 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9369 // because AND/OR works well enough for 8/32-bit values. 9370 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9371 9372 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9373 effect(KILL cr); 9374 9375 ins_cost(125); 9376 format %{ "btrq $dst, log2(not($con))\t# long" %} 9377 ins_encode %{ 9378 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9379 %} 9380 ins_pipe(ialu_mem_imm); 9381 %} 9382 9383 // BMI1 instructions 9384 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9385 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9386 predicate(UseBMI1Instructions); 9387 effect(KILL cr); 9388 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9389 9390 ins_cost(125); 9391 format %{ "andnq $dst, $src1, $src2" %} 9392 9393 ins_encode %{ 9394 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9395 %} 9396 ins_pipe(ialu_reg_mem); 9397 %} 9398 9399 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9400 match(Set dst (AndL (XorL src1 minus_1) src2)); 9401 predicate(UseBMI1Instructions); 9402 effect(KILL cr); 9403 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9404 9405 format %{ "andnq $dst, $src1, $src2" %} 9406 9407 ins_encode %{ 9408 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9409 %} 9410 ins_pipe(ialu_reg_mem); 9411 %} 9412 9413 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9414 match(Set dst (AndL (SubL imm_zero src) src)); 9415 predicate(UseBMI1Instructions); 9416 effect(KILL cr); 9417 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9418 9419 format %{ "blsiq $dst, $src" %} 9420 9421 ins_encode %{ 9422 __ blsiq($dst$$Register, $src$$Register); 9423 %} 9424 ins_pipe(ialu_reg); 9425 %} 9426 9427 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9428 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9429 predicate(UseBMI1Instructions); 9430 effect(KILL cr); 9431 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9432 9433 ins_cost(125); 9434 format %{ "blsiq $dst, $src" %} 9435 9436 ins_encode %{ 9437 __ blsiq($dst$$Register, $src$$Address); 9438 %} 9439 ins_pipe(ialu_reg_mem); 9440 %} 9441 9442 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9443 %{ 9444 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9445 predicate(UseBMI1Instructions); 9446 effect(KILL cr); 9447 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9448 9449 ins_cost(125); 9450 format %{ "blsmskq $dst, $src" %} 9451 9452 ins_encode %{ 9453 __ blsmskq($dst$$Register, $src$$Address); 9454 %} 9455 ins_pipe(ialu_reg_mem); 9456 %} 9457 9458 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9459 %{ 9460 match(Set dst (XorL (AddL src minus_1) src)); 9461 predicate(UseBMI1Instructions); 9462 effect(KILL cr); 9463 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9464 9465 format %{ "blsmskq $dst, $src" %} 9466 9467 ins_encode %{ 9468 __ blsmskq($dst$$Register, $src$$Register); 9469 %} 9470 9471 ins_pipe(ialu_reg); 9472 %} 9473 9474 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9475 %{ 9476 match(Set dst (AndL (AddL src minus_1) src) ); 9477 predicate(UseBMI1Instructions); 9478 effect(KILL cr); 9479 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9480 9481 format %{ "blsrq $dst, $src" %} 9482 9483 ins_encode %{ 9484 __ blsrq($dst$$Register, $src$$Register); 9485 %} 9486 9487 ins_pipe(ialu_reg); 9488 %} 9489 9490 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9491 %{ 9492 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9493 predicate(UseBMI1Instructions); 9494 effect(KILL cr); 9495 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9496 9497 ins_cost(125); 9498 format %{ "blsrq $dst, $src" %} 9499 9500 ins_encode %{ 9501 __ blsrq($dst$$Register, $src$$Address); 9502 %} 9503 9504 ins_pipe(ialu_reg); 9505 %} 9506 9507 // Or Instructions 9508 // Or Register with Register 9509 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9510 %{ 9511 match(Set dst (OrL dst src)); 9512 effect(KILL cr); 9513 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); 9514 9515 format %{ "orq $dst, $src\t# long" %} 9516 ins_encode %{ 9517 __ orq($dst$$Register, $src$$Register); 9518 %} 9519 ins_pipe(ialu_reg_reg); 9520 %} 9521 9522 // Use any_RegP to match R15 (TLS register) without spilling. 9523 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9524 match(Set dst (OrL dst (CastP2X src))); 9525 effect(KILL cr); 9526 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); 9527 9528 format %{ "orq $dst, $src\t# long" %} 9529 ins_encode %{ 9530 __ orq($dst$$Register, $src$$Register); 9531 %} 9532 ins_pipe(ialu_reg_reg); 9533 %} 9534 9535 9536 // Or Register with Immediate 9537 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9538 %{ 9539 match(Set dst (OrL dst src)); 9540 effect(KILL cr); 9541 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9542 9543 format %{ "orq $dst, $src\t# long" %} 9544 ins_encode %{ 9545 __ orq($dst$$Register, $src$$constant); 9546 %} 9547 ins_pipe(ialu_reg); 9548 %} 9549 9550 // Or Register with Memory 9551 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9552 %{ 9553 match(Set dst (OrL dst (LoadL src))); 9554 effect(KILL cr); 9555 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); 9556 9557 ins_cost(150); 9558 format %{ "orq $dst, $src\t# long" %} 9559 ins_encode %{ 9560 __ orq($dst$$Register, $src$$Address); 9561 %} 9562 ins_pipe(ialu_reg_mem); 9563 %} 9564 9565 // Or Memory with Register 9566 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9567 %{ 9568 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9569 effect(KILL cr); 9570 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9571 9572 ins_cost(150); 9573 format %{ "orq $dst, $src\t# long" %} 9574 ins_encode %{ 9575 __ orq($dst$$Address, $src$$Register); 9576 %} 9577 ins_pipe(ialu_mem_reg); 9578 %} 9579 9580 // Or Memory with Immediate 9581 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9582 %{ 9583 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9584 effect(KILL cr); 9585 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9586 9587 ins_cost(125); 9588 format %{ "orq $dst, $src\t# long" %} 9589 ins_encode %{ 9590 __ orq($dst$$Address, $src$$constant); 9591 %} 9592 ins_pipe(ialu_mem_imm); 9593 %} 9594 9595 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9596 %{ 9597 // con should be a pure 64-bit power of 2 immediate 9598 // because AND/OR works well enough for 8/32-bit values. 9599 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9600 9601 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9602 effect(KILL cr); 9603 9604 ins_cost(125); 9605 format %{ "btsq $dst, log2($con)\t# long" %} 9606 ins_encode %{ 9607 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9608 %} 9609 ins_pipe(ialu_mem_imm); 9610 %} 9611 9612 // Xor Instructions 9613 // Xor Register with Register 9614 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9615 %{ 9616 match(Set dst (XorL 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 format %{ "xorq $dst, $src\t# long" %} 9621 ins_encode %{ 9622 __ xorq($dst$$Register, $src$$Register); 9623 %} 9624 ins_pipe(ialu_reg_reg); 9625 %} 9626 9627 // Xor Register with Immediate -1 9628 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9629 match(Set dst (XorL dst imm)); 9630 9631 format %{ "notq $dst" %} 9632 ins_encode %{ 9633 __ notq($dst$$Register); 9634 %} 9635 ins_pipe(ialu_reg); 9636 %} 9637 9638 // Xor Register with Immediate 9639 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9640 %{ 9641 match(Set dst (XorL dst src)); 9642 effect(KILL cr); 9643 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); 9644 9645 format %{ "xorq $dst, $src\t# long" %} 9646 ins_encode %{ 9647 __ xorq($dst$$Register, $src$$constant); 9648 %} 9649 ins_pipe(ialu_reg); 9650 %} 9651 9652 // Xor Register with Memory 9653 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9654 %{ 9655 match(Set dst (XorL dst (LoadL src))); 9656 effect(KILL cr); 9657 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); 9658 9659 ins_cost(150); 9660 format %{ "xorq $dst, $src\t# long" %} 9661 ins_encode %{ 9662 __ xorq($dst$$Register, $src$$Address); 9663 %} 9664 ins_pipe(ialu_reg_mem); 9665 %} 9666 9667 // Xor Memory with Register 9668 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9669 %{ 9670 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9671 effect(KILL cr); 9672 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9673 9674 ins_cost(150); 9675 format %{ "xorq $dst, $src\t# long" %} 9676 ins_encode %{ 9677 __ xorq($dst$$Address, $src$$Register); 9678 %} 9679 ins_pipe(ialu_mem_reg); 9680 %} 9681 9682 // Xor Memory with Immediate 9683 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9684 %{ 9685 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9686 effect(KILL cr); 9687 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9688 9689 ins_cost(125); 9690 format %{ "xorq $dst, $src\t# long" %} 9691 ins_encode %{ 9692 __ xorq($dst$$Address, $src$$constant); 9693 %} 9694 ins_pipe(ialu_mem_imm); 9695 %} 9696 9697 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9698 %{ 9699 match(Set dst (CmpLTMask p q)); 9700 effect(KILL cr); 9701 9702 ins_cost(400); 9703 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9704 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 9705 "negl $dst" %} 9706 ins_encode %{ 9707 __ cmpl($p$$Register, $q$$Register); 9708 __ setcc(Assembler::less, $dst$$Register); 9709 __ negl($dst$$Register); 9710 %} 9711 ins_pipe(pipe_slow); 9712 %} 9713 9714 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9715 %{ 9716 match(Set dst (CmpLTMask dst zero)); 9717 effect(KILL cr); 9718 9719 ins_cost(100); 9720 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9721 ins_encode %{ 9722 __ sarl($dst$$Register, 31); 9723 %} 9724 ins_pipe(ialu_reg); 9725 %} 9726 9727 /* Better to save a register than avoid a branch */ 9728 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9729 %{ 9730 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9731 effect(KILL cr); 9732 ins_cost(300); 9733 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9734 "jge done\n\t" 9735 "addl $p,$y\n" 9736 "done: " %} 9737 ins_encode %{ 9738 Register Rp = $p$$Register; 9739 Register Rq = $q$$Register; 9740 Register Ry = $y$$Register; 9741 Label done; 9742 __ subl(Rp, Rq); 9743 __ jccb(Assembler::greaterEqual, done); 9744 __ addl(Rp, Ry); 9745 __ bind(done); 9746 %} 9747 ins_pipe(pipe_cmplt); 9748 %} 9749 9750 /* Better to save a register than avoid a branch */ 9751 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9752 %{ 9753 match(Set y (AndI (CmpLTMask p q) y)); 9754 effect(KILL cr); 9755 9756 ins_cost(300); 9757 9758 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9759 "jlt done\n\t" 9760 "xorl $y, $y\n" 9761 "done: " %} 9762 ins_encode %{ 9763 Register Rp = $p$$Register; 9764 Register Rq = $q$$Register; 9765 Register Ry = $y$$Register; 9766 Label done; 9767 __ cmpl(Rp, Rq); 9768 __ jccb(Assembler::less, done); 9769 __ xorl(Ry, Ry); 9770 __ bind(done); 9771 %} 9772 ins_pipe(pipe_cmplt); 9773 %} 9774 9775 9776 //---------- FP Instructions------------------------------------------------ 9777 9778 // Really expensive, avoid 9779 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9780 %{ 9781 match(Set cr (CmpF src1 src2)); 9782 9783 ins_cost(500); 9784 format %{ "ucomiss $src1, $src2\n\t" 9785 "jnp,s exit\n\t" 9786 "pushfq\t# saw NaN, set CF\n\t" 9787 "andq [rsp], #0xffffff2b\n\t" 9788 "popfq\n" 9789 "exit:" %} 9790 ins_encode %{ 9791 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9792 emit_cmpfp_fixup(masm); 9793 %} 9794 ins_pipe(pipe_slow); 9795 %} 9796 9797 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9798 match(Set cr (CmpF src1 src2)); 9799 9800 ins_cost(100); 9801 format %{ "ucomiss $src1, $src2" %} 9802 ins_encode %{ 9803 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9804 %} 9805 ins_pipe(pipe_slow); 9806 %} 9807 9808 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9809 match(Set cr (CmpF src1 (LoadF src2))); 9810 9811 ins_cost(100); 9812 format %{ "ucomiss $src1, $src2" %} 9813 ins_encode %{ 9814 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9815 %} 9816 ins_pipe(pipe_slow); 9817 %} 9818 9819 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9820 match(Set cr (CmpF src con)); 9821 ins_cost(100); 9822 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9823 ins_encode %{ 9824 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9825 %} 9826 ins_pipe(pipe_slow); 9827 %} 9828 9829 // Really expensive, avoid 9830 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9831 %{ 9832 match(Set cr (CmpD src1 src2)); 9833 9834 ins_cost(500); 9835 format %{ "ucomisd $src1, $src2\n\t" 9836 "jnp,s exit\n\t" 9837 "pushfq\t# saw NaN, set CF\n\t" 9838 "andq [rsp], #0xffffff2b\n\t" 9839 "popfq\n" 9840 "exit:" %} 9841 ins_encode %{ 9842 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9843 emit_cmpfp_fixup(masm); 9844 %} 9845 ins_pipe(pipe_slow); 9846 %} 9847 9848 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9849 match(Set cr (CmpD src1 src2)); 9850 9851 ins_cost(100); 9852 format %{ "ucomisd $src1, $src2 test" %} 9853 ins_encode %{ 9854 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9855 %} 9856 ins_pipe(pipe_slow); 9857 %} 9858 9859 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9860 match(Set cr (CmpD src1 (LoadD src2))); 9861 9862 ins_cost(100); 9863 format %{ "ucomisd $src1, $src2" %} 9864 ins_encode %{ 9865 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9866 %} 9867 ins_pipe(pipe_slow); 9868 %} 9869 9870 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9871 match(Set cr (CmpD src con)); 9872 ins_cost(100); 9873 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9874 ins_encode %{ 9875 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9876 %} 9877 ins_pipe(pipe_slow); 9878 %} 9879 9880 // Compare into -1,0,1 9881 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9882 %{ 9883 match(Set dst (CmpF3 src1 src2)); 9884 effect(KILL cr); 9885 9886 ins_cost(275); 9887 format %{ "ucomiss $src1, $src2\n\t" 9888 "movl $dst, #-1\n\t" 9889 "jp,s done\n\t" 9890 "jb,s done\n\t" 9891 "setne $dst\n\t" 9892 "movzbl $dst, $dst\n" 9893 "done:" %} 9894 ins_encode %{ 9895 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9896 emit_cmpfp3(masm, $dst$$Register); 9897 %} 9898 ins_pipe(pipe_slow); 9899 %} 9900 9901 // Compare into -1,0,1 9902 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9903 %{ 9904 match(Set dst (CmpF3 src1 (LoadF src2))); 9905 effect(KILL cr); 9906 9907 ins_cost(275); 9908 format %{ "ucomiss $src1, $src2\n\t" 9909 "movl $dst, #-1\n\t" 9910 "jp,s done\n\t" 9911 "jb,s done\n\t" 9912 "setne $dst\n\t" 9913 "movzbl $dst, $dst\n" 9914 "done:" %} 9915 ins_encode %{ 9916 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9917 emit_cmpfp3(masm, $dst$$Register); 9918 %} 9919 ins_pipe(pipe_slow); 9920 %} 9921 9922 // Compare into -1,0,1 9923 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9924 match(Set dst (CmpF3 src con)); 9925 effect(KILL cr); 9926 9927 ins_cost(275); 9928 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9929 "movl $dst, #-1\n\t" 9930 "jp,s done\n\t" 9931 "jb,s done\n\t" 9932 "setne $dst\n\t" 9933 "movzbl $dst, $dst\n" 9934 "done:" %} 9935 ins_encode %{ 9936 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9937 emit_cmpfp3(masm, $dst$$Register); 9938 %} 9939 ins_pipe(pipe_slow); 9940 %} 9941 9942 // Compare into -1,0,1 9943 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9944 %{ 9945 match(Set dst (CmpD3 src1 src2)); 9946 effect(KILL cr); 9947 9948 ins_cost(275); 9949 format %{ "ucomisd $src1, $src2\n\t" 9950 "movl $dst, #-1\n\t" 9951 "jp,s done\n\t" 9952 "jb,s done\n\t" 9953 "setne $dst\n\t" 9954 "movzbl $dst, $dst\n" 9955 "done:" %} 9956 ins_encode %{ 9957 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9958 emit_cmpfp3(masm, $dst$$Register); 9959 %} 9960 ins_pipe(pipe_slow); 9961 %} 9962 9963 // Compare into -1,0,1 9964 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9965 %{ 9966 match(Set dst (CmpD3 src1 (LoadD src2))); 9967 effect(KILL cr); 9968 9969 ins_cost(275); 9970 format %{ "ucomisd $src1, $src2\n\t" 9971 "movl $dst, #-1\n\t" 9972 "jp,s done\n\t" 9973 "jb,s done\n\t" 9974 "setne $dst\n\t" 9975 "movzbl $dst, $dst\n" 9976 "done:" %} 9977 ins_encode %{ 9978 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9979 emit_cmpfp3(masm, $dst$$Register); 9980 %} 9981 ins_pipe(pipe_slow); 9982 %} 9983 9984 // Compare into -1,0,1 9985 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9986 match(Set dst (CmpD3 src con)); 9987 effect(KILL cr); 9988 9989 ins_cost(275); 9990 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9991 "movl $dst, #-1\n\t" 9992 "jp,s done\n\t" 9993 "jb,s done\n\t" 9994 "setne $dst\n\t" 9995 "movzbl $dst, $dst\n" 9996 "done:" %} 9997 ins_encode %{ 9998 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9999 emit_cmpfp3(masm, $dst$$Register); 10000 %} 10001 ins_pipe(pipe_slow); 10002 %} 10003 10004 //----------Arithmetic Conversion Instructions--------------------------------- 10005 10006 instruct convF2D_reg_reg(regD dst, regF src) 10007 %{ 10008 match(Set dst (ConvF2D src)); 10009 10010 format %{ "cvtss2sd $dst, $src" %} 10011 ins_encode %{ 10012 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10013 %} 10014 ins_pipe(pipe_slow); // XXX 10015 %} 10016 10017 instruct convF2D_reg_mem(regD dst, memory src) 10018 %{ 10019 predicate(UseAVX == 0); 10020 match(Set dst (ConvF2D (LoadF src))); 10021 10022 format %{ "cvtss2sd $dst, $src" %} 10023 ins_encode %{ 10024 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10025 %} 10026 ins_pipe(pipe_slow); // XXX 10027 %} 10028 10029 instruct convD2F_reg_reg(regF dst, regD src) 10030 %{ 10031 match(Set dst (ConvD2F src)); 10032 10033 format %{ "cvtsd2ss $dst, $src" %} 10034 ins_encode %{ 10035 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10036 %} 10037 ins_pipe(pipe_slow); // XXX 10038 %} 10039 10040 instruct convD2F_reg_mem(regF dst, memory src) 10041 %{ 10042 predicate(UseAVX == 0); 10043 match(Set dst (ConvD2F (LoadD src))); 10044 10045 format %{ "cvtsd2ss $dst, $src" %} 10046 ins_encode %{ 10047 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10048 %} 10049 ins_pipe(pipe_slow); // XXX 10050 %} 10051 10052 // XXX do mem variants 10053 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10054 %{ 10055 match(Set dst (ConvF2I src)); 10056 effect(KILL cr); 10057 format %{ "convert_f2i $dst, $src" %} 10058 ins_encode %{ 10059 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10060 %} 10061 ins_pipe(pipe_slow); 10062 %} 10063 10064 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10065 %{ 10066 match(Set dst (ConvF2L src)); 10067 effect(KILL cr); 10068 format %{ "convert_f2l $dst, $src"%} 10069 ins_encode %{ 10070 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10071 %} 10072 ins_pipe(pipe_slow); 10073 %} 10074 10075 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10076 %{ 10077 match(Set dst (ConvD2I src)); 10078 effect(KILL cr); 10079 format %{ "convert_d2i $dst, $src"%} 10080 ins_encode %{ 10081 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10082 %} 10083 ins_pipe(pipe_slow); 10084 %} 10085 10086 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10087 %{ 10088 match(Set dst (ConvD2L src)); 10089 effect(KILL cr); 10090 format %{ "convert_d2l $dst, $src"%} 10091 ins_encode %{ 10092 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10093 %} 10094 ins_pipe(pipe_slow); 10095 %} 10096 10097 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10098 %{ 10099 match(Set dst (RoundD src)); 10100 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10101 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10102 ins_encode %{ 10103 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10104 %} 10105 ins_pipe(pipe_slow); 10106 %} 10107 10108 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10109 %{ 10110 match(Set dst (RoundF src)); 10111 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10112 format %{ "round_float $dst,$src" %} 10113 ins_encode %{ 10114 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10115 %} 10116 ins_pipe(pipe_slow); 10117 %} 10118 10119 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10120 %{ 10121 predicate(!UseXmmI2F); 10122 match(Set dst (ConvI2F src)); 10123 10124 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10125 ins_encode %{ 10126 if (UseAVX > 0) { 10127 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10128 } 10129 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10130 %} 10131 ins_pipe(pipe_slow); // XXX 10132 %} 10133 10134 instruct convI2F_reg_mem(regF dst, memory src) 10135 %{ 10136 predicate(UseAVX == 0); 10137 match(Set dst (ConvI2F (LoadI src))); 10138 10139 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10140 ins_encode %{ 10141 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10142 %} 10143 ins_pipe(pipe_slow); // XXX 10144 %} 10145 10146 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10147 %{ 10148 predicate(!UseXmmI2D); 10149 match(Set dst (ConvI2D src)); 10150 10151 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10152 ins_encode %{ 10153 if (UseAVX > 0) { 10154 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10155 } 10156 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10157 %} 10158 ins_pipe(pipe_slow); // XXX 10159 %} 10160 10161 instruct convI2D_reg_mem(regD dst, memory src) 10162 %{ 10163 predicate(UseAVX == 0); 10164 match(Set dst (ConvI2D (LoadI src))); 10165 10166 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10167 ins_encode %{ 10168 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10169 %} 10170 ins_pipe(pipe_slow); // XXX 10171 %} 10172 10173 instruct convXI2F_reg(regF dst, rRegI src) 10174 %{ 10175 predicate(UseXmmI2F); 10176 match(Set dst (ConvI2F src)); 10177 10178 format %{ "movdl $dst, $src\n\t" 10179 "cvtdq2psl $dst, $dst\t# i2f" %} 10180 ins_encode %{ 10181 __ movdl($dst$$XMMRegister, $src$$Register); 10182 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10183 %} 10184 ins_pipe(pipe_slow); // XXX 10185 %} 10186 10187 instruct convXI2D_reg(regD dst, rRegI src) 10188 %{ 10189 predicate(UseXmmI2D); 10190 match(Set dst (ConvI2D src)); 10191 10192 format %{ "movdl $dst, $src\n\t" 10193 "cvtdq2pdl $dst, $dst\t# i2d" %} 10194 ins_encode %{ 10195 __ movdl($dst$$XMMRegister, $src$$Register); 10196 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10197 %} 10198 ins_pipe(pipe_slow); // XXX 10199 %} 10200 10201 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10202 %{ 10203 match(Set dst (ConvL2F src)); 10204 10205 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10206 ins_encode %{ 10207 if (UseAVX > 0) { 10208 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10209 } 10210 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10211 %} 10212 ins_pipe(pipe_slow); // XXX 10213 %} 10214 10215 instruct convL2F_reg_mem(regF dst, memory src) 10216 %{ 10217 predicate(UseAVX == 0); 10218 match(Set dst (ConvL2F (LoadL src))); 10219 10220 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10221 ins_encode %{ 10222 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10223 %} 10224 ins_pipe(pipe_slow); // XXX 10225 %} 10226 10227 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10228 %{ 10229 match(Set dst (ConvL2D src)); 10230 10231 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10232 ins_encode %{ 10233 if (UseAVX > 0) { 10234 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10235 } 10236 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10237 %} 10238 ins_pipe(pipe_slow); // XXX 10239 %} 10240 10241 instruct convL2D_reg_mem(regD dst, memory src) 10242 %{ 10243 predicate(UseAVX == 0); 10244 match(Set dst (ConvL2D (LoadL src))); 10245 10246 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10247 ins_encode %{ 10248 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10249 %} 10250 ins_pipe(pipe_slow); // XXX 10251 %} 10252 10253 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10254 %{ 10255 match(Set dst (ConvI2L src)); 10256 10257 ins_cost(125); 10258 format %{ "movslq $dst, $src\t# i2l" %} 10259 ins_encode %{ 10260 __ movslq($dst$$Register, $src$$Register); 10261 %} 10262 ins_pipe(ialu_reg_reg); 10263 %} 10264 10265 // Zero-extend convert int to long 10266 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10267 %{ 10268 match(Set dst (AndL (ConvI2L src) mask)); 10269 10270 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10271 ins_encode %{ 10272 if ($dst$$reg != $src$$reg) { 10273 __ movl($dst$$Register, $src$$Register); 10274 } 10275 %} 10276 ins_pipe(ialu_reg_reg); 10277 %} 10278 10279 // Zero-extend convert int to long 10280 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10281 %{ 10282 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10283 10284 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10285 ins_encode %{ 10286 __ movl($dst$$Register, $src$$Address); 10287 %} 10288 ins_pipe(ialu_reg_mem); 10289 %} 10290 10291 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10292 %{ 10293 match(Set dst (AndL src mask)); 10294 10295 format %{ "movl $dst, $src\t# zero-extend long" %} 10296 ins_encode %{ 10297 __ movl($dst$$Register, $src$$Register); 10298 %} 10299 ins_pipe(ialu_reg_reg); 10300 %} 10301 10302 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10303 %{ 10304 match(Set dst (ConvL2I src)); 10305 10306 format %{ "movl $dst, $src\t# l2i" %} 10307 ins_encode %{ 10308 __ movl($dst$$Register, $src$$Register); 10309 %} 10310 ins_pipe(ialu_reg_reg); 10311 %} 10312 10313 10314 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10315 match(Set dst (MoveF2I src)); 10316 effect(DEF dst, USE src); 10317 10318 ins_cost(125); 10319 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10320 ins_encode %{ 10321 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10322 %} 10323 ins_pipe(ialu_reg_mem); 10324 %} 10325 10326 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10327 match(Set dst (MoveI2F src)); 10328 effect(DEF dst, USE src); 10329 10330 ins_cost(125); 10331 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10332 ins_encode %{ 10333 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10334 %} 10335 ins_pipe(pipe_slow); 10336 %} 10337 10338 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10339 match(Set dst (MoveD2L src)); 10340 effect(DEF dst, USE src); 10341 10342 ins_cost(125); 10343 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10344 ins_encode %{ 10345 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10346 %} 10347 ins_pipe(ialu_reg_mem); 10348 %} 10349 10350 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10351 predicate(!UseXmmLoadAndClearUpper); 10352 match(Set dst (MoveL2D src)); 10353 effect(DEF dst, USE src); 10354 10355 ins_cost(125); 10356 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10357 ins_encode %{ 10358 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10359 %} 10360 ins_pipe(pipe_slow); 10361 %} 10362 10363 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10364 predicate(UseXmmLoadAndClearUpper); 10365 match(Set dst (MoveL2D src)); 10366 effect(DEF dst, USE src); 10367 10368 ins_cost(125); 10369 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10370 ins_encode %{ 10371 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10372 %} 10373 ins_pipe(pipe_slow); 10374 %} 10375 10376 10377 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10378 match(Set dst (MoveF2I src)); 10379 effect(DEF dst, USE src); 10380 10381 ins_cost(95); // XXX 10382 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10383 ins_encode %{ 10384 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10385 %} 10386 ins_pipe(pipe_slow); 10387 %} 10388 10389 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10390 match(Set dst (MoveI2F src)); 10391 effect(DEF dst, USE src); 10392 10393 ins_cost(100); 10394 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10395 ins_encode %{ 10396 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10397 %} 10398 ins_pipe( ialu_mem_reg ); 10399 %} 10400 10401 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10402 match(Set dst (MoveD2L src)); 10403 effect(DEF dst, USE src); 10404 10405 ins_cost(95); // XXX 10406 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10407 ins_encode %{ 10408 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10409 %} 10410 ins_pipe(pipe_slow); 10411 %} 10412 10413 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10414 match(Set dst (MoveL2D src)); 10415 effect(DEF dst, USE src); 10416 10417 ins_cost(100); 10418 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10419 ins_encode %{ 10420 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10421 %} 10422 ins_pipe(ialu_mem_reg); 10423 %} 10424 10425 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10426 match(Set dst (MoveF2I src)); 10427 effect(DEF dst, USE src); 10428 ins_cost(85); 10429 format %{ "movd $dst,$src\t# MoveF2I" %} 10430 ins_encode %{ 10431 __ movdl($dst$$Register, $src$$XMMRegister); 10432 %} 10433 ins_pipe( pipe_slow ); 10434 %} 10435 10436 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10437 match(Set dst (MoveD2L src)); 10438 effect(DEF dst, USE src); 10439 ins_cost(85); 10440 format %{ "movd $dst,$src\t# MoveD2L" %} 10441 ins_encode %{ 10442 __ movdq($dst$$Register, $src$$XMMRegister); 10443 %} 10444 ins_pipe( pipe_slow ); 10445 %} 10446 10447 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10448 match(Set dst (MoveI2F src)); 10449 effect(DEF dst, USE src); 10450 ins_cost(100); 10451 format %{ "movd $dst,$src\t# MoveI2F" %} 10452 ins_encode %{ 10453 __ movdl($dst$$XMMRegister, $src$$Register); 10454 %} 10455 ins_pipe( pipe_slow ); 10456 %} 10457 10458 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10459 match(Set dst (MoveL2D src)); 10460 effect(DEF dst, USE src); 10461 ins_cost(100); 10462 format %{ "movd $dst,$src\t# MoveL2D" %} 10463 ins_encode %{ 10464 __ movdq($dst$$XMMRegister, $src$$Register); 10465 %} 10466 ins_pipe( pipe_slow ); 10467 %} 10468 10469 // Fast clearing of an array 10470 // Small non-constant lenght ClearArray for non-AVX512 targets. 10471 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10472 Universe dummy, rFlagsReg cr) 10473 %{ 10474 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 10475 match(Set dummy (ClearArray cnt base)); 10476 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10477 10478 format %{ $$template 10479 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10480 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10481 $$emit$$"jg LARGE\n\t" 10482 $$emit$$"dec rcx\n\t" 10483 $$emit$$"js DONE\t# Zero length\n\t" 10484 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10485 $$emit$$"dec rcx\n\t" 10486 $$emit$$"jge LOOP\n\t" 10487 $$emit$$"jmp DONE\n\t" 10488 $$emit$$"# LARGE:\n\t" 10489 if (UseFastStosb) { 10490 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10491 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10492 } else if (UseXMMForObjInit) { 10493 $$emit$$"mov rdi,rax\n\t" 10494 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10495 $$emit$$"jmpq L_zero_64_bytes\n\t" 10496 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10497 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10498 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10499 $$emit$$"add 0x40,rax\n\t" 10500 $$emit$$"# L_zero_64_bytes:\n\t" 10501 $$emit$$"sub 0x8,rcx\n\t" 10502 $$emit$$"jge L_loop\n\t" 10503 $$emit$$"add 0x4,rcx\n\t" 10504 $$emit$$"jl L_tail\n\t" 10505 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10506 $$emit$$"add 0x20,rax\n\t" 10507 $$emit$$"sub 0x4,rcx\n\t" 10508 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10509 $$emit$$"add 0x4,rcx\n\t" 10510 $$emit$$"jle L_end\n\t" 10511 $$emit$$"dec rcx\n\t" 10512 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10513 $$emit$$"vmovq xmm0,(rax)\n\t" 10514 $$emit$$"add 0x8,rax\n\t" 10515 $$emit$$"dec rcx\n\t" 10516 $$emit$$"jge L_sloop\n\t" 10517 $$emit$$"# L_end:\n\t" 10518 } else { 10519 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10520 } 10521 $$emit$$"# DONE" 10522 %} 10523 ins_encode %{ 10524 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10525 $tmp$$XMMRegister, false, knoreg); 10526 %} 10527 ins_pipe(pipe_slow); 10528 %} 10529 10530 // Small non-constant length ClearArray for AVX512 targets. 10531 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10532 Universe dummy, rFlagsReg cr) 10533 %{ 10534 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 10535 match(Set dummy (ClearArray cnt base)); 10536 ins_cost(125); 10537 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10538 10539 format %{ $$template 10540 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10541 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10542 $$emit$$"jg LARGE\n\t" 10543 $$emit$$"dec rcx\n\t" 10544 $$emit$$"js DONE\t# Zero length\n\t" 10545 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10546 $$emit$$"dec rcx\n\t" 10547 $$emit$$"jge LOOP\n\t" 10548 $$emit$$"jmp DONE\n\t" 10549 $$emit$$"# LARGE:\n\t" 10550 if (UseFastStosb) { 10551 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10552 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10553 } else if (UseXMMForObjInit) { 10554 $$emit$$"mov rdi,rax\n\t" 10555 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10556 $$emit$$"jmpq L_zero_64_bytes\n\t" 10557 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10558 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10559 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10560 $$emit$$"add 0x40,rax\n\t" 10561 $$emit$$"# L_zero_64_bytes:\n\t" 10562 $$emit$$"sub 0x8,rcx\n\t" 10563 $$emit$$"jge L_loop\n\t" 10564 $$emit$$"add 0x4,rcx\n\t" 10565 $$emit$$"jl L_tail\n\t" 10566 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10567 $$emit$$"add 0x20,rax\n\t" 10568 $$emit$$"sub 0x4,rcx\n\t" 10569 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10570 $$emit$$"add 0x4,rcx\n\t" 10571 $$emit$$"jle L_end\n\t" 10572 $$emit$$"dec rcx\n\t" 10573 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10574 $$emit$$"vmovq xmm0,(rax)\n\t" 10575 $$emit$$"add 0x8,rax\n\t" 10576 $$emit$$"dec rcx\n\t" 10577 $$emit$$"jge L_sloop\n\t" 10578 $$emit$$"# L_end:\n\t" 10579 } else { 10580 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10581 } 10582 $$emit$$"# DONE" 10583 %} 10584 ins_encode %{ 10585 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10586 $tmp$$XMMRegister, false, $ktmp$$KRegister); 10587 %} 10588 ins_pipe(pipe_slow); 10589 %} 10590 10591 // Large non-constant length ClearArray for non-AVX512 targets. 10592 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10593 Universe dummy, rFlagsReg cr) 10594 %{ 10595 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 10596 match(Set dummy (ClearArray cnt base)); 10597 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10598 10599 format %{ $$template 10600 if (UseFastStosb) { 10601 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10602 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10603 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10604 } else if (UseXMMForObjInit) { 10605 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10606 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10607 $$emit$$"jmpq L_zero_64_bytes\n\t" 10608 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10609 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10610 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10611 $$emit$$"add 0x40,rax\n\t" 10612 $$emit$$"# L_zero_64_bytes:\n\t" 10613 $$emit$$"sub 0x8,rcx\n\t" 10614 $$emit$$"jge L_loop\n\t" 10615 $$emit$$"add 0x4,rcx\n\t" 10616 $$emit$$"jl L_tail\n\t" 10617 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10618 $$emit$$"add 0x20,rax\n\t" 10619 $$emit$$"sub 0x4,rcx\n\t" 10620 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10621 $$emit$$"add 0x4,rcx\n\t" 10622 $$emit$$"jle L_end\n\t" 10623 $$emit$$"dec rcx\n\t" 10624 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10625 $$emit$$"vmovq xmm0,(rax)\n\t" 10626 $$emit$$"add 0x8,rax\n\t" 10627 $$emit$$"dec rcx\n\t" 10628 $$emit$$"jge L_sloop\n\t" 10629 $$emit$$"# L_end:\n\t" 10630 } else { 10631 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10632 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10633 } 10634 %} 10635 ins_encode %{ 10636 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10637 $tmp$$XMMRegister, true, knoreg); 10638 %} 10639 ins_pipe(pipe_slow); 10640 %} 10641 10642 // Large non-constant length ClearArray for AVX512 targets. 10643 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10644 Universe dummy, rFlagsReg cr) 10645 %{ 10646 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 10647 match(Set dummy (ClearArray cnt base)); 10648 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10649 10650 format %{ $$template 10651 if (UseFastStosb) { 10652 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10653 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10654 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10655 } else if (UseXMMForObjInit) { 10656 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10657 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10658 $$emit$$"jmpq L_zero_64_bytes\n\t" 10659 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10660 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10661 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10662 $$emit$$"add 0x40,rax\n\t" 10663 $$emit$$"# L_zero_64_bytes:\n\t" 10664 $$emit$$"sub 0x8,rcx\n\t" 10665 $$emit$$"jge L_loop\n\t" 10666 $$emit$$"add 0x4,rcx\n\t" 10667 $$emit$$"jl L_tail\n\t" 10668 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10669 $$emit$$"add 0x20,rax\n\t" 10670 $$emit$$"sub 0x4,rcx\n\t" 10671 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10672 $$emit$$"add 0x4,rcx\n\t" 10673 $$emit$$"jle L_end\n\t" 10674 $$emit$$"dec rcx\n\t" 10675 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10676 $$emit$$"vmovq xmm0,(rax)\n\t" 10677 $$emit$$"add 0x8,rax\n\t" 10678 $$emit$$"dec rcx\n\t" 10679 $$emit$$"jge L_sloop\n\t" 10680 $$emit$$"# L_end:\n\t" 10681 } else { 10682 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10683 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10684 } 10685 %} 10686 ins_encode %{ 10687 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10688 $tmp$$XMMRegister, true, $ktmp$$KRegister); 10689 %} 10690 ins_pipe(pipe_slow); 10691 %} 10692 10693 // Small constant length ClearArray for AVX512 targets. 10694 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 10695 %{ 10696 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 10697 match(Set dummy (ClearArray cnt base)); 10698 ins_cost(100); 10699 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 10700 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10701 ins_encode %{ 10702 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10703 %} 10704 ins_pipe(pipe_slow); 10705 %} 10706 10707 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10708 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10709 %{ 10710 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10711 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10712 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10713 10714 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10715 ins_encode %{ 10716 __ string_compare($str1$$Register, $str2$$Register, 10717 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10718 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10719 %} 10720 ins_pipe( pipe_slow ); 10721 %} 10722 10723 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10724 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10725 %{ 10726 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10727 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10728 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10729 10730 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10731 ins_encode %{ 10732 __ string_compare($str1$$Register, $str2$$Register, 10733 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10734 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10735 %} 10736 ins_pipe( pipe_slow ); 10737 %} 10738 10739 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10740 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10741 %{ 10742 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10743 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10744 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10745 10746 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10747 ins_encode %{ 10748 __ string_compare($str1$$Register, $str2$$Register, 10749 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10750 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10751 %} 10752 ins_pipe( pipe_slow ); 10753 %} 10754 10755 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10756 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10757 %{ 10758 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10759 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10760 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10761 10762 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10763 ins_encode %{ 10764 __ string_compare($str1$$Register, $str2$$Register, 10765 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10766 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10767 %} 10768 ins_pipe( pipe_slow ); 10769 %} 10770 10771 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10772 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10773 %{ 10774 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10775 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10776 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10777 10778 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10779 ins_encode %{ 10780 __ string_compare($str1$$Register, $str2$$Register, 10781 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10782 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 10783 %} 10784 ins_pipe( pipe_slow ); 10785 %} 10786 10787 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10788 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10789 %{ 10790 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10791 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10792 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10793 10794 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10795 ins_encode %{ 10796 __ string_compare($str1$$Register, $str2$$Register, 10797 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10798 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 10799 %} 10800 ins_pipe( pipe_slow ); 10801 %} 10802 10803 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10804 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10805 %{ 10806 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10807 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10808 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10809 10810 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10811 ins_encode %{ 10812 __ string_compare($str2$$Register, $str1$$Register, 10813 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10814 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 10815 %} 10816 ins_pipe( pipe_slow ); 10817 %} 10818 10819 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10820 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10821 %{ 10822 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10823 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10824 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10825 10826 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10827 ins_encode %{ 10828 __ string_compare($str2$$Register, $str1$$Register, 10829 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10830 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 10831 %} 10832 ins_pipe( pipe_slow ); 10833 %} 10834 10835 // fast search of substring with known size. 10836 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10837 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10838 %{ 10839 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10840 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10841 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10842 10843 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10844 ins_encode %{ 10845 int icnt2 = (int)$int_cnt2$$constant; 10846 if (icnt2 >= 16) { 10847 // IndexOf for constant substrings with size >= 16 elements 10848 // which don't need to be loaded through stack. 10849 __ string_indexofC8($str1$$Register, $str2$$Register, 10850 $cnt1$$Register, $cnt2$$Register, 10851 icnt2, $result$$Register, 10852 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10853 } else { 10854 // Small strings are loaded through stack if they cross page boundary. 10855 __ string_indexof($str1$$Register, $str2$$Register, 10856 $cnt1$$Register, $cnt2$$Register, 10857 icnt2, $result$$Register, 10858 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10859 } 10860 %} 10861 ins_pipe( pipe_slow ); 10862 %} 10863 10864 // fast search of substring with known size. 10865 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10866 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10867 %{ 10868 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10869 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10870 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10871 10872 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10873 ins_encode %{ 10874 int icnt2 = (int)$int_cnt2$$constant; 10875 if (icnt2 >= 8) { 10876 // IndexOf for constant substrings with size >= 8 elements 10877 // which don't need to be loaded through stack. 10878 __ string_indexofC8($str1$$Register, $str2$$Register, 10879 $cnt1$$Register, $cnt2$$Register, 10880 icnt2, $result$$Register, 10881 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10882 } else { 10883 // Small strings are loaded through stack if they cross page boundary. 10884 __ string_indexof($str1$$Register, $str2$$Register, 10885 $cnt1$$Register, $cnt2$$Register, 10886 icnt2, $result$$Register, 10887 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10888 } 10889 %} 10890 ins_pipe( pipe_slow ); 10891 %} 10892 10893 // fast search of substring with known size. 10894 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10895 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10896 %{ 10897 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10898 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10899 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10900 10901 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10902 ins_encode %{ 10903 int icnt2 = (int)$int_cnt2$$constant; 10904 if (icnt2 >= 8) { 10905 // IndexOf for constant substrings with size >= 8 elements 10906 // which don't need to be loaded through stack. 10907 __ string_indexofC8($str1$$Register, $str2$$Register, 10908 $cnt1$$Register, $cnt2$$Register, 10909 icnt2, $result$$Register, 10910 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10911 } else { 10912 // Small strings are loaded through stack if they cross page boundary. 10913 __ string_indexof($str1$$Register, $str2$$Register, 10914 $cnt1$$Register, $cnt2$$Register, 10915 icnt2, $result$$Register, 10916 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10917 } 10918 %} 10919 ins_pipe( pipe_slow ); 10920 %} 10921 10922 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10923 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10924 %{ 10925 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10926 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10927 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10928 10929 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10930 ins_encode %{ 10931 __ string_indexof($str1$$Register, $str2$$Register, 10932 $cnt1$$Register, $cnt2$$Register, 10933 (-1), $result$$Register, 10934 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10935 %} 10936 ins_pipe( pipe_slow ); 10937 %} 10938 10939 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10940 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10941 %{ 10942 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10943 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10944 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10945 10946 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10947 ins_encode %{ 10948 __ string_indexof($str1$$Register, $str2$$Register, 10949 $cnt1$$Register, $cnt2$$Register, 10950 (-1), $result$$Register, 10951 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10952 %} 10953 ins_pipe( pipe_slow ); 10954 %} 10955 10956 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10957 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10958 %{ 10959 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10960 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10961 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10962 10963 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10964 ins_encode %{ 10965 __ string_indexof($str1$$Register, $str2$$Register, 10966 $cnt1$$Register, $cnt2$$Register, 10967 (-1), $result$$Register, 10968 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10969 %} 10970 ins_pipe( pipe_slow ); 10971 %} 10972 10973 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10974 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10975 %{ 10976 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 10977 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10978 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10979 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10980 ins_encode %{ 10981 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10982 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10983 %} 10984 ins_pipe( pipe_slow ); 10985 %} 10986 10987 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10988 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 10989 %{ 10990 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 10991 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10992 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10993 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10994 ins_encode %{ 10995 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10996 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 10997 %} 10998 ins_pipe( pipe_slow ); 10999 %} 11000 11001 // fast string equals 11002 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11003 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11004 %{ 11005 predicate(!VM_Version::supports_avx512vlbw()); 11006 match(Set result (StrEquals (Binary str1 str2) cnt)); 11007 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11008 11009 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11010 ins_encode %{ 11011 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11012 $cnt$$Register, $result$$Register, $tmp3$$Register, 11013 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11014 %} 11015 ins_pipe( pipe_slow ); 11016 %} 11017 11018 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11019 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11020 %{ 11021 predicate(VM_Version::supports_avx512vlbw()); 11022 match(Set result (StrEquals (Binary str1 str2) cnt)); 11023 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11024 11025 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11026 ins_encode %{ 11027 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11028 $cnt$$Register, $result$$Register, $tmp3$$Register, 11029 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11030 %} 11031 ins_pipe( pipe_slow ); 11032 %} 11033 11034 // fast array equals 11035 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11036 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11037 %{ 11038 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11039 match(Set result (AryEq ary1 ary2)); 11040 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11041 11042 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11043 ins_encode %{ 11044 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11045 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11046 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11047 %} 11048 ins_pipe( pipe_slow ); 11049 %} 11050 11051 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11052 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11053 %{ 11054 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11055 match(Set result (AryEq ary1 ary2)); 11056 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11057 11058 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11059 ins_encode %{ 11060 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11061 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11062 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11063 %} 11064 ins_pipe( pipe_slow ); 11065 %} 11066 11067 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11068 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11069 %{ 11070 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11071 match(Set result (AryEq ary1 ary2)); 11072 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11073 11074 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11075 ins_encode %{ 11076 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11077 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11078 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11079 %} 11080 ins_pipe( pipe_slow ); 11081 %} 11082 11083 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11084 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11085 %{ 11086 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11087 match(Set result (AryEq ary1 ary2)); 11088 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11089 11090 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11091 ins_encode %{ 11092 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11093 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11094 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11095 %} 11096 ins_pipe( pipe_slow ); 11097 %} 11098 11099 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11100 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11101 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11102 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11103 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11104 %{ 11105 predicate(UseAVX >= 2); 11106 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11107 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11108 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11109 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11110 USE basic_type, KILL cr); 11111 11112 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11113 ins_encode %{ 11114 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11115 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11116 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11117 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11118 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11119 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11120 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11121 %} 11122 ins_pipe( pipe_slow ); 11123 %} 11124 11125 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11126 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11127 %{ 11128 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11129 match(Set result (CountPositives ary1 len)); 11130 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11131 11132 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11133 ins_encode %{ 11134 __ count_positives($ary1$$Register, $len$$Register, 11135 $result$$Register, $tmp3$$Register, 11136 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11137 %} 11138 ins_pipe( pipe_slow ); 11139 %} 11140 11141 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11142 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11143 %{ 11144 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11145 match(Set result (CountPositives ary1 len)); 11146 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11147 11148 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11149 ins_encode %{ 11150 __ count_positives($ary1$$Register, $len$$Register, 11151 $result$$Register, $tmp3$$Register, 11152 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11153 %} 11154 ins_pipe( pipe_slow ); 11155 %} 11156 11157 // fast char[] to byte[] compression 11158 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11159 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11160 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11161 match(Set result (StrCompressedCopy src (Binary dst len))); 11162 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11163 USE_KILL len, KILL tmp5, KILL cr); 11164 11165 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11166 ins_encode %{ 11167 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11168 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11169 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11170 knoreg, knoreg); 11171 %} 11172 ins_pipe( pipe_slow ); 11173 %} 11174 11175 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11176 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11177 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11178 match(Set result (StrCompressedCopy src (Binary dst len))); 11179 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11180 USE_KILL len, KILL tmp5, KILL cr); 11181 11182 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11183 ins_encode %{ 11184 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11185 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11186 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11187 $ktmp1$$KRegister, $ktmp2$$KRegister); 11188 %} 11189 ins_pipe( pipe_slow ); 11190 %} 11191 // fast byte[] to char[] inflation 11192 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11193 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11194 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11195 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11196 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11197 11198 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11199 ins_encode %{ 11200 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11201 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11202 %} 11203 ins_pipe( pipe_slow ); 11204 %} 11205 11206 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11207 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11208 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11209 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11210 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11211 11212 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11213 ins_encode %{ 11214 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11215 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11216 %} 11217 ins_pipe( pipe_slow ); 11218 %} 11219 11220 // encode char[] to byte[] in ISO_8859_1 11221 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11222 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11223 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11224 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11225 match(Set result (EncodeISOArray src (Binary dst len))); 11226 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11227 11228 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11229 ins_encode %{ 11230 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11231 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11232 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11233 %} 11234 ins_pipe( pipe_slow ); 11235 %} 11236 11237 // encode char[] to byte[] in ASCII 11238 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11239 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11240 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11241 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11242 match(Set result (EncodeISOArray src (Binary dst len))); 11243 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11244 11245 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11246 ins_encode %{ 11247 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11248 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11249 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11250 %} 11251 ins_pipe( pipe_slow ); 11252 %} 11253 11254 //----------Overflow Math Instructions----------------------------------------- 11255 11256 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11257 %{ 11258 match(Set cr (OverflowAddI op1 op2)); 11259 effect(DEF cr, USE_KILL op1, USE op2); 11260 11261 format %{ "addl $op1, $op2\t# overflow check int" %} 11262 11263 ins_encode %{ 11264 __ addl($op1$$Register, $op2$$Register); 11265 %} 11266 ins_pipe(ialu_reg_reg); 11267 %} 11268 11269 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11270 %{ 11271 match(Set cr (OverflowAddI op1 op2)); 11272 effect(DEF cr, USE_KILL op1, USE op2); 11273 11274 format %{ "addl $op1, $op2\t# overflow check int" %} 11275 11276 ins_encode %{ 11277 __ addl($op1$$Register, $op2$$constant); 11278 %} 11279 ins_pipe(ialu_reg_reg); 11280 %} 11281 11282 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11283 %{ 11284 match(Set cr (OverflowAddL op1 op2)); 11285 effect(DEF cr, USE_KILL op1, USE op2); 11286 11287 format %{ "addq $op1, $op2\t# overflow check long" %} 11288 ins_encode %{ 11289 __ addq($op1$$Register, $op2$$Register); 11290 %} 11291 ins_pipe(ialu_reg_reg); 11292 %} 11293 11294 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11295 %{ 11296 match(Set cr (OverflowAddL op1 op2)); 11297 effect(DEF cr, USE_KILL op1, USE op2); 11298 11299 format %{ "addq $op1, $op2\t# overflow check long" %} 11300 ins_encode %{ 11301 __ addq($op1$$Register, $op2$$constant); 11302 %} 11303 ins_pipe(ialu_reg_reg); 11304 %} 11305 11306 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11307 %{ 11308 match(Set cr (OverflowSubI op1 op2)); 11309 11310 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11311 ins_encode %{ 11312 __ cmpl($op1$$Register, $op2$$Register); 11313 %} 11314 ins_pipe(ialu_reg_reg); 11315 %} 11316 11317 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11318 %{ 11319 match(Set cr (OverflowSubI op1 op2)); 11320 11321 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11322 ins_encode %{ 11323 __ cmpl($op1$$Register, $op2$$constant); 11324 %} 11325 ins_pipe(ialu_reg_reg); 11326 %} 11327 11328 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11329 %{ 11330 match(Set cr (OverflowSubL op1 op2)); 11331 11332 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11333 ins_encode %{ 11334 __ cmpq($op1$$Register, $op2$$Register); 11335 %} 11336 ins_pipe(ialu_reg_reg); 11337 %} 11338 11339 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11340 %{ 11341 match(Set cr (OverflowSubL op1 op2)); 11342 11343 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11344 ins_encode %{ 11345 __ cmpq($op1$$Register, $op2$$constant); 11346 %} 11347 ins_pipe(ialu_reg_reg); 11348 %} 11349 11350 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11351 %{ 11352 match(Set cr (OverflowSubI zero op2)); 11353 effect(DEF cr, USE_KILL op2); 11354 11355 format %{ "negl $op2\t# overflow check int" %} 11356 ins_encode %{ 11357 __ negl($op2$$Register); 11358 %} 11359 ins_pipe(ialu_reg_reg); 11360 %} 11361 11362 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11363 %{ 11364 match(Set cr (OverflowSubL zero op2)); 11365 effect(DEF cr, USE_KILL op2); 11366 11367 format %{ "negq $op2\t# overflow check long" %} 11368 ins_encode %{ 11369 __ negq($op2$$Register); 11370 %} 11371 ins_pipe(ialu_reg_reg); 11372 %} 11373 11374 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11375 %{ 11376 match(Set cr (OverflowMulI op1 op2)); 11377 effect(DEF cr, USE_KILL op1, USE op2); 11378 11379 format %{ "imull $op1, $op2\t# overflow check int" %} 11380 ins_encode %{ 11381 __ imull($op1$$Register, $op2$$Register); 11382 %} 11383 ins_pipe(ialu_reg_reg_alu0); 11384 %} 11385 11386 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11387 %{ 11388 match(Set cr (OverflowMulI op1 op2)); 11389 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11390 11391 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11392 ins_encode %{ 11393 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11394 %} 11395 ins_pipe(ialu_reg_reg_alu0); 11396 %} 11397 11398 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11399 %{ 11400 match(Set cr (OverflowMulL op1 op2)); 11401 effect(DEF cr, USE_KILL op1, USE op2); 11402 11403 format %{ "imulq $op1, $op2\t# overflow check long" %} 11404 ins_encode %{ 11405 __ imulq($op1$$Register, $op2$$Register); 11406 %} 11407 ins_pipe(ialu_reg_reg_alu0); 11408 %} 11409 11410 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11411 %{ 11412 match(Set cr (OverflowMulL op1 op2)); 11413 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11414 11415 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11416 ins_encode %{ 11417 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11418 %} 11419 ins_pipe(ialu_reg_reg_alu0); 11420 %} 11421 11422 11423 //----------Control Flow Instructions------------------------------------------ 11424 // Signed compare Instructions 11425 11426 // XXX more variants!! 11427 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11428 %{ 11429 match(Set cr (CmpI op1 op2)); 11430 effect(DEF cr, USE op1, USE op2); 11431 11432 format %{ "cmpl $op1, $op2" %} 11433 ins_encode %{ 11434 __ cmpl($op1$$Register, $op2$$Register); 11435 %} 11436 ins_pipe(ialu_cr_reg_reg); 11437 %} 11438 11439 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11440 %{ 11441 match(Set cr (CmpI op1 op2)); 11442 11443 format %{ "cmpl $op1, $op2" %} 11444 ins_encode %{ 11445 __ cmpl($op1$$Register, $op2$$constant); 11446 %} 11447 ins_pipe(ialu_cr_reg_imm); 11448 %} 11449 11450 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11451 %{ 11452 match(Set cr (CmpI op1 (LoadI op2))); 11453 11454 ins_cost(500); // XXX 11455 format %{ "cmpl $op1, $op2" %} 11456 ins_encode %{ 11457 __ cmpl($op1$$Register, $op2$$Address); 11458 %} 11459 ins_pipe(ialu_cr_reg_mem); 11460 %} 11461 11462 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11463 %{ 11464 match(Set cr (CmpI src zero)); 11465 11466 format %{ "testl $src, $src" %} 11467 ins_encode %{ 11468 __ testl($src$$Register, $src$$Register); 11469 %} 11470 ins_pipe(ialu_cr_reg_imm); 11471 %} 11472 11473 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11474 %{ 11475 match(Set cr (CmpI (AndI src con) zero)); 11476 11477 format %{ "testl $src, $con" %} 11478 ins_encode %{ 11479 __ testl($src$$Register, $con$$constant); 11480 %} 11481 ins_pipe(ialu_cr_reg_imm); 11482 %} 11483 11484 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11485 %{ 11486 match(Set cr (CmpI (AndI src1 src2) zero)); 11487 11488 format %{ "testl $src1, $src2" %} 11489 ins_encode %{ 11490 __ testl($src1$$Register, $src2$$Register); 11491 %} 11492 ins_pipe(ialu_cr_reg_imm); 11493 %} 11494 11495 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11496 %{ 11497 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11498 11499 format %{ "testl $src, $mem" %} 11500 ins_encode %{ 11501 __ testl($src$$Register, $mem$$Address); 11502 %} 11503 ins_pipe(ialu_cr_reg_mem); 11504 %} 11505 11506 // Unsigned compare Instructions; really, same as signed except they 11507 // produce an rFlagsRegU instead of rFlagsReg. 11508 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11509 %{ 11510 match(Set cr (CmpU op1 op2)); 11511 11512 format %{ "cmpl $op1, $op2\t# unsigned" %} 11513 ins_encode %{ 11514 __ cmpl($op1$$Register, $op2$$Register); 11515 %} 11516 ins_pipe(ialu_cr_reg_reg); 11517 %} 11518 11519 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11520 %{ 11521 match(Set cr (CmpU op1 op2)); 11522 11523 format %{ "cmpl $op1, $op2\t# unsigned" %} 11524 ins_encode %{ 11525 __ cmpl($op1$$Register, $op2$$constant); 11526 %} 11527 ins_pipe(ialu_cr_reg_imm); 11528 %} 11529 11530 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11531 %{ 11532 match(Set cr (CmpU op1 (LoadI op2))); 11533 11534 ins_cost(500); // XXX 11535 format %{ "cmpl $op1, $op2\t# unsigned" %} 11536 ins_encode %{ 11537 __ cmpl($op1$$Register, $op2$$Address); 11538 %} 11539 ins_pipe(ialu_cr_reg_mem); 11540 %} 11541 11542 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11543 %{ 11544 match(Set cr (CmpU src zero)); 11545 11546 format %{ "testl $src, $src\t# unsigned" %} 11547 ins_encode %{ 11548 __ testl($src$$Register, $src$$Register); 11549 %} 11550 ins_pipe(ialu_cr_reg_imm); 11551 %} 11552 11553 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11554 %{ 11555 match(Set cr (CmpP op1 op2)); 11556 11557 format %{ "cmpq $op1, $op2\t# ptr" %} 11558 ins_encode %{ 11559 __ cmpq($op1$$Register, $op2$$Register); 11560 %} 11561 ins_pipe(ialu_cr_reg_reg); 11562 %} 11563 11564 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11565 %{ 11566 match(Set cr (CmpP op1 (LoadP op2))); 11567 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11568 11569 ins_cost(500); // XXX 11570 format %{ "cmpq $op1, $op2\t# ptr" %} 11571 ins_encode %{ 11572 __ cmpq($op1$$Register, $op2$$Address); 11573 %} 11574 ins_pipe(ialu_cr_reg_mem); 11575 %} 11576 11577 // XXX this is generalized by compP_rReg_mem??? 11578 // Compare raw pointer (used in out-of-heap check). 11579 // Only works because non-oop pointers must be raw pointers 11580 // and raw pointers have no anti-dependencies. 11581 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11582 %{ 11583 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11584 n->in(2)->as_Load()->barrier_data() == 0); 11585 match(Set cr (CmpP op1 (LoadP op2))); 11586 11587 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11588 ins_encode %{ 11589 __ cmpq($op1$$Register, $op2$$Address); 11590 %} 11591 ins_pipe(ialu_cr_reg_mem); 11592 %} 11593 11594 // This will generate a signed flags result. This should be OK since 11595 // any compare to a zero should be eq/neq. 11596 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11597 %{ 11598 match(Set cr (CmpP src zero)); 11599 11600 format %{ "testq $src, $src\t# ptr" %} 11601 ins_encode %{ 11602 __ testq($src$$Register, $src$$Register); 11603 %} 11604 ins_pipe(ialu_cr_reg_imm); 11605 %} 11606 11607 // This will generate a signed flags result. This should be OK since 11608 // any compare to a zero should be eq/neq. 11609 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11610 %{ 11611 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11612 n->in(1)->as_Load()->barrier_data() == 0); 11613 match(Set cr (CmpP (LoadP op) zero)); 11614 11615 ins_cost(500); // XXX 11616 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11617 ins_encode %{ 11618 __ testq($op$$Address, 0xFFFFFFFF); 11619 %} 11620 ins_pipe(ialu_cr_reg_imm); 11621 %} 11622 11623 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11624 %{ 11625 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11626 n->in(1)->as_Load()->barrier_data() == 0); 11627 match(Set cr (CmpP (LoadP mem) zero)); 11628 11629 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11630 ins_encode %{ 11631 __ cmpq(r12, $mem$$Address); 11632 %} 11633 ins_pipe(ialu_cr_reg_mem); 11634 %} 11635 11636 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11637 %{ 11638 match(Set cr (CmpN op1 op2)); 11639 11640 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11641 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11642 ins_pipe(ialu_cr_reg_reg); 11643 %} 11644 11645 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11646 %{ 11647 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11648 match(Set cr (CmpN src (LoadN mem))); 11649 11650 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11651 ins_encode %{ 11652 __ cmpl($src$$Register, $mem$$Address); 11653 %} 11654 ins_pipe(ialu_cr_reg_mem); 11655 %} 11656 11657 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11658 match(Set cr (CmpN op1 op2)); 11659 11660 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11661 ins_encode %{ 11662 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11663 %} 11664 ins_pipe(ialu_cr_reg_imm); 11665 %} 11666 11667 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11668 %{ 11669 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11670 match(Set cr (CmpN src (LoadN mem))); 11671 11672 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11673 ins_encode %{ 11674 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11675 %} 11676 ins_pipe(ialu_cr_reg_mem); 11677 %} 11678 11679 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11680 match(Set cr (CmpN op1 op2)); 11681 11682 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11683 ins_encode %{ 11684 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11685 %} 11686 ins_pipe(ialu_cr_reg_imm); 11687 %} 11688 11689 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11690 %{ 11691 predicate(!UseCompactObjectHeaders); 11692 match(Set cr (CmpN src (LoadNKlass mem))); 11693 11694 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11695 ins_encode %{ 11696 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11697 %} 11698 ins_pipe(ialu_cr_reg_mem); 11699 %} 11700 11701 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11702 match(Set cr (CmpN src zero)); 11703 11704 format %{ "testl $src, $src\t# compressed ptr" %} 11705 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11706 ins_pipe(ialu_cr_reg_imm); 11707 %} 11708 11709 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11710 %{ 11711 predicate(CompressedOops::base() != nullptr && 11712 n->in(1)->as_Load()->barrier_data() == 0); 11713 match(Set cr (CmpN (LoadN mem) zero)); 11714 11715 ins_cost(500); // XXX 11716 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11717 ins_encode %{ 11718 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11719 %} 11720 ins_pipe(ialu_cr_reg_mem); 11721 %} 11722 11723 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11724 %{ 11725 predicate(CompressedOops::base() == nullptr && 11726 n->in(1)->as_Load()->barrier_data() == 0); 11727 match(Set cr (CmpN (LoadN mem) zero)); 11728 11729 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11730 ins_encode %{ 11731 __ cmpl(r12, $mem$$Address); 11732 %} 11733 ins_pipe(ialu_cr_reg_mem); 11734 %} 11735 11736 // Yanked all unsigned pointer compare operations. 11737 // Pointer compares are done with CmpP which is already unsigned. 11738 11739 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11740 %{ 11741 match(Set cr (CmpL op1 op2)); 11742 11743 format %{ "cmpq $op1, $op2" %} 11744 ins_encode %{ 11745 __ cmpq($op1$$Register, $op2$$Register); 11746 %} 11747 ins_pipe(ialu_cr_reg_reg); 11748 %} 11749 11750 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11751 %{ 11752 match(Set cr (CmpL op1 op2)); 11753 11754 format %{ "cmpq $op1, $op2" %} 11755 ins_encode %{ 11756 __ cmpq($op1$$Register, $op2$$constant); 11757 %} 11758 ins_pipe(ialu_cr_reg_imm); 11759 %} 11760 11761 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11762 %{ 11763 match(Set cr (CmpL op1 (LoadL op2))); 11764 11765 format %{ "cmpq $op1, $op2" %} 11766 ins_encode %{ 11767 __ cmpq($op1$$Register, $op2$$Address); 11768 %} 11769 ins_pipe(ialu_cr_reg_mem); 11770 %} 11771 11772 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11773 %{ 11774 match(Set cr (CmpL src zero)); 11775 11776 format %{ "testq $src, $src" %} 11777 ins_encode %{ 11778 __ testq($src$$Register, $src$$Register); 11779 %} 11780 ins_pipe(ialu_cr_reg_imm); 11781 %} 11782 11783 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11784 %{ 11785 match(Set cr (CmpL (AndL src con) zero)); 11786 11787 format %{ "testq $src, $con\t# long" %} 11788 ins_encode %{ 11789 __ testq($src$$Register, $con$$constant); 11790 %} 11791 ins_pipe(ialu_cr_reg_imm); 11792 %} 11793 11794 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 11795 %{ 11796 match(Set cr (CmpL (AndL src1 src2) zero)); 11797 11798 format %{ "testq $src1, $src2\t# long" %} 11799 ins_encode %{ 11800 __ testq($src1$$Register, $src2$$Register); 11801 %} 11802 ins_pipe(ialu_cr_reg_imm); 11803 %} 11804 11805 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11806 %{ 11807 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11808 11809 format %{ "testq $src, $mem" %} 11810 ins_encode %{ 11811 __ testq($src$$Register, $mem$$Address); 11812 %} 11813 ins_pipe(ialu_cr_reg_mem); 11814 %} 11815 11816 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11817 %{ 11818 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11819 11820 format %{ "testq $src, $mem" %} 11821 ins_encode %{ 11822 __ testq($src$$Register, $mem$$Address); 11823 %} 11824 ins_pipe(ialu_cr_reg_mem); 11825 %} 11826 11827 // Manifest a CmpU result in an integer register. Very painful. 11828 // This is the test to avoid. 11829 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 11830 %{ 11831 match(Set dst (CmpU3 src1 src2)); 11832 effect(KILL flags); 11833 11834 ins_cost(275); // XXX 11835 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 11836 "movl $dst, -1\n\t" 11837 "jb,u done\n\t" 11838 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11839 "done:" %} 11840 ins_encode %{ 11841 Label done; 11842 __ cmpl($src1$$Register, $src2$$Register); 11843 __ movl($dst$$Register, -1); 11844 __ jccb(Assembler::below, done); 11845 __ setcc(Assembler::notZero, $dst$$Register); 11846 __ bind(done); 11847 %} 11848 ins_pipe(pipe_slow); 11849 %} 11850 11851 // Manifest a CmpL result in an integer register. Very painful. 11852 // This is the test to avoid. 11853 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11854 %{ 11855 match(Set dst (CmpL3 src1 src2)); 11856 effect(KILL flags); 11857 11858 ins_cost(275); // XXX 11859 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11860 "movl $dst, -1\n\t" 11861 "jl,s done\n\t" 11862 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11863 "done:" %} 11864 ins_encode %{ 11865 Label done; 11866 __ cmpq($src1$$Register, $src2$$Register); 11867 __ movl($dst$$Register, -1); 11868 __ jccb(Assembler::less, done); 11869 __ setcc(Assembler::notZero, $dst$$Register); 11870 __ bind(done); 11871 %} 11872 ins_pipe(pipe_slow); 11873 %} 11874 11875 // Manifest a CmpUL result in an integer register. Very painful. 11876 // This is the test to avoid. 11877 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11878 %{ 11879 match(Set dst (CmpUL3 src1 src2)); 11880 effect(KILL flags); 11881 11882 ins_cost(275); // XXX 11883 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11884 "movl $dst, -1\n\t" 11885 "jb,u done\n\t" 11886 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11887 "done:" %} 11888 ins_encode %{ 11889 Label done; 11890 __ cmpq($src1$$Register, $src2$$Register); 11891 __ movl($dst$$Register, -1); 11892 __ jccb(Assembler::below, done); 11893 __ setcc(Assembler::notZero, $dst$$Register); 11894 __ bind(done); 11895 %} 11896 ins_pipe(pipe_slow); 11897 %} 11898 11899 // Unsigned long compare Instructions; really, same as signed long except they 11900 // produce an rFlagsRegU instead of rFlagsReg. 11901 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11902 %{ 11903 match(Set cr (CmpUL op1 op2)); 11904 11905 format %{ "cmpq $op1, $op2\t# unsigned" %} 11906 ins_encode %{ 11907 __ cmpq($op1$$Register, $op2$$Register); 11908 %} 11909 ins_pipe(ialu_cr_reg_reg); 11910 %} 11911 11912 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11913 %{ 11914 match(Set cr (CmpUL op1 op2)); 11915 11916 format %{ "cmpq $op1, $op2\t# unsigned" %} 11917 ins_encode %{ 11918 __ cmpq($op1$$Register, $op2$$constant); 11919 %} 11920 ins_pipe(ialu_cr_reg_imm); 11921 %} 11922 11923 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11924 %{ 11925 match(Set cr (CmpUL op1 (LoadL op2))); 11926 11927 format %{ "cmpq $op1, $op2\t# unsigned" %} 11928 ins_encode %{ 11929 __ cmpq($op1$$Register, $op2$$Address); 11930 %} 11931 ins_pipe(ialu_cr_reg_mem); 11932 %} 11933 11934 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11935 %{ 11936 match(Set cr (CmpUL src zero)); 11937 11938 format %{ "testq $src, $src\t# unsigned" %} 11939 ins_encode %{ 11940 __ testq($src$$Register, $src$$Register); 11941 %} 11942 ins_pipe(ialu_cr_reg_imm); 11943 %} 11944 11945 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11946 %{ 11947 match(Set cr (CmpI (LoadB mem) imm)); 11948 11949 ins_cost(125); 11950 format %{ "cmpb $mem, $imm" %} 11951 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11952 ins_pipe(ialu_cr_reg_mem); 11953 %} 11954 11955 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 11956 %{ 11957 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11958 11959 ins_cost(125); 11960 format %{ "testb $mem, $imm\t# ubyte" %} 11961 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11962 ins_pipe(ialu_cr_reg_mem); 11963 %} 11964 11965 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 11966 %{ 11967 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11968 11969 ins_cost(125); 11970 format %{ "testb $mem, $imm\t# byte" %} 11971 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11972 ins_pipe(ialu_cr_reg_mem); 11973 %} 11974 11975 //----------Max and Min-------------------------------------------------------- 11976 // Min Instructions 11977 11978 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11979 %{ 11980 effect(USE_DEF dst, USE src, USE cr); 11981 11982 format %{ "cmovlgt $dst, $src\t# min" %} 11983 ins_encode %{ 11984 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 11985 %} 11986 ins_pipe(pipe_cmov_reg); 11987 %} 11988 11989 11990 instruct minI_rReg(rRegI dst, rRegI src) 11991 %{ 11992 match(Set dst (MinI dst src)); 11993 11994 ins_cost(200); 11995 expand %{ 11996 rFlagsReg cr; 11997 compI_rReg(cr, dst, src); 11998 cmovI_reg_g(dst, src, cr); 11999 %} 12000 %} 12001 12002 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12003 %{ 12004 effect(USE_DEF dst, USE src, USE cr); 12005 12006 format %{ "cmovllt $dst, $src\t# max" %} 12007 ins_encode %{ 12008 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12009 %} 12010 ins_pipe(pipe_cmov_reg); 12011 %} 12012 12013 12014 instruct maxI_rReg(rRegI dst, rRegI src) 12015 %{ 12016 match(Set dst (MaxI dst src)); 12017 12018 ins_cost(200); 12019 expand %{ 12020 rFlagsReg cr; 12021 compI_rReg(cr, dst, src); 12022 cmovI_reg_l(dst, src, cr); 12023 %} 12024 %} 12025 12026 // ============================================================================ 12027 // Branch Instructions 12028 12029 // Jump Direct - Label defines a relative address from JMP+1 12030 instruct jmpDir(label labl) 12031 %{ 12032 match(Goto); 12033 effect(USE labl); 12034 12035 ins_cost(300); 12036 format %{ "jmp $labl" %} 12037 size(5); 12038 ins_encode %{ 12039 Label* L = $labl$$label; 12040 __ jmp(*L, false); // Always long jump 12041 %} 12042 ins_pipe(pipe_jmp); 12043 %} 12044 12045 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12046 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12047 %{ 12048 match(If cop cr); 12049 effect(USE labl); 12050 12051 ins_cost(300); 12052 format %{ "j$cop $labl" %} 12053 size(6); 12054 ins_encode %{ 12055 Label* L = $labl$$label; 12056 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12057 %} 12058 ins_pipe(pipe_jcc); 12059 %} 12060 12061 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12062 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12063 %{ 12064 match(CountedLoopEnd cop cr); 12065 effect(USE labl); 12066 12067 ins_cost(300); 12068 format %{ "j$cop $labl\t# loop end" %} 12069 size(6); 12070 ins_encode %{ 12071 Label* L = $labl$$label; 12072 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12073 %} 12074 ins_pipe(pipe_jcc); 12075 %} 12076 12077 // Jump Direct Conditional - using unsigned comparison 12078 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12079 match(If cop cmp); 12080 effect(USE labl); 12081 12082 ins_cost(300); 12083 format %{ "j$cop,u $labl" %} 12084 size(6); 12085 ins_encode %{ 12086 Label* L = $labl$$label; 12087 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12088 %} 12089 ins_pipe(pipe_jcc); 12090 %} 12091 12092 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12093 match(If cop cmp); 12094 effect(USE labl); 12095 12096 ins_cost(200); 12097 format %{ "j$cop,u $labl" %} 12098 size(6); 12099 ins_encode %{ 12100 Label* L = $labl$$label; 12101 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12102 %} 12103 ins_pipe(pipe_jcc); 12104 %} 12105 12106 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12107 match(If cop cmp); 12108 effect(USE labl); 12109 12110 ins_cost(200); 12111 format %{ $$template 12112 if ($cop$$cmpcode == Assembler::notEqual) { 12113 $$emit$$"jp,u $labl\n\t" 12114 $$emit$$"j$cop,u $labl" 12115 } else { 12116 $$emit$$"jp,u done\n\t" 12117 $$emit$$"j$cop,u $labl\n\t" 12118 $$emit$$"done:" 12119 } 12120 %} 12121 ins_encode %{ 12122 Label* l = $labl$$label; 12123 if ($cop$$cmpcode == Assembler::notEqual) { 12124 __ jcc(Assembler::parity, *l, false); 12125 __ jcc(Assembler::notEqual, *l, false); 12126 } else if ($cop$$cmpcode == Assembler::equal) { 12127 Label done; 12128 __ jccb(Assembler::parity, done); 12129 __ jcc(Assembler::equal, *l, false); 12130 __ bind(done); 12131 } else { 12132 ShouldNotReachHere(); 12133 } 12134 %} 12135 ins_pipe(pipe_jcc); 12136 %} 12137 12138 // ============================================================================ 12139 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12140 // superklass array for an instance of the superklass. Set a hidden 12141 // internal cache on a hit (cache is checked with exposed code in 12142 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12143 // encoding ALSO sets flags. 12144 12145 instruct partialSubtypeCheck(rdi_RegP result, 12146 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12147 rFlagsReg cr) 12148 %{ 12149 match(Set result (PartialSubtypeCheck sub super)); 12150 predicate(!UseSecondarySupersTable); 12151 effect(KILL rcx, KILL cr); 12152 12153 ins_cost(1100); // slightly larger than the next version 12154 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12155 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12156 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12157 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12158 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12159 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12160 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12161 "miss:\t" %} 12162 12163 ins_encode %{ 12164 Label miss; 12165 // NB: Callers may assume that, when $result is a valid register, 12166 // check_klass_subtype_slow_path_linear sets it to a nonzero 12167 // value. 12168 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 12169 $rcx$$Register, $result$$Register, 12170 nullptr, &miss, 12171 /*set_cond_codes:*/ true); 12172 __ xorptr($result$$Register, $result$$Register); 12173 __ bind(miss); 12174 %} 12175 12176 ins_pipe(pipe_slow); 12177 %} 12178 12179 // ============================================================================ 12180 // Two versions of hashtable-based partialSubtypeCheck, both used when 12181 // we need to search for a super class in the secondary supers array. 12182 // The first is used when we don't know _a priori_ the class being 12183 // searched for. The second, far more common, is used when we do know: 12184 // this is used for instanceof, checkcast, and any case where C2 can 12185 // determine it by constant propagation. 12186 12187 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 12188 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12189 rFlagsReg cr) 12190 %{ 12191 match(Set result (PartialSubtypeCheck sub super)); 12192 predicate(UseSecondarySupersTable); 12193 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12194 12195 ins_cost(1000); 12196 format %{ "partialSubtypeCheck $result, $sub, $super" %} 12197 12198 ins_encode %{ 12199 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 12200 $temp3$$Register, $temp4$$Register, $result$$Register); 12201 %} 12202 12203 ins_pipe(pipe_slow); 12204 %} 12205 12206 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12207 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12208 rFlagsReg cr) 12209 %{ 12210 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12211 predicate(UseSecondarySupersTable); 12212 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12213 12214 ins_cost(700); // smaller than the next version 12215 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12216 12217 ins_encode %{ 12218 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12219 if (InlineSecondarySupersTest) { 12220 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12221 $temp3$$Register, $temp4$$Register, $result$$Register, 12222 super_klass_slot); 12223 } else { 12224 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12225 } 12226 %} 12227 12228 ins_pipe(pipe_slow); 12229 %} 12230 12231 // ============================================================================ 12232 // Branch Instructions -- short offset versions 12233 // 12234 // These instructions are used to replace jumps of a long offset (the default 12235 // match) with jumps of a shorter offset. These instructions are all tagged 12236 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12237 // match rules in general matching. Instead, the ADLC generates a conversion 12238 // method in the MachNode which can be used to do in-place replacement of the 12239 // long variant with the shorter variant. The compiler will determine if a 12240 // branch can be taken by the is_short_branch_offset() predicate in the machine 12241 // specific code section of the file. 12242 12243 // Jump Direct - Label defines a relative address from JMP+1 12244 instruct jmpDir_short(label labl) %{ 12245 match(Goto); 12246 effect(USE labl); 12247 12248 ins_cost(300); 12249 format %{ "jmp,s $labl" %} 12250 size(2); 12251 ins_encode %{ 12252 Label* L = $labl$$label; 12253 __ jmpb(*L); 12254 %} 12255 ins_pipe(pipe_jmp); 12256 ins_short_branch(1); 12257 %} 12258 12259 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12260 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12261 match(If cop cr); 12262 effect(USE labl); 12263 12264 ins_cost(300); 12265 format %{ "j$cop,s $labl" %} 12266 size(2); 12267 ins_encode %{ 12268 Label* L = $labl$$label; 12269 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12270 %} 12271 ins_pipe(pipe_jcc); 12272 ins_short_branch(1); 12273 %} 12274 12275 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12276 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12277 match(CountedLoopEnd cop cr); 12278 effect(USE labl); 12279 12280 ins_cost(300); 12281 format %{ "j$cop,s $labl\t# loop end" %} 12282 size(2); 12283 ins_encode %{ 12284 Label* L = $labl$$label; 12285 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12286 %} 12287 ins_pipe(pipe_jcc); 12288 ins_short_branch(1); 12289 %} 12290 12291 // Jump Direct Conditional - using unsigned comparison 12292 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12293 match(If cop cmp); 12294 effect(USE labl); 12295 12296 ins_cost(300); 12297 format %{ "j$cop,us $labl" %} 12298 size(2); 12299 ins_encode %{ 12300 Label* L = $labl$$label; 12301 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12302 %} 12303 ins_pipe(pipe_jcc); 12304 ins_short_branch(1); 12305 %} 12306 12307 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12308 match(If cop cmp); 12309 effect(USE labl); 12310 12311 ins_cost(300); 12312 format %{ "j$cop,us $labl" %} 12313 size(2); 12314 ins_encode %{ 12315 Label* L = $labl$$label; 12316 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12317 %} 12318 ins_pipe(pipe_jcc); 12319 ins_short_branch(1); 12320 %} 12321 12322 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12323 match(If cop cmp); 12324 effect(USE labl); 12325 12326 ins_cost(300); 12327 format %{ $$template 12328 if ($cop$$cmpcode == Assembler::notEqual) { 12329 $$emit$$"jp,u,s $labl\n\t" 12330 $$emit$$"j$cop,u,s $labl" 12331 } else { 12332 $$emit$$"jp,u,s done\n\t" 12333 $$emit$$"j$cop,u,s $labl\n\t" 12334 $$emit$$"done:" 12335 } 12336 %} 12337 size(4); 12338 ins_encode %{ 12339 Label* l = $labl$$label; 12340 if ($cop$$cmpcode == Assembler::notEqual) { 12341 __ jccb(Assembler::parity, *l); 12342 __ jccb(Assembler::notEqual, *l); 12343 } else if ($cop$$cmpcode == Assembler::equal) { 12344 Label done; 12345 __ jccb(Assembler::parity, done); 12346 __ jccb(Assembler::equal, *l); 12347 __ bind(done); 12348 } else { 12349 ShouldNotReachHere(); 12350 } 12351 %} 12352 ins_pipe(pipe_jcc); 12353 ins_short_branch(1); 12354 %} 12355 12356 // ============================================================================ 12357 // inlined locking and unlocking 12358 12359 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12360 predicate(LockingMode != LM_LIGHTWEIGHT); 12361 match(Set cr (FastLock object box)); 12362 effect(TEMP tmp, TEMP scr, USE_KILL box); 12363 ins_cost(300); 12364 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12365 ins_encode %{ 12366 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12367 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12368 %} 12369 ins_pipe(pipe_slow); 12370 %} 12371 12372 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12373 predicate(LockingMode != LM_LIGHTWEIGHT); 12374 match(Set cr (FastUnlock object box)); 12375 effect(TEMP tmp, USE_KILL box); 12376 ins_cost(300); 12377 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12378 ins_encode %{ 12379 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12380 %} 12381 ins_pipe(pipe_slow); 12382 %} 12383 12384 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12385 predicate(LockingMode == LM_LIGHTWEIGHT); 12386 match(Set cr (FastLock object box)); 12387 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12388 ins_cost(300); 12389 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12390 ins_encode %{ 12391 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12392 %} 12393 ins_pipe(pipe_slow); 12394 %} 12395 12396 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12397 predicate(LockingMode == LM_LIGHTWEIGHT); 12398 match(Set cr (FastUnlock object rax_reg)); 12399 effect(TEMP tmp, USE_KILL rax_reg); 12400 ins_cost(300); 12401 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12402 ins_encode %{ 12403 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12404 %} 12405 ins_pipe(pipe_slow); 12406 %} 12407 12408 12409 // ============================================================================ 12410 // Safepoint Instructions 12411 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12412 %{ 12413 match(SafePoint poll); 12414 effect(KILL cr, USE poll); 12415 12416 format %{ "testl rax, [$poll]\t" 12417 "# Safepoint: poll for GC" %} 12418 ins_cost(125); 12419 ins_encode %{ 12420 __ relocate(relocInfo::poll_type); 12421 address pre_pc = __ pc(); 12422 __ testl(rax, Address($poll$$Register, 0)); 12423 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12424 %} 12425 ins_pipe(ialu_reg_mem); 12426 %} 12427 12428 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12429 match(Set dst (MaskAll src)); 12430 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12431 ins_encode %{ 12432 int mask_len = Matcher::vector_length(this); 12433 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12434 %} 12435 ins_pipe( pipe_slow ); 12436 %} 12437 12438 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12439 predicate(Matcher::vector_length(n) > 32); 12440 match(Set dst (MaskAll src)); 12441 effect(TEMP tmp); 12442 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12443 ins_encode %{ 12444 int mask_len = Matcher::vector_length(this); 12445 __ movslq($tmp$$Register, $src$$Register); 12446 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12447 %} 12448 ins_pipe( pipe_slow ); 12449 %} 12450 12451 // ============================================================================ 12452 // Procedure Call/Return Instructions 12453 // Call Java Static Instruction 12454 // Note: If this code changes, the corresponding ret_addr_offset() and 12455 // compute_padding() functions will have to be adjusted. 12456 instruct CallStaticJavaDirect(method meth) %{ 12457 match(CallStaticJava); 12458 effect(USE meth); 12459 12460 ins_cost(300); 12461 format %{ "call,static " %} 12462 opcode(0xE8); /* E8 cd */ 12463 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12464 ins_pipe(pipe_slow); 12465 ins_alignment(4); 12466 %} 12467 12468 // Call Java Dynamic Instruction 12469 // Note: If this code changes, the corresponding ret_addr_offset() and 12470 // compute_padding() functions will have to be adjusted. 12471 instruct CallDynamicJavaDirect(method meth) 12472 %{ 12473 match(CallDynamicJava); 12474 effect(USE meth); 12475 12476 ins_cost(300); 12477 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12478 "call,dynamic " %} 12479 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12480 ins_pipe(pipe_slow); 12481 ins_alignment(4); 12482 %} 12483 12484 // Call Runtime Instruction 12485 instruct CallRuntimeDirect(method meth) 12486 %{ 12487 match(CallRuntime); 12488 effect(USE meth); 12489 12490 ins_cost(300); 12491 format %{ "call,runtime " %} 12492 ins_encode(clear_avx, Java_To_Runtime(meth)); 12493 ins_pipe(pipe_slow); 12494 %} 12495 12496 // Call runtime without safepoint 12497 instruct CallLeafDirect(method meth) 12498 %{ 12499 match(CallLeaf); 12500 effect(USE meth); 12501 12502 ins_cost(300); 12503 format %{ "call_leaf,runtime " %} 12504 ins_encode(clear_avx, Java_To_Runtime(meth)); 12505 ins_pipe(pipe_slow); 12506 %} 12507 12508 // Call runtime without safepoint and with vector arguments 12509 instruct CallLeafDirectVector(method meth) 12510 %{ 12511 match(CallLeafVector); 12512 effect(USE meth); 12513 12514 ins_cost(300); 12515 format %{ "call_leaf,vector " %} 12516 ins_encode(Java_To_Runtime(meth)); 12517 ins_pipe(pipe_slow); 12518 %} 12519 12520 // Call runtime without safepoint 12521 instruct CallLeafNoFPDirect(method meth) 12522 %{ 12523 match(CallLeafNoFP); 12524 effect(USE meth); 12525 12526 ins_cost(300); 12527 format %{ "call_leaf_nofp,runtime " %} 12528 ins_encode(clear_avx, Java_To_Runtime(meth)); 12529 ins_pipe(pipe_slow); 12530 %} 12531 12532 // Return Instruction 12533 // Remove the return address & jump to it. 12534 // Notice: We always emit a nop after a ret to make sure there is room 12535 // for safepoint patching 12536 instruct Ret() 12537 %{ 12538 match(Return); 12539 12540 format %{ "ret" %} 12541 ins_encode %{ 12542 __ ret(0); 12543 %} 12544 ins_pipe(pipe_jmp); 12545 %} 12546 12547 // Tail Call; Jump from runtime stub to Java code. 12548 // Also known as an 'interprocedural jump'. 12549 // Target of jump will eventually return to caller. 12550 // TailJump below removes the return address. 12551 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12552 // emitted just above the TailCall which has reset rbp to the caller state. 12553 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12554 %{ 12555 match(TailCall jump_target method_ptr); 12556 12557 ins_cost(300); 12558 format %{ "jmp $jump_target\t# rbx holds method" %} 12559 ins_encode %{ 12560 __ jmp($jump_target$$Register); 12561 %} 12562 ins_pipe(pipe_jmp); 12563 %} 12564 12565 // Tail Jump; remove the return address; jump to target. 12566 // TailCall above leaves the return address around. 12567 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12568 %{ 12569 match(TailJump jump_target ex_oop); 12570 12571 ins_cost(300); 12572 format %{ "popq rdx\t# pop return address\n\t" 12573 "jmp $jump_target" %} 12574 ins_encode %{ 12575 __ popq(as_Register(RDX_enc)); 12576 __ jmp($jump_target$$Register); 12577 %} 12578 ins_pipe(pipe_jmp); 12579 %} 12580 12581 // Forward exception. 12582 instruct ForwardExceptionjmp() 12583 %{ 12584 match(ForwardException); 12585 12586 format %{ "jmp forward_exception_stub" %} 12587 ins_encode %{ 12588 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 12589 %} 12590 ins_pipe(pipe_jmp); 12591 %} 12592 12593 // Create exception oop: created by stack-crawling runtime code. 12594 // Created exception is now available to this handler, and is setup 12595 // just prior to jumping to this handler. No code emitted. 12596 instruct CreateException(rax_RegP ex_oop) 12597 %{ 12598 match(Set ex_oop (CreateEx)); 12599 12600 size(0); 12601 // use the following format syntax 12602 format %{ "# exception oop is in rax; no code emitted" %} 12603 ins_encode(); 12604 ins_pipe(empty); 12605 %} 12606 12607 // Rethrow exception: 12608 // The exception oop will come in the first argument position. 12609 // Then JUMP (not call) to the rethrow stub code. 12610 instruct RethrowException() 12611 %{ 12612 match(Rethrow); 12613 12614 // use the following format syntax 12615 format %{ "jmp rethrow_stub" %} 12616 ins_encode %{ 12617 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12618 %} 12619 ins_pipe(pipe_jmp); 12620 %} 12621 12622 // ============================================================================ 12623 // This name is KNOWN by the ADLC and cannot be changed. 12624 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12625 // for this guy. 12626 instruct tlsLoadP(r15_RegP dst) %{ 12627 match(Set dst (ThreadLocal)); 12628 effect(DEF dst); 12629 12630 size(0); 12631 format %{ "# TLS is in R15" %} 12632 ins_encode( /*empty encoding*/ ); 12633 ins_pipe(ialu_reg_reg); 12634 %} 12635 12636 12637 //----------PEEPHOLE RULES----------------------------------------------------- 12638 // These must follow all instruction definitions as they use the names 12639 // defined in the instructions definitions. 12640 // 12641 // peeppredicate ( rule_predicate ); 12642 // // the predicate unless which the peephole rule will be ignored 12643 // 12644 // peepmatch ( root_instr_name [preceding_instruction]* ); 12645 // 12646 // peepprocedure ( procedure_name ); 12647 // // provide a procedure name to perform the optimization, the procedure should 12648 // // reside in the architecture dependent peephole file, the method has the 12649 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12650 // // with the arguments being the basic block, the current node index inside the 12651 // // block, the register allocator, the functions upon invoked return a new node 12652 // // defined in peepreplace, and the rules of the nodes appearing in the 12653 // // corresponding peepmatch, the function return true if successful, else 12654 // // return false 12655 // 12656 // peepconstraint %{ 12657 // (instruction_number.operand_name relational_op instruction_number.operand_name 12658 // [, ...] ); 12659 // // instruction numbers are zero-based using left to right order in peepmatch 12660 // 12661 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12662 // // provide an instruction_number.operand_name for each operand that appears 12663 // // in the replacement instruction's match rule 12664 // 12665 // ---------VM FLAGS--------------------------------------------------------- 12666 // 12667 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12668 // 12669 // Each peephole rule is given an identifying number starting with zero and 12670 // increasing by one in the order seen by the parser. An individual peephole 12671 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12672 // on the command-line. 12673 // 12674 // ---------CURRENT LIMITATIONS---------------------------------------------- 12675 // 12676 // Only transformations inside a basic block (do we need more for peephole) 12677 // 12678 // ---------EXAMPLE---------------------------------------------------------- 12679 // 12680 // // pertinent parts of existing instructions in architecture description 12681 // instruct movI(rRegI dst, rRegI src) 12682 // %{ 12683 // match(Set dst (CopyI src)); 12684 // %} 12685 // 12686 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12687 // %{ 12688 // match(Set dst (AddI dst src)); 12689 // effect(KILL cr); 12690 // %} 12691 // 12692 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12693 // %{ 12694 // match(Set dst (AddI dst src)); 12695 // %} 12696 // 12697 // 1. Simple replacement 12698 // - Only match adjacent instructions in same basic block 12699 // - Only equality constraints 12700 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12701 // - Only one replacement instruction 12702 // 12703 // // Change (inc mov) to lea 12704 // peephole %{ 12705 // // lea should only be emitted when beneficial 12706 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12707 // // increment preceded by register-register move 12708 // peepmatch ( incI_rReg movI ); 12709 // // require that the destination register of the increment 12710 // // match the destination register of the move 12711 // peepconstraint ( 0.dst == 1.dst ); 12712 // // construct a replacement instruction that sets 12713 // // the destination to ( move's source register + one ) 12714 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12715 // %} 12716 // 12717 // 2. Procedural replacement 12718 // - More flexible finding relevent nodes 12719 // - More flexible constraints 12720 // - More flexible transformations 12721 // - May utilise architecture-dependent API more effectively 12722 // - Currently only one replacement instruction due to adlc parsing capabilities 12723 // 12724 // // Change (inc mov) to lea 12725 // peephole %{ 12726 // // lea should only be emitted when beneficial 12727 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12728 // // the rule numbers of these nodes inside are passed into the function below 12729 // peepmatch ( incI_rReg movI ); 12730 // // the method that takes the responsibility of transformation 12731 // peepprocedure ( inc_mov_to_lea ); 12732 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12733 // // node is passed into the function above 12734 // peepreplace ( leaI_rReg_immI() ); 12735 // %} 12736 12737 // These instructions is not matched by the matcher but used by the peephole 12738 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12739 %{ 12740 predicate(false); 12741 match(Set dst (AddI src1 src2)); 12742 format %{ "leal $dst, [$src1 + $src2]" %} 12743 ins_encode %{ 12744 Register dst = $dst$$Register; 12745 Register src1 = $src1$$Register; 12746 Register src2 = $src2$$Register; 12747 if (src1 != rbp && src1 != r13) { 12748 __ leal(dst, Address(src1, src2, Address::times_1)); 12749 } else { 12750 assert(src2 != rbp && src2 != r13, ""); 12751 __ leal(dst, Address(src2, src1, Address::times_1)); 12752 } 12753 %} 12754 ins_pipe(ialu_reg_reg); 12755 %} 12756 12757 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 12758 %{ 12759 predicate(false); 12760 match(Set dst (AddI src1 src2)); 12761 format %{ "leal $dst, [$src1 + $src2]" %} 12762 ins_encode %{ 12763 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 12764 %} 12765 ins_pipe(ialu_reg_reg); 12766 %} 12767 12768 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 12769 %{ 12770 predicate(false); 12771 match(Set dst (LShiftI src shift)); 12772 format %{ "leal $dst, [$src << $shift]" %} 12773 ins_encode %{ 12774 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12775 Register src = $src$$Register; 12776 if (scale == Address::times_2 && src != rbp && src != r13) { 12777 __ leal($dst$$Register, Address(src, src, Address::times_1)); 12778 } else { 12779 __ leal($dst$$Register, Address(noreg, src, scale)); 12780 } 12781 %} 12782 ins_pipe(ialu_reg_reg); 12783 %} 12784 12785 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 12786 %{ 12787 predicate(false); 12788 match(Set dst (AddL src1 src2)); 12789 format %{ "leaq $dst, [$src1 + $src2]" %} 12790 ins_encode %{ 12791 Register dst = $dst$$Register; 12792 Register src1 = $src1$$Register; 12793 Register src2 = $src2$$Register; 12794 if (src1 != rbp && src1 != r13) { 12795 __ leaq(dst, Address(src1, src2, Address::times_1)); 12796 } else { 12797 assert(src2 != rbp && src2 != r13, ""); 12798 __ leaq(dst, Address(src2, src1, Address::times_1)); 12799 } 12800 %} 12801 ins_pipe(ialu_reg_reg); 12802 %} 12803 12804 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 12805 %{ 12806 predicate(false); 12807 match(Set dst (AddL src1 src2)); 12808 format %{ "leaq $dst, [$src1 + $src2]" %} 12809 ins_encode %{ 12810 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 12811 %} 12812 ins_pipe(ialu_reg_reg); 12813 %} 12814 12815 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 12816 %{ 12817 predicate(false); 12818 match(Set dst (LShiftL src shift)); 12819 format %{ "leaq $dst, [$src << $shift]" %} 12820 ins_encode %{ 12821 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12822 Register src = $src$$Register; 12823 if (scale == Address::times_2 && src != rbp && src != r13) { 12824 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 12825 } else { 12826 __ leaq($dst$$Register, Address(noreg, src, scale)); 12827 } 12828 %} 12829 ins_pipe(ialu_reg_reg); 12830 %} 12831 12832 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 12833 // sal}) with lea instructions. The {add, sal} rules are beneficial in 12834 // processors with at least partial ALU support for lea 12835 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 12836 // beneficial for processors with full ALU support 12837 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 12838 12839 peephole 12840 %{ 12841 peeppredicate(VM_Version::supports_fast_2op_lea()); 12842 peepmatch (addI_rReg); 12843 peepprocedure (lea_coalesce_reg); 12844 peepreplace (leaI_rReg_rReg_peep()); 12845 %} 12846 12847 peephole 12848 %{ 12849 peeppredicate(VM_Version::supports_fast_2op_lea()); 12850 peepmatch (addI_rReg_imm); 12851 peepprocedure (lea_coalesce_imm); 12852 peepreplace (leaI_rReg_immI_peep()); 12853 %} 12854 12855 peephole 12856 %{ 12857 peeppredicate(VM_Version::supports_fast_3op_lea() || 12858 VM_Version::is_intel_cascade_lake()); 12859 peepmatch (incI_rReg); 12860 peepprocedure (lea_coalesce_imm); 12861 peepreplace (leaI_rReg_immI_peep()); 12862 %} 12863 12864 peephole 12865 %{ 12866 peeppredicate(VM_Version::supports_fast_3op_lea() || 12867 VM_Version::is_intel_cascade_lake()); 12868 peepmatch (decI_rReg); 12869 peepprocedure (lea_coalesce_imm); 12870 peepreplace (leaI_rReg_immI_peep()); 12871 %} 12872 12873 peephole 12874 %{ 12875 peeppredicate(VM_Version::supports_fast_2op_lea()); 12876 peepmatch (salI_rReg_immI2); 12877 peepprocedure (lea_coalesce_imm); 12878 peepreplace (leaI_rReg_immI2_peep()); 12879 %} 12880 12881 peephole 12882 %{ 12883 peeppredicate(VM_Version::supports_fast_2op_lea()); 12884 peepmatch (addL_rReg); 12885 peepprocedure (lea_coalesce_reg); 12886 peepreplace (leaL_rReg_rReg_peep()); 12887 %} 12888 12889 peephole 12890 %{ 12891 peeppredicate(VM_Version::supports_fast_2op_lea()); 12892 peepmatch (addL_rReg_imm); 12893 peepprocedure (lea_coalesce_imm); 12894 peepreplace (leaL_rReg_immL32_peep()); 12895 %} 12896 12897 peephole 12898 %{ 12899 peeppredicate(VM_Version::supports_fast_3op_lea() || 12900 VM_Version::is_intel_cascade_lake()); 12901 peepmatch (incL_rReg); 12902 peepprocedure (lea_coalesce_imm); 12903 peepreplace (leaL_rReg_immL32_peep()); 12904 %} 12905 12906 peephole 12907 %{ 12908 peeppredicate(VM_Version::supports_fast_3op_lea() || 12909 VM_Version::is_intel_cascade_lake()); 12910 peepmatch (decL_rReg); 12911 peepprocedure (lea_coalesce_imm); 12912 peepreplace (leaL_rReg_immL32_peep()); 12913 %} 12914 12915 peephole 12916 %{ 12917 peeppredicate(VM_Version::supports_fast_2op_lea()); 12918 peepmatch (salL_rReg_immI2); 12919 peepprocedure (lea_coalesce_imm); 12920 peepreplace (leaL_rReg_immI2_peep()); 12921 %} 12922 12923 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 12924 // 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 12925 12926 //int variant 12927 peephole 12928 %{ 12929 peepmatch (testI_reg); 12930 peepprocedure (test_may_remove); 12931 %} 12932 12933 //long variant 12934 peephole 12935 %{ 12936 peepmatch (testL_reg); 12937 peepprocedure (test_may_remove); 12938 %} 12939 12940 12941 //----------SMARTSPILL RULES--------------------------------------------------- 12942 // These must follow all instruction definitions as they use the names 12943 // defined in the instructions definitions.