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 extern RegMask _ANY_REG_mask; 430 extern RegMask _PTR_REG_mask; 431 extern RegMask _PTR_REG_NO_RBP_mask; 432 extern RegMask _PTR_NO_RAX_REG_mask; 433 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 434 extern RegMask _LONG_REG_mask; 435 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 436 extern RegMask _LONG_NO_RCX_REG_mask; 437 extern RegMask _LONG_NO_RBP_R13_REG_mask; 438 extern RegMask _INT_REG_mask; 439 extern RegMask _INT_NO_RAX_RDX_REG_mask; 440 extern RegMask _INT_NO_RCX_REG_mask; 441 extern RegMask _INT_NO_RBP_R13_REG_mask; 442 extern RegMask _FLOAT_REG_mask; 443 444 extern RegMask _STACK_OR_PTR_REG_mask; 445 extern RegMask _STACK_OR_LONG_REG_mask; 446 extern RegMask _STACK_OR_INT_REG_mask; 447 448 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 449 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 450 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 451 452 %} 453 454 source %{ 455 #define RELOC_IMM64 Assembler::imm_operand 456 #define RELOC_DISP32 Assembler::disp32_operand 457 458 #define __ masm-> 459 460 RegMask _ANY_REG_mask; 461 RegMask _PTR_REG_mask; 462 RegMask _PTR_REG_NO_RBP_mask; 463 RegMask _PTR_NO_RAX_REG_mask; 464 RegMask _PTR_NO_RAX_RBX_REG_mask; 465 RegMask _LONG_REG_mask; 466 RegMask _LONG_NO_RAX_RDX_REG_mask; 467 RegMask _LONG_NO_RCX_REG_mask; 468 RegMask _LONG_NO_RBP_R13_REG_mask; 469 RegMask _INT_REG_mask; 470 RegMask _INT_NO_RAX_RDX_REG_mask; 471 RegMask _INT_NO_RCX_REG_mask; 472 RegMask _INT_NO_RBP_R13_REG_mask; 473 RegMask _FLOAT_REG_mask; 474 RegMask _STACK_OR_PTR_REG_mask; 475 RegMask _STACK_OR_LONG_REG_mask; 476 RegMask _STACK_OR_INT_REG_mask; 477 478 static bool need_r12_heapbase() { 479 return UseCompressedOops; 480 } 481 482 void reg_mask_init() { 483 constexpr Register egprs[] = {r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31}; 484 485 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 486 // We derive a number of subsets from it. 487 _ANY_REG_mask = _ALL_REG_mask; 488 489 if (PreserveFramePointer) { 490 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 491 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 492 } 493 if (need_r12_heapbase()) { 494 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 495 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 496 } 497 498 _PTR_REG_mask = _ANY_REG_mask; 499 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 500 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 501 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 502 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 503 if (!UseAPX) { 504 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 505 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 506 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg()->next())); 507 } 508 } 509 510 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 511 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 512 513 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 514 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 515 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 516 517 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 518 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 519 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 520 521 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 522 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 523 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 524 525 526 _LONG_REG_mask = _PTR_REG_mask; 527 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 528 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 529 530 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 531 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 532 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 533 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 534 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 535 536 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 537 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 538 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 539 540 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 541 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 542 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 543 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 544 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 545 546 _INT_REG_mask = _ALL_INT_REG_mask; 547 if (!UseAPX) { 548 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 549 _INT_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 550 } 551 } 552 553 if (PreserveFramePointer) { 554 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 555 } 556 if (need_r12_heapbase()) { 557 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 558 } 559 560 _STACK_OR_INT_REG_mask = _INT_REG_mask; 561 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 562 563 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 564 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 565 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 566 567 _INT_NO_RCX_REG_mask = _INT_REG_mask; 568 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 569 570 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 571 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 572 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 573 574 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 575 // from the float_reg_legacy/float_reg_evex register class. 576 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 577 } 578 579 static bool generate_vzeroupper(Compile* C) { 580 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 581 } 582 583 static int clear_avx_size() { 584 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 585 } 586 587 // !!!!! Special hack to get all types of calls to specify the byte offset 588 // from the start of the call to the point where the return address 589 // will point. 590 int MachCallStaticJavaNode::ret_addr_offset() 591 { 592 int offset = 5; // 5 bytes from start of call to where return address points 593 offset += clear_avx_size(); 594 return offset; 595 } 596 597 int MachCallDynamicJavaNode::ret_addr_offset() 598 { 599 int offset = 15; // 15 bytes from start of call to where return address points 600 offset += clear_avx_size(); 601 return offset; 602 } 603 604 int MachCallRuntimeNode::ret_addr_offset() { 605 int offset = 13; // movq r10,#addr; callq (r10) 606 if (this->ideal_Opcode() != Op_CallLeafVector) { 607 offset += clear_avx_size(); 608 } 609 return offset; 610 } 611 // 612 // Compute padding required for nodes which need alignment 613 // 614 615 // The address of the call instruction needs to be 4-byte aligned to 616 // ensure that it does not span a cache line so that it can be patched. 617 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 618 { 619 current_offset += clear_avx_size(); // skip vzeroupper 620 current_offset += 1; // skip call opcode byte 621 return align_up(current_offset, alignment_required()) - current_offset; 622 } 623 624 // The address of the call instruction needs to be 4-byte aligned to 625 // ensure that it does not span a cache line so that it can be patched. 626 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 627 { 628 current_offset += clear_avx_size(); // skip vzeroupper 629 current_offset += 11; // skip movq instruction + call opcode byte 630 return align_up(current_offset, alignment_required()) - current_offset; 631 } 632 633 // This could be in MacroAssembler but it's fairly C2 specific 634 static void emit_cmpfp_fixup(MacroAssembler* masm) { 635 Label exit; 636 __ jccb(Assembler::noParity, exit); 637 __ pushf(); 638 // 639 // comiss/ucomiss instructions set ZF,PF,CF flags and 640 // zero OF,AF,SF for NaN values. 641 // Fixup flags by zeroing ZF,PF so that compare of NaN 642 // values returns 'less than' result (CF is set). 643 // Leave the rest of flags unchanged. 644 // 645 // 7 6 5 4 3 2 1 0 646 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 647 // 0 0 1 0 1 0 1 1 (0x2B) 648 // 649 __ andq(Address(rsp, 0), 0xffffff2b); 650 __ popf(); 651 __ bind(exit); 652 } 653 654 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 655 Label done; 656 __ movl(dst, -1); 657 __ jcc(Assembler::parity, done); 658 __ jcc(Assembler::below, done); 659 __ setcc(Assembler::notEqual, dst); 660 __ bind(done); 661 } 662 663 // Math.min() # Math.max() 664 // -------------------------- 665 // ucomis[s/d] # 666 // ja -> b # a 667 // jp -> NaN # NaN 668 // jb -> a # b 669 // je # 670 // |-jz -> a | b # a & b 671 // | -> a # 672 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 673 XMMRegister a, XMMRegister b, 674 XMMRegister xmmt, Register rt, 675 bool min, bool single) { 676 677 Label nan, zero, below, above, done; 678 679 if (single) 680 __ ucomiss(a, b); 681 else 682 __ ucomisd(a, b); 683 684 if (dst->encoding() != (min ? b : a)->encoding()) 685 __ jccb(Assembler::above, above); // CF=0 & ZF=0 686 else 687 __ jccb(Assembler::above, done); 688 689 __ jccb(Assembler::parity, nan); // PF=1 690 __ jccb(Assembler::below, below); // CF=1 691 692 // equal 693 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 694 if (single) { 695 __ ucomiss(a, xmmt); 696 __ jccb(Assembler::equal, zero); 697 698 __ movflt(dst, a); 699 __ jmp(done); 700 } 701 else { 702 __ ucomisd(a, xmmt); 703 __ jccb(Assembler::equal, zero); 704 705 __ movdbl(dst, a); 706 __ jmp(done); 707 } 708 709 __ bind(zero); 710 if (min) 711 __ vpor(dst, a, b, Assembler::AVX_128bit); 712 else 713 __ vpand(dst, a, b, Assembler::AVX_128bit); 714 715 __ jmp(done); 716 717 __ bind(above); 718 if (single) 719 __ movflt(dst, min ? b : a); 720 else 721 __ movdbl(dst, min ? b : a); 722 723 __ jmp(done); 724 725 __ bind(nan); 726 if (single) { 727 __ movl(rt, 0x7fc00000); // Float.NaN 728 __ movdl(dst, rt); 729 } 730 else { 731 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 732 __ movdq(dst, rt); 733 } 734 __ jmp(done); 735 736 __ bind(below); 737 if (single) 738 __ movflt(dst, min ? a : b); 739 else 740 __ movdbl(dst, min ? a : b); 741 742 __ bind(done); 743 } 744 745 //============================================================================= 746 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 747 748 int ConstantTable::calculate_table_base_offset() const { 749 return 0; // absolute addressing, no offset 750 } 751 752 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 753 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 754 ShouldNotReachHere(); 755 } 756 757 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 758 // Empty encoding 759 } 760 761 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 762 return 0; 763 } 764 765 #ifndef PRODUCT 766 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 767 st->print("# MachConstantBaseNode (empty encoding)"); 768 } 769 #endif 770 771 772 //============================================================================= 773 #ifndef PRODUCT 774 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 775 Compile* C = ra_->C; 776 777 int framesize = C->output()->frame_size_in_bytes(); 778 int bangsize = C->output()->bang_size_in_bytes(); 779 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 780 // Remove wordSize for return addr which is already pushed. 781 framesize -= wordSize; 782 783 if (C->output()->need_stack_bang(bangsize)) { 784 framesize -= wordSize; 785 st->print("# stack bang (%d bytes)", bangsize); 786 st->print("\n\t"); 787 st->print("pushq rbp\t# Save rbp"); 788 if (PreserveFramePointer) { 789 st->print("\n\t"); 790 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 791 } 792 if (framesize) { 793 st->print("\n\t"); 794 st->print("subq rsp, #%d\t# Create frame",framesize); 795 } 796 } else { 797 st->print("subq rsp, #%d\t# Create frame",framesize); 798 st->print("\n\t"); 799 framesize -= wordSize; 800 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 801 if (PreserveFramePointer) { 802 st->print("\n\t"); 803 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 804 if (framesize > 0) { 805 st->print("\n\t"); 806 st->print("addq rbp, #%d", framesize); 807 } 808 } 809 } 810 811 if (VerifyStackAtCalls) { 812 st->print("\n\t"); 813 framesize -= wordSize; 814 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 815 #ifdef ASSERT 816 st->print("\n\t"); 817 st->print("# stack alignment check"); 818 #endif 819 } 820 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 821 st->print("\n\t"); 822 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 823 st->print("\n\t"); 824 st->print("je fast_entry\t"); 825 st->print("\n\t"); 826 st->print("call #nmethod_entry_barrier_stub\t"); 827 st->print("\n\tfast_entry:"); 828 } 829 st->cr(); 830 } 831 #endif 832 833 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 834 Compile* C = ra_->C; 835 836 int framesize = C->output()->frame_size_in_bytes(); 837 int bangsize = C->output()->bang_size_in_bytes(); 838 839 if (C->clinit_barrier_on_entry()) { 840 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 841 assert(!C->method()->holder()->is_not_initialized() || C->do_clinit_barriers(), "initialization should have been started"); 842 843 Label L_skip_barrier; 844 Register klass = rscratch1; 845 846 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 847 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 848 849 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 850 851 __ bind(L_skip_barrier); 852 } 853 854 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 855 856 C->output()->set_frame_complete(__ offset()); 857 858 if (C->has_mach_constant_base_node()) { 859 // NOTE: We set the table base offset here because users might be 860 // emitted before MachConstantBaseNode. 861 ConstantTable& constant_table = C->output()->constant_table(); 862 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 863 } 864 } 865 866 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 867 { 868 return MachNode::size(ra_); // too many variables; just compute it 869 // the hard way 870 } 871 872 int MachPrologNode::reloc() const 873 { 874 return 0; // a large enough number 875 } 876 877 //============================================================================= 878 #ifndef PRODUCT 879 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 880 { 881 Compile* C = ra_->C; 882 if (generate_vzeroupper(C)) { 883 st->print("vzeroupper"); 884 st->cr(); st->print("\t"); 885 } 886 887 int framesize = C->output()->frame_size_in_bytes(); 888 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 889 // Remove word for return adr already pushed 890 // and RBP 891 framesize -= 2*wordSize; 892 893 if (framesize) { 894 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 895 st->print("\t"); 896 } 897 898 st->print_cr("popq rbp"); 899 if (do_polling() && C->is_method_compilation()) { 900 st->print("\t"); 901 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 902 "ja #safepoint_stub\t" 903 "# Safepoint: poll for GC"); 904 } 905 } 906 #endif 907 908 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 909 { 910 Compile* C = ra_->C; 911 912 if (generate_vzeroupper(C)) { 913 // Clear upper bits of YMM registers when current compiled code uses 914 // wide vectors to avoid AVX <-> SSE transition penalty during call. 915 __ vzeroupper(); 916 } 917 918 int framesize = C->output()->frame_size_in_bytes(); 919 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 920 // Remove word for return adr already pushed 921 // and RBP 922 framesize -= 2*wordSize; 923 924 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 925 926 if (framesize) { 927 __ addq(rsp, framesize); 928 } 929 930 __ popq(rbp); 931 932 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 933 __ reserved_stack_check(); 934 } 935 936 if (do_polling() && C->is_method_compilation()) { 937 Label dummy_label; 938 Label* code_stub = &dummy_label; 939 if (!C->output()->in_scratch_emit_size()) { 940 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 941 C->output()->add_stub(stub); 942 code_stub = &stub->entry(); 943 } 944 __ relocate(relocInfo::poll_return_type); 945 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 946 } 947 } 948 949 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 950 { 951 return MachNode::size(ra_); // too many variables; just compute it 952 // the hard way 953 } 954 955 int MachEpilogNode::reloc() const 956 { 957 return 2; // a large enough number 958 } 959 960 const Pipeline* MachEpilogNode::pipeline() const 961 { 962 return MachNode::pipeline_class(); 963 } 964 965 //============================================================================= 966 967 enum RC { 968 rc_bad, 969 rc_int, 970 rc_kreg, 971 rc_float, 972 rc_stack 973 }; 974 975 static enum RC rc_class(OptoReg::Name reg) 976 { 977 if( !OptoReg::is_valid(reg) ) return rc_bad; 978 979 if (OptoReg::is_stack(reg)) return rc_stack; 980 981 VMReg r = OptoReg::as_VMReg(reg); 982 983 if (r->is_Register()) return rc_int; 984 985 if (r->is_KRegister()) return rc_kreg; 986 987 assert(r->is_XMMRegister(), "must be"); 988 return rc_float; 989 } 990 991 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 992 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 993 int src_hi, int dst_hi, uint ireg, outputStream* st); 994 995 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 996 int stack_offset, int reg, uint ireg, outputStream* st); 997 998 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 999 int dst_offset, uint ireg, outputStream* st) { 1000 if (masm) { 1001 switch (ireg) { 1002 case Op_VecS: 1003 __ movq(Address(rsp, -8), rax); 1004 __ movl(rax, Address(rsp, src_offset)); 1005 __ movl(Address(rsp, dst_offset), rax); 1006 __ movq(rax, Address(rsp, -8)); 1007 break; 1008 case Op_VecD: 1009 __ pushq(Address(rsp, src_offset)); 1010 __ popq (Address(rsp, dst_offset)); 1011 break; 1012 case Op_VecX: 1013 __ pushq(Address(rsp, src_offset)); 1014 __ popq (Address(rsp, dst_offset)); 1015 __ pushq(Address(rsp, src_offset+8)); 1016 __ popq (Address(rsp, dst_offset+8)); 1017 break; 1018 case Op_VecY: 1019 __ vmovdqu(Address(rsp, -32), xmm0); 1020 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1021 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1022 __ vmovdqu(xmm0, Address(rsp, -32)); 1023 break; 1024 case Op_VecZ: 1025 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1026 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1027 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1028 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1029 break; 1030 default: 1031 ShouldNotReachHere(); 1032 } 1033 #ifndef PRODUCT 1034 } else { 1035 switch (ireg) { 1036 case Op_VecS: 1037 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1038 "movl rax, [rsp + #%d]\n\t" 1039 "movl [rsp + #%d], rax\n\t" 1040 "movq rax, [rsp - #8]", 1041 src_offset, dst_offset); 1042 break; 1043 case Op_VecD: 1044 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1045 "popq [rsp + #%d]", 1046 src_offset, dst_offset); 1047 break; 1048 case Op_VecX: 1049 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1050 "popq [rsp + #%d]\n\t" 1051 "pushq [rsp + #%d]\n\t" 1052 "popq [rsp + #%d]", 1053 src_offset, dst_offset, src_offset+8, dst_offset+8); 1054 break; 1055 case Op_VecY: 1056 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1057 "vmovdqu xmm0, [rsp + #%d]\n\t" 1058 "vmovdqu [rsp + #%d], xmm0\n\t" 1059 "vmovdqu xmm0, [rsp - #32]", 1060 src_offset, dst_offset); 1061 break; 1062 case Op_VecZ: 1063 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1064 "vmovdqu xmm0, [rsp + #%d]\n\t" 1065 "vmovdqu [rsp + #%d], xmm0\n\t" 1066 "vmovdqu xmm0, [rsp - #64]", 1067 src_offset, dst_offset); 1068 break; 1069 default: 1070 ShouldNotReachHere(); 1071 } 1072 #endif 1073 } 1074 } 1075 1076 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1077 PhaseRegAlloc* ra_, 1078 bool do_size, 1079 outputStream* st) const { 1080 assert(masm != nullptr || st != nullptr, "sanity"); 1081 // Get registers to move 1082 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1083 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1084 OptoReg::Name dst_second = ra_->get_reg_second(this); 1085 OptoReg::Name dst_first = ra_->get_reg_first(this); 1086 1087 enum RC src_second_rc = rc_class(src_second); 1088 enum RC src_first_rc = rc_class(src_first); 1089 enum RC dst_second_rc = rc_class(dst_second); 1090 enum RC dst_first_rc = rc_class(dst_first); 1091 1092 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1093 "must move at least 1 register" ); 1094 1095 if (src_first == dst_first && src_second == dst_second) { 1096 // Self copy, no move 1097 return 0; 1098 } 1099 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1100 uint ireg = ideal_reg(); 1101 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1102 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1103 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1104 // mem -> mem 1105 int src_offset = ra_->reg2offset(src_first); 1106 int dst_offset = ra_->reg2offset(dst_first); 1107 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1108 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1109 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1110 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1111 int stack_offset = ra_->reg2offset(dst_first); 1112 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1113 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1114 int stack_offset = ra_->reg2offset(src_first); 1115 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1116 } else { 1117 ShouldNotReachHere(); 1118 } 1119 return 0; 1120 } 1121 if (src_first_rc == rc_stack) { 1122 // mem -> 1123 if (dst_first_rc == rc_stack) { 1124 // mem -> mem 1125 assert(src_second != dst_first, "overlap"); 1126 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1127 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1128 // 64-bit 1129 int src_offset = ra_->reg2offset(src_first); 1130 int dst_offset = ra_->reg2offset(dst_first); 1131 if (masm) { 1132 __ pushq(Address(rsp, src_offset)); 1133 __ popq (Address(rsp, dst_offset)); 1134 #ifndef PRODUCT 1135 } else { 1136 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1137 "popq [rsp + #%d]", 1138 src_offset, dst_offset); 1139 #endif 1140 } 1141 } else { 1142 // 32-bit 1143 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1144 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1145 // No pushl/popl, so: 1146 int src_offset = ra_->reg2offset(src_first); 1147 int dst_offset = ra_->reg2offset(dst_first); 1148 if (masm) { 1149 __ movq(Address(rsp, -8), rax); 1150 __ movl(rax, Address(rsp, src_offset)); 1151 __ movl(Address(rsp, dst_offset), rax); 1152 __ movq(rax, Address(rsp, -8)); 1153 #ifndef PRODUCT 1154 } else { 1155 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1156 "movl rax, [rsp + #%d]\n\t" 1157 "movl [rsp + #%d], rax\n\t" 1158 "movq rax, [rsp - #8]", 1159 src_offset, dst_offset); 1160 #endif 1161 } 1162 } 1163 return 0; 1164 } else if (dst_first_rc == rc_int) { 1165 // mem -> gpr 1166 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1167 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1168 // 64-bit 1169 int offset = ra_->reg2offset(src_first); 1170 if (masm) { 1171 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1172 #ifndef PRODUCT 1173 } else { 1174 st->print("movq %s, [rsp + #%d]\t# spill", 1175 Matcher::regName[dst_first], 1176 offset); 1177 #endif 1178 } 1179 } else { 1180 // 32-bit 1181 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1182 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1183 int offset = ra_->reg2offset(src_first); 1184 if (masm) { 1185 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1186 #ifndef PRODUCT 1187 } else { 1188 st->print("movl %s, [rsp + #%d]\t# spill", 1189 Matcher::regName[dst_first], 1190 offset); 1191 #endif 1192 } 1193 } 1194 return 0; 1195 } else if (dst_first_rc == rc_float) { 1196 // mem-> xmm 1197 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1198 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1199 // 64-bit 1200 int offset = ra_->reg2offset(src_first); 1201 if (masm) { 1202 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1203 #ifndef PRODUCT 1204 } else { 1205 st->print("%s %s, [rsp + #%d]\t# spill", 1206 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1207 Matcher::regName[dst_first], 1208 offset); 1209 #endif 1210 } 1211 } else { 1212 // 32-bit 1213 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1214 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1215 int offset = ra_->reg2offset(src_first); 1216 if (masm) { 1217 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1218 #ifndef PRODUCT 1219 } else { 1220 st->print("movss %s, [rsp + #%d]\t# spill", 1221 Matcher::regName[dst_first], 1222 offset); 1223 #endif 1224 } 1225 } 1226 return 0; 1227 } else if (dst_first_rc == rc_kreg) { 1228 // mem -> kreg 1229 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1230 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1231 // 64-bit 1232 int offset = ra_->reg2offset(src_first); 1233 if (masm) { 1234 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1235 #ifndef PRODUCT 1236 } else { 1237 st->print("kmovq %s, [rsp + #%d]\t# spill", 1238 Matcher::regName[dst_first], 1239 offset); 1240 #endif 1241 } 1242 } 1243 return 0; 1244 } 1245 } else if (src_first_rc == rc_int) { 1246 // gpr -> 1247 if (dst_first_rc == rc_stack) { 1248 // gpr -> mem 1249 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1250 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1251 // 64-bit 1252 int offset = ra_->reg2offset(dst_first); 1253 if (masm) { 1254 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1255 #ifndef PRODUCT 1256 } else { 1257 st->print("movq [rsp + #%d], %s\t# spill", 1258 offset, 1259 Matcher::regName[src_first]); 1260 #endif 1261 } 1262 } else { 1263 // 32-bit 1264 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1265 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1266 int offset = ra_->reg2offset(dst_first); 1267 if (masm) { 1268 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1269 #ifndef PRODUCT 1270 } else { 1271 st->print("movl [rsp + #%d], %s\t# spill", 1272 offset, 1273 Matcher::regName[src_first]); 1274 #endif 1275 } 1276 } 1277 return 0; 1278 } else if (dst_first_rc == rc_int) { 1279 // gpr -> gpr 1280 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1281 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1282 // 64-bit 1283 if (masm) { 1284 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1285 as_Register(Matcher::_regEncode[src_first])); 1286 #ifndef PRODUCT 1287 } else { 1288 st->print("movq %s, %s\t# spill", 1289 Matcher::regName[dst_first], 1290 Matcher::regName[src_first]); 1291 #endif 1292 } 1293 return 0; 1294 } else { 1295 // 32-bit 1296 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1297 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1298 if (masm) { 1299 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1300 as_Register(Matcher::_regEncode[src_first])); 1301 #ifndef PRODUCT 1302 } else { 1303 st->print("movl %s, %s\t# spill", 1304 Matcher::regName[dst_first], 1305 Matcher::regName[src_first]); 1306 #endif 1307 } 1308 return 0; 1309 } 1310 } else if (dst_first_rc == rc_float) { 1311 // gpr -> xmm 1312 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1313 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1314 // 64-bit 1315 if (masm) { 1316 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1317 #ifndef PRODUCT 1318 } else { 1319 st->print("movdq %s, %s\t# spill", 1320 Matcher::regName[dst_first], 1321 Matcher::regName[src_first]); 1322 #endif 1323 } 1324 } else { 1325 // 32-bit 1326 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1327 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1328 if (masm) { 1329 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1330 #ifndef PRODUCT 1331 } else { 1332 st->print("movdl %s, %s\t# spill", 1333 Matcher::regName[dst_first], 1334 Matcher::regName[src_first]); 1335 #endif 1336 } 1337 } 1338 return 0; 1339 } else if (dst_first_rc == rc_kreg) { 1340 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1341 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1342 // 64-bit 1343 if (masm) { 1344 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1345 #ifndef PRODUCT 1346 } else { 1347 st->print("kmovq %s, %s\t# spill", 1348 Matcher::regName[dst_first], 1349 Matcher::regName[src_first]); 1350 #endif 1351 } 1352 } 1353 Unimplemented(); 1354 return 0; 1355 } 1356 } else if (src_first_rc == rc_float) { 1357 // xmm -> 1358 if (dst_first_rc == rc_stack) { 1359 // xmm -> mem 1360 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1361 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1362 // 64-bit 1363 int offset = ra_->reg2offset(dst_first); 1364 if (masm) { 1365 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1366 #ifndef PRODUCT 1367 } else { 1368 st->print("movsd [rsp + #%d], %s\t# spill", 1369 offset, 1370 Matcher::regName[src_first]); 1371 #endif 1372 } 1373 } else { 1374 // 32-bit 1375 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1376 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1377 int offset = ra_->reg2offset(dst_first); 1378 if (masm) { 1379 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1380 #ifndef PRODUCT 1381 } else { 1382 st->print("movss [rsp + #%d], %s\t# spill", 1383 offset, 1384 Matcher::regName[src_first]); 1385 #endif 1386 } 1387 } 1388 return 0; 1389 } else if (dst_first_rc == rc_int) { 1390 // xmm -> gpr 1391 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1392 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1393 // 64-bit 1394 if (masm) { 1395 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1396 #ifndef PRODUCT 1397 } else { 1398 st->print("movdq %s, %s\t# spill", 1399 Matcher::regName[dst_first], 1400 Matcher::regName[src_first]); 1401 #endif 1402 } 1403 } else { 1404 // 32-bit 1405 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1406 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1407 if (masm) { 1408 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1409 #ifndef PRODUCT 1410 } else { 1411 st->print("movdl %s, %s\t# spill", 1412 Matcher::regName[dst_first], 1413 Matcher::regName[src_first]); 1414 #endif 1415 } 1416 } 1417 return 0; 1418 } else if (dst_first_rc == rc_float) { 1419 // xmm -> xmm 1420 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1421 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1422 // 64-bit 1423 if (masm) { 1424 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1425 #ifndef PRODUCT 1426 } else { 1427 st->print("%s %s, %s\t# spill", 1428 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1429 Matcher::regName[dst_first], 1430 Matcher::regName[src_first]); 1431 #endif 1432 } 1433 } else { 1434 // 32-bit 1435 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1436 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1437 if (masm) { 1438 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1439 #ifndef PRODUCT 1440 } else { 1441 st->print("%s %s, %s\t# spill", 1442 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1443 Matcher::regName[dst_first], 1444 Matcher::regName[src_first]); 1445 #endif 1446 } 1447 } 1448 return 0; 1449 } else if (dst_first_rc == rc_kreg) { 1450 assert(false, "Illegal spilling"); 1451 return 0; 1452 } 1453 } else if (src_first_rc == rc_kreg) { 1454 if (dst_first_rc == rc_stack) { 1455 // mem -> kreg 1456 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1457 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1458 // 64-bit 1459 int offset = ra_->reg2offset(dst_first); 1460 if (masm) { 1461 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1462 #ifndef PRODUCT 1463 } else { 1464 st->print("kmovq [rsp + #%d] , %s\t# spill", 1465 offset, 1466 Matcher::regName[src_first]); 1467 #endif 1468 } 1469 } 1470 return 0; 1471 } else if (dst_first_rc == rc_int) { 1472 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1473 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1474 // 64-bit 1475 if (masm) { 1476 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1477 #ifndef PRODUCT 1478 } else { 1479 st->print("kmovq %s, %s\t# spill", 1480 Matcher::regName[dst_first], 1481 Matcher::regName[src_first]); 1482 #endif 1483 } 1484 } 1485 Unimplemented(); 1486 return 0; 1487 } else if (dst_first_rc == rc_kreg) { 1488 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1489 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1490 // 64-bit 1491 if (masm) { 1492 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1493 #ifndef PRODUCT 1494 } else { 1495 st->print("kmovq %s, %s\t# spill", 1496 Matcher::regName[dst_first], 1497 Matcher::regName[src_first]); 1498 #endif 1499 } 1500 } 1501 return 0; 1502 } else if (dst_first_rc == rc_float) { 1503 assert(false, "Illegal spill"); 1504 return 0; 1505 } 1506 } 1507 1508 assert(0," foo "); 1509 Unimplemented(); 1510 return 0; 1511 } 1512 1513 #ifndef PRODUCT 1514 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1515 implementation(nullptr, ra_, false, st); 1516 } 1517 #endif 1518 1519 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1520 implementation(masm, ra_, false, nullptr); 1521 } 1522 1523 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1524 return MachNode::size(ra_); 1525 } 1526 1527 //============================================================================= 1528 #ifndef PRODUCT 1529 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1530 { 1531 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1532 int reg = ra_->get_reg_first(this); 1533 st->print("leaq %s, [rsp + #%d]\t# box lock", 1534 Matcher::regName[reg], offset); 1535 } 1536 #endif 1537 1538 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1539 { 1540 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1541 int reg = ra_->get_encode(this); 1542 1543 __ lea(as_Register(reg), Address(rsp, offset)); 1544 } 1545 1546 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1547 { 1548 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1549 return (offset < 0x80) ? 5 : 8; // REX 1550 } 1551 1552 //============================================================================= 1553 #ifndef PRODUCT 1554 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1555 { 1556 if (UseCompressedClassPointers) { 1557 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1558 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1559 } else { 1560 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1561 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1562 } 1563 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1564 } 1565 #endif 1566 1567 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1568 { 1569 __ ic_check(InteriorEntryAlignment); 1570 } 1571 1572 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1573 { 1574 return MachNode::size(ra_); // too many variables; just compute it 1575 // the hard way 1576 } 1577 1578 1579 //============================================================================= 1580 1581 bool Matcher::supports_vector_calling_convention(void) { 1582 if (EnableVectorSupport && UseVectorStubs) { 1583 return true; 1584 } 1585 return false; 1586 } 1587 1588 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1589 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1590 int lo = XMM0_num; 1591 int hi = XMM0b_num; 1592 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1593 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1594 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1595 return OptoRegPair(hi, lo); 1596 } 1597 1598 // Is this branch offset short enough that a short branch can be used? 1599 // 1600 // NOTE: If the platform does not provide any short branch variants, then 1601 // this method should return false for offset 0. 1602 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1603 // The passed offset is relative to address of the branch. 1604 // On 86 a branch displacement is calculated relative to address 1605 // of a next instruction. 1606 offset -= br_size; 1607 1608 // the short version of jmpConUCF2 contains multiple branches, 1609 // making the reach slightly less 1610 if (rule == jmpConUCF2_rule) 1611 return (-126 <= offset && offset <= 125); 1612 return (-128 <= offset && offset <= 127); 1613 } 1614 1615 // Return whether or not this register is ever used as an argument. 1616 // This function is used on startup to build the trampoline stubs in 1617 // generateOptoStub. Registers not mentioned will be killed by the VM 1618 // call in the trampoline, and arguments in those registers not be 1619 // available to the callee. 1620 bool Matcher::can_be_java_arg(int reg) 1621 { 1622 return 1623 reg == RDI_num || reg == RDI_H_num || 1624 reg == RSI_num || reg == RSI_H_num || 1625 reg == RDX_num || reg == RDX_H_num || 1626 reg == RCX_num || reg == RCX_H_num || 1627 reg == R8_num || reg == R8_H_num || 1628 reg == R9_num || reg == R9_H_num || 1629 reg == R12_num || reg == R12_H_num || 1630 reg == XMM0_num || reg == XMM0b_num || 1631 reg == XMM1_num || reg == XMM1b_num || 1632 reg == XMM2_num || reg == XMM2b_num || 1633 reg == XMM3_num || reg == XMM3b_num || 1634 reg == XMM4_num || reg == XMM4b_num || 1635 reg == XMM5_num || reg == XMM5b_num || 1636 reg == XMM6_num || reg == XMM6b_num || 1637 reg == XMM7_num || reg == XMM7b_num; 1638 } 1639 1640 bool Matcher::is_spillable_arg(int reg) 1641 { 1642 return can_be_java_arg(reg); 1643 } 1644 1645 uint Matcher::int_pressure_limit() 1646 { 1647 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1648 } 1649 1650 uint Matcher::float_pressure_limit() 1651 { 1652 // After experiment around with different values, the following default threshold 1653 // works best for LCM's register pressure scheduling on x64. 1654 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1655 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1656 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1657 } 1658 1659 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1660 // In 64 bit mode a code which use multiply when 1661 // devisor is constant is faster than hardware 1662 // DIV instruction (it uses MulHiL). 1663 return false; 1664 } 1665 1666 // Register for DIVI projection of divmodI 1667 RegMask Matcher::divI_proj_mask() { 1668 return INT_RAX_REG_mask(); 1669 } 1670 1671 // Register for MODI projection of divmodI 1672 RegMask Matcher::modI_proj_mask() { 1673 return INT_RDX_REG_mask(); 1674 } 1675 1676 // Register for DIVL projection of divmodL 1677 RegMask Matcher::divL_proj_mask() { 1678 return LONG_RAX_REG_mask(); 1679 } 1680 1681 // Register for MODL projection of divmodL 1682 RegMask Matcher::modL_proj_mask() { 1683 return LONG_RDX_REG_mask(); 1684 } 1685 1686 // Register for saving SP into on method handle invokes. Not used on x86_64. 1687 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1688 return NO_REG_mask(); 1689 } 1690 1691 %} 1692 1693 //----------ENCODING BLOCK----------------------------------------------------- 1694 // This block specifies the encoding classes used by the compiler to 1695 // output byte streams. Encoding classes are parameterized macros 1696 // used by Machine Instruction Nodes in order to generate the bit 1697 // encoding of the instruction. Operands specify their base encoding 1698 // interface with the interface keyword. There are currently 1699 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1700 // COND_INTER. REG_INTER causes an operand to generate a function 1701 // which returns its register number when queried. CONST_INTER causes 1702 // an operand to generate a function which returns the value of the 1703 // constant when queried. MEMORY_INTER causes an operand to generate 1704 // four functions which return the Base Register, the Index Register, 1705 // the Scale Value, and the Offset Value of the operand when queried. 1706 // COND_INTER causes an operand to generate six functions which return 1707 // the encoding code (ie - encoding bits for the instruction) 1708 // associated with each basic boolean condition for a conditional 1709 // instruction. 1710 // 1711 // Instructions specify two basic values for encoding. Again, a 1712 // function is available to check if the constant displacement is an 1713 // oop. They use the ins_encode keyword to specify their encoding 1714 // classes (which must be a sequence of enc_class names, and their 1715 // parameters, specified in the encoding block), and they use the 1716 // opcode keyword to specify, in order, their primary, secondary, and 1717 // tertiary opcode. Only the opcode sections which a particular 1718 // instruction needs for encoding need to be specified. 1719 encode %{ 1720 enc_class cdql_enc(no_rax_rdx_RegI div) 1721 %{ 1722 // Full implementation of Java idiv and irem; checks for 1723 // special case as described in JVM spec., p.243 & p.271. 1724 // 1725 // normal case special case 1726 // 1727 // input : rax: dividend min_int 1728 // reg: divisor -1 1729 // 1730 // output: rax: quotient (= rax idiv reg) min_int 1731 // rdx: remainder (= rax irem reg) 0 1732 // 1733 // Code sequnce: 1734 // 1735 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1736 // 5: 75 07/08 jne e <normal> 1737 // 7: 33 d2 xor %edx,%edx 1738 // [div >= 8 -> offset + 1] 1739 // [REX_B] 1740 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1741 // c: 74 03/04 je 11 <done> 1742 // 000000000000000e <normal>: 1743 // e: 99 cltd 1744 // [div >= 8 -> offset + 1] 1745 // [REX_B] 1746 // f: f7 f9 idiv $div 1747 // 0000000000000011 <done>: 1748 Label normal; 1749 Label done; 1750 1751 // cmp $0x80000000,%eax 1752 __ cmpl(as_Register(RAX_enc), 0x80000000); 1753 1754 // jne e <normal> 1755 __ jccb(Assembler::notEqual, normal); 1756 1757 // xor %edx,%edx 1758 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1759 1760 // cmp $0xffffffffffffffff,%ecx 1761 __ cmpl($div$$Register, -1); 1762 1763 // je 11 <done> 1764 __ jccb(Assembler::equal, done); 1765 1766 // <normal> 1767 // cltd 1768 __ bind(normal); 1769 __ cdql(); 1770 1771 // idivl 1772 // <done> 1773 __ idivl($div$$Register); 1774 __ bind(done); 1775 %} 1776 1777 enc_class cdqq_enc(no_rax_rdx_RegL div) 1778 %{ 1779 // Full implementation of Java ldiv and lrem; checks for 1780 // special case as described in JVM spec., p.243 & p.271. 1781 // 1782 // normal case special case 1783 // 1784 // input : rax: dividend min_long 1785 // reg: divisor -1 1786 // 1787 // output: rax: quotient (= rax idiv reg) min_long 1788 // rdx: remainder (= rax irem reg) 0 1789 // 1790 // Code sequnce: 1791 // 1792 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1793 // 7: 00 00 80 1794 // a: 48 39 d0 cmp %rdx,%rax 1795 // d: 75 08 jne 17 <normal> 1796 // f: 33 d2 xor %edx,%edx 1797 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1798 // 15: 74 05 je 1c <done> 1799 // 0000000000000017 <normal>: 1800 // 17: 48 99 cqto 1801 // 19: 48 f7 f9 idiv $div 1802 // 000000000000001c <done>: 1803 Label normal; 1804 Label done; 1805 1806 // mov $0x8000000000000000,%rdx 1807 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1808 1809 // cmp %rdx,%rax 1810 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1811 1812 // jne 17 <normal> 1813 __ jccb(Assembler::notEqual, normal); 1814 1815 // xor %edx,%edx 1816 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1817 1818 // cmp $0xffffffffffffffff,$div 1819 __ cmpq($div$$Register, -1); 1820 1821 // je 1e <done> 1822 __ jccb(Assembler::equal, done); 1823 1824 // <normal> 1825 // cqto 1826 __ bind(normal); 1827 __ cdqq(); 1828 1829 // idivq (note: must be emitted by the user of this rule) 1830 // <done> 1831 __ idivq($div$$Register); 1832 __ bind(done); 1833 %} 1834 1835 enc_class enc_PartialSubtypeCheck() 1836 %{ 1837 Register Rrdi = as_Register(RDI_enc); // result register 1838 Register Rrax = as_Register(RAX_enc); // super class 1839 Register Rrcx = as_Register(RCX_enc); // killed 1840 Register Rrsi = as_Register(RSI_enc); // sub class 1841 Label miss; 1842 const bool set_cond_codes = true; 1843 1844 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1845 nullptr, &miss, 1846 /*set_cond_codes:*/ true); 1847 if ($primary) { 1848 __ xorptr(Rrdi, Rrdi); 1849 } 1850 __ bind(miss); 1851 %} 1852 1853 enc_class clear_avx %{ 1854 debug_only(int off0 = __ offset()); 1855 if (generate_vzeroupper(Compile::current())) { 1856 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1857 // Clear upper bits of YMM registers when current compiled code uses 1858 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1859 __ vzeroupper(); 1860 } 1861 debug_only(int off1 = __ offset()); 1862 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1863 %} 1864 1865 enc_class Java_To_Runtime(method meth) %{ 1866 // No relocation needed 1867 if (SCCache::is_on_for_write()) { 1868 // Created runtime_call_type relocation when caching code 1869 __ lea(r10, RuntimeAddress((address)$meth$$method)); 1870 } else { 1871 __ mov64(r10, (int64_t) $meth$$method); 1872 } 1873 __ call(r10); 1874 __ post_call_nop(); 1875 %} 1876 1877 enc_class Java_Static_Call(method meth) 1878 %{ 1879 // JAVA STATIC CALL 1880 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1881 // determine who we intended to call. 1882 if (!_method) { 1883 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1884 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1885 // The NOP here is purely to ensure that eliding a call to 1886 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1887 __ addr_nop_5(); 1888 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1889 } else { 1890 int method_index = resolved_method_index(masm); 1891 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1892 : static_call_Relocation::spec(method_index); 1893 address mark = __ pc(); 1894 int call_offset = __ offset(); 1895 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1896 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1897 // Calls of the same statically bound method can share 1898 // a stub to the interpreter. 1899 __ code()->shared_stub_to_interp_for(_method, call_offset); 1900 } else { 1901 // Emit stubs for static call. 1902 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1903 __ clear_inst_mark(); 1904 if (stub == nullptr) { 1905 ciEnv::current()->record_failure("CodeCache is full"); 1906 return; 1907 } 1908 } 1909 } 1910 __ post_call_nop(); 1911 %} 1912 1913 enc_class Java_Dynamic_Call(method meth) %{ 1914 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1915 __ post_call_nop(); 1916 %} 1917 1918 %} 1919 1920 1921 1922 //----------FRAME-------------------------------------------------------------- 1923 // Definition of frame structure and management information. 1924 // 1925 // S T A C K L A Y O U T Allocators stack-slot number 1926 // | (to get allocators register number 1927 // G Owned by | | v add OptoReg::stack0()) 1928 // r CALLER | | 1929 // o | +--------+ pad to even-align allocators stack-slot 1930 // w V | pad0 | numbers; owned by CALLER 1931 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1932 // h ^ | in | 5 1933 // | | args | 4 Holes in incoming args owned by SELF 1934 // | | | | 3 1935 // | | +--------+ 1936 // V | | old out| Empty on Intel, window on Sparc 1937 // | old |preserve| Must be even aligned. 1938 // | SP-+--------+----> Matcher::_old_SP, even aligned 1939 // | | in | 3 area for Intel ret address 1940 // Owned by |preserve| Empty on Sparc. 1941 // SELF +--------+ 1942 // | | pad2 | 2 pad to align old SP 1943 // | +--------+ 1 1944 // | | locks | 0 1945 // | +--------+----> OptoReg::stack0(), even aligned 1946 // | | pad1 | 11 pad to align new SP 1947 // | +--------+ 1948 // | | | 10 1949 // | | spills | 9 spills 1950 // V | | 8 (pad0 slot for callee) 1951 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1952 // ^ | out | 7 1953 // | | args | 6 Holes in outgoing args owned by CALLEE 1954 // Owned by +--------+ 1955 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1956 // | new |preserve| Must be even-aligned. 1957 // | SP-+--------+----> Matcher::_new_SP, even aligned 1958 // | | | 1959 // 1960 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1961 // known from SELF's arguments and the Java calling convention. 1962 // Region 6-7 is determined per call site. 1963 // Note 2: If the calling convention leaves holes in the incoming argument 1964 // area, those holes are owned by SELF. Holes in the outgoing area 1965 // are owned by the CALLEE. Holes should not be necessary in the 1966 // incoming area, as the Java calling convention is completely under 1967 // the control of the AD file. Doubles can be sorted and packed to 1968 // avoid holes. Holes in the outgoing arguments may be necessary for 1969 // varargs C calling conventions. 1970 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1971 // even aligned with pad0 as needed. 1972 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1973 // region 6-11 is even aligned; it may be padded out more so that 1974 // the region from SP to FP meets the minimum stack alignment. 1975 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1976 // alignment. Region 11, pad1, may be dynamically extended so that 1977 // SP meets the minimum alignment. 1978 1979 frame 1980 %{ 1981 // These three registers define part of the calling convention 1982 // between compiled code and the interpreter. 1983 inline_cache_reg(RAX); // Inline Cache Register 1984 1985 // Optional: name the operand used by cisc-spilling to access 1986 // [stack_pointer + offset] 1987 cisc_spilling_operand_name(indOffset32); 1988 1989 // Number of stack slots consumed by locking an object 1990 sync_stack_slots(2); 1991 1992 // Compiled code's Frame Pointer 1993 frame_pointer(RSP); 1994 1995 // Interpreter stores its frame pointer in a register which is 1996 // stored to the stack by I2CAdaptors. 1997 // I2CAdaptors convert from interpreted java to compiled java. 1998 interpreter_frame_pointer(RBP); 1999 2000 // Stack alignment requirement 2001 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2002 2003 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2004 // for calls to C. Supports the var-args backing area for register parms. 2005 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2006 2007 // The after-PROLOG location of the return address. Location of 2008 // return address specifies a type (REG or STACK) and a number 2009 // representing the register number (i.e. - use a register name) or 2010 // stack slot. 2011 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2012 // Otherwise, it is above the locks and verification slot and alignment word 2013 return_addr(STACK - 2 + 2014 align_up((Compile::current()->in_preserve_stack_slots() + 2015 Compile::current()->fixed_slots()), 2016 stack_alignment_in_slots())); 2017 2018 // Location of compiled Java return values. Same as C for now. 2019 return_value 2020 %{ 2021 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2022 "only return normal values"); 2023 2024 static const int lo[Op_RegL + 1] = { 2025 0, 2026 0, 2027 RAX_num, // Op_RegN 2028 RAX_num, // Op_RegI 2029 RAX_num, // Op_RegP 2030 XMM0_num, // Op_RegF 2031 XMM0_num, // Op_RegD 2032 RAX_num // Op_RegL 2033 }; 2034 static const int hi[Op_RegL + 1] = { 2035 0, 2036 0, 2037 OptoReg::Bad, // Op_RegN 2038 OptoReg::Bad, // Op_RegI 2039 RAX_H_num, // Op_RegP 2040 OptoReg::Bad, // Op_RegF 2041 XMM0b_num, // Op_RegD 2042 RAX_H_num // Op_RegL 2043 }; 2044 // Excluded flags and vector registers. 2045 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2046 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2047 %} 2048 %} 2049 2050 //----------ATTRIBUTES--------------------------------------------------------- 2051 //----------Operand Attributes------------------------------------------------- 2052 op_attrib op_cost(0); // Required cost attribute 2053 2054 //----------Instruction Attributes--------------------------------------------- 2055 ins_attrib ins_cost(100); // Required cost attribute 2056 ins_attrib ins_size(8); // Required size attribute (in bits) 2057 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2058 // a non-matching short branch variant 2059 // of some long branch? 2060 ins_attrib ins_alignment(1); // Required alignment attribute (must 2061 // be a power of 2) specifies the 2062 // alignment that some part of the 2063 // instruction (not necessarily the 2064 // start) requires. If > 1, a 2065 // compute_padding() function must be 2066 // provided for the instruction 2067 2068 //----------OPERANDS----------------------------------------------------------- 2069 // Operand definitions must precede instruction definitions for correct parsing 2070 // in the ADLC because operands constitute user defined types which are used in 2071 // instruction definitions. 2072 2073 //----------Simple Operands---------------------------------------------------- 2074 // Immediate Operands 2075 // Integer Immediate 2076 operand immI() 2077 %{ 2078 match(ConI); 2079 2080 op_cost(10); 2081 format %{ %} 2082 interface(CONST_INTER); 2083 %} 2084 2085 // Constant for test vs zero 2086 operand immI_0() 2087 %{ 2088 predicate(n->get_int() == 0); 2089 match(ConI); 2090 2091 op_cost(0); 2092 format %{ %} 2093 interface(CONST_INTER); 2094 %} 2095 2096 // Constant for increment 2097 operand immI_1() 2098 %{ 2099 predicate(n->get_int() == 1); 2100 match(ConI); 2101 2102 op_cost(0); 2103 format %{ %} 2104 interface(CONST_INTER); 2105 %} 2106 2107 // Constant for decrement 2108 operand immI_M1() 2109 %{ 2110 predicate(n->get_int() == -1); 2111 match(ConI); 2112 2113 op_cost(0); 2114 format %{ %} 2115 interface(CONST_INTER); 2116 %} 2117 2118 operand immI_2() 2119 %{ 2120 predicate(n->get_int() == 2); 2121 match(ConI); 2122 2123 op_cost(0); 2124 format %{ %} 2125 interface(CONST_INTER); 2126 %} 2127 2128 operand immI_4() 2129 %{ 2130 predicate(n->get_int() == 4); 2131 match(ConI); 2132 2133 op_cost(0); 2134 format %{ %} 2135 interface(CONST_INTER); 2136 %} 2137 2138 operand immI_8() 2139 %{ 2140 predicate(n->get_int() == 8); 2141 match(ConI); 2142 2143 op_cost(0); 2144 format %{ %} 2145 interface(CONST_INTER); 2146 %} 2147 2148 // Valid scale values for addressing modes 2149 operand immI2() 2150 %{ 2151 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2152 match(ConI); 2153 2154 format %{ %} 2155 interface(CONST_INTER); 2156 %} 2157 2158 operand immU7() 2159 %{ 2160 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2161 match(ConI); 2162 2163 op_cost(5); 2164 format %{ %} 2165 interface(CONST_INTER); 2166 %} 2167 2168 operand immI8() 2169 %{ 2170 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2171 match(ConI); 2172 2173 op_cost(5); 2174 format %{ %} 2175 interface(CONST_INTER); 2176 %} 2177 2178 operand immU8() 2179 %{ 2180 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2181 match(ConI); 2182 2183 op_cost(5); 2184 format %{ %} 2185 interface(CONST_INTER); 2186 %} 2187 2188 operand immI16() 2189 %{ 2190 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2191 match(ConI); 2192 2193 op_cost(10); 2194 format %{ %} 2195 interface(CONST_INTER); 2196 %} 2197 2198 // Int Immediate non-negative 2199 operand immU31() 2200 %{ 2201 predicate(n->get_int() >= 0); 2202 match(ConI); 2203 2204 op_cost(0); 2205 format %{ %} 2206 interface(CONST_INTER); 2207 %} 2208 2209 // Pointer Immediate 2210 operand immP() 2211 %{ 2212 match(ConP); 2213 2214 op_cost(10); 2215 format %{ %} 2216 interface(CONST_INTER); 2217 %} 2218 2219 // Null Pointer Immediate 2220 operand immP0() 2221 %{ 2222 predicate(n->get_ptr() == 0); 2223 match(ConP); 2224 2225 op_cost(5); 2226 format %{ %} 2227 interface(CONST_INTER); 2228 %} 2229 2230 // Pointer Immediate 2231 operand immN() %{ 2232 match(ConN); 2233 2234 op_cost(10); 2235 format %{ %} 2236 interface(CONST_INTER); 2237 %} 2238 2239 operand immNKlass() %{ 2240 match(ConNKlass); 2241 2242 op_cost(10); 2243 format %{ %} 2244 interface(CONST_INTER); 2245 %} 2246 2247 // Null Pointer Immediate 2248 operand immN0() %{ 2249 predicate(n->get_narrowcon() == 0); 2250 match(ConN); 2251 2252 op_cost(5); 2253 format %{ %} 2254 interface(CONST_INTER); 2255 %} 2256 2257 operand immP31() 2258 %{ 2259 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2260 && (n->get_ptr() >> 31) == 0); 2261 match(ConP); 2262 2263 op_cost(5); 2264 format %{ %} 2265 interface(CONST_INTER); 2266 %} 2267 2268 2269 // Long Immediate 2270 operand immL() 2271 %{ 2272 match(ConL); 2273 2274 op_cost(20); 2275 format %{ %} 2276 interface(CONST_INTER); 2277 %} 2278 2279 // Long Immediate 8-bit 2280 operand immL8() 2281 %{ 2282 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2283 match(ConL); 2284 2285 op_cost(5); 2286 format %{ %} 2287 interface(CONST_INTER); 2288 %} 2289 2290 // Long Immediate 32-bit unsigned 2291 operand immUL32() 2292 %{ 2293 predicate(n->get_long() == (unsigned int) (n->get_long())); 2294 match(ConL); 2295 2296 op_cost(10); 2297 format %{ %} 2298 interface(CONST_INTER); 2299 %} 2300 2301 // Long Immediate 32-bit signed 2302 operand immL32() 2303 %{ 2304 predicate(n->get_long() == (int) (n->get_long())); 2305 match(ConL); 2306 2307 op_cost(15); 2308 format %{ %} 2309 interface(CONST_INTER); 2310 %} 2311 2312 operand immL_Pow2() 2313 %{ 2314 predicate(is_power_of_2((julong)n->get_long())); 2315 match(ConL); 2316 2317 op_cost(15); 2318 format %{ %} 2319 interface(CONST_INTER); 2320 %} 2321 2322 operand immL_NotPow2() 2323 %{ 2324 predicate(is_power_of_2((julong)~n->get_long())); 2325 match(ConL); 2326 2327 op_cost(15); 2328 format %{ %} 2329 interface(CONST_INTER); 2330 %} 2331 2332 // Long Immediate zero 2333 operand immL0() 2334 %{ 2335 predicate(n->get_long() == 0L); 2336 match(ConL); 2337 2338 op_cost(10); 2339 format %{ %} 2340 interface(CONST_INTER); 2341 %} 2342 2343 // Constant for increment 2344 operand immL1() 2345 %{ 2346 predicate(n->get_long() == 1); 2347 match(ConL); 2348 2349 format %{ %} 2350 interface(CONST_INTER); 2351 %} 2352 2353 // Constant for decrement 2354 operand immL_M1() 2355 %{ 2356 predicate(n->get_long() == -1); 2357 match(ConL); 2358 2359 format %{ %} 2360 interface(CONST_INTER); 2361 %} 2362 2363 // Long Immediate: low 32-bit mask 2364 operand immL_32bits() 2365 %{ 2366 predicate(n->get_long() == 0xFFFFFFFFL); 2367 match(ConL); 2368 op_cost(20); 2369 2370 format %{ %} 2371 interface(CONST_INTER); 2372 %} 2373 2374 // Int Immediate: 2^n-1, positive 2375 operand immI_Pow2M1() 2376 %{ 2377 predicate((n->get_int() > 0) 2378 && is_power_of_2((juint)n->get_int() + 1)); 2379 match(ConI); 2380 2381 op_cost(20); 2382 format %{ %} 2383 interface(CONST_INTER); 2384 %} 2385 2386 // Float Immediate zero 2387 operand immF0() 2388 %{ 2389 predicate(jint_cast(n->getf()) == 0); 2390 match(ConF); 2391 2392 op_cost(5); 2393 format %{ %} 2394 interface(CONST_INTER); 2395 %} 2396 2397 // Float Immediate 2398 operand immF() 2399 %{ 2400 match(ConF); 2401 2402 op_cost(15); 2403 format %{ %} 2404 interface(CONST_INTER); 2405 %} 2406 2407 // Double Immediate zero 2408 operand immD0() 2409 %{ 2410 predicate(jlong_cast(n->getd()) == 0); 2411 match(ConD); 2412 2413 op_cost(5); 2414 format %{ %} 2415 interface(CONST_INTER); 2416 %} 2417 2418 // Double Immediate 2419 operand immD() 2420 %{ 2421 match(ConD); 2422 2423 op_cost(15); 2424 format %{ %} 2425 interface(CONST_INTER); 2426 %} 2427 2428 // Immediates for special shifts (sign extend) 2429 2430 // Constants for increment 2431 operand immI_16() 2432 %{ 2433 predicate(n->get_int() == 16); 2434 match(ConI); 2435 2436 format %{ %} 2437 interface(CONST_INTER); 2438 %} 2439 2440 operand immI_24() 2441 %{ 2442 predicate(n->get_int() == 24); 2443 match(ConI); 2444 2445 format %{ %} 2446 interface(CONST_INTER); 2447 %} 2448 2449 // Constant for byte-wide masking 2450 operand immI_255() 2451 %{ 2452 predicate(n->get_int() == 255); 2453 match(ConI); 2454 2455 format %{ %} 2456 interface(CONST_INTER); 2457 %} 2458 2459 // Constant for short-wide masking 2460 operand immI_65535() 2461 %{ 2462 predicate(n->get_int() == 65535); 2463 match(ConI); 2464 2465 format %{ %} 2466 interface(CONST_INTER); 2467 %} 2468 2469 // Constant for byte-wide masking 2470 operand immL_255() 2471 %{ 2472 predicate(n->get_long() == 255); 2473 match(ConL); 2474 2475 format %{ %} 2476 interface(CONST_INTER); 2477 %} 2478 2479 // Constant for short-wide masking 2480 operand immL_65535() 2481 %{ 2482 predicate(n->get_long() == 65535); 2483 match(ConL); 2484 2485 format %{ %} 2486 interface(CONST_INTER); 2487 %} 2488 2489 // AOT Runtime Constants Address 2490 operand immAOTRuntimeConstantsAddress() 2491 %{ 2492 // Check if the address is in the range of AOT Runtime Constants 2493 predicate(AOTRuntimeConstants::contains((address)(n->get_ptr()))); 2494 match(ConP); 2495 2496 op_cost(0); 2497 format %{ %} 2498 interface(CONST_INTER); 2499 %} 2500 2501 operand kReg() 2502 %{ 2503 constraint(ALLOC_IN_RC(vectmask_reg)); 2504 match(RegVectMask); 2505 format %{%} 2506 interface(REG_INTER); 2507 %} 2508 2509 // Register Operands 2510 // Integer Register 2511 operand rRegI() 2512 %{ 2513 constraint(ALLOC_IN_RC(int_reg)); 2514 match(RegI); 2515 2516 match(rax_RegI); 2517 match(rbx_RegI); 2518 match(rcx_RegI); 2519 match(rdx_RegI); 2520 match(rdi_RegI); 2521 2522 format %{ %} 2523 interface(REG_INTER); 2524 %} 2525 2526 // Special Registers 2527 operand rax_RegI() 2528 %{ 2529 constraint(ALLOC_IN_RC(int_rax_reg)); 2530 match(RegI); 2531 match(rRegI); 2532 2533 format %{ "RAX" %} 2534 interface(REG_INTER); 2535 %} 2536 2537 // Special Registers 2538 operand rbx_RegI() 2539 %{ 2540 constraint(ALLOC_IN_RC(int_rbx_reg)); 2541 match(RegI); 2542 match(rRegI); 2543 2544 format %{ "RBX" %} 2545 interface(REG_INTER); 2546 %} 2547 2548 operand rcx_RegI() 2549 %{ 2550 constraint(ALLOC_IN_RC(int_rcx_reg)); 2551 match(RegI); 2552 match(rRegI); 2553 2554 format %{ "RCX" %} 2555 interface(REG_INTER); 2556 %} 2557 2558 operand rdx_RegI() 2559 %{ 2560 constraint(ALLOC_IN_RC(int_rdx_reg)); 2561 match(RegI); 2562 match(rRegI); 2563 2564 format %{ "RDX" %} 2565 interface(REG_INTER); 2566 %} 2567 2568 operand rdi_RegI() 2569 %{ 2570 constraint(ALLOC_IN_RC(int_rdi_reg)); 2571 match(RegI); 2572 match(rRegI); 2573 2574 format %{ "RDI" %} 2575 interface(REG_INTER); 2576 %} 2577 2578 operand no_rax_rdx_RegI() 2579 %{ 2580 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2581 match(RegI); 2582 match(rbx_RegI); 2583 match(rcx_RegI); 2584 match(rdi_RegI); 2585 2586 format %{ %} 2587 interface(REG_INTER); 2588 %} 2589 2590 operand no_rbp_r13_RegI() 2591 %{ 2592 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2593 match(RegI); 2594 match(rRegI); 2595 match(rax_RegI); 2596 match(rbx_RegI); 2597 match(rcx_RegI); 2598 match(rdx_RegI); 2599 match(rdi_RegI); 2600 2601 format %{ %} 2602 interface(REG_INTER); 2603 %} 2604 2605 // Pointer Register 2606 operand any_RegP() 2607 %{ 2608 constraint(ALLOC_IN_RC(any_reg)); 2609 match(RegP); 2610 match(rax_RegP); 2611 match(rbx_RegP); 2612 match(rdi_RegP); 2613 match(rsi_RegP); 2614 match(rbp_RegP); 2615 match(r15_RegP); 2616 match(rRegP); 2617 2618 format %{ %} 2619 interface(REG_INTER); 2620 %} 2621 2622 operand rRegP() 2623 %{ 2624 constraint(ALLOC_IN_RC(ptr_reg)); 2625 match(RegP); 2626 match(rax_RegP); 2627 match(rbx_RegP); 2628 match(rdi_RegP); 2629 match(rsi_RegP); 2630 match(rbp_RegP); // See Q&A below about 2631 match(r15_RegP); // r15_RegP and rbp_RegP. 2632 2633 format %{ %} 2634 interface(REG_INTER); 2635 %} 2636 2637 operand rRegN() %{ 2638 constraint(ALLOC_IN_RC(int_reg)); 2639 match(RegN); 2640 2641 format %{ %} 2642 interface(REG_INTER); 2643 %} 2644 2645 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2646 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2647 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2648 // The output of an instruction is controlled by the allocator, which respects 2649 // register class masks, not match rules. Unless an instruction mentions 2650 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2651 // by the allocator as an input. 2652 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2653 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2654 // result, RBP is not included in the output of the instruction either. 2655 2656 // This operand is not allowed to use RBP even if 2657 // RBP is not used to hold the frame pointer. 2658 operand no_rbp_RegP() 2659 %{ 2660 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2661 match(RegP); 2662 match(rbx_RegP); 2663 match(rsi_RegP); 2664 match(rdi_RegP); 2665 2666 format %{ %} 2667 interface(REG_INTER); 2668 %} 2669 2670 // Special Registers 2671 // Return a pointer value 2672 operand rax_RegP() 2673 %{ 2674 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2675 match(RegP); 2676 match(rRegP); 2677 2678 format %{ %} 2679 interface(REG_INTER); 2680 %} 2681 2682 // Special Registers 2683 // Return a compressed pointer value 2684 operand rax_RegN() 2685 %{ 2686 constraint(ALLOC_IN_RC(int_rax_reg)); 2687 match(RegN); 2688 match(rRegN); 2689 2690 format %{ %} 2691 interface(REG_INTER); 2692 %} 2693 2694 // Used in AtomicAdd 2695 operand rbx_RegP() 2696 %{ 2697 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2698 match(RegP); 2699 match(rRegP); 2700 2701 format %{ %} 2702 interface(REG_INTER); 2703 %} 2704 2705 operand rsi_RegP() 2706 %{ 2707 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2708 match(RegP); 2709 match(rRegP); 2710 2711 format %{ %} 2712 interface(REG_INTER); 2713 %} 2714 2715 operand rbp_RegP() 2716 %{ 2717 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2718 match(RegP); 2719 match(rRegP); 2720 2721 format %{ %} 2722 interface(REG_INTER); 2723 %} 2724 2725 // Used in rep stosq 2726 operand rdi_RegP() 2727 %{ 2728 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2729 match(RegP); 2730 match(rRegP); 2731 2732 format %{ %} 2733 interface(REG_INTER); 2734 %} 2735 2736 operand r15_RegP() 2737 %{ 2738 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2739 match(RegP); 2740 match(rRegP); 2741 2742 format %{ %} 2743 interface(REG_INTER); 2744 %} 2745 2746 operand rRegL() 2747 %{ 2748 constraint(ALLOC_IN_RC(long_reg)); 2749 match(RegL); 2750 match(rax_RegL); 2751 match(rdx_RegL); 2752 2753 format %{ %} 2754 interface(REG_INTER); 2755 %} 2756 2757 // Special Registers 2758 operand no_rax_rdx_RegL() 2759 %{ 2760 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2761 match(RegL); 2762 match(rRegL); 2763 2764 format %{ %} 2765 interface(REG_INTER); 2766 %} 2767 2768 operand rax_RegL() 2769 %{ 2770 constraint(ALLOC_IN_RC(long_rax_reg)); 2771 match(RegL); 2772 match(rRegL); 2773 2774 format %{ "RAX" %} 2775 interface(REG_INTER); 2776 %} 2777 2778 operand rcx_RegL() 2779 %{ 2780 constraint(ALLOC_IN_RC(long_rcx_reg)); 2781 match(RegL); 2782 match(rRegL); 2783 2784 format %{ %} 2785 interface(REG_INTER); 2786 %} 2787 2788 operand rdx_RegL() 2789 %{ 2790 constraint(ALLOC_IN_RC(long_rdx_reg)); 2791 match(RegL); 2792 match(rRegL); 2793 2794 format %{ %} 2795 interface(REG_INTER); 2796 %} 2797 2798 operand r11_RegL() 2799 %{ 2800 constraint(ALLOC_IN_RC(long_r11_reg)); 2801 match(RegL); 2802 match(rRegL); 2803 2804 format %{ %} 2805 interface(REG_INTER); 2806 %} 2807 2808 operand no_rbp_r13_RegL() 2809 %{ 2810 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2811 match(RegL); 2812 match(rRegL); 2813 match(rax_RegL); 2814 match(rcx_RegL); 2815 match(rdx_RegL); 2816 2817 format %{ %} 2818 interface(REG_INTER); 2819 %} 2820 2821 // Flags register, used as output of compare instructions 2822 operand rFlagsReg() 2823 %{ 2824 constraint(ALLOC_IN_RC(int_flags)); 2825 match(RegFlags); 2826 2827 format %{ "RFLAGS" %} 2828 interface(REG_INTER); 2829 %} 2830 2831 // Flags register, used as output of FLOATING POINT compare instructions 2832 operand rFlagsRegU() 2833 %{ 2834 constraint(ALLOC_IN_RC(int_flags)); 2835 match(RegFlags); 2836 2837 format %{ "RFLAGS_U" %} 2838 interface(REG_INTER); 2839 %} 2840 2841 operand rFlagsRegUCF() %{ 2842 constraint(ALLOC_IN_RC(int_flags)); 2843 match(RegFlags); 2844 predicate(false); 2845 2846 format %{ "RFLAGS_U_CF" %} 2847 interface(REG_INTER); 2848 %} 2849 2850 // Float register operands 2851 operand regF() %{ 2852 constraint(ALLOC_IN_RC(float_reg)); 2853 match(RegF); 2854 2855 format %{ %} 2856 interface(REG_INTER); 2857 %} 2858 2859 // Float register operands 2860 operand legRegF() %{ 2861 constraint(ALLOC_IN_RC(float_reg_legacy)); 2862 match(RegF); 2863 2864 format %{ %} 2865 interface(REG_INTER); 2866 %} 2867 2868 // Float register operands 2869 operand vlRegF() %{ 2870 constraint(ALLOC_IN_RC(float_reg_vl)); 2871 match(RegF); 2872 2873 format %{ %} 2874 interface(REG_INTER); 2875 %} 2876 2877 // Double register operands 2878 operand regD() %{ 2879 constraint(ALLOC_IN_RC(double_reg)); 2880 match(RegD); 2881 2882 format %{ %} 2883 interface(REG_INTER); 2884 %} 2885 2886 // Double register operands 2887 operand legRegD() %{ 2888 constraint(ALLOC_IN_RC(double_reg_legacy)); 2889 match(RegD); 2890 2891 format %{ %} 2892 interface(REG_INTER); 2893 %} 2894 2895 // Double register operands 2896 operand vlRegD() %{ 2897 constraint(ALLOC_IN_RC(double_reg_vl)); 2898 match(RegD); 2899 2900 format %{ %} 2901 interface(REG_INTER); 2902 %} 2903 2904 //----------Memory Operands---------------------------------------------------- 2905 // Direct Memory Operand 2906 // operand direct(immP addr) 2907 // %{ 2908 // match(addr); 2909 2910 // format %{ "[$addr]" %} 2911 // interface(MEMORY_INTER) %{ 2912 // base(0xFFFFFFFF); 2913 // index(0x4); 2914 // scale(0x0); 2915 // disp($addr); 2916 // %} 2917 // %} 2918 2919 // Indirect Memory Operand 2920 operand indirect(any_RegP reg) 2921 %{ 2922 constraint(ALLOC_IN_RC(ptr_reg)); 2923 match(reg); 2924 2925 format %{ "[$reg]" %} 2926 interface(MEMORY_INTER) %{ 2927 base($reg); 2928 index(0x4); 2929 scale(0x0); 2930 disp(0x0); 2931 %} 2932 %} 2933 2934 // Indirect Memory Plus Short Offset Operand 2935 operand indOffset8(any_RegP reg, immL8 off) 2936 %{ 2937 constraint(ALLOC_IN_RC(ptr_reg)); 2938 match(AddP reg off); 2939 2940 format %{ "[$reg + $off (8-bit)]" %} 2941 interface(MEMORY_INTER) %{ 2942 base($reg); 2943 index(0x4); 2944 scale(0x0); 2945 disp($off); 2946 %} 2947 %} 2948 2949 // Indirect Memory Plus Long Offset Operand 2950 operand indOffset32(any_RegP reg, immL32 off) 2951 %{ 2952 constraint(ALLOC_IN_RC(ptr_reg)); 2953 match(AddP reg off); 2954 2955 format %{ "[$reg + $off (32-bit)]" %} 2956 interface(MEMORY_INTER) %{ 2957 base($reg); 2958 index(0x4); 2959 scale(0x0); 2960 disp($off); 2961 %} 2962 %} 2963 2964 // Indirect Memory Plus Index Register Plus Offset Operand 2965 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2966 %{ 2967 constraint(ALLOC_IN_RC(ptr_reg)); 2968 match(AddP (AddP reg lreg) off); 2969 2970 op_cost(10); 2971 format %{"[$reg + $off + $lreg]" %} 2972 interface(MEMORY_INTER) %{ 2973 base($reg); 2974 index($lreg); 2975 scale(0x0); 2976 disp($off); 2977 %} 2978 %} 2979 2980 // Indirect Memory Plus Index Register Plus Offset Operand 2981 operand indIndex(any_RegP reg, rRegL lreg) 2982 %{ 2983 constraint(ALLOC_IN_RC(ptr_reg)); 2984 match(AddP reg lreg); 2985 2986 op_cost(10); 2987 format %{"[$reg + $lreg]" %} 2988 interface(MEMORY_INTER) %{ 2989 base($reg); 2990 index($lreg); 2991 scale(0x0); 2992 disp(0x0); 2993 %} 2994 %} 2995 2996 // Indirect Memory Times Scale Plus Index Register 2997 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2998 %{ 2999 constraint(ALLOC_IN_RC(ptr_reg)); 3000 match(AddP reg (LShiftL lreg scale)); 3001 3002 op_cost(10); 3003 format %{"[$reg + $lreg << $scale]" %} 3004 interface(MEMORY_INTER) %{ 3005 base($reg); 3006 index($lreg); 3007 scale($scale); 3008 disp(0x0); 3009 %} 3010 %} 3011 3012 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3013 %{ 3014 constraint(ALLOC_IN_RC(ptr_reg)); 3015 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3016 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3017 3018 op_cost(10); 3019 format %{"[$reg + pos $idx << $scale]" %} 3020 interface(MEMORY_INTER) %{ 3021 base($reg); 3022 index($idx); 3023 scale($scale); 3024 disp(0x0); 3025 %} 3026 %} 3027 3028 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3029 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3030 %{ 3031 constraint(ALLOC_IN_RC(ptr_reg)); 3032 match(AddP (AddP reg (LShiftL lreg scale)) off); 3033 3034 op_cost(10); 3035 format %{"[$reg + $off + $lreg << $scale]" %} 3036 interface(MEMORY_INTER) %{ 3037 base($reg); 3038 index($lreg); 3039 scale($scale); 3040 disp($off); 3041 %} 3042 %} 3043 3044 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3045 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3046 %{ 3047 constraint(ALLOC_IN_RC(ptr_reg)); 3048 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3049 match(AddP (AddP reg (ConvI2L idx)) off); 3050 3051 op_cost(10); 3052 format %{"[$reg + $off + $idx]" %} 3053 interface(MEMORY_INTER) %{ 3054 base($reg); 3055 index($idx); 3056 scale(0x0); 3057 disp($off); 3058 %} 3059 %} 3060 3061 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3062 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3063 %{ 3064 constraint(ALLOC_IN_RC(ptr_reg)); 3065 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3066 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3067 3068 op_cost(10); 3069 format %{"[$reg + $off + $idx << $scale]" %} 3070 interface(MEMORY_INTER) %{ 3071 base($reg); 3072 index($idx); 3073 scale($scale); 3074 disp($off); 3075 %} 3076 %} 3077 3078 // Indirect Narrow Oop Plus Offset Operand 3079 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3080 // we can't free r12 even with CompressedOops::base() == nullptr. 3081 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3082 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3083 constraint(ALLOC_IN_RC(ptr_reg)); 3084 match(AddP (DecodeN reg) off); 3085 3086 op_cost(10); 3087 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3088 interface(MEMORY_INTER) %{ 3089 base(0xc); // R12 3090 index($reg); 3091 scale(0x3); 3092 disp($off); 3093 %} 3094 %} 3095 3096 // Indirect Memory Operand 3097 operand indirectNarrow(rRegN reg) 3098 %{ 3099 predicate(CompressedOops::shift() == 0); 3100 constraint(ALLOC_IN_RC(ptr_reg)); 3101 match(DecodeN reg); 3102 3103 format %{ "[$reg]" %} 3104 interface(MEMORY_INTER) %{ 3105 base($reg); 3106 index(0x4); 3107 scale(0x0); 3108 disp(0x0); 3109 %} 3110 %} 3111 3112 // Indirect Memory Plus Short Offset Operand 3113 operand indOffset8Narrow(rRegN reg, immL8 off) 3114 %{ 3115 predicate(CompressedOops::shift() == 0); 3116 constraint(ALLOC_IN_RC(ptr_reg)); 3117 match(AddP (DecodeN reg) off); 3118 3119 format %{ "[$reg + $off (8-bit)]" %} 3120 interface(MEMORY_INTER) %{ 3121 base($reg); 3122 index(0x4); 3123 scale(0x0); 3124 disp($off); 3125 %} 3126 %} 3127 3128 // Indirect Memory Plus Long Offset Operand 3129 operand indOffset32Narrow(rRegN reg, immL32 off) 3130 %{ 3131 predicate(CompressedOops::shift() == 0); 3132 constraint(ALLOC_IN_RC(ptr_reg)); 3133 match(AddP (DecodeN reg) off); 3134 3135 format %{ "[$reg + $off (32-bit)]" %} 3136 interface(MEMORY_INTER) %{ 3137 base($reg); 3138 index(0x4); 3139 scale(0x0); 3140 disp($off); 3141 %} 3142 %} 3143 3144 // Indirect Memory Plus Index Register Plus Offset Operand 3145 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3146 %{ 3147 predicate(CompressedOops::shift() == 0); 3148 constraint(ALLOC_IN_RC(ptr_reg)); 3149 match(AddP (AddP (DecodeN reg) lreg) off); 3150 3151 op_cost(10); 3152 format %{"[$reg + $off + $lreg]" %} 3153 interface(MEMORY_INTER) %{ 3154 base($reg); 3155 index($lreg); 3156 scale(0x0); 3157 disp($off); 3158 %} 3159 %} 3160 3161 // Indirect Memory Plus Index Register Plus Offset Operand 3162 operand indIndexNarrow(rRegN reg, rRegL lreg) 3163 %{ 3164 predicate(CompressedOops::shift() == 0); 3165 constraint(ALLOC_IN_RC(ptr_reg)); 3166 match(AddP (DecodeN reg) lreg); 3167 3168 op_cost(10); 3169 format %{"[$reg + $lreg]" %} 3170 interface(MEMORY_INTER) %{ 3171 base($reg); 3172 index($lreg); 3173 scale(0x0); 3174 disp(0x0); 3175 %} 3176 %} 3177 3178 // Indirect Memory Times Scale Plus Index Register 3179 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3180 %{ 3181 predicate(CompressedOops::shift() == 0); 3182 constraint(ALLOC_IN_RC(ptr_reg)); 3183 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3184 3185 op_cost(10); 3186 format %{"[$reg + $lreg << $scale]" %} 3187 interface(MEMORY_INTER) %{ 3188 base($reg); 3189 index($lreg); 3190 scale($scale); 3191 disp(0x0); 3192 %} 3193 %} 3194 3195 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3196 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3197 %{ 3198 predicate(CompressedOops::shift() == 0); 3199 constraint(ALLOC_IN_RC(ptr_reg)); 3200 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3201 3202 op_cost(10); 3203 format %{"[$reg + $off + $lreg << $scale]" %} 3204 interface(MEMORY_INTER) %{ 3205 base($reg); 3206 index($lreg); 3207 scale($scale); 3208 disp($off); 3209 %} 3210 %} 3211 3212 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3213 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3214 %{ 3215 constraint(ALLOC_IN_RC(ptr_reg)); 3216 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3217 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3218 3219 op_cost(10); 3220 format %{"[$reg + $off + $idx]" %} 3221 interface(MEMORY_INTER) %{ 3222 base($reg); 3223 index($idx); 3224 scale(0x0); 3225 disp($off); 3226 %} 3227 %} 3228 3229 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3230 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3231 %{ 3232 constraint(ALLOC_IN_RC(ptr_reg)); 3233 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3234 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3235 3236 op_cost(10); 3237 format %{"[$reg + $off + $idx << $scale]" %} 3238 interface(MEMORY_INTER) %{ 3239 base($reg); 3240 index($idx); 3241 scale($scale); 3242 disp($off); 3243 %} 3244 %} 3245 3246 //----------Special Memory Operands-------------------------------------------- 3247 // Stack Slot Operand - This operand is used for loading and storing temporary 3248 // values on the stack where a match requires a value to 3249 // flow through memory. 3250 operand stackSlotP(sRegP reg) 3251 %{ 3252 constraint(ALLOC_IN_RC(stack_slots)); 3253 // No match rule because this operand is only generated in matching 3254 3255 format %{ "[$reg]" %} 3256 interface(MEMORY_INTER) %{ 3257 base(0x4); // RSP 3258 index(0x4); // No Index 3259 scale(0x0); // No Scale 3260 disp($reg); // Stack Offset 3261 %} 3262 %} 3263 3264 operand stackSlotI(sRegI reg) 3265 %{ 3266 constraint(ALLOC_IN_RC(stack_slots)); 3267 // No match rule because this operand is only generated in matching 3268 3269 format %{ "[$reg]" %} 3270 interface(MEMORY_INTER) %{ 3271 base(0x4); // RSP 3272 index(0x4); // No Index 3273 scale(0x0); // No Scale 3274 disp($reg); // Stack Offset 3275 %} 3276 %} 3277 3278 operand stackSlotF(sRegF reg) 3279 %{ 3280 constraint(ALLOC_IN_RC(stack_slots)); 3281 // No match rule because this operand is only generated in matching 3282 3283 format %{ "[$reg]" %} 3284 interface(MEMORY_INTER) %{ 3285 base(0x4); // RSP 3286 index(0x4); // No Index 3287 scale(0x0); // No Scale 3288 disp($reg); // Stack Offset 3289 %} 3290 %} 3291 3292 operand stackSlotD(sRegD reg) 3293 %{ 3294 constraint(ALLOC_IN_RC(stack_slots)); 3295 // No match rule because this operand is only generated in matching 3296 3297 format %{ "[$reg]" %} 3298 interface(MEMORY_INTER) %{ 3299 base(0x4); // RSP 3300 index(0x4); // No Index 3301 scale(0x0); // No Scale 3302 disp($reg); // Stack Offset 3303 %} 3304 %} 3305 operand stackSlotL(sRegL reg) 3306 %{ 3307 constraint(ALLOC_IN_RC(stack_slots)); 3308 // No match rule because this operand is only generated in matching 3309 3310 format %{ "[$reg]" %} 3311 interface(MEMORY_INTER) %{ 3312 base(0x4); // RSP 3313 index(0x4); // No Index 3314 scale(0x0); // No Scale 3315 disp($reg); // Stack Offset 3316 %} 3317 %} 3318 3319 //----------Conditional Branch Operands---------------------------------------- 3320 // Comparison Op - This is the operation of the comparison, and is limited to 3321 // the following set of codes: 3322 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3323 // 3324 // Other attributes of the comparison, such as unsignedness, are specified 3325 // by the comparison instruction that sets a condition code flags register. 3326 // That result is represented by a flags operand whose subtype is appropriate 3327 // to the unsignedness (etc.) of the comparison. 3328 // 3329 // Later, the instruction which matches both the Comparison Op (a Bool) and 3330 // the flags (produced by the Cmp) specifies the coding of the comparison op 3331 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3332 3333 // Comparison Code 3334 operand cmpOp() 3335 %{ 3336 match(Bool); 3337 3338 format %{ "" %} 3339 interface(COND_INTER) %{ 3340 equal(0x4, "e"); 3341 not_equal(0x5, "ne"); 3342 less(0xC, "l"); 3343 greater_equal(0xD, "ge"); 3344 less_equal(0xE, "le"); 3345 greater(0xF, "g"); 3346 overflow(0x0, "o"); 3347 no_overflow(0x1, "no"); 3348 %} 3349 %} 3350 3351 // Comparison Code, unsigned compare. Used by FP also, with 3352 // C2 (unordered) turned into GT or LT already. The other bits 3353 // C0 and C3 are turned into Carry & Zero flags. 3354 operand cmpOpU() 3355 %{ 3356 match(Bool); 3357 3358 format %{ "" %} 3359 interface(COND_INTER) %{ 3360 equal(0x4, "e"); 3361 not_equal(0x5, "ne"); 3362 less(0x2, "b"); 3363 greater_equal(0x3, "ae"); 3364 less_equal(0x6, "be"); 3365 greater(0x7, "a"); 3366 overflow(0x0, "o"); 3367 no_overflow(0x1, "no"); 3368 %} 3369 %} 3370 3371 3372 // Floating comparisons that don't require any fixup for the unordered case, 3373 // If both inputs of the comparison are the same, ZF is always set so we 3374 // don't need to use cmpOpUCF2 for eq/ne 3375 operand cmpOpUCF() %{ 3376 match(Bool); 3377 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3378 n->as_Bool()->_test._test == BoolTest::ge || 3379 n->as_Bool()->_test._test == BoolTest::le || 3380 n->as_Bool()->_test._test == BoolTest::gt || 3381 n->in(1)->in(1) == n->in(1)->in(2)); 3382 format %{ "" %} 3383 interface(COND_INTER) %{ 3384 equal(0xb, "np"); 3385 not_equal(0xa, "p"); 3386 less(0x2, "b"); 3387 greater_equal(0x3, "ae"); 3388 less_equal(0x6, "be"); 3389 greater(0x7, "a"); 3390 overflow(0x0, "o"); 3391 no_overflow(0x1, "no"); 3392 %} 3393 %} 3394 3395 3396 // Floating comparisons that can be fixed up with extra conditional jumps 3397 operand cmpOpUCF2() %{ 3398 match(Bool); 3399 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3400 n->as_Bool()->_test._test == BoolTest::eq) && 3401 n->in(1)->in(1) != n->in(1)->in(2)); 3402 format %{ "" %} 3403 interface(COND_INTER) %{ 3404 equal(0x4, "e"); 3405 not_equal(0x5, "ne"); 3406 less(0x2, "b"); 3407 greater_equal(0x3, "ae"); 3408 less_equal(0x6, "be"); 3409 greater(0x7, "a"); 3410 overflow(0x0, "o"); 3411 no_overflow(0x1, "no"); 3412 %} 3413 %} 3414 3415 //----------OPERAND CLASSES---------------------------------------------------- 3416 // Operand Classes are groups of operands that are used as to simplify 3417 // instruction definitions by not requiring the AD writer to specify separate 3418 // instructions for every form of operand when the instruction accepts 3419 // multiple operand types with the same basic encoding and format. The classic 3420 // case of this is memory operands. 3421 3422 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3423 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3424 indCompressedOopOffset, 3425 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3426 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3427 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3428 3429 //----------PIPELINE----------------------------------------------------------- 3430 // Rules which define the behavior of the target architectures pipeline. 3431 pipeline %{ 3432 3433 //----------ATTRIBUTES--------------------------------------------------------- 3434 attributes %{ 3435 variable_size_instructions; // Fixed size instructions 3436 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3437 instruction_unit_size = 1; // An instruction is 1 bytes long 3438 instruction_fetch_unit_size = 16; // The processor fetches one line 3439 instruction_fetch_units = 1; // of 16 bytes 3440 3441 // List of nop instructions 3442 nops( MachNop ); 3443 %} 3444 3445 //----------RESOURCES---------------------------------------------------------- 3446 // Resources are the functional units available to the machine 3447 3448 // Generic P2/P3 pipeline 3449 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3450 // 3 instructions decoded per cycle. 3451 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3452 // 3 ALU op, only ALU0 handles mul instructions. 3453 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3454 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3455 BR, FPU, 3456 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3457 3458 //----------PIPELINE DESCRIPTION----------------------------------------------- 3459 // Pipeline Description specifies the stages in the machine's pipeline 3460 3461 // Generic P2/P3 pipeline 3462 pipe_desc(S0, S1, S2, S3, S4, S5); 3463 3464 //----------PIPELINE CLASSES--------------------------------------------------- 3465 // Pipeline Classes describe the stages in which input and output are 3466 // referenced by the hardware pipeline. 3467 3468 // Naming convention: ialu or fpu 3469 // Then: _reg 3470 // Then: _reg if there is a 2nd register 3471 // Then: _long if it's a pair of instructions implementing a long 3472 // Then: _fat if it requires the big decoder 3473 // Or: _mem if it requires the big decoder and a memory unit. 3474 3475 // Integer ALU reg operation 3476 pipe_class ialu_reg(rRegI dst) 3477 %{ 3478 single_instruction; 3479 dst : S4(write); 3480 dst : S3(read); 3481 DECODE : S0; // any decoder 3482 ALU : S3; // any alu 3483 %} 3484 3485 // Long ALU reg operation 3486 pipe_class ialu_reg_long(rRegL dst) 3487 %{ 3488 instruction_count(2); 3489 dst : S4(write); 3490 dst : S3(read); 3491 DECODE : S0(2); // any 2 decoders 3492 ALU : S3(2); // both alus 3493 %} 3494 3495 // Integer ALU reg operation using big decoder 3496 pipe_class ialu_reg_fat(rRegI dst) 3497 %{ 3498 single_instruction; 3499 dst : S4(write); 3500 dst : S3(read); 3501 D0 : S0; // big decoder only 3502 ALU : S3; // any alu 3503 %} 3504 3505 // Integer ALU reg-reg operation 3506 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3507 %{ 3508 single_instruction; 3509 dst : S4(write); 3510 src : S3(read); 3511 DECODE : S0; // any decoder 3512 ALU : S3; // any alu 3513 %} 3514 3515 // Integer ALU reg-reg operation 3516 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3517 %{ 3518 single_instruction; 3519 dst : S4(write); 3520 src : S3(read); 3521 D0 : S0; // big decoder only 3522 ALU : S3; // any alu 3523 %} 3524 3525 // Integer ALU reg-mem operation 3526 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3527 %{ 3528 single_instruction; 3529 dst : S5(write); 3530 mem : S3(read); 3531 D0 : S0; // big decoder only 3532 ALU : S4; // any alu 3533 MEM : S3; // any mem 3534 %} 3535 3536 // Integer mem operation (prefetch) 3537 pipe_class ialu_mem(memory mem) 3538 %{ 3539 single_instruction; 3540 mem : S3(read); 3541 D0 : S0; // big decoder only 3542 MEM : S3; // any mem 3543 %} 3544 3545 // Integer Store to Memory 3546 pipe_class ialu_mem_reg(memory mem, rRegI src) 3547 %{ 3548 single_instruction; 3549 mem : S3(read); 3550 src : S5(read); 3551 D0 : S0; // big decoder only 3552 ALU : S4; // any alu 3553 MEM : S3; 3554 %} 3555 3556 // // Long Store to Memory 3557 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3558 // %{ 3559 // instruction_count(2); 3560 // mem : S3(read); 3561 // src : S5(read); 3562 // D0 : S0(2); // big decoder only; twice 3563 // ALU : S4(2); // any 2 alus 3564 // MEM : S3(2); // Both mems 3565 // %} 3566 3567 // Integer Store to Memory 3568 pipe_class ialu_mem_imm(memory mem) 3569 %{ 3570 single_instruction; 3571 mem : S3(read); 3572 D0 : S0; // big decoder only 3573 ALU : S4; // any alu 3574 MEM : S3; 3575 %} 3576 3577 // Integer ALU0 reg-reg operation 3578 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3579 %{ 3580 single_instruction; 3581 dst : S4(write); 3582 src : S3(read); 3583 D0 : S0; // Big decoder only 3584 ALU0 : S3; // only alu0 3585 %} 3586 3587 // Integer ALU0 reg-mem operation 3588 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3589 %{ 3590 single_instruction; 3591 dst : S5(write); 3592 mem : S3(read); 3593 D0 : S0; // big decoder only 3594 ALU0 : S4; // ALU0 only 3595 MEM : S3; // any mem 3596 %} 3597 3598 // Integer ALU reg-reg operation 3599 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3600 %{ 3601 single_instruction; 3602 cr : S4(write); 3603 src1 : S3(read); 3604 src2 : S3(read); 3605 DECODE : S0; // any decoder 3606 ALU : S3; // any alu 3607 %} 3608 3609 // Integer ALU reg-imm operation 3610 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3611 %{ 3612 single_instruction; 3613 cr : S4(write); 3614 src1 : S3(read); 3615 DECODE : S0; // any decoder 3616 ALU : S3; // any alu 3617 %} 3618 3619 // Integer ALU reg-mem operation 3620 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3621 %{ 3622 single_instruction; 3623 cr : S4(write); 3624 src1 : S3(read); 3625 src2 : S3(read); 3626 D0 : S0; // big decoder only 3627 ALU : S4; // any alu 3628 MEM : S3; 3629 %} 3630 3631 // Conditional move reg-reg 3632 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3633 %{ 3634 instruction_count(4); 3635 y : S4(read); 3636 q : S3(read); 3637 p : S3(read); 3638 DECODE : S0(4); // any decoder 3639 %} 3640 3641 // Conditional move reg-reg 3642 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3643 %{ 3644 single_instruction; 3645 dst : S4(write); 3646 src : S3(read); 3647 cr : S3(read); 3648 DECODE : S0; // any decoder 3649 %} 3650 3651 // Conditional move reg-mem 3652 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3653 %{ 3654 single_instruction; 3655 dst : S4(write); 3656 src : S3(read); 3657 cr : S3(read); 3658 DECODE : S0; // any decoder 3659 MEM : S3; 3660 %} 3661 3662 // Conditional move reg-reg long 3663 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3664 %{ 3665 single_instruction; 3666 dst : S4(write); 3667 src : S3(read); 3668 cr : S3(read); 3669 DECODE : S0(2); // any 2 decoders 3670 %} 3671 3672 // Float reg-reg operation 3673 pipe_class fpu_reg(regD dst) 3674 %{ 3675 instruction_count(2); 3676 dst : S3(read); 3677 DECODE : S0(2); // any 2 decoders 3678 FPU : S3; 3679 %} 3680 3681 // Float reg-reg operation 3682 pipe_class fpu_reg_reg(regD dst, regD src) 3683 %{ 3684 instruction_count(2); 3685 dst : S4(write); 3686 src : S3(read); 3687 DECODE : S0(2); // any 2 decoders 3688 FPU : S3; 3689 %} 3690 3691 // Float reg-reg operation 3692 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3693 %{ 3694 instruction_count(3); 3695 dst : S4(write); 3696 src1 : S3(read); 3697 src2 : S3(read); 3698 DECODE : S0(3); // any 3 decoders 3699 FPU : S3(2); 3700 %} 3701 3702 // Float reg-reg operation 3703 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3704 %{ 3705 instruction_count(4); 3706 dst : S4(write); 3707 src1 : S3(read); 3708 src2 : S3(read); 3709 src3 : S3(read); 3710 DECODE : S0(4); // any 3 decoders 3711 FPU : S3(2); 3712 %} 3713 3714 // Float reg-reg operation 3715 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3716 %{ 3717 instruction_count(4); 3718 dst : S4(write); 3719 src1 : S3(read); 3720 src2 : S3(read); 3721 src3 : S3(read); 3722 DECODE : S1(3); // any 3 decoders 3723 D0 : S0; // Big decoder only 3724 FPU : S3(2); 3725 MEM : S3; 3726 %} 3727 3728 // Float reg-mem operation 3729 pipe_class fpu_reg_mem(regD dst, memory mem) 3730 %{ 3731 instruction_count(2); 3732 dst : S5(write); 3733 mem : S3(read); 3734 D0 : S0; // big decoder only 3735 DECODE : S1; // any decoder for FPU POP 3736 FPU : S4; 3737 MEM : S3; // any mem 3738 %} 3739 3740 // Float reg-mem operation 3741 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3742 %{ 3743 instruction_count(3); 3744 dst : S5(write); 3745 src1 : S3(read); 3746 mem : S3(read); 3747 D0 : S0; // big decoder only 3748 DECODE : S1(2); // any decoder for FPU POP 3749 FPU : S4; 3750 MEM : S3; // any mem 3751 %} 3752 3753 // Float mem-reg operation 3754 pipe_class fpu_mem_reg(memory mem, regD src) 3755 %{ 3756 instruction_count(2); 3757 src : S5(read); 3758 mem : S3(read); 3759 DECODE : S0; // any decoder for FPU PUSH 3760 D0 : S1; // big decoder only 3761 FPU : S4; 3762 MEM : S3; // any mem 3763 %} 3764 3765 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3766 %{ 3767 instruction_count(3); 3768 src1 : S3(read); 3769 src2 : S3(read); 3770 mem : S3(read); 3771 DECODE : S0(2); // any decoder for FPU PUSH 3772 D0 : S1; // big decoder only 3773 FPU : S4; 3774 MEM : S3; // any mem 3775 %} 3776 3777 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3778 %{ 3779 instruction_count(3); 3780 src1 : S3(read); 3781 src2 : S3(read); 3782 mem : S4(read); 3783 DECODE : S0; // any decoder for FPU PUSH 3784 D0 : S0(2); // big decoder only 3785 FPU : S4; 3786 MEM : S3(2); // any mem 3787 %} 3788 3789 pipe_class fpu_mem_mem(memory dst, memory src1) 3790 %{ 3791 instruction_count(2); 3792 src1 : S3(read); 3793 dst : S4(read); 3794 D0 : S0(2); // big decoder only 3795 MEM : S3(2); // any mem 3796 %} 3797 3798 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3799 %{ 3800 instruction_count(3); 3801 src1 : S3(read); 3802 src2 : S3(read); 3803 dst : S4(read); 3804 D0 : S0(3); // big decoder only 3805 FPU : S4; 3806 MEM : S3(3); // any mem 3807 %} 3808 3809 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3810 %{ 3811 instruction_count(3); 3812 src1 : S4(read); 3813 mem : S4(read); 3814 DECODE : S0; // any decoder for FPU PUSH 3815 D0 : S0(2); // big decoder only 3816 FPU : S4; 3817 MEM : S3(2); // any mem 3818 %} 3819 3820 // Float load constant 3821 pipe_class fpu_reg_con(regD dst) 3822 %{ 3823 instruction_count(2); 3824 dst : S5(write); 3825 D0 : S0; // big decoder only for the load 3826 DECODE : S1; // any decoder for FPU POP 3827 FPU : S4; 3828 MEM : S3; // any mem 3829 %} 3830 3831 // Float load constant 3832 pipe_class fpu_reg_reg_con(regD dst, regD src) 3833 %{ 3834 instruction_count(3); 3835 dst : S5(write); 3836 src : S3(read); 3837 D0 : S0; // big decoder only for the load 3838 DECODE : S1(2); // any decoder for FPU POP 3839 FPU : S4; 3840 MEM : S3; // any mem 3841 %} 3842 3843 // UnConditional branch 3844 pipe_class pipe_jmp(label labl) 3845 %{ 3846 single_instruction; 3847 BR : S3; 3848 %} 3849 3850 // Conditional branch 3851 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3852 %{ 3853 single_instruction; 3854 cr : S1(read); 3855 BR : S3; 3856 %} 3857 3858 // Allocation idiom 3859 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3860 %{ 3861 instruction_count(1); force_serialization; 3862 fixed_latency(6); 3863 heap_ptr : S3(read); 3864 DECODE : S0(3); 3865 D0 : S2; 3866 MEM : S3; 3867 ALU : S3(2); 3868 dst : S5(write); 3869 BR : S5; 3870 %} 3871 3872 // Generic big/slow expanded idiom 3873 pipe_class pipe_slow() 3874 %{ 3875 instruction_count(10); multiple_bundles; force_serialization; 3876 fixed_latency(100); 3877 D0 : S0(2); 3878 MEM : S3(2); 3879 %} 3880 3881 // The real do-nothing guy 3882 pipe_class empty() 3883 %{ 3884 instruction_count(0); 3885 %} 3886 3887 // Define the class for the Nop node 3888 define 3889 %{ 3890 MachNop = empty; 3891 %} 3892 3893 %} 3894 3895 //----------INSTRUCTIONS------------------------------------------------------- 3896 // 3897 // match -- States which machine-independent subtree may be replaced 3898 // by this instruction. 3899 // ins_cost -- The estimated cost of this instruction is used by instruction 3900 // selection to identify a minimum cost tree of machine 3901 // instructions that matches a tree of machine-independent 3902 // instructions. 3903 // format -- A string providing the disassembly for this instruction. 3904 // The value of an instruction's operand may be inserted 3905 // by referring to it with a '$' prefix. 3906 // opcode -- Three instruction opcodes may be provided. These are referred 3907 // to within an encode class as $primary, $secondary, and $tertiary 3908 // rrspectively. The primary opcode is commonly used to 3909 // indicate the type of machine instruction, while secondary 3910 // and tertiary are often used for prefix options or addressing 3911 // modes. 3912 // ins_encode -- A list of encode classes with parameters. The encode class 3913 // name must have been defined in an 'enc_class' specification 3914 // in the encode section of the architecture description. 3915 3916 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3917 // Load Float 3918 instruct MoveF2VL(vlRegF dst, regF src) %{ 3919 match(Set dst src); 3920 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3921 ins_encode %{ 3922 ShouldNotReachHere(); 3923 %} 3924 ins_pipe( fpu_reg_reg ); 3925 %} 3926 3927 // Load Float 3928 instruct MoveF2LEG(legRegF dst, regF src) %{ 3929 match(Set dst src); 3930 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3931 ins_encode %{ 3932 ShouldNotReachHere(); 3933 %} 3934 ins_pipe( fpu_reg_reg ); 3935 %} 3936 3937 // Load Float 3938 instruct MoveVL2F(regF dst, vlRegF src) %{ 3939 match(Set dst src); 3940 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3941 ins_encode %{ 3942 ShouldNotReachHere(); 3943 %} 3944 ins_pipe( fpu_reg_reg ); 3945 %} 3946 3947 // Load Float 3948 instruct MoveLEG2F(regF dst, legRegF src) %{ 3949 match(Set dst src); 3950 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3951 ins_encode %{ 3952 ShouldNotReachHere(); 3953 %} 3954 ins_pipe( fpu_reg_reg ); 3955 %} 3956 3957 // Load Double 3958 instruct MoveD2VL(vlRegD dst, regD src) %{ 3959 match(Set dst src); 3960 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3961 ins_encode %{ 3962 ShouldNotReachHere(); 3963 %} 3964 ins_pipe( fpu_reg_reg ); 3965 %} 3966 3967 // Load Double 3968 instruct MoveD2LEG(legRegD dst, regD src) %{ 3969 match(Set dst src); 3970 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3971 ins_encode %{ 3972 ShouldNotReachHere(); 3973 %} 3974 ins_pipe( fpu_reg_reg ); 3975 %} 3976 3977 // Load Double 3978 instruct MoveVL2D(regD dst, vlRegD src) %{ 3979 match(Set dst src); 3980 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3981 ins_encode %{ 3982 ShouldNotReachHere(); 3983 %} 3984 ins_pipe( fpu_reg_reg ); 3985 %} 3986 3987 // Load Double 3988 instruct MoveLEG2D(regD dst, legRegD src) %{ 3989 match(Set dst src); 3990 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3991 ins_encode %{ 3992 ShouldNotReachHere(); 3993 %} 3994 ins_pipe( fpu_reg_reg ); 3995 %} 3996 3997 //----------Load/Store/Move Instructions--------------------------------------- 3998 //----------Load Instructions-------------------------------------------------- 3999 4000 // Load Byte (8 bit signed) 4001 instruct loadB(rRegI dst, memory mem) 4002 %{ 4003 match(Set dst (LoadB mem)); 4004 4005 ins_cost(125); 4006 format %{ "movsbl $dst, $mem\t# byte" %} 4007 4008 ins_encode %{ 4009 __ movsbl($dst$$Register, $mem$$Address); 4010 %} 4011 4012 ins_pipe(ialu_reg_mem); 4013 %} 4014 4015 // Load Byte (8 bit signed) into Long Register 4016 instruct loadB2L(rRegL dst, memory mem) 4017 %{ 4018 match(Set dst (ConvI2L (LoadB mem))); 4019 4020 ins_cost(125); 4021 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4022 4023 ins_encode %{ 4024 __ movsbq($dst$$Register, $mem$$Address); 4025 %} 4026 4027 ins_pipe(ialu_reg_mem); 4028 %} 4029 4030 // Load Unsigned Byte (8 bit UNsigned) 4031 instruct loadUB(rRegI dst, memory mem) 4032 %{ 4033 match(Set dst (LoadUB mem)); 4034 4035 ins_cost(125); 4036 format %{ "movzbl $dst, $mem\t# ubyte" %} 4037 4038 ins_encode %{ 4039 __ movzbl($dst$$Register, $mem$$Address); 4040 %} 4041 4042 ins_pipe(ialu_reg_mem); 4043 %} 4044 4045 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4046 instruct loadUB2L(rRegL dst, memory mem) 4047 %{ 4048 match(Set dst (ConvI2L (LoadUB mem))); 4049 4050 ins_cost(125); 4051 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4052 4053 ins_encode %{ 4054 __ movzbq($dst$$Register, $mem$$Address); 4055 %} 4056 4057 ins_pipe(ialu_reg_mem); 4058 %} 4059 4060 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4061 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4062 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4063 effect(KILL cr); 4064 4065 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4066 "andl $dst, right_n_bits($mask, 8)" %} 4067 ins_encode %{ 4068 Register Rdst = $dst$$Register; 4069 __ movzbq(Rdst, $mem$$Address); 4070 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4071 %} 4072 ins_pipe(ialu_reg_mem); 4073 %} 4074 4075 // Load Short (16 bit signed) 4076 instruct loadS(rRegI dst, memory mem) 4077 %{ 4078 match(Set dst (LoadS mem)); 4079 4080 ins_cost(125); 4081 format %{ "movswl $dst, $mem\t# short" %} 4082 4083 ins_encode %{ 4084 __ movswl($dst$$Register, $mem$$Address); 4085 %} 4086 4087 ins_pipe(ialu_reg_mem); 4088 %} 4089 4090 // Load Short (16 bit signed) to Byte (8 bit signed) 4091 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4092 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4093 4094 ins_cost(125); 4095 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4096 ins_encode %{ 4097 __ movsbl($dst$$Register, $mem$$Address); 4098 %} 4099 ins_pipe(ialu_reg_mem); 4100 %} 4101 4102 // Load Short (16 bit signed) into Long Register 4103 instruct loadS2L(rRegL dst, memory mem) 4104 %{ 4105 match(Set dst (ConvI2L (LoadS mem))); 4106 4107 ins_cost(125); 4108 format %{ "movswq $dst, $mem\t# short -> long" %} 4109 4110 ins_encode %{ 4111 __ movswq($dst$$Register, $mem$$Address); 4112 %} 4113 4114 ins_pipe(ialu_reg_mem); 4115 %} 4116 4117 // Load Unsigned Short/Char (16 bit UNsigned) 4118 instruct loadUS(rRegI dst, memory mem) 4119 %{ 4120 match(Set dst (LoadUS mem)); 4121 4122 ins_cost(125); 4123 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4124 4125 ins_encode %{ 4126 __ movzwl($dst$$Register, $mem$$Address); 4127 %} 4128 4129 ins_pipe(ialu_reg_mem); 4130 %} 4131 4132 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4133 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4134 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4135 4136 ins_cost(125); 4137 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4138 ins_encode %{ 4139 __ movsbl($dst$$Register, $mem$$Address); 4140 %} 4141 ins_pipe(ialu_reg_mem); 4142 %} 4143 4144 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4145 instruct loadUS2L(rRegL dst, memory mem) 4146 %{ 4147 match(Set dst (ConvI2L (LoadUS mem))); 4148 4149 ins_cost(125); 4150 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4151 4152 ins_encode %{ 4153 __ movzwq($dst$$Register, $mem$$Address); 4154 %} 4155 4156 ins_pipe(ialu_reg_mem); 4157 %} 4158 4159 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4160 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4161 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4162 4163 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4164 ins_encode %{ 4165 __ movzbq($dst$$Register, $mem$$Address); 4166 %} 4167 ins_pipe(ialu_reg_mem); 4168 %} 4169 4170 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4171 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4172 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4173 effect(KILL cr); 4174 4175 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4176 "andl $dst, right_n_bits($mask, 16)" %} 4177 ins_encode %{ 4178 Register Rdst = $dst$$Register; 4179 __ movzwq(Rdst, $mem$$Address); 4180 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4181 %} 4182 ins_pipe(ialu_reg_mem); 4183 %} 4184 4185 // Load Integer 4186 instruct loadI(rRegI dst, memory mem) 4187 %{ 4188 match(Set dst (LoadI mem)); 4189 4190 ins_cost(125); 4191 format %{ "movl $dst, $mem\t# int" %} 4192 4193 ins_encode %{ 4194 __ movl($dst$$Register, $mem$$Address); 4195 %} 4196 4197 ins_pipe(ialu_reg_mem); 4198 %} 4199 4200 // Load Integer (32 bit signed) to Byte (8 bit signed) 4201 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4202 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4203 4204 ins_cost(125); 4205 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4206 ins_encode %{ 4207 __ movsbl($dst$$Register, $mem$$Address); 4208 %} 4209 ins_pipe(ialu_reg_mem); 4210 %} 4211 4212 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4213 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4214 match(Set dst (AndI (LoadI mem) mask)); 4215 4216 ins_cost(125); 4217 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4218 ins_encode %{ 4219 __ movzbl($dst$$Register, $mem$$Address); 4220 %} 4221 ins_pipe(ialu_reg_mem); 4222 %} 4223 4224 // Load Integer (32 bit signed) to Short (16 bit signed) 4225 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4226 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4227 4228 ins_cost(125); 4229 format %{ "movswl $dst, $mem\t# int -> short" %} 4230 ins_encode %{ 4231 __ movswl($dst$$Register, $mem$$Address); 4232 %} 4233 ins_pipe(ialu_reg_mem); 4234 %} 4235 4236 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4237 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4238 match(Set dst (AndI (LoadI mem) mask)); 4239 4240 ins_cost(125); 4241 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4242 ins_encode %{ 4243 __ movzwl($dst$$Register, $mem$$Address); 4244 %} 4245 ins_pipe(ialu_reg_mem); 4246 %} 4247 4248 // Load Integer into Long Register 4249 instruct loadI2L(rRegL dst, memory mem) 4250 %{ 4251 match(Set dst (ConvI2L (LoadI mem))); 4252 4253 ins_cost(125); 4254 format %{ "movslq $dst, $mem\t# int -> long" %} 4255 4256 ins_encode %{ 4257 __ movslq($dst$$Register, $mem$$Address); 4258 %} 4259 4260 ins_pipe(ialu_reg_mem); 4261 %} 4262 4263 // Load Integer with mask 0xFF into Long Register 4264 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4265 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4266 4267 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4268 ins_encode %{ 4269 __ movzbq($dst$$Register, $mem$$Address); 4270 %} 4271 ins_pipe(ialu_reg_mem); 4272 %} 4273 4274 // Load Integer with mask 0xFFFF into Long Register 4275 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4276 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4277 4278 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4279 ins_encode %{ 4280 __ movzwq($dst$$Register, $mem$$Address); 4281 %} 4282 ins_pipe(ialu_reg_mem); 4283 %} 4284 4285 // Load Integer with a 31-bit mask into Long Register 4286 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4287 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4288 effect(KILL cr); 4289 4290 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4291 "andl $dst, $mask" %} 4292 ins_encode %{ 4293 Register Rdst = $dst$$Register; 4294 __ movl(Rdst, $mem$$Address); 4295 __ andl(Rdst, $mask$$constant); 4296 %} 4297 ins_pipe(ialu_reg_mem); 4298 %} 4299 4300 // Load Unsigned Integer into Long Register 4301 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4302 %{ 4303 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4304 4305 ins_cost(125); 4306 format %{ "movl $dst, $mem\t# uint -> long" %} 4307 4308 ins_encode %{ 4309 __ movl($dst$$Register, $mem$$Address); 4310 %} 4311 4312 ins_pipe(ialu_reg_mem); 4313 %} 4314 4315 // Load Long 4316 instruct loadL(rRegL dst, memory mem) 4317 %{ 4318 match(Set dst (LoadL mem)); 4319 4320 ins_cost(125); 4321 format %{ "movq $dst, $mem\t# long" %} 4322 4323 ins_encode %{ 4324 __ movq($dst$$Register, $mem$$Address); 4325 %} 4326 4327 ins_pipe(ialu_reg_mem); // XXX 4328 %} 4329 4330 // Load Range 4331 instruct loadRange(rRegI dst, memory mem) 4332 %{ 4333 match(Set dst (LoadRange mem)); 4334 4335 ins_cost(125); // XXX 4336 format %{ "movl $dst, $mem\t# range" %} 4337 ins_encode %{ 4338 __ movl($dst$$Register, $mem$$Address); 4339 %} 4340 ins_pipe(ialu_reg_mem); 4341 %} 4342 4343 // Load Pointer 4344 instruct loadP(rRegP dst, memory mem) 4345 %{ 4346 match(Set dst (LoadP mem)); 4347 predicate(n->as_Load()->barrier_data() == 0); 4348 4349 ins_cost(125); // XXX 4350 format %{ "movq $dst, $mem\t# ptr" %} 4351 ins_encode %{ 4352 __ movq($dst$$Register, $mem$$Address); 4353 %} 4354 ins_pipe(ialu_reg_mem); // XXX 4355 %} 4356 4357 // Load Compressed Pointer 4358 instruct loadN(rRegN dst, memory mem) 4359 %{ 4360 match(Set dst (LoadN mem)); 4361 4362 ins_cost(125); // XXX 4363 format %{ "movl $dst, $mem\t# compressed ptr" %} 4364 ins_encode %{ 4365 __ movl($dst$$Register, $mem$$Address); 4366 %} 4367 ins_pipe(ialu_reg_mem); // XXX 4368 %} 4369 4370 4371 // Load Klass Pointer 4372 instruct loadKlass(rRegP dst, memory mem) 4373 %{ 4374 match(Set dst (LoadKlass mem)); 4375 4376 ins_cost(125); // XXX 4377 format %{ "movq $dst, $mem\t# class" %} 4378 ins_encode %{ 4379 __ movq($dst$$Register, $mem$$Address); 4380 %} 4381 ins_pipe(ialu_reg_mem); // XXX 4382 %} 4383 4384 // Load narrow Klass Pointer 4385 instruct loadNKlass(rRegN dst, memory mem) 4386 %{ 4387 match(Set dst (LoadNKlass mem)); 4388 4389 ins_cost(125); // XXX 4390 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4391 ins_encode %{ 4392 __ movl($dst$$Register, $mem$$Address); 4393 %} 4394 ins_pipe(ialu_reg_mem); // XXX 4395 %} 4396 4397 // Load Float 4398 instruct loadF(regF dst, memory mem) 4399 %{ 4400 match(Set dst (LoadF mem)); 4401 4402 ins_cost(145); // XXX 4403 format %{ "movss $dst, $mem\t# float" %} 4404 ins_encode %{ 4405 __ movflt($dst$$XMMRegister, $mem$$Address); 4406 %} 4407 ins_pipe(pipe_slow); // XXX 4408 %} 4409 4410 // Load Double 4411 instruct loadD_partial(regD dst, memory mem) 4412 %{ 4413 predicate(!UseXmmLoadAndClearUpper); 4414 match(Set dst (LoadD mem)); 4415 4416 ins_cost(145); // XXX 4417 format %{ "movlpd $dst, $mem\t# double" %} 4418 ins_encode %{ 4419 __ movdbl($dst$$XMMRegister, $mem$$Address); 4420 %} 4421 ins_pipe(pipe_slow); // XXX 4422 %} 4423 4424 instruct loadD(regD dst, memory mem) 4425 %{ 4426 predicate(UseXmmLoadAndClearUpper); 4427 match(Set dst (LoadD mem)); 4428 4429 ins_cost(145); // XXX 4430 format %{ "movsd $dst, $mem\t# double" %} 4431 ins_encode %{ 4432 __ movdbl($dst$$XMMRegister, $mem$$Address); 4433 %} 4434 ins_pipe(pipe_slow); // XXX 4435 %} 4436 4437 instruct loadAOTRCAddress(rRegP dst, immAOTRuntimeConstantsAddress con) 4438 %{ 4439 match(Set dst con); 4440 4441 format %{ "leaq $dst, $con\t# AOT Runtime Constants Address" %} 4442 4443 ins_encode %{ 4444 __ load_aotrc_address($dst$$Register, (address)$con$$constant); 4445 %} 4446 4447 ins_pipe(ialu_reg_fat); 4448 %} 4449 4450 // max = java.lang.Math.max(float a, float b) 4451 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4452 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4453 match(Set dst (MaxF a b)); 4454 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4455 format %{ "maxF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4456 ins_encode %{ 4457 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4458 %} 4459 ins_pipe( pipe_slow ); 4460 %} 4461 4462 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4463 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4464 match(Set dst (MaxF a b)); 4465 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4466 4467 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 4468 ins_encode %{ 4469 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4470 false /*min*/, true /*single*/); 4471 %} 4472 ins_pipe( pipe_slow ); 4473 %} 4474 4475 // max = java.lang.Math.max(double a, double b) 4476 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4477 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4478 match(Set dst (MaxD a b)); 4479 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4480 format %{ "maxD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4481 ins_encode %{ 4482 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4483 %} 4484 ins_pipe( pipe_slow ); 4485 %} 4486 4487 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4488 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4489 match(Set dst (MaxD a b)); 4490 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4491 4492 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 4493 ins_encode %{ 4494 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4495 false /*min*/, false /*single*/); 4496 %} 4497 ins_pipe( pipe_slow ); 4498 %} 4499 4500 // min = java.lang.Math.min(float a, float b) 4501 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4502 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4503 match(Set dst (MinF a b)); 4504 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4505 format %{ "minF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4506 ins_encode %{ 4507 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4508 %} 4509 ins_pipe( pipe_slow ); 4510 %} 4511 4512 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4513 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4514 match(Set dst (MinF a b)); 4515 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4516 4517 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 4518 ins_encode %{ 4519 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4520 true /*min*/, true /*single*/); 4521 %} 4522 ins_pipe( pipe_slow ); 4523 %} 4524 4525 // min = java.lang.Math.min(double a, double b) 4526 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4527 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4528 match(Set dst (MinD a b)); 4529 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4530 format %{ "minD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4531 ins_encode %{ 4532 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4533 %} 4534 ins_pipe( pipe_slow ); 4535 %} 4536 4537 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4538 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4539 match(Set dst (MinD a b)); 4540 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4541 4542 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 4543 ins_encode %{ 4544 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4545 true /*min*/, false /*single*/); 4546 %} 4547 ins_pipe( pipe_slow ); 4548 %} 4549 4550 // Load Effective Address 4551 instruct leaP8(rRegP dst, indOffset8 mem) 4552 %{ 4553 match(Set dst mem); 4554 4555 ins_cost(110); // XXX 4556 format %{ "leaq $dst, $mem\t# ptr 8" %} 4557 ins_encode %{ 4558 __ leaq($dst$$Register, $mem$$Address); 4559 %} 4560 ins_pipe(ialu_reg_reg_fat); 4561 %} 4562 4563 instruct leaP32(rRegP dst, indOffset32 mem) 4564 %{ 4565 match(Set dst mem); 4566 4567 ins_cost(110); 4568 format %{ "leaq $dst, $mem\t# ptr 32" %} 4569 ins_encode %{ 4570 __ leaq($dst$$Register, $mem$$Address); 4571 %} 4572 ins_pipe(ialu_reg_reg_fat); 4573 %} 4574 4575 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4576 %{ 4577 match(Set dst mem); 4578 4579 ins_cost(110); 4580 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4581 ins_encode %{ 4582 __ leaq($dst$$Register, $mem$$Address); 4583 %} 4584 ins_pipe(ialu_reg_reg_fat); 4585 %} 4586 4587 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4588 %{ 4589 match(Set dst mem); 4590 4591 ins_cost(110); 4592 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4593 ins_encode %{ 4594 __ leaq($dst$$Register, $mem$$Address); 4595 %} 4596 ins_pipe(ialu_reg_reg_fat); 4597 %} 4598 4599 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4600 %{ 4601 match(Set dst mem); 4602 4603 ins_cost(110); 4604 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4605 ins_encode %{ 4606 __ leaq($dst$$Register, $mem$$Address); 4607 %} 4608 ins_pipe(ialu_reg_reg_fat); 4609 %} 4610 4611 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4612 %{ 4613 match(Set dst mem); 4614 4615 ins_cost(110); 4616 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4617 ins_encode %{ 4618 __ leaq($dst$$Register, $mem$$Address); 4619 %} 4620 ins_pipe(ialu_reg_reg_fat); 4621 %} 4622 4623 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4624 %{ 4625 match(Set dst mem); 4626 4627 ins_cost(110); 4628 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4629 ins_encode %{ 4630 __ leaq($dst$$Register, $mem$$Address); 4631 %} 4632 ins_pipe(ialu_reg_reg_fat); 4633 %} 4634 4635 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4636 %{ 4637 match(Set dst mem); 4638 4639 ins_cost(110); 4640 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4641 ins_encode %{ 4642 __ leaq($dst$$Register, $mem$$Address); 4643 %} 4644 ins_pipe(ialu_reg_reg_fat); 4645 %} 4646 4647 // Load Effective Address which uses Narrow (32-bits) oop 4648 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4649 %{ 4650 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4651 match(Set dst mem); 4652 4653 ins_cost(110); 4654 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4655 ins_encode %{ 4656 __ leaq($dst$$Register, $mem$$Address); 4657 %} 4658 ins_pipe(ialu_reg_reg_fat); 4659 %} 4660 4661 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4662 %{ 4663 predicate(CompressedOops::shift() == 0); 4664 match(Set dst mem); 4665 4666 ins_cost(110); // XXX 4667 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4668 ins_encode %{ 4669 __ leaq($dst$$Register, $mem$$Address); 4670 %} 4671 ins_pipe(ialu_reg_reg_fat); 4672 %} 4673 4674 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4675 %{ 4676 predicate(CompressedOops::shift() == 0); 4677 match(Set dst mem); 4678 4679 ins_cost(110); 4680 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4681 ins_encode %{ 4682 __ leaq($dst$$Register, $mem$$Address); 4683 %} 4684 ins_pipe(ialu_reg_reg_fat); 4685 %} 4686 4687 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4688 %{ 4689 predicate(CompressedOops::shift() == 0); 4690 match(Set dst mem); 4691 4692 ins_cost(110); 4693 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4694 ins_encode %{ 4695 __ leaq($dst$$Register, $mem$$Address); 4696 %} 4697 ins_pipe(ialu_reg_reg_fat); 4698 %} 4699 4700 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4701 %{ 4702 predicate(CompressedOops::shift() == 0); 4703 match(Set dst mem); 4704 4705 ins_cost(110); 4706 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4707 ins_encode %{ 4708 __ leaq($dst$$Register, $mem$$Address); 4709 %} 4710 ins_pipe(ialu_reg_reg_fat); 4711 %} 4712 4713 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4714 %{ 4715 predicate(CompressedOops::shift() == 0); 4716 match(Set dst mem); 4717 4718 ins_cost(110); 4719 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4720 ins_encode %{ 4721 __ leaq($dst$$Register, $mem$$Address); 4722 %} 4723 ins_pipe(ialu_reg_reg_fat); 4724 %} 4725 4726 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4727 %{ 4728 predicate(CompressedOops::shift() == 0); 4729 match(Set dst mem); 4730 4731 ins_cost(110); 4732 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4733 ins_encode %{ 4734 __ leaq($dst$$Register, $mem$$Address); 4735 %} 4736 ins_pipe(ialu_reg_reg_fat); 4737 %} 4738 4739 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4740 %{ 4741 predicate(CompressedOops::shift() == 0); 4742 match(Set dst mem); 4743 4744 ins_cost(110); 4745 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4746 ins_encode %{ 4747 __ leaq($dst$$Register, $mem$$Address); 4748 %} 4749 ins_pipe(ialu_reg_reg_fat); 4750 %} 4751 4752 instruct loadConI(rRegI dst, immI src) 4753 %{ 4754 match(Set dst src); 4755 4756 format %{ "movl $dst, $src\t# int" %} 4757 ins_encode %{ 4758 __ movl($dst$$Register, $src$$constant); 4759 %} 4760 ins_pipe(ialu_reg_fat); // XXX 4761 %} 4762 4763 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4764 %{ 4765 match(Set dst src); 4766 effect(KILL cr); 4767 4768 ins_cost(50); 4769 format %{ "xorl $dst, $dst\t# int" %} 4770 ins_encode %{ 4771 __ xorl($dst$$Register, $dst$$Register); 4772 %} 4773 ins_pipe(ialu_reg); 4774 %} 4775 4776 instruct loadConL(rRegL dst, immL src) 4777 %{ 4778 match(Set dst src); 4779 4780 ins_cost(150); 4781 format %{ "movq $dst, $src\t# long" %} 4782 ins_encode %{ 4783 __ mov64($dst$$Register, $src$$constant); 4784 %} 4785 ins_pipe(ialu_reg); 4786 %} 4787 4788 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4789 %{ 4790 match(Set dst src); 4791 effect(KILL cr); 4792 4793 ins_cost(50); 4794 format %{ "xorl $dst, $dst\t# long" %} 4795 ins_encode %{ 4796 __ xorl($dst$$Register, $dst$$Register); 4797 %} 4798 ins_pipe(ialu_reg); // XXX 4799 %} 4800 4801 instruct loadConUL32(rRegL dst, immUL32 src) 4802 %{ 4803 match(Set dst src); 4804 4805 ins_cost(60); 4806 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4807 ins_encode %{ 4808 __ movl($dst$$Register, $src$$constant); 4809 %} 4810 ins_pipe(ialu_reg); 4811 %} 4812 4813 instruct loadConL32(rRegL dst, immL32 src) 4814 %{ 4815 match(Set dst src); 4816 4817 ins_cost(70); 4818 format %{ "movq $dst, $src\t# long (32-bit)" %} 4819 ins_encode %{ 4820 __ movq($dst$$Register, $src$$constant); 4821 %} 4822 ins_pipe(ialu_reg); 4823 %} 4824 4825 instruct loadConP(rRegP dst, immP con) %{ 4826 match(Set dst con); 4827 4828 format %{ "movq $dst, $con\t# ptr" %} 4829 ins_encode %{ 4830 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4831 %} 4832 ins_pipe(ialu_reg_fat); // XXX 4833 %} 4834 4835 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4836 %{ 4837 match(Set dst src); 4838 effect(KILL cr); 4839 4840 ins_cost(50); 4841 format %{ "xorl $dst, $dst\t# ptr" %} 4842 ins_encode %{ 4843 __ xorl($dst$$Register, $dst$$Register); 4844 %} 4845 ins_pipe(ialu_reg); 4846 %} 4847 4848 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4849 %{ 4850 match(Set dst src); 4851 effect(KILL cr); 4852 4853 ins_cost(60); 4854 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4855 ins_encode %{ 4856 __ movl($dst$$Register, $src$$constant); 4857 %} 4858 ins_pipe(ialu_reg); 4859 %} 4860 4861 instruct loadConF(regF dst, immF con) %{ 4862 match(Set dst con); 4863 ins_cost(125); 4864 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4865 ins_encode %{ 4866 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4867 %} 4868 ins_pipe(pipe_slow); 4869 %} 4870 4871 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4872 match(Set dst src); 4873 effect(KILL cr); 4874 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4875 ins_encode %{ 4876 __ xorq($dst$$Register, $dst$$Register); 4877 %} 4878 ins_pipe(ialu_reg); 4879 %} 4880 4881 instruct loadConN(rRegN dst, immN src) %{ 4882 match(Set dst src); 4883 4884 ins_cost(125); 4885 format %{ "movl $dst, $src\t# compressed ptr" %} 4886 ins_encode %{ 4887 address con = (address)$src$$constant; 4888 if (con == nullptr) { 4889 ShouldNotReachHere(); 4890 } else { 4891 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4892 } 4893 %} 4894 ins_pipe(ialu_reg_fat); // XXX 4895 %} 4896 4897 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4898 match(Set dst src); 4899 4900 ins_cost(125); 4901 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4902 ins_encode %{ 4903 address con = (address)$src$$constant; 4904 if (con == nullptr) { 4905 ShouldNotReachHere(); 4906 } else { 4907 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4908 } 4909 %} 4910 ins_pipe(ialu_reg_fat); // XXX 4911 %} 4912 4913 instruct loadConF0(regF dst, immF0 src) 4914 %{ 4915 match(Set dst src); 4916 ins_cost(100); 4917 4918 format %{ "xorps $dst, $dst\t# float 0.0" %} 4919 ins_encode %{ 4920 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4921 %} 4922 ins_pipe(pipe_slow); 4923 %} 4924 4925 // Use the same format since predicate() can not be used here. 4926 instruct loadConD(regD dst, immD con) %{ 4927 match(Set dst con); 4928 ins_cost(125); 4929 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4930 ins_encode %{ 4931 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4932 %} 4933 ins_pipe(pipe_slow); 4934 %} 4935 4936 instruct loadConD0(regD dst, immD0 src) 4937 %{ 4938 match(Set dst src); 4939 ins_cost(100); 4940 4941 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4942 ins_encode %{ 4943 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4944 %} 4945 ins_pipe(pipe_slow); 4946 %} 4947 4948 instruct loadSSI(rRegI dst, stackSlotI src) 4949 %{ 4950 match(Set dst src); 4951 4952 ins_cost(125); 4953 format %{ "movl $dst, $src\t# int stk" %} 4954 ins_encode %{ 4955 __ movl($dst$$Register, $src$$Address); 4956 %} 4957 ins_pipe(ialu_reg_mem); 4958 %} 4959 4960 instruct loadSSL(rRegL dst, stackSlotL src) 4961 %{ 4962 match(Set dst src); 4963 4964 ins_cost(125); 4965 format %{ "movq $dst, $src\t# long stk" %} 4966 ins_encode %{ 4967 __ movq($dst$$Register, $src$$Address); 4968 %} 4969 ins_pipe(ialu_reg_mem); 4970 %} 4971 4972 instruct loadSSP(rRegP dst, stackSlotP src) 4973 %{ 4974 match(Set dst src); 4975 4976 ins_cost(125); 4977 format %{ "movq $dst, $src\t# ptr stk" %} 4978 ins_encode %{ 4979 __ movq($dst$$Register, $src$$Address); 4980 %} 4981 ins_pipe(ialu_reg_mem); 4982 %} 4983 4984 instruct loadSSF(regF dst, stackSlotF src) 4985 %{ 4986 match(Set dst src); 4987 4988 ins_cost(125); 4989 format %{ "movss $dst, $src\t# float stk" %} 4990 ins_encode %{ 4991 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 4992 %} 4993 ins_pipe(pipe_slow); // XXX 4994 %} 4995 4996 // Use the same format since predicate() can not be used here. 4997 instruct loadSSD(regD dst, stackSlotD src) 4998 %{ 4999 match(Set dst src); 5000 5001 ins_cost(125); 5002 format %{ "movsd $dst, $src\t# double stk" %} 5003 ins_encode %{ 5004 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5005 %} 5006 ins_pipe(pipe_slow); // XXX 5007 %} 5008 5009 // Prefetch instructions for allocation. 5010 // Must be safe to execute with invalid address (cannot fault). 5011 5012 instruct prefetchAlloc( memory mem ) %{ 5013 predicate(AllocatePrefetchInstr==3); 5014 match(PrefetchAllocation mem); 5015 ins_cost(125); 5016 5017 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5018 ins_encode %{ 5019 __ prefetchw($mem$$Address); 5020 %} 5021 ins_pipe(ialu_mem); 5022 %} 5023 5024 instruct prefetchAllocNTA( memory mem ) %{ 5025 predicate(AllocatePrefetchInstr==0); 5026 match(PrefetchAllocation mem); 5027 ins_cost(125); 5028 5029 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5030 ins_encode %{ 5031 __ prefetchnta($mem$$Address); 5032 %} 5033 ins_pipe(ialu_mem); 5034 %} 5035 5036 instruct prefetchAllocT0( memory mem ) %{ 5037 predicate(AllocatePrefetchInstr==1); 5038 match(PrefetchAllocation mem); 5039 ins_cost(125); 5040 5041 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5042 ins_encode %{ 5043 __ prefetcht0($mem$$Address); 5044 %} 5045 ins_pipe(ialu_mem); 5046 %} 5047 5048 instruct prefetchAllocT2( memory mem ) %{ 5049 predicate(AllocatePrefetchInstr==2); 5050 match(PrefetchAllocation mem); 5051 ins_cost(125); 5052 5053 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5054 ins_encode %{ 5055 __ prefetcht2($mem$$Address); 5056 %} 5057 ins_pipe(ialu_mem); 5058 %} 5059 5060 //----------Store Instructions------------------------------------------------- 5061 5062 // Store Byte 5063 instruct storeB(memory mem, rRegI src) 5064 %{ 5065 match(Set mem (StoreB mem src)); 5066 5067 ins_cost(125); // XXX 5068 format %{ "movb $mem, $src\t# byte" %} 5069 ins_encode %{ 5070 __ movb($mem$$Address, $src$$Register); 5071 %} 5072 ins_pipe(ialu_mem_reg); 5073 %} 5074 5075 // Store Char/Short 5076 instruct storeC(memory mem, rRegI src) 5077 %{ 5078 match(Set mem (StoreC mem src)); 5079 5080 ins_cost(125); // XXX 5081 format %{ "movw $mem, $src\t# char/short" %} 5082 ins_encode %{ 5083 __ movw($mem$$Address, $src$$Register); 5084 %} 5085 ins_pipe(ialu_mem_reg); 5086 %} 5087 5088 // Store Integer 5089 instruct storeI(memory mem, rRegI src) 5090 %{ 5091 match(Set mem (StoreI mem src)); 5092 5093 ins_cost(125); // XXX 5094 format %{ "movl $mem, $src\t# int" %} 5095 ins_encode %{ 5096 __ movl($mem$$Address, $src$$Register); 5097 %} 5098 ins_pipe(ialu_mem_reg); 5099 %} 5100 5101 // Store Long 5102 instruct storeL(memory mem, rRegL src) 5103 %{ 5104 match(Set mem (StoreL mem src)); 5105 5106 ins_cost(125); // XXX 5107 format %{ "movq $mem, $src\t# long" %} 5108 ins_encode %{ 5109 __ movq($mem$$Address, $src$$Register); 5110 %} 5111 ins_pipe(ialu_mem_reg); // XXX 5112 %} 5113 5114 // Store Pointer 5115 instruct storeP(memory mem, any_RegP src) 5116 %{ 5117 predicate(n->as_Store()->barrier_data() == 0); 5118 match(Set mem (StoreP mem src)); 5119 5120 ins_cost(125); // XXX 5121 format %{ "movq $mem, $src\t# ptr" %} 5122 ins_encode %{ 5123 __ movq($mem$$Address, $src$$Register); 5124 %} 5125 ins_pipe(ialu_mem_reg); 5126 %} 5127 5128 instruct storeImmP0(memory mem, immP0 zero) 5129 %{ 5130 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5131 match(Set mem (StoreP mem zero)); 5132 5133 ins_cost(125); // XXX 5134 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5135 ins_encode %{ 5136 __ movq($mem$$Address, r12); 5137 %} 5138 ins_pipe(ialu_mem_reg); 5139 %} 5140 5141 // Store Null Pointer, mark word, or other simple pointer constant. 5142 instruct storeImmP(memory mem, immP31 src) 5143 %{ 5144 predicate(n->as_Store()->barrier_data() == 0); 5145 match(Set mem (StoreP mem src)); 5146 5147 ins_cost(150); // XXX 5148 format %{ "movq $mem, $src\t# ptr" %} 5149 ins_encode %{ 5150 __ movq($mem$$Address, $src$$constant); 5151 %} 5152 ins_pipe(ialu_mem_imm); 5153 %} 5154 5155 // Store Compressed Pointer 5156 instruct storeN(memory mem, rRegN src) 5157 %{ 5158 match(Set mem (StoreN mem src)); 5159 5160 ins_cost(125); // XXX 5161 format %{ "movl $mem, $src\t# compressed ptr" %} 5162 ins_encode %{ 5163 __ movl($mem$$Address, $src$$Register); 5164 %} 5165 ins_pipe(ialu_mem_reg); 5166 %} 5167 5168 instruct storeNKlass(memory mem, rRegN src) 5169 %{ 5170 match(Set mem (StoreNKlass mem src)); 5171 5172 ins_cost(125); // XXX 5173 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5174 ins_encode %{ 5175 __ movl($mem$$Address, $src$$Register); 5176 %} 5177 ins_pipe(ialu_mem_reg); 5178 %} 5179 5180 instruct storeImmN0(memory mem, immN0 zero) 5181 %{ 5182 predicate(CompressedOops::base() == nullptr); 5183 match(Set mem (StoreN mem zero)); 5184 5185 ins_cost(125); // XXX 5186 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5187 ins_encode %{ 5188 __ movl($mem$$Address, r12); 5189 %} 5190 ins_pipe(ialu_mem_reg); 5191 %} 5192 5193 instruct storeImmN(memory mem, immN src) 5194 %{ 5195 match(Set mem (StoreN mem src)); 5196 5197 ins_cost(150); // XXX 5198 format %{ "movl $mem, $src\t# compressed ptr" %} 5199 ins_encode %{ 5200 address con = (address)$src$$constant; 5201 if (con == nullptr) { 5202 __ movl($mem$$Address, 0); 5203 } else { 5204 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5205 } 5206 %} 5207 ins_pipe(ialu_mem_imm); 5208 %} 5209 5210 instruct storeImmNKlass(memory mem, immNKlass src) 5211 %{ 5212 match(Set mem (StoreNKlass mem src)); 5213 5214 ins_cost(150); // XXX 5215 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5216 ins_encode %{ 5217 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5218 %} 5219 ins_pipe(ialu_mem_imm); 5220 %} 5221 5222 // Store Integer Immediate 5223 instruct storeImmI0(memory mem, immI_0 zero) 5224 %{ 5225 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5226 match(Set mem (StoreI mem zero)); 5227 5228 ins_cost(125); // XXX 5229 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5230 ins_encode %{ 5231 __ movl($mem$$Address, r12); 5232 %} 5233 ins_pipe(ialu_mem_reg); 5234 %} 5235 5236 instruct storeImmI(memory mem, immI src) 5237 %{ 5238 match(Set mem (StoreI mem src)); 5239 5240 ins_cost(150); 5241 format %{ "movl $mem, $src\t# int" %} 5242 ins_encode %{ 5243 __ movl($mem$$Address, $src$$constant); 5244 %} 5245 ins_pipe(ialu_mem_imm); 5246 %} 5247 5248 // Store Long Immediate 5249 instruct storeImmL0(memory mem, immL0 zero) 5250 %{ 5251 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5252 match(Set mem (StoreL mem zero)); 5253 5254 ins_cost(125); // XXX 5255 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5256 ins_encode %{ 5257 __ movq($mem$$Address, r12); 5258 %} 5259 ins_pipe(ialu_mem_reg); 5260 %} 5261 5262 instruct storeImmL(memory mem, immL32 src) 5263 %{ 5264 match(Set mem (StoreL mem src)); 5265 5266 ins_cost(150); 5267 format %{ "movq $mem, $src\t# long" %} 5268 ins_encode %{ 5269 __ movq($mem$$Address, $src$$constant); 5270 %} 5271 ins_pipe(ialu_mem_imm); 5272 %} 5273 5274 // Store Short/Char Immediate 5275 instruct storeImmC0(memory mem, immI_0 zero) 5276 %{ 5277 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5278 match(Set mem (StoreC mem zero)); 5279 5280 ins_cost(125); // XXX 5281 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5282 ins_encode %{ 5283 __ movw($mem$$Address, r12); 5284 %} 5285 ins_pipe(ialu_mem_reg); 5286 %} 5287 5288 instruct storeImmI16(memory mem, immI16 src) 5289 %{ 5290 predicate(UseStoreImmI16); 5291 match(Set mem (StoreC mem src)); 5292 5293 ins_cost(150); 5294 format %{ "movw $mem, $src\t# short/char" %} 5295 ins_encode %{ 5296 __ movw($mem$$Address, $src$$constant); 5297 %} 5298 ins_pipe(ialu_mem_imm); 5299 %} 5300 5301 // Store Byte Immediate 5302 instruct storeImmB0(memory mem, immI_0 zero) 5303 %{ 5304 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5305 match(Set mem (StoreB mem zero)); 5306 5307 ins_cost(125); // XXX 5308 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5309 ins_encode %{ 5310 __ movb($mem$$Address, r12); 5311 %} 5312 ins_pipe(ialu_mem_reg); 5313 %} 5314 5315 instruct storeImmB(memory mem, immI8 src) 5316 %{ 5317 match(Set mem (StoreB mem src)); 5318 5319 ins_cost(150); // XXX 5320 format %{ "movb $mem, $src\t# byte" %} 5321 ins_encode %{ 5322 __ movb($mem$$Address, $src$$constant); 5323 %} 5324 ins_pipe(ialu_mem_imm); 5325 %} 5326 5327 // Store CMS card-mark Immediate 5328 instruct storeImmCM0_reg(memory mem, immI_0 zero) 5329 %{ 5330 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5331 match(Set mem (StoreCM mem zero)); 5332 5333 ins_cost(125); // XXX 5334 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5335 ins_encode %{ 5336 __ movb($mem$$Address, r12); 5337 %} 5338 ins_pipe(ialu_mem_reg); 5339 %} 5340 5341 instruct storeImmCM0(memory mem, immI_0 src) 5342 %{ 5343 match(Set mem (StoreCM mem src)); 5344 5345 ins_cost(150); // XXX 5346 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5347 ins_encode %{ 5348 __ movb($mem$$Address, $src$$constant); 5349 %} 5350 ins_pipe(ialu_mem_imm); 5351 %} 5352 5353 // Store Float 5354 instruct storeF(memory mem, regF src) 5355 %{ 5356 match(Set mem (StoreF mem src)); 5357 5358 ins_cost(95); // XXX 5359 format %{ "movss $mem, $src\t# float" %} 5360 ins_encode %{ 5361 __ movflt($mem$$Address, $src$$XMMRegister); 5362 %} 5363 ins_pipe(pipe_slow); // XXX 5364 %} 5365 5366 // Store immediate Float value (it is faster than store from XMM register) 5367 instruct storeF0(memory mem, immF0 zero) 5368 %{ 5369 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5370 match(Set mem (StoreF mem zero)); 5371 5372 ins_cost(25); // XXX 5373 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5374 ins_encode %{ 5375 __ movl($mem$$Address, r12); 5376 %} 5377 ins_pipe(ialu_mem_reg); 5378 %} 5379 5380 instruct storeF_imm(memory mem, immF src) 5381 %{ 5382 match(Set mem (StoreF mem src)); 5383 5384 ins_cost(50); 5385 format %{ "movl $mem, $src\t# float" %} 5386 ins_encode %{ 5387 __ movl($mem$$Address, jint_cast($src$$constant)); 5388 %} 5389 ins_pipe(ialu_mem_imm); 5390 %} 5391 5392 // Store Double 5393 instruct storeD(memory mem, regD src) 5394 %{ 5395 match(Set mem (StoreD mem src)); 5396 5397 ins_cost(95); // XXX 5398 format %{ "movsd $mem, $src\t# double" %} 5399 ins_encode %{ 5400 __ movdbl($mem$$Address, $src$$XMMRegister); 5401 %} 5402 ins_pipe(pipe_slow); // XXX 5403 %} 5404 5405 // Store immediate double 0.0 (it is faster than store from XMM register) 5406 instruct storeD0_imm(memory mem, immD0 src) 5407 %{ 5408 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5409 match(Set mem (StoreD mem src)); 5410 5411 ins_cost(50); 5412 format %{ "movq $mem, $src\t# double 0." %} 5413 ins_encode %{ 5414 __ movq($mem$$Address, $src$$constant); 5415 %} 5416 ins_pipe(ialu_mem_imm); 5417 %} 5418 5419 instruct storeD0(memory mem, immD0 zero) 5420 %{ 5421 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5422 match(Set mem (StoreD mem zero)); 5423 5424 ins_cost(25); // XXX 5425 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5426 ins_encode %{ 5427 __ movq($mem$$Address, r12); 5428 %} 5429 ins_pipe(ialu_mem_reg); 5430 %} 5431 5432 instruct storeSSI(stackSlotI dst, rRegI src) 5433 %{ 5434 match(Set dst src); 5435 5436 ins_cost(100); 5437 format %{ "movl $dst, $src\t# int stk" %} 5438 ins_encode %{ 5439 __ movl($dst$$Address, $src$$Register); 5440 %} 5441 ins_pipe( ialu_mem_reg ); 5442 %} 5443 5444 instruct storeSSL(stackSlotL dst, rRegL src) 5445 %{ 5446 match(Set dst src); 5447 5448 ins_cost(100); 5449 format %{ "movq $dst, $src\t# long stk" %} 5450 ins_encode %{ 5451 __ movq($dst$$Address, $src$$Register); 5452 %} 5453 ins_pipe(ialu_mem_reg); 5454 %} 5455 5456 instruct storeSSP(stackSlotP dst, rRegP src) 5457 %{ 5458 match(Set dst src); 5459 5460 ins_cost(100); 5461 format %{ "movq $dst, $src\t# ptr stk" %} 5462 ins_encode %{ 5463 __ movq($dst$$Address, $src$$Register); 5464 %} 5465 ins_pipe(ialu_mem_reg); 5466 %} 5467 5468 instruct storeSSF(stackSlotF dst, regF src) 5469 %{ 5470 match(Set dst src); 5471 5472 ins_cost(95); // XXX 5473 format %{ "movss $dst, $src\t# float stk" %} 5474 ins_encode %{ 5475 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5476 %} 5477 ins_pipe(pipe_slow); // XXX 5478 %} 5479 5480 instruct storeSSD(stackSlotD dst, regD src) 5481 %{ 5482 match(Set dst src); 5483 5484 ins_cost(95); // XXX 5485 format %{ "movsd $dst, $src\t# double stk" %} 5486 ins_encode %{ 5487 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5488 %} 5489 ins_pipe(pipe_slow); // XXX 5490 %} 5491 5492 instruct cacheWB(indirect addr) 5493 %{ 5494 predicate(VM_Version::supports_data_cache_line_flush()); 5495 match(CacheWB addr); 5496 5497 ins_cost(100); 5498 format %{"cache wb $addr" %} 5499 ins_encode %{ 5500 assert($addr->index_position() < 0, "should be"); 5501 assert($addr$$disp == 0, "should be"); 5502 __ cache_wb(Address($addr$$base$$Register, 0)); 5503 %} 5504 ins_pipe(pipe_slow); // XXX 5505 %} 5506 5507 instruct cacheWBPreSync() 5508 %{ 5509 predicate(VM_Version::supports_data_cache_line_flush()); 5510 match(CacheWBPreSync); 5511 5512 ins_cost(100); 5513 format %{"cache wb presync" %} 5514 ins_encode %{ 5515 __ cache_wbsync(true); 5516 %} 5517 ins_pipe(pipe_slow); // XXX 5518 %} 5519 5520 instruct cacheWBPostSync() 5521 %{ 5522 predicate(VM_Version::supports_data_cache_line_flush()); 5523 match(CacheWBPostSync); 5524 5525 ins_cost(100); 5526 format %{"cache wb postsync" %} 5527 ins_encode %{ 5528 __ cache_wbsync(false); 5529 %} 5530 ins_pipe(pipe_slow); // XXX 5531 %} 5532 5533 //----------BSWAP Instructions------------------------------------------------- 5534 instruct bytes_reverse_int(rRegI dst) %{ 5535 match(Set dst (ReverseBytesI dst)); 5536 5537 format %{ "bswapl $dst" %} 5538 ins_encode %{ 5539 __ bswapl($dst$$Register); 5540 %} 5541 ins_pipe( ialu_reg ); 5542 %} 5543 5544 instruct bytes_reverse_long(rRegL dst) %{ 5545 match(Set dst (ReverseBytesL dst)); 5546 5547 format %{ "bswapq $dst" %} 5548 ins_encode %{ 5549 __ bswapq($dst$$Register); 5550 %} 5551 ins_pipe( ialu_reg); 5552 %} 5553 5554 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5555 match(Set dst (ReverseBytesUS dst)); 5556 effect(KILL cr); 5557 5558 format %{ "bswapl $dst\n\t" 5559 "shrl $dst,16\n\t" %} 5560 ins_encode %{ 5561 __ bswapl($dst$$Register); 5562 __ shrl($dst$$Register, 16); 5563 %} 5564 ins_pipe( ialu_reg ); 5565 %} 5566 5567 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5568 match(Set dst (ReverseBytesS dst)); 5569 effect(KILL cr); 5570 5571 format %{ "bswapl $dst\n\t" 5572 "sar $dst,16\n\t" %} 5573 ins_encode %{ 5574 __ bswapl($dst$$Register); 5575 __ sarl($dst$$Register, 16); 5576 %} 5577 ins_pipe( ialu_reg ); 5578 %} 5579 5580 //---------- Zeros Count Instructions ------------------------------------------ 5581 5582 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5583 predicate(UseCountLeadingZerosInstruction); 5584 match(Set dst (CountLeadingZerosI src)); 5585 effect(KILL cr); 5586 5587 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5588 ins_encode %{ 5589 __ lzcntl($dst$$Register, $src$$Register); 5590 %} 5591 ins_pipe(ialu_reg); 5592 %} 5593 5594 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5595 predicate(UseCountLeadingZerosInstruction); 5596 match(Set dst (CountLeadingZerosI (LoadI src))); 5597 effect(KILL cr); 5598 ins_cost(175); 5599 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5600 ins_encode %{ 5601 __ lzcntl($dst$$Register, $src$$Address); 5602 %} 5603 ins_pipe(ialu_reg_mem); 5604 %} 5605 5606 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5607 predicate(!UseCountLeadingZerosInstruction); 5608 match(Set dst (CountLeadingZerosI src)); 5609 effect(KILL cr); 5610 5611 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5612 "jnz skip\n\t" 5613 "movl $dst, -1\n" 5614 "skip:\n\t" 5615 "negl $dst\n\t" 5616 "addl $dst, 31" %} 5617 ins_encode %{ 5618 Register Rdst = $dst$$Register; 5619 Register Rsrc = $src$$Register; 5620 Label skip; 5621 __ bsrl(Rdst, Rsrc); 5622 __ jccb(Assembler::notZero, skip); 5623 __ movl(Rdst, -1); 5624 __ bind(skip); 5625 __ negl(Rdst); 5626 __ addl(Rdst, BitsPerInt - 1); 5627 %} 5628 ins_pipe(ialu_reg); 5629 %} 5630 5631 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5632 predicate(UseCountLeadingZerosInstruction); 5633 match(Set dst (CountLeadingZerosL src)); 5634 effect(KILL cr); 5635 5636 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5637 ins_encode %{ 5638 __ lzcntq($dst$$Register, $src$$Register); 5639 %} 5640 ins_pipe(ialu_reg); 5641 %} 5642 5643 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5644 predicate(UseCountLeadingZerosInstruction); 5645 match(Set dst (CountLeadingZerosL (LoadL src))); 5646 effect(KILL cr); 5647 ins_cost(175); 5648 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5649 ins_encode %{ 5650 __ lzcntq($dst$$Register, $src$$Address); 5651 %} 5652 ins_pipe(ialu_reg_mem); 5653 %} 5654 5655 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5656 predicate(!UseCountLeadingZerosInstruction); 5657 match(Set dst (CountLeadingZerosL src)); 5658 effect(KILL cr); 5659 5660 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5661 "jnz skip\n\t" 5662 "movl $dst, -1\n" 5663 "skip:\n\t" 5664 "negl $dst\n\t" 5665 "addl $dst, 63" %} 5666 ins_encode %{ 5667 Register Rdst = $dst$$Register; 5668 Register Rsrc = $src$$Register; 5669 Label skip; 5670 __ bsrq(Rdst, Rsrc); 5671 __ jccb(Assembler::notZero, skip); 5672 __ movl(Rdst, -1); 5673 __ bind(skip); 5674 __ negl(Rdst); 5675 __ addl(Rdst, BitsPerLong - 1); 5676 %} 5677 ins_pipe(ialu_reg); 5678 %} 5679 5680 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5681 predicate(UseCountTrailingZerosInstruction); 5682 match(Set dst (CountTrailingZerosI src)); 5683 effect(KILL cr); 5684 5685 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5686 ins_encode %{ 5687 __ tzcntl($dst$$Register, $src$$Register); 5688 %} 5689 ins_pipe(ialu_reg); 5690 %} 5691 5692 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5693 predicate(UseCountTrailingZerosInstruction); 5694 match(Set dst (CountTrailingZerosI (LoadI src))); 5695 effect(KILL cr); 5696 ins_cost(175); 5697 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5698 ins_encode %{ 5699 __ tzcntl($dst$$Register, $src$$Address); 5700 %} 5701 ins_pipe(ialu_reg_mem); 5702 %} 5703 5704 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5705 predicate(!UseCountTrailingZerosInstruction); 5706 match(Set dst (CountTrailingZerosI src)); 5707 effect(KILL cr); 5708 5709 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5710 "jnz done\n\t" 5711 "movl $dst, 32\n" 5712 "done:" %} 5713 ins_encode %{ 5714 Register Rdst = $dst$$Register; 5715 Label done; 5716 __ bsfl(Rdst, $src$$Register); 5717 __ jccb(Assembler::notZero, done); 5718 __ movl(Rdst, BitsPerInt); 5719 __ bind(done); 5720 %} 5721 ins_pipe(ialu_reg); 5722 %} 5723 5724 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5725 predicate(UseCountTrailingZerosInstruction); 5726 match(Set dst (CountTrailingZerosL src)); 5727 effect(KILL cr); 5728 5729 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5730 ins_encode %{ 5731 __ tzcntq($dst$$Register, $src$$Register); 5732 %} 5733 ins_pipe(ialu_reg); 5734 %} 5735 5736 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5737 predicate(UseCountTrailingZerosInstruction); 5738 match(Set dst (CountTrailingZerosL (LoadL src))); 5739 effect(KILL cr); 5740 ins_cost(175); 5741 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5742 ins_encode %{ 5743 __ tzcntq($dst$$Register, $src$$Address); 5744 %} 5745 ins_pipe(ialu_reg_mem); 5746 %} 5747 5748 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5749 predicate(!UseCountTrailingZerosInstruction); 5750 match(Set dst (CountTrailingZerosL src)); 5751 effect(KILL cr); 5752 5753 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5754 "jnz done\n\t" 5755 "movl $dst, 64\n" 5756 "done:" %} 5757 ins_encode %{ 5758 Register Rdst = $dst$$Register; 5759 Label done; 5760 __ bsfq(Rdst, $src$$Register); 5761 __ jccb(Assembler::notZero, done); 5762 __ movl(Rdst, BitsPerLong); 5763 __ bind(done); 5764 %} 5765 ins_pipe(ialu_reg); 5766 %} 5767 5768 //--------------- Reverse Operation Instructions ---------------- 5769 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5770 predicate(!VM_Version::supports_gfni()); 5771 match(Set dst (ReverseI src)); 5772 effect(TEMP dst, TEMP rtmp, KILL cr); 5773 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5774 ins_encode %{ 5775 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5776 %} 5777 ins_pipe( ialu_reg ); 5778 %} 5779 5780 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5781 predicate(VM_Version::supports_gfni()); 5782 match(Set dst (ReverseI src)); 5783 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5784 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5785 ins_encode %{ 5786 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5787 %} 5788 ins_pipe( ialu_reg ); 5789 %} 5790 5791 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5792 predicate(!VM_Version::supports_gfni()); 5793 match(Set dst (ReverseL src)); 5794 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5795 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5796 ins_encode %{ 5797 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5798 %} 5799 ins_pipe( ialu_reg ); 5800 %} 5801 5802 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5803 predicate(VM_Version::supports_gfni()); 5804 match(Set dst (ReverseL src)); 5805 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5806 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5807 ins_encode %{ 5808 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5809 %} 5810 ins_pipe( ialu_reg ); 5811 %} 5812 5813 //---------- Population Count Instructions ------------------------------------- 5814 5815 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5816 predicate(UsePopCountInstruction); 5817 match(Set dst (PopCountI src)); 5818 effect(KILL cr); 5819 5820 format %{ "popcnt $dst, $src" %} 5821 ins_encode %{ 5822 __ popcntl($dst$$Register, $src$$Register); 5823 %} 5824 ins_pipe(ialu_reg); 5825 %} 5826 5827 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5828 predicate(UsePopCountInstruction); 5829 match(Set dst (PopCountI (LoadI mem))); 5830 effect(KILL cr); 5831 5832 format %{ "popcnt $dst, $mem" %} 5833 ins_encode %{ 5834 __ popcntl($dst$$Register, $mem$$Address); 5835 %} 5836 ins_pipe(ialu_reg); 5837 %} 5838 5839 // Note: Long.bitCount(long) returns an int. 5840 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5841 predicate(UsePopCountInstruction); 5842 match(Set dst (PopCountL src)); 5843 effect(KILL cr); 5844 5845 format %{ "popcnt $dst, $src" %} 5846 ins_encode %{ 5847 __ popcntq($dst$$Register, $src$$Register); 5848 %} 5849 ins_pipe(ialu_reg); 5850 %} 5851 5852 // Note: Long.bitCount(long) returns an int. 5853 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5854 predicate(UsePopCountInstruction); 5855 match(Set dst (PopCountL (LoadL mem))); 5856 effect(KILL cr); 5857 5858 format %{ "popcnt $dst, $mem" %} 5859 ins_encode %{ 5860 __ popcntq($dst$$Register, $mem$$Address); 5861 %} 5862 ins_pipe(ialu_reg); 5863 %} 5864 5865 5866 //----------MemBar Instructions----------------------------------------------- 5867 // Memory barrier flavors 5868 5869 instruct membar_acquire() 5870 %{ 5871 match(MemBarAcquire); 5872 match(LoadFence); 5873 ins_cost(0); 5874 5875 size(0); 5876 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5877 ins_encode(); 5878 ins_pipe(empty); 5879 %} 5880 5881 instruct membar_acquire_lock() 5882 %{ 5883 match(MemBarAcquireLock); 5884 ins_cost(0); 5885 5886 size(0); 5887 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5888 ins_encode(); 5889 ins_pipe(empty); 5890 %} 5891 5892 instruct membar_release() 5893 %{ 5894 match(MemBarRelease); 5895 match(StoreFence); 5896 ins_cost(0); 5897 5898 size(0); 5899 format %{ "MEMBAR-release ! (empty encoding)" %} 5900 ins_encode(); 5901 ins_pipe(empty); 5902 %} 5903 5904 instruct membar_release_lock() 5905 %{ 5906 match(MemBarReleaseLock); 5907 ins_cost(0); 5908 5909 size(0); 5910 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5911 ins_encode(); 5912 ins_pipe(empty); 5913 %} 5914 5915 instruct membar_volatile(rFlagsReg cr) %{ 5916 match(MemBarVolatile); 5917 effect(KILL cr); 5918 ins_cost(400); 5919 5920 format %{ 5921 $$template 5922 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5923 %} 5924 ins_encode %{ 5925 __ membar(Assembler::StoreLoad); 5926 %} 5927 ins_pipe(pipe_slow); 5928 %} 5929 5930 instruct unnecessary_membar_volatile() 5931 %{ 5932 match(MemBarVolatile); 5933 predicate(Matcher::post_store_load_barrier(n)); 5934 ins_cost(0); 5935 5936 size(0); 5937 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5938 ins_encode(); 5939 ins_pipe(empty); 5940 %} 5941 5942 instruct membar_storestore() %{ 5943 match(MemBarStoreStore); 5944 match(StoreStoreFence); 5945 ins_cost(0); 5946 5947 size(0); 5948 format %{ "MEMBAR-storestore (empty encoding)" %} 5949 ins_encode( ); 5950 ins_pipe(empty); 5951 %} 5952 5953 //----------Move Instructions-------------------------------------------------- 5954 5955 instruct castX2P(rRegP dst, rRegL src) 5956 %{ 5957 match(Set dst (CastX2P src)); 5958 5959 format %{ "movq $dst, $src\t# long->ptr" %} 5960 ins_encode %{ 5961 if ($dst$$reg != $src$$reg) { 5962 __ movptr($dst$$Register, $src$$Register); 5963 } 5964 %} 5965 ins_pipe(ialu_reg_reg); // XXX 5966 %} 5967 5968 instruct castP2X(rRegL dst, rRegP src) 5969 %{ 5970 match(Set dst (CastP2X src)); 5971 5972 format %{ "movq $dst, $src\t# ptr -> long" %} 5973 ins_encode %{ 5974 if ($dst$$reg != $src$$reg) { 5975 __ movptr($dst$$Register, $src$$Register); 5976 } 5977 %} 5978 ins_pipe(ialu_reg_reg); // XXX 5979 %} 5980 5981 // Convert oop into int for vectors alignment masking 5982 instruct convP2I(rRegI dst, rRegP src) 5983 %{ 5984 match(Set dst (ConvL2I (CastP2X src))); 5985 5986 format %{ "movl $dst, $src\t# ptr -> int" %} 5987 ins_encode %{ 5988 __ movl($dst$$Register, $src$$Register); 5989 %} 5990 ins_pipe(ialu_reg_reg); // XXX 5991 %} 5992 5993 // Convert compressed oop into int for vectors alignment masking 5994 // in case of 32bit oops (heap < 4Gb). 5995 instruct convN2I(rRegI dst, rRegN src) 5996 %{ 5997 predicate(CompressedOops::shift() == 0); 5998 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5999 6000 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6001 ins_encode %{ 6002 __ movl($dst$$Register, $src$$Register); 6003 %} 6004 ins_pipe(ialu_reg_reg); // XXX 6005 %} 6006 6007 // Convert oop pointer into compressed form 6008 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6009 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6010 match(Set dst (EncodeP src)); 6011 effect(KILL cr); 6012 format %{ "encode_heap_oop $dst,$src" %} 6013 ins_encode %{ 6014 Register s = $src$$Register; 6015 Register d = $dst$$Register; 6016 if (s != d) { 6017 __ movq(d, s); 6018 } 6019 __ encode_heap_oop(d); 6020 %} 6021 ins_pipe(ialu_reg_long); 6022 %} 6023 6024 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6025 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6026 match(Set dst (EncodeP src)); 6027 effect(KILL cr); 6028 format %{ "encode_heap_oop_not_null $dst,$src" %} 6029 ins_encode %{ 6030 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6031 %} 6032 ins_pipe(ialu_reg_long); 6033 %} 6034 6035 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6036 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6037 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6038 match(Set dst (DecodeN src)); 6039 effect(KILL cr); 6040 format %{ "decode_heap_oop $dst,$src" %} 6041 ins_encode %{ 6042 Register s = $src$$Register; 6043 Register d = $dst$$Register; 6044 if (s != d) { 6045 __ movq(d, s); 6046 } 6047 __ decode_heap_oop(d); 6048 %} 6049 ins_pipe(ialu_reg_long); 6050 %} 6051 6052 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6053 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6054 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6055 match(Set dst (DecodeN src)); 6056 effect(KILL cr); 6057 format %{ "decode_heap_oop_not_null $dst,$src" %} 6058 ins_encode %{ 6059 Register s = $src$$Register; 6060 Register d = $dst$$Register; 6061 if (s != d) { 6062 __ decode_heap_oop_not_null(d, s); 6063 } else { 6064 __ decode_heap_oop_not_null(d); 6065 } 6066 %} 6067 ins_pipe(ialu_reg_long); 6068 %} 6069 6070 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6071 match(Set dst (EncodePKlass src)); 6072 effect(TEMP dst, KILL cr); 6073 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6074 ins_encode %{ 6075 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6076 %} 6077 ins_pipe(ialu_reg_long); 6078 %} 6079 6080 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6081 match(Set dst (DecodeNKlass src)); 6082 effect(TEMP dst, KILL cr); 6083 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6084 ins_encode %{ 6085 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6086 %} 6087 ins_pipe(ialu_reg_long); 6088 %} 6089 6090 //----------Conditional Move--------------------------------------------------- 6091 // Jump 6092 // dummy instruction for generating temp registers 6093 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6094 match(Jump (LShiftL switch_val shift)); 6095 ins_cost(350); 6096 predicate(false); 6097 effect(TEMP dest); 6098 6099 format %{ "leaq $dest, [$constantaddress]\n\t" 6100 "jmp [$dest + $switch_val << $shift]\n\t" %} 6101 ins_encode %{ 6102 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6103 // to do that and the compiler is using that register as one it can allocate. 6104 // So we build it all by hand. 6105 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6106 // ArrayAddress dispatch(table, index); 6107 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6108 __ lea($dest$$Register, $constantaddress); 6109 __ jmp(dispatch); 6110 %} 6111 ins_pipe(pipe_jmp); 6112 %} 6113 6114 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6115 match(Jump (AddL (LShiftL switch_val shift) offset)); 6116 ins_cost(350); 6117 effect(TEMP dest); 6118 6119 format %{ "leaq $dest, [$constantaddress]\n\t" 6120 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6121 ins_encode %{ 6122 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6123 // to do that and the compiler is using that register as one it can allocate. 6124 // So we build it all by hand. 6125 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6126 // ArrayAddress dispatch(table, index); 6127 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6128 __ lea($dest$$Register, $constantaddress); 6129 __ jmp(dispatch); 6130 %} 6131 ins_pipe(pipe_jmp); 6132 %} 6133 6134 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6135 match(Jump switch_val); 6136 ins_cost(350); 6137 effect(TEMP dest); 6138 6139 format %{ "leaq $dest, [$constantaddress]\n\t" 6140 "jmp [$dest + $switch_val]\n\t" %} 6141 ins_encode %{ 6142 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6143 // to do that and the compiler is using that register as one it can allocate. 6144 // So we build it all by hand. 6145 // Address index(noreg, switch_reg, Address::times_1); 6146 // ArrayAddress dispatch(table, index); 6147 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6148 __ lea($dest$$Register, $constantaddress); 6149 __ jmp(dispatch); 6150 %} 6151 ins_pipe(pipe_jmp); 6152 %} 6153 6154 // Conditional move 6155 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6156 %{ 6157 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6158 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6159 6160 ins_cost(100); // XXX 6161 format %{ "setbn$cop $dst\t# signed, int" %} 6162 ins_encode %{ 6163 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6164 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6165 %} 6166 ins_pipe(ialu_reg); 6167 %} 6168 6169 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6170 %{ 6171 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6172 6173 ins_cost(200); // XXX 6174 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6175 ins_encode %{ 6176 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6177 %} 6178 ins_pipe(pipe_cmov_reg); 6179 %} 6180 6181 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6182 %{ 6183 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6184 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6185 6186 ins_cost(100); // XXX 6187 format %{ "setbn$cop $dst\t# unsigned, int" %} 6188 ins_encode %{ 6189 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6190 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6191 %} 6192 ins_pipe(ialu_reg); 6193 %} 6194 6195 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6196 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6197 6198 ins_cost(200); // XXX 6199 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6200 ins_encode %{ 6201 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6202 %} 6203 ins_pipe(pipe_cmov_reg); 6204 %} 6205 6206 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6207 %{ 6208 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6209 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6210 6211 ins_cost(100); // XXX 6212 format %{ "setbn$cop $dst\t# unsigned, int" %} 6213 ins_encode %{ 6214 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6215 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6216 %} 6217 ins_pipe(ialu_reg); 6218 %} 6219 6220 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6221 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6222 ins_cost(200); 6223 expand %{ 6224 cmovI_regU(cop, cr, dst, src); 6225 %} 6226 %} 6227 6228 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6229 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6230 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6231 6232 ins_cost(200); // XXX 6233 format %{ "cmovpl $dst, $src\n\t" 6234 "cmovnel $dst, $src" %} 6235 ins_encode %{ 6236 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6237 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6238 %} 6239 ins_pipe(pipe_cmov_reg); 6240 %} 6241 6242 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6243 // inputs of the CMove 6244 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6245 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6246 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6247 6248 ins_cost(200); // XXX 6249 format %{ "cmovpl $dst, $src\n\t" 6250 "cmovnel $dst, $src" %} 6251 ins_encode %{ 6252 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6253 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6254 %} 6255 ins_pipe(pipe_cmov_reg); 6256 %} 6257 6258 // Conditional move 6259 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6260 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6261 6262 ins_cost(250); // XXX 6263 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6264 ins_encode %{ 6265 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6266 %} 6267 ins_pipe(pipe_cmov_mem); 6268 %} 6269 6270 // Conditional move 6271 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6272 %{ 6273 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6274 6275 ins_cost(250); // XXX 6276 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6277 ins_encode %{ 6278 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6279 %} 6280 ins_pipe(pipe_cmov_mem); 6281 %} 6282 6283 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6284 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6285 ins_cost(250); 6286 expand %{ 6287 cmovI_memU(cop, cr, dst, src); 6288 %} 6289 %} 6290 6291 // Conditional move 6292 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6293 %{ 6294 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6295 6296 ins_cost(200); // XXX 6297 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6298 ins_encode %{ 6299 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6300 %} 6301 ins_pipe(pipe_cmov_reg); 6302 %} 6303 6304 // Conditional move 6305 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6306 %{ 6307 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6308 6309 ins_cost(200); // XXX 6310 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6311 ins_encode %{ 6312 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6313 %} 6314 ins_pipe(pipe_cmov_reg); 6315 %} 6316 6317 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6318 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6319 ins_cost(200); 6320 expand %{ 6321 cmovN_regU(cop, cr, dst, src); 6322 %} 6323 %} 6324 6325 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6326 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6327 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6328 6329 ins_cost(200); // XXX 6330 format %{ "cmovpl $dst, $src\n\t" 6331 "cmovnel $dst, $src" %} 6332 ins_encode %{ 6333 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6334 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6335 %} 6336 ins_pipe(pipe_cmov_reg); 6337 %} 6338 6339 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6340 // inputs of the CMove 6341 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6342 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6343 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6344 6345 ins_cost(200); // XXX 6346 format %{ "cmovpl $dst, $src\n\t" 6347 "cmovnel $dst, $src" %} 6348 ins_encode %{ 6349 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6350 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6351 %} 6352 ins_pipe(pipe_cmov_reg); 6353 %} 6354 6355 // Conditional move 6356 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6357 %{ 6358 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6359 6360 ins_cost(200); // XXX 6361 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6362 ins_encode %{ 6363 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6364 %} 6365 ins_pipe(pipe_cmov_reg); // XXX 6366 %} 6367 6368 // Conditional move 6369 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6370 %{ 6371 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6372 6373 ins_cost(200); // XXX 6374 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6375 ins_encode %{ 6376 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6377 %} 6378 ins_pipe(pipe_cmov_reg); // XXX 6379 %} 6380 6381 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6382 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6383 ins_cost(200); 6384 expand %{ 6385 cmovP_regU(cop, cr, dst, src); 6386 %} 6387 %} 6388 6389 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6390 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6391 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6392 6393 ins_cost(200); // XXX 6394 format %{ "cmovpq $dst, $src\n\t" 6395 "cmovneq $dst, $src" %} 6396 ins_encode %{ 6397 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6398 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6399 %} 6400 ins_pipe(pipe_cmov_reg); 6401 %} 6402 6403 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6404 // inputs of the CMove 6405 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6406 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6407 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6408 6409 ins_cost(200); // XXX 6410 format %{ "cmovpq $dst, $src\n\t" 6411 "cmovneq $dst, $src" %} 6412 ins_encode %{ 6413 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6414 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6415 %} 6416 ins_pipe(pipe_cmov_reg); 6417 %} 6418 6419 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6420 %{ 6421 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6422 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6423 6424 ins_cost(100); // XXX 6425 format %{ "setbn$cop $dst\t# signed, long" %} 6426 ins_encode %{ 6427 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6428 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6429 %} 6430 ins_pipe(ialu_reg); 6431 %} 6432 6433 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6434 %{ 6435 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6436 6437 ins_cost(200); // XXX 6438 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6439 ins_encode %{ 6440 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6441 %} 6442 ins_pipe(pipe_cmov_reg); // XXX 6443 %} 6444 6445 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6446 %{ 6447 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6448 6449 ins_cost(200); // XXX 6450 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6451 ins_encode %{ 6452 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6453 %} 6454 ins_pipe(pipe_cmov_mem); // XXX 6455 %} 6456 6457 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6458 %{ 6459 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6460 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6461 6462 ins_cost(100); // XXX 6463 format %{ "setbn$cop $dst\t# unsigned, long" %} 6464 ins_encode %{ 6465 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6466 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6467 %} 6468 ins_pipe(ialu_reg); 6469 %} 6470 6471 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6472 %{ 6473 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6474 6475 ins_cost(200); // XXX 6476 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6477 ins_encode %{ 6478 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6479 %} 6480 ins_pipe(pipe_cmov_reg); // XXX 6481 %} 6482 6483 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6484 %{ 6485 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6486 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6487 6488 ins_cost(100); // XXX 6489 format %{ "setbn$cop $dst\t# unsigned, long" %} 6490 ins_encode %{ 6491 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6492 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6493 %} 6494 ins_pipe(ialu_reg); 6495 %} 6496 6497 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6498 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6499 ins_cost(200); 6500 expand %{ 6501 cmovL_regU(cop, cr, dst, src); 6502 %} 6503 %} 6504 6505 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6506 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6507 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6508 6509 ins_cost(200); // XXX 6510 format %{ "cmovpq $dst, $src\n\t" 6511 "cmovneq $dst, $src" %} 6512 ins_encode %{ 6513 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6514 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6515 %} 6516 ins_pipe(pipe_cmov_reg); 6517 %} 6518 6519 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6520 // inputs of the CMove 6521 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6522 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6523 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6524 6525 ins_cost(200); // XXX 6526 format %{ "cmovpq $dst, $src\n\t" 6527 "cmovneq $dst, $src" %} 6528 ins_encode %{ 6529 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6530 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6531 %} 6532 ins_pipe(pipe_cmov_reg); 6533 %} 6534 6535 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6536 %{ 6537 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6538 6539 ins_cost(200); // XXX 6540 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6541 ins_encode %{ 6542 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6543 %} 6544 ins_pipe(pipe_cmov_mem); // XXX 6545 %} 6546 6547 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6548 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6549 ins_cost(200); 6550 expand %{ 6551 cmovL_memU(cop, cr, dst, src); 6552 %} 6553 %} 6554 6555 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6556 %{ 6557 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6558 6559 ins_cost(200); // XXX 6560 format %{ "jn$cop skip\t# signed cmove float\n\t" 6561 "movss $dst, $src\n" 6562 "skip:" %} 6563 ins_encode %{ 6564 Label Lskip; 6565 // Invert sense of branch from sense of CMOV 6566 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6567 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6568 __ bind(Lskip); 6569 %} 6570 ins_pipe(pipe_slow); 6571 %} 6572 6573 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6574 %{ 6575 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6576 6577 ins_cost(200); // XXX 6578 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6579 "movss $dst, $src\n" 6580 "skip:" %} 6581 ins_encode %{ 6582 Label Lskip; 6583 // Invert sense of branch from sense of CMOV 6584 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6585 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6586 __ bind(Lskip); 6587 %} 6588 ins_pipe(pipe_slow); 6589 %} 6590 6591 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6592 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6593 ins_cost(200); 6594 expand %{ 6595 cmovF_regU(cop, cr, dst, src); 6596 %} 6597 %} 6598 6599 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6600 %{ 6601 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6602 6603 ins_cost(200); // XXX 6604 format %{ "jn$cop skip\t# signed cmove double\n\t" 6605 "movsd $dst, $src\n" 6606 "skip:" %} 6607 ins_encode %{ 6608 Label Lskip; 6609 // Invert sense of branch from sense of CMOV 6610 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6611 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6612 __ bind(Lskip); 6613 %} 6614 ins_pipe(pipe_slow); 6615 %} 6616 6617 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6618 %{ 6619 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6620 6621 ins_cost(200); // XXX 6622 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6623 "movsd $dst, $src\n" 6624 "skip:" %} 6625 ins_encode %{ 6626 Label Lskip; 6627 // Invert sense of branch from sense of CMOV 6628 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6629 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6630 __ bind(Lskip); 6631 %} 6632 ins_pipe(pipe_slow); 6633 %} 6634 6635 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6636 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6637 ins_cost(200); 6638 expand %{ 6639 cmovD_regU(cop, cr, dst, src); 6640 %} 6641 %} 6642 6643 //----------Arithmetic Instructions-------------------------------------------- 6644 //----------Addition Instructions---------------------------------------------- 6645 6646 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6647 %{ 6648 match(Set dst (AddI dst src)); 6649 effect(KILL cr); 6650 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); 6651 format %{ "addl $dst, $src\t# int" %} 6652 ins_encode %{ 6653 __ addl($dst$$Register, $src$$Register); 6654 %} 6655 ins_pipe(ialu_reg_reg); 6656 %} 6657 6658 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6659 %{ 6660 match(Set dst (AddI dst src)); 6661 effect(KILL cr); 6662 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); 6663 6664 format %{ "addl $dst, $src\t# int" %} 6665 ins_encode %{ 6666 __ addl($dst$$Register, $src$$constant); 6667 %} 6668 ins_pipe( ialu_reg ); 6669 %} 6670 6671 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6672 %{ 6673 match(Set dst (AddI dst (LoadI src))); 6674 effect(KILL cr); 6675 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6676 6677 ins_cost(150); // XXX 6678 format %{ "addl $dst, $src\t# int" %} 6679 ins_encode %{ 6680 __ addl($dst$$Register, $src$$Address); 6681 %} 6682 ins_pipe(ialu_reg_mem); 6683 %} 6684 6685 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6686 %{ 6687 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6688 effect(KILL cr); 6689 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); 6690 6691 ins_cost(150); // XXX 6692 format %{ "addl $dst, $src\t# int" %} 6693 ins_encode %{ 6694 __ addl($dst$$Address, $src$$Register); 6695 %} 6696 ins_pipe(ialu_mem_reg); 6697 %} 6698 6699 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6700 %{ 6701 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6702 effect(KILL cr); 6703 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); 6704 6705 6706 ins_cost(125); // XXX 6707 format %{ "addl $dst, $src\t# int" %} 6708 ins_encode %{ 6709 __ addl($dst$$Address, $src$$constant); 6710 %} 6711 ins_pipe(ialu_mem_imm); 6712 %} 6713 6714 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6715 %{ 6716 predicate(UseIncDec); 6717 match(Set dst (AddI dst src)); 6718 effect(KILL cr); 6719 6720 format %{ "incl $dst\t# int" %} 6721 ins_encode %{ 6722 __ incrementl($dst$$Register); 6723 %} 6724 ins_pipe(ialu_reg); 6725 %} 6726 6727 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6728 %{ 6729 predicate(UseIncDec); 6730 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6731 effect(KILL cr); 6732 6733 ins_cost(125); // XXX 6734 format %{ "incl $dst\t# int" %} 6735 ins_encode %{ 6736 __ incrementl($dst$$Address); 6737 %} 6738 ins_pipe(ialu_mem_imm); 6739 %} 6740 6741 // XXX why does that use AddI 6742 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6743 %{ 6744 predicate(UseIncDec); 6745 match(Set dst (AddI dst src)); 6746 effect(KILL cr); 6747 6748 format %{ "decl $dst\t# int" %} 6749 ins_encode %{ 6750 __ decrementl($dst$$Register); 6751 %} 6752 ins_pipe(ialu_reg); 6753 %} 6754 6755 // XXX why does that use AddI 6756 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6757 %{ 6758 predicate(UseIncDec); 6759 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6760 effect(KILL cr); 6761 6762 ins_cost(125); // XXX 6763 format %{ "decl $dst\t# int" %} 6764 ins_encode %{ 6765 __ decrementl($dst$$Address); 6766 %} 6767 ins_pipe(ialu_mem_imm); 6768 %} 6769 6770 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6771 %{ 6772 predicate(VM_Version::supports_fast_2op_lea()); 6773 match(Set dst (AddI (LShiftI index scale) disp)); 6774 6775 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6776 ins_encode %{ 6777 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6778 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6779 %} 6780 ins_pipe(ialu_reg_reg); 6781 %} 6782 6783 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6784 %{ 6785 predicate(VM_Version::supports_fast_3op_lea()); 6786 match(Set dst (AddI (AddI base index) disp)); 6787 6788 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6789 ins_encode %{ 6790 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6791 %} 6792 ins_pipe(ialu_reg_reg); 6793 %} 6794 6795 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6796 %{ 6797 predicate(VM_Version::supports_fast_2op_lea()); 6798 match(Set dst (AddI base (LShiftI index scale))); 6799 6800 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6801 ins_encode %{ 6802 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6803 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6804 %} 6805 ins_pipe(ialu_reg_reg); 6806 %} 6807 6808 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6809 %{ 6810 predicate(VM_Version::supports_fast_3op_lea()); 6811 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6812 6813 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6814 ins_encode %{ 6815 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6816 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6817 %} 6818 ins_pipe(ialu_reg_reg); 6819 %} 6820 6821 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6822 %{ 6823 match(Set dst (AddL dst src)); 6824 effect(KILL cr); 6825 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6826 6827 format %{ "addq $dst, $src\t# long" %} 6828 ins_encode %{ 6829 __ addq($dst$$Register, $src$$Register); 6830 %} 6831 ins_pipe(ialu_reg_reg); 6832 %} 6833 6834 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6835 %{ 6836 match(Set dst (AddL dst src)); 6837 effect(KILL cr); 6838 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); 6839 6840 format %{ "addq $dst, $src\t# long" %} 6841 ins_encode %{ 6842 __ addq($dst$$Register, $src$$constant); 6843 %} 6844 ins_pipe( ialu_reg ); 6845 %} 6846 6847 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6848 %{ 6849 match(Set dst (AddL dst (LoadL src))); 6850 effect(KILL cr); 6851 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6852 6853 ins_cost(150); // XXX 6854 format %{ "addq $dst, $src\t# long" %} 6855 ins_encode %{ 6856 __ addq($dst$$Register, $src$$Address); 6857 %} 6858 ins_pipe(ialu_reg_mem); 6859 %} 6860 6861 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6862 %{ 6863 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6864 effect(KILL cr); 6865 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); 6866 6867 ins_cost(150); // XXX 6868 format %{ "addq $dst, $src\t# long" %} 6869 ins_encode %{ 6870 __ addq($dst$$Address, $src$$Register); 6871 %} 6872 ins_pipe(ialu_mem_reg); 6873 %} 6874 6875 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6876 %{ 6877 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6878 effect(KILL cr); 6879 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); 6880 6881 ins_cost(125); // XXX 6882 format %{ "addq $dst, $src\t# long" %} 6883 ins_encode %{ 6884 __ addq($dst$$Address, $src$$constant); 6885 %} 6886 ins_pipe(ialu_mem_imm); 6887 %} 6888 6889 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6890 %{ 6891 predicate(UseIncDec); 6892 match(Set dst (AddL dst src)); 6893 effect(KILL cr); 6894 6895 format %{ "incq $dst\t# long" %} 6896 ins_encode %{ 6897 __ incrementq($dst$$Register); 6898 %} 6899 ins_pipe(ialu_reg); 6900 %} 6901 6902 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6903 %{ 6904 predicate(UseIncDec); 6905 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6906 effect(KILL cr); 6907 6908 ins_cost(125); // XXX 6909 format %{ "incq $dst\t# long" %} 6910 ins_encode %{ 6911 __ incrementq($dst$$Address); 6912 %} 6913 ins_pipe(ialu_mem_imm); 6914 %} 6915 6916 // XXX why does that use AddL 6917 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6918 %{ 6919 predicate(UseIncDec); 6920 match(Set dst (AddL dst src)); 6921 effect(KILL cr); 6922 6923 format %{ "decq $dst\t# long" %} 6924 ins_encode %{ 6925 __ decrementq($dst$$Register); 6926 %} 6927 ins_pipe(ialu_reg); 6928 %} 6929 6930 // XXX why does that use AddL 6931 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6932 %{ 6933 predicate(UseIncDec); 6934 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6935 effect(KILL cr); 6936 6937 ins_cost(125); // XXX 6938 format %{ "decq $dst\t# long" %} 6939 ins_encode %{ 6940 __ decrementq($dst$$Address); 6941 %} 6942 ins_pipe(ialu_mem_imm); 6943 %} 6944 6945 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6946 %{ 6947 predicate(VM_Version::supports_fast_2op_lea()); 6948 match(Set dst (AddL (LShiftL index scale) disp)); 6949 6950 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6951 ins_encode %{ 6952 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6953 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6954 %} 6955 ins_pipe(ialu_reg_reg); 6956 %} 6957 6958 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6959 %{ 6960 predicate(VM_Version::supports_fast_3op_lea()); 6961 match(Set dst (AddL (AddL base index) disp)); 6962 6963 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6964 ins_encode %{ 6965 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6966 %} 6967 ins_pipe(ialu_reg_reg); 6968 %} 6969 6970 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6971 %{ 6972 predicate(VM_Version::supports_fast_2op_lea()); 6973 match(Set dst (AddL base (LShiftL index scale))); 6974 6975 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6976 ins_encode %{ 6977 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6978 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6979 %} 6980 ins_pipe(ialu_reg_reg); 6981 %} 6982 6983 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6984 %{ 6985 predicate(VM_Version::supports_fast_3op_lea()); 6986 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6987 6988 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6989 ins_encode %{ 6990 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6991 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6992 %} 6993 ins_pipe(ialu_reg_reg); 6994 %} 6995 6996 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6997 %{ 6998 match(Set dst (AddP dst src)); 6999 effect(KILL cr); 7000 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); 7001 7002 format %{ "addq $dst, $src\t# ptr" %} 7003 ins_encode %{ 7004 __ addq($dst$$Register, $src$$Register); 7005 %} 7006 ins_pipe(ialu_reg_reg); 7007 %} 7008 7009 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7010 %{ 7011 match(Set dst (AddP dst src)); 7012 effect(KILL cr); 7013 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); 7014 7015 format %{ "addq $dst, $src\t# ptr" %} 7016 ins_encode %{ 7017 __ addq($dst$$Register, $src$$constant); 7018 %} 7019 ins_pipe( ialu_reg ); 7020 %} 7021 7022 // XXX addP mem ops ???? 7023 7024 instruct checkCastPP(rRegP dst) 7025 %{ 7026 match(Set dst (CheckCastPP dst)); 7027 7028 size(0); 7029 format %{ "# checkcastPP of $dst" %} 7030 ins_encode(/* empty encoding */); 7031 ins_pipe(empty); 7032 %} 7033 7034 instruct castPP(rRegP dst) 7035 %{ 7036 match(Set dst (CastPP dst)); 7037 7038 size(0); 7039 format %{ "# castPP of $dst" %} 7040 ins_encode(/* empty encoding */); 7041 ins_pipe(empty); 7042 %} 7043 7044 instruct castII(rRegI dst) 7045 %{ 7046 match(Set dst (CastII dst)); 7047 7048 size(0); 7049 format %{ "# castII of $dst" %} 7050 ins_encode(/* empty encoding */); 7051 ins_cost(0); 7052 ins_pipe(empty); 7053 %} 7054 7055 instruct castLL(rRegL dst) 7056 %{ 7057 match(Set dst (CastLL dst)); 7058 7059 size(0); 7060 format %{ "# castLL of $dst" %} 7061 ins_encode(/* empty encoding */); 7062 ins_cost(0); 7063 ins_pipe(empty); 7064 %} 7065 7066 instruct castFF(regF dst) 7067 %{ 7068 match(Set dst (CastFF dst)); 7069 7070 size(0); 7071 format %{ "# castFF of $dst" %} 7072 ins_encode(/* empty encoding */); 7073 ins_cost(0); 7074 ins_pipe(empty); 7075 %} 7076 7077 instruct castDD(regD dst) 7078 %{ 7079 match(Set dst (CastDD dst)); 7080 7081 size(0); 7082 format %{ "# castDD of $dst" %} 7083 ins_encode(/* empty encoding */); 7084 ins_cost(0); 7085 ins_pipe(empty); 7086 %} 7087 7088 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7089 instruct compareAndSwapP(rRegI res, 7090 memory mem_ptr, 7091 rax_RegP oldval, rRegP newval, 7092 rFlagsReg cr) 7093 %{ 7094 predicate(n->as_LoadStore()->barrier_data() == 0); 7095 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7096 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7097 effect(KILL cr, KILL oldval); 7098 7099 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7100 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7101 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7102 ins_encode %{ 7103 __ lock(); 7104 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7105 __ setcc(Assembler::equal, $res$$Register); 7106 %} 7107 ins_pipe( pipe_cmpxchg ); 7108 %} 7109 7110 instruct compareAndSwapL(rRegI res, 7111 memory mem_ptr, 7112 rax_RegL oldval, rRegL newval, 7113 rFlagsReg cr) 7114 %{ 7115 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7116 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7117 effect(KILL cr, KILL oldval); 7118 7119 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7120 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7121 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7122 ins_encode %{ 7123 __ lock(); 7124 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7125 __ setcc(Assembler::equal, $res$$Register); 7126 %} 7127 ins_pipe( pipe_cmpxchg ); 7128 %} 7129 7130 instruct compareAndSwapI(rRegI res, 7131 memory mem_ptr, 7132 rax_RegI oldval, rRegI newval, 7133 rFlagsReg cr) 7134 %{ 7135 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7136 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7137 effect(KILL cr, KILL oldval); 7138 7139 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7140 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7141 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7142 ins_encode %{ 7143 __ lock(); 7144 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7145 __ setcc(Assembler::equal, $res$$Register); 7146 %} 7147 ins_pipe( pipe_cmpxchg ); 7148 %} 7149 7150 instruct compareAndSwapB(rRegI res, 7151 memory mem_ptr, 7152 rax_RegI oldval, rRegI newval, 7153 rFlagsReg cr) 7154 %{ 7155 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7156 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7157 effect(KILL cr, KILL oldval); 7158 7159 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7160 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7161 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7162 ins_encode %{ 7163 __ lock(); 7164 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7165 __ setcc(Assembler::equal, $res$$Register); 7166 %} 7167 ins_pipe( pipe_cmpxchg ); 7168 %} 7169 7170 instruct compareAndSwapS(rRegI res, 7171 memory mem_ptr, 7172 rax_RegI oldval, rRegI newval, 7173 rFlagsReg cr) 7174 %{ 7175 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7176 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7177 effect(KILL cr, KILL oldval); 7178 7179 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7180 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7181 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7182 ins_encode %{ 7183 __ lock(); 7184 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7185 __ setcc(Assembler::equal, $res$$Register); 7186 %} 7187 ins_pipe( pipe_cmpxchg ); 7188 %} 7189 7190 instruct compareAndSwapN(rRegI res, 7191 memory mem_ptr, 7192 rax_RegN oldval, rRegN newval, 7193 rFlagsReg cr) %{ 7194 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7195 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7196 effect(KILL cr, KILL oldval); 7197 7198 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7199 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7200 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7201 ins_encode %{ 7202 __ lock(); 7203 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7204 __ setcc(Assembler::equal, $res$$Register); 7205 %} 7206 ins_pipe( pipe_cmpxchg ); 7207 %} 7208 7209 instruct compareAndExchangeB( 7210 memory mem_ptr, 7211 rax_RegI oldval, rRegI newval, 7212 rFlagsReg cr) 7213 %{ 7214 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7215 effect(KILL cr); 7216 7217 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7218 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7219 ins_encode %{ 7220 __ lock(); 7221 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7222 %} 7223 ins_pipe( pipe_cmpxchg ); 7224 %} 7225 7226 instruct compareAndExchangeS( 7227 memory mem_ptr, 7228 rax_RegI oldval, rRegI newval, 7229 rFlagsReg cr) 7230 %{ 7231 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7232 effect(KILL cr); 7233 7234 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7235 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7236 ins_encode %{ 7237 __ lock(); 7238 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7239 %} 7240 ins_pipe( pipe_cmpxchg ); 7241 %} 7242 7243 instruct compareAndExchangeI( 7244 memory mem_ptr, 7245 rax_RegI oldval, rRegI newval, 7246 rFlagsReg cr) 7247 %{ 7248 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7249 effect(KILL cr); 7250 7251 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7252 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7253 ins_encode %{ 7254 __ lock(); 7255 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7256 %} 7257 ins_pipe( pipe_cmpxchg ); 7258 %} 7259 7260 instruct compareAndExchangeL( 7261 memory mem_ptr, 7262 rax_RegL oldval, rRegL newval, 7263 rFlagsReg cr) 7264 %{ 7265 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7266 effect(KILL cr); 7267 7268 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7269 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7270 ins_encode %{ 7271 __ lock(); 7272 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7273 %} 7274 ins_pipe( pipe_cmpxchg ); 7275 %} 7276 7277 instruct compareAndExchangeN( 7278 memory mem_ptr, 7279 rax_RegN oldval, rRegN newval, 7280 rFlagsReg cr) %{ 7281 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7282 effect(KILL cr); 7283 7284 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7285 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7286 ins_encode %{ 7287 __ lock(); 7288 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7289 %} 7290 ins_pipe( pipe_cmpxchg ); 7291 %} 7292 7293 instruct compareAndExchangeP( 7294 memory mem_ptr, 7295 rax_RegP oldval, rRegP newval, 7296 rFlagsReg cr) 7297 %{ 7298 predicate(n->as_LoadStore()->barrier_data() == 0); 7299 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7300 effect(KILL cr); 7301 7302 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7303 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7304 ins_encode %{ 7305 __ lock(); 7306 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7307 %} 7308 ins_pipe( pipe_cmpxchg ); 7309 %} 7310 7311 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7312 predicate(n->as_LoadStore()->result_not_used()); 7313 match(Set dummy (GetAndAddB mem add)); 7314 effect(KILL cr); 7315 format %{ "addb_lock $mem, $add" %} 7316 ins_encode %{ 7317 __ lock(); 7318 __ addb($mem$$Address, $add$$Register); 7319 %} 7320 ins_pipe(pipe_cmpxchg); 7321 %} 7322 7323 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7324 predicate(n->as_LoadStore()->result_not_used()); 7325 match(Set dummy (GetAndAddB mem add)); 7326 effect(KILL cr); 7327 format %{ "addb_lock $mem, $add" %} 7328 ins_encode %{ 7329 __ lock(); 7330 __ addb($mem$$Address, $add$$constant); 7331 %} 7332 ins_pipe(pipe_cmpxchg); 7333 %} 7334 7335 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7336 predicate(!n->as_LoadStore()->result_not_used()); 7337 match(Set newval (GetAndAddB mem newval)); 7338 effect(KILL cr); 7339 format %{ "xaddb_lock $mem, $newval" %} 7340 ins_encode %{ 7341 __ lock(); 7342 __ xaddb($mem$$Address, $newval$$Register); 7343 %} 7344 ins_pipe(pipe_cmpxchg); 7345 %} 7346 7347 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7348 predicate(n->as_LoadStore()->result_not_used()); 7349 match(Set dummy (GetAndAddS mem add)); 7350 effect(KILL cr); 7351 format %{ "addw_lock $mem, $add" %} 7352 ins_encode %{ 7353 __ lock(); 7354 __ addw($mem$$Address, $add$$Register); 7355 %} 7356 ins_pipe(pipe_cmpxchg); 7357 %} 7358 7359 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7360 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7361 match(Set dummy (GetAndAddS mem add)); 7362 effect(KILL cr); 7363 format %{ "addw_lock $mem, $add" %} 7364 ins_encode %{ 7365 __ lock(); 7366 __ addw($mem$$Address, $add$$constant); 7367 %} 7368 ins_pipe(pipe_cmpxchg); 7369 %} 7370 7371 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7372 predicate(!n->as_LoadStore()->result_not_used()); 7373 match(Set newval (GetAndAddS mem newval)); 7374 effect(KILL cr); 7375 format %{ "xaddw_lock $mem, $newval" %} 7376 ins_encode %{ 7377 __ lock(); 7378 __ xaddw($mem$$Address, $newval$$Register); 7379 %} 7380 ins_pipe(pipe_cmpxchg); 7381 %} 7382 7383 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7384 predicate(n->as_LoadStore()->result_not_used()); 7385 match(Set dummy (GetAndAddI mem add)); 7386 effect(KILL cr); 7387 format %{ "addl_lock $mem, $add" %} 7388 ins_encode %{ 7389 __ lock(); 7390 __ addl($mem$$Address, $add$$Register); 7391 %} 7392 ins_pipe(pipe_cmpxchg); 7393 %} 7394 7395 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7396 predicate(n->as_LoadStore()->result_not_used()); 7397 match(Set dummy (GetAndAddI mem add)); 7398 effect(KILL cr); 7399 format %{ "addl_lock $mem, $add" %} 7400 ins_encode %{ 7401 __ lock(); 7402 __ addl($mem$$Address, $add$$constant); 7403 %} 7404 ins_pipe(pipe_cmpxchg); 7405 %} 7406 7407 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7408 predicate(!n->as_LoadStore()->result_not_used()); 7409 match(Set newval (GetAndAddI mem newval)); 7410 effect(KILL cr); 7411 format %{ "xaddl_lock $mem, $newval" %} 7412 ins_encode %{ 7413 __ lock(); 7414 __ xaddl($mem$$Address, $newval$$Register); 7415 %} 7416 ins_pipe(pipe_cmpxchg); 7417 %} 7418 7419 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7420 predicate(n->as_LoadStore()->result_not_used()); 7421 match(Set dummy (GetAndAddL mem add)); 7422 effect(KILL cr); 7423 format %{ "addq_lock $mem, $add" %} 7424 ins_encode %{ 7425 __ lock(); 7426 __ addq($mem$$Address, $add$$Register); 7427 %} 7428 ins_pipe(pipe_cmpxchg); 7429 %} 7430 7431 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7432 predicate(n->as_LoadStore()->result_not_used()); 7433 match(Set dummy (GetAndAddL mem add)); 7434 effect(KILL cr); 7435 format %{ "addq_lock $mem, $add" %} 7436 ins_encode %{ 7437 __ lock(); 7438 __ addq($mem$$Address, $add$$constant); 7439 %} 7440 ins_pipe(pipe_cmpxchg); 7441 %} 7442 7443 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7444 predicate(!n->as_LoadStore()->result_not_used()); 7445 match(Set newval (GetAndAddL mem newval)); 7446 effect(KILL cr); 7447 format %{ "xaddq_lock $mem, $newval" %} 7448 ins_encode %{ 7449 __ lock(); 7450 __ xaddq($mem$$Address, $newval$$Register); 7451 %} 7452 ins_pipe(pipe_cmpxchg); 7453 %} 7454 7455 instruct xchgB( memory mem, rRegI newval) %{ 7456 match(Set newval (GetAndSetB mem newval)); 7457 format %{ "XCHGB $newval,[$mem]" %} 7458 ins_encode %{ 7459 __ xchgb($newval$$Register, $mem$$Address); 7460 %} 7461 ins_pipe( pipe_cmpxchg ); 7462 %} 7463 7464 instruct xchgS( memory mem, rRegI newval) %{ 7465 match(Set newval (GetAndSetS mem newval)); 7466 format %{ "XCHGW $newval,[$mem]" %} 7467 ins_encode %{ 7468 __ xchgw($newval$$Register, $mem$$Address); 7469 %} 7470 ins_pipe( pipe_cmpxchg ); 7471 %} 7472 7473 instruct xchgI( memory mem, rRegI newval) %{ 7474 match(Set newval (GetAndSetI mem newval)); 7475 format %{ "XCHGL $newval,[$mem]" %} 7476 ins_encode %{ 7477 __ xchgl($newval$$Register, $mem$$Address); 7478 %} 7479 ins_pipe( pipe_cmpxchg ); 7480 %} 7481 7482 instruct xchgL( memory mem, rRegL newval) %{ 7483 match(Set newval (GetAndSetL mem newval)); 7484 format %{ "XCHGL $newval,[$mem]" %} 7485 ins_encode %{ 7486 __ xchgq($newval$$Register, $mem$$Address); 7487 %} 7488 ins_pipe( pipe_cmpxchg ); 7489 %} 7490 7491 instruct xchgP( memory mem, rRegP newval) %{ 7492 match(Set newval (GetAndSetP mem newval)); 7493 predicate(n->as_LoadStore()->barrier_data() == 0); 7494 format %{ "XCHGQ $newval,[$mem]" %} 7495 ins_encode %{ 7496 __ xchgq($newval$$Register, $mem$$Address); 7497 %} 7498 ins_pipe( pipe_cmpxchg ); 7499 %} 7500 7501 instruct xchgN( memory mem, rRegN newval) %{ 7502 match(Set newval (GetAndSetN mem newval)); 7503 format %{ "XCHGL $newval,$mem]" %} 7504 ins_encode %{ 7505 __ xchgl($newval$$Register, $mem$$Address); 7506 %} 7507 ins_pipe( pipe_cmpxchg ); 7508 %} 7509 7510 //----------Abs Instructions------------------------------------------- 7511 7512 // Integer Absolute Instructions 7513 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7514 %{ 7515 match(Set dst (AbsI src)); 7516 effect(TEMP dst, KILL cr); 7517 format %{ "xorl $dst, $dst\t# abs int\n\t" 7518 "subl $dst, $src\n\t" 7519 "cmovll $dst, $src" %} 7520 ins_encode %{ 7521 __ xorl($dst$$Register, $dst$$Register); 7522 __ subl($dst$$Register, $src$$Register); 7523 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7524 %} 7525 7526 ins_pipe(ialu_reg_reg); 7527 %} 7528 7529 // Long Absolute Instructions 7530 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7531 %{ 7532 match(Set dst (AbsL src)); 7533 effect(TEMP dst, KILL cr); 7534 format %{ "xorl $dst, $dst\t# abs long\n\t" 7535 "subq $dst, $src\n\t" 7536 "cmovlq $dst, $src" %} 7537 ins_encode %{ 7538 __ xorl($dst$$Register, $dst$$Register); 7539 __ subq($dst$$Register, $src$$Register); 7540 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7541 %} 7542 7543 ins_pipe(ialu_reg_reg); 7544 %} 7545 7546 //----------Subtraction Instructions------------------------------------------- 7547 7548 // Integer Subtraction Instructions 7549 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7550 %{ 7551 match(Set dst (SubI dst src)); 7552 effect(KILL cr); 7553 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); 7554 7555 format %{ "subl $dst, $src\t# int" %} 7556 ins_encode %{ 7557 __ subl($dst$$Register, $src$$Register); 7558 %} 7559 ins_pipe(ialu_reg_reg); 7560 %} 7561 7562 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7563 %{ 7564 match(Set dst (SubI dst (LoadI src))); 7565 effect(KILL cr); 7566 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); 7567 7568 ins_cost(150); 7569 format %{ "subl $dst, $src\t# int" %} 7570 ins_encode %{ 7571 __ subl($dst$$Register, $src$$Address); 7572 %} 7573 ins_pipe(ialu_reg_mem); 7574 %} 7575 7576 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7577 %{ 7578 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7579 effect(KILL cr); 7580 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); 7581 7582 ins_cost(150); 7583 format %{ "subl $dst, $src\t# int" %} 7584 ins_encode %{ 7585 __ subl($dst$$Address, $src$$Register); 7586 %} 7587 ins_pipe(ialu_mem_reg); 7588 %} 7589 7590 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7591 %{ 7592 match(Set dst (SubL dst src)); 7593 effect(KILL cr); 7594 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); 7595 7596 format %{ "subq $dst, $src\t# long" %} 7597 ins_encode %{ 7598 __ subq($dst$$Register, $src$$Register); 7599 %} 7600 ins_pipe(ialu_reg_reg); 7601 %} 7602 7603 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7604 %{ 7605 match(Set dst (SubL dst (LoadL src))); 7606 effect(KILL cr); 7607 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); 7608 7609 ins_cost(150); 7610 format %{ "subq $dst, $src\t# long" %} 7611 ins_encode %{ 7612 __ subq($dst$$Register, $src$$Address); 7613 %} 7614 ins_pipe(ialu_reg_mem); 7615 %} 7616 7617 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7618 %{ 7619 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7620 effect(KILL cr); 7621 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); 7622 7623 ins_cost(150); 7624 format %{ "subq $dst, $src\t# long" %} 7625 ins_encode %{ 7626 __ subq($dst$$Address, $src$$Register); 7627 %} 7628 ins_pipe(ialu_mem_reg); 7629 %} 7630 7631 // Subtract from a pointer 7632 // XXX hmpf??? 7633 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7634 %{ 7635 match(Set dst (AddP dst (SubI zero src))); 7636 effect(KILL cr); 7637 7638 format %{ "subq $dst, $src\t# ptr - int" %} 7639 ins_encode %{ 7640 __ subq($dst$$Register, $src$$Register); 7641 %} 7642 ins_pipe(ialu_reg_reg); 7643 %} 7644 7645 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7646 %{ 7647 match(Set dst (SubI zero dst)); 7648 effect(KILL cr); 7649 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7650 7651 format %{ "negl $dst\t# int" %} 7652 ins_encode %{ 7653 __ negl($dst$$Register); 7654 %} 7655 ins_pipe(ialu_reg); 7656 %} 7657 7658 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7659 %{ 7660 match(Set dst (NegI dst)); 7661 effect(KILL cr); 7662 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7663 7664 format %{ "negl $dst\t# int" %} 7665 ins_encode %{ 7666 __ negl($dst$$Register); 7667 %} 7668 ins_pipe(ialu_reg); 7669 %} 7670 7671 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7672 %{ 7673 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7674 effect(KILL cr); 7675 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7676 7677 format %{ "negl $dst\t# int" %} 7678 ins_encode %{ 7679 __ negl($dst$$Address); 7680 %} 7681 ins_pipe(ialu_reg); 7682 %} 7683 7684 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7685 %{ 7686 match(Set dst (SubL zero dst)); 7687 effect(KILL cr); 7688 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7689 7690 format %{ "negq $dst\t# long" %} 7691 ins_encode %{ 7692 __ negq($dst$$Register); 7693 %} 7694 ins_pipe(ialu_reg); 7695 %} 7696 7697 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7698 %{ 7699 match(Set dst (NegL dst)); 7700 effect(KILL cr); 7701 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7702 7703 format %{ "negq $dst\t# int" %} 7704 ins_encode %{ 7705 __ negq($dst$$Register); 7706 %} 7707 ins_pipe(ialu_reg); 7708 %} 7709 7710 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7711 %{ 7712 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7713 effect(KILL cr); 7714 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7715 7716 format %{ "negq $dst\t# long" %} 7717 ins_encode %{ 7718 __ negq($dst$$Address); 7719 %} 7720 ins_pipe(ialu_reg); 7721 %} 7722 7723 //----------Multiplication/Division Instructions------------------------------- 7724 // Integer Multiplication Instructions 7725 // Multiply Register 7726 7727 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7728 %{ 7729 match(Set dst (MulI dst src)); 7730 effect(KILL cr); 7731 7732 ins_cost(300); 7733 format %{ "imull $dst, $src\t# int" %} 7734 ins_encode %{ 7735 __ imull($dst$$Register, $src$$Register); 7736 %} 7737 ins_pipe(ialu_reg_reg_alu0); 7738 %} 7739 7740 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7741 %{ 7742 match(Set dst (MulI src imm)); 7743 effect(KILL cr); 7744 7745 ins_cost(300); 7746 format %{ "imull $dst, $src, $imm\t# int" %} 7747 ins_encode %{ 7748 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7749 %} 7750 ins_pipe(ialu_reg_reg_alu0); 7751 %} 7752 7753 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7754 %{ 7755 match(Set dst (MulI dst (LoadI src))); 7756 effect(KILL cr); 7757 7758 ins_cost(350); 7759 format %{ "imull $dst, $src\t# int" %} 7760 ins_encode %{ 7761 __ imull($dst$$Register, $src$$Address); 7762 %} 7763 ins_pipe(ialu_reg_mem_alu0); 7764 %} 7765 7766 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7767 %{ 7768 match(Set dst (MulI (LoadI src) imm)); 7769 effect(KILL cr); 7770 7771 ins_cost(300); 7772 format %{ "imull $dst, $src, $imm\t# int" %} 7773 ins_encode %{ 7774 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7775 %} 7776 ins_pipe(ialu_reg_mem_alu0); 7777 %} 7778 7779 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7780 %{ 7781 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7782 effect(KILL cr, KILL src2); 7783 7784 expand %{ mulI_rReg(dst, src1, cr); 7785 mulI_rReg(src2, src3, cr); 7786 addI_rReg(dst, src2, cr); %} 7787 %} 7788 7789 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7790 %{ 7791 match(Set dst (MulL dst src)); 7792 effect(KILL cr); 7793 7794 ins_cost(300); 7795 format %{ "imulq $dst, $src\t# long" %} 7796 ins_encode %{ 7797 __ imulq($dst$$Register, $src$$Register); 7798 %} 7799 ins_pipe(ialu_reg_reg_alu0); 7800 %} 7801 7802 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7803 %{ 7804 match(Set dst (MulL src imm)); 7805 effect(KILL cr); 7806 7807 ins_cost(300); 7808 format %{ "imulq $dst, $src, $imm\t# long" %} 7809 ins_encode %{ 7810 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7811 %} 7812 ins_pipe(ialu_reg_reg_alu0); 7813 %} 7814 7815 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7816 %{ 7817 match(Set dst (MulL dst (LoadL src))); 7818 effect(KILL cr); 7819 7820 ins_cost(350); 7821 format %{ "imulq $dst, $src\t# long" %} 7822 ins_encode %{ 7823 __ imulq($dst$$Register, $src$$Address); 7824 %} 7825 ins_pipe(ialu_reg_mem_alu0); 7826 %} 7827 7828 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7829 %{ 7830 match(Set dst (MulL (LoadL src) imm)); 7831 effect(KILL cr); 7832 7833 ins_cost(300); 7834 format %{ "imulq $dst, $src, $imm\t# long" %} 7835 ins_encode %{ 7836 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7837 %} 7838 ins_pipe(ialu_reg_mem_alu0); 7839 %} 7840 7841 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7842 %{ 7843 match(Set dst (MulHiL src rax)); 7844 effect(USE_KILL rax, KILL cr); 7845 7846 ins_cost(300); 7847 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7848 ins_encode %{ 7849 __ imulq($src$$Register); 7850 %} 7851 ins_pipe(ialu_reg_reg_alu0); 7852 %} 7853 7854 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7855 %{ 7856 match(Set dst (UMulHiL src rax)); 7857 effect(USE_KILL rax, KILL cr); 7858 7859 ins_cost(300); 7860 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7861 ins_encode %{ 7862 __ mulq($src$$Register); 7863 %} 7864 ins_pipe(ialu_reg_reg_alu0); 7865 %} 7866 7867 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7868 rFlagsReg cr) 7869 %{ 7870 match(Set rax (DivI rax div)); 7871 effect(KILL rdx, KILL cr); 7872 7873 ins_cost(30*100+10*100); // XXX 7874 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7875 "jne,s normal\n\t" 7876 "xorl rdx, rdx\n\t" 7877 "cmpl $div, -1\n\t" 7878 "je,s done\n" 7879 "normal: cdql\n\t" 7880 "idivl $div\n" 7881 "done:" %} 7882 ins_encode(cdql_enc(div)); 7883 ins_pipe(ialu_reg_reg_alu0); 7884 %} 7885 7886 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7887 rFlagsReg cr) 7888 %{ 7889 match(Set rax (DivL rax div)); 7890 effect(KILL rdx, KILL cr); 7891 7892 ins_cost(30*100+10*100); // XXX 7893 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7894 "cmpq rax, rdx\n\t" 7895 "jne,s normal\n\t" 7896 "xorl rdx, rdx\n\t" 7897 "cmpq $div, -1\n\t" 7898 "je,s done\n" 7899 "normal: cdqq\n\t" 7900 "idivq $div\n" 7901 "done:" %} 7902 ins_encode(cdqq_enc(div)); 7903 ins_pipe(ialu_reg_reg_alu0); 7904 %} 7905 7906 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7907 %{ 7908 match(Set rax (UDivI rax div)); 7909 effect(KILL rdx, KILL cr); 7910 7911 ins_cost(300); 7912 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7913 ins_encode %{ 7914 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7915 %} 7916 ins_pipe(ialu_reg_reg_alu0); 7917 %} 7918 7919 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7920 %{ 7921 match(Set rax (UDivL rax div)); 7922 effect(KILL rdx, KILL cr); 7923 7924 ins_cost(300); 7925 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7926 ins_encode %{ 7927 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7928 %} 7929 ins_pipe(ialu_reg_reg_alu0); 7930 %} 7931 7932 // Integer DIVMOD with Register, both quotient and mod results 7933 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7934 rFlagsReg cr) 7935 %{ 7936 match(DivModI rax div); 7937 effect(KILL cr); 7938 7939 ins_cost(30*100+10*100); // XXX 7940 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7941 "jne,s normal\n\t" 7942 "xorl rdx, rdx\n\t" 7943 "cmpl $div, -1\n\t" 7944 "je,s done\n" 7945 "normal: cdql\n\t" 7946 "idivl $div\n" 7947 "done:" %} 7948 ins_encode(cdql_enc(div)); 7949 ins_pipe(pipe_slow); 7950 %} 7951 7952 // Long DIVMOD with Register, both quotient and mod results 7953 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7954 rFlagsReg cr) 7955 %{ 7956 match(DivModL rax div); 7957 effect(KILL cr); 7958 7959 ins_cost(30*100+10*100); // XXX 7960 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7961 "cmpq rax, rdx\n\t" 7962 "jne,s normal\n\t" 7963 "xorl rdx, rdx\n\t" 7964 "cmpq $div, -1\n\t" 7965 "je,s done\n" 7966 "normal: cdqq\n\t" 7967 "idivq $div\n" 7968 "done:" %} 7969 ins_encode(cdqq_enc(div)); 7970 ins_pipe(pipe_slow); 7971 %} 7972 7973 // Unsigned integer DIVMOD with Register, both quotient and mod results 7974 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7975 no_rax_rdx_RegI div, rFlagsReg cr) 7976 %{ 7977 match(UDivModI rax div); 7978 effect(TEMP tmp, KILL cr); 7979 7980 ins_cost(300); 7981 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7982 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7983 %} 7984 ins_encode %{ 7985 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7986 %} 7987 ins_pipe(pipe_slow); 7988 %} 7989 7990 // Unsigned long DIVMOD with Register, both quotient and mod results 7991 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7992 no_rax_rdx_RegL div, rFlagsReg cr) 7993 %{ 7994 match(UDivModL rax div); 7995 effect(TEMP tmp, KILL cr); 7996 7997 ins_cost(300); 7998 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7999 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8000 %} 8001 ins_encode %{ 8002 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8003 %} 8004 ins_pipe(pipe_slow); 8005 %} 8006 8007 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8008 rFlagsReg cr) 8009 %{ 8010 match(Set rdx (ModI rax div)); 8011 effect(KILL rax, KILL cr); 8012 8013 ins_cost(300); // XXX 8014 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8015 "jne,s normal\n\t" 8016 "xorl rdx, rdx\n\t" 8017 "cmpl $div, -1\n\t" 8018 "je,s done\n" 8019 "normal: cdql\n\t" 8020 "idivl $div\n" 8021 "done:" %} 8022 ins_encode(cdql_enc(div)); 8023 ins_pipe(ialu_reg_reg_alu0); 8024 %} 8025 8026 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8027 rFlagsReg cr) 8028 %{ 8029 match(Set rdx (ModL rax div)); 8030 effect(KILL rax, KILL cr); 8031 8032 ins_cost(300); // XXX 8033 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8034 "cmpq rax, rdx\n\t" 8035 "jne,s normal\n\t" 8036 "xorl rdx, rdx\n\t" 8037 "cmpq $div, -1\n\t" 8038 "je,s done\n" 8039 "normal: cdqq\n\t" 8040 "idivq $div\n" 8041 "done:" %} 8042 ins_encode(cdqq_enc(div)); 8043 ins_pipe(ialu_reg_reg_alu0); 8044 %} 8045 8046 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8047 %{ 8048 match(Set rdx (UModI rax div)); 8049 effect(KILL rax, KILL cr); 8050 8051 ins_cost(300); 8052 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8053 ins_encode %{ 8054 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8055 %} 8056 ins_pipe(ialu_reg_reg_alu0); 8057 %} 8058 8059 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8060 %{ 8061 match(Set rdx (UModL rax div)); 8062 effect(KILL rax, KILL cr); 8063 8064 ins_cost(300); 8065 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8066 ins_encode %{ 8067 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8068 %} 8069 ins_pipe(ialu_reg_reg_alu0); 8070 %} 8071 8072 // Integer Shift Instructions 8073 // Shift Left by one, two, three 8074 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8075 %{ 8076 match(Set dst (LShiftI dst shift)); 8077 effect(KILL cr); 8078 8079 format %{ "sall $dst, $shift" %} 8080 ins_encode %{ 8081 __ sall($dst$$Register, $shift$$constant); 8082 %} 8083 ins_pipe(ialu_reg); 8084 %} 8085 8086 // Shift Left by 8-bit immediate 8087 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8088 %{ 8089 match(Set dst (LShiftI dst shift)); 8090 effect(KILL cr); 8091 8092 format %{ "sall $dst, $shift" %} 8093 ins_encode %{ 8094 __ sall($dst$$Register, $shift$$constant); 8095 %} 8096 ins_pipe(ialu_reg); 8097 %} 8098 8099 // Shift Left by 8-bit immediate 8100 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8101 %{ 8102 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8103 effect(KILL cr); 8104 8105 format %{ "sall $dst, $shift" %} 8106 ins_encode %{ 8107 __ sall($dst$$Address, $shift$$constant); 8108 %} 8109 ins_pipe(ialu_mem_imm); 8110 %} 8111 8112 // Shift Left by variable 8113 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8114 %{ 8115 predicate(!VM_Version::supports_bmi2()); 8116 match(Set dst (LShiftI dst shift)); 8117 effect(KILL cr); 8118 8119 format %{ "sall $dst, $shift" %} 8120 ins_encode %{ 8121 __ sall($dst$$Register); 8122 %} 8123 ins_pipe(ialu_reg_reg); 8124 %} 8125 8126 // Shift Left by variable 8127 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8128 %{ 8129 predicate(!VM_Version::supports_bmi2()); 8130 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8131 effect(KILL cr); 8132 8133 format %{ "sall $dst, $shift" %} 8134 ins_encode %{ 8135 __ sall($dst$$Address); 8136 %} 8137 ins_pipe(ialu_mem_reg); 8138 %} 8139 8140 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8141 %{ 8142 predicate(VM_Version::supports_bmi2()); 8143 match(Set dst (LShiftI src shift)); 8144 8145 format %{ "shlxl $dst, $src, $shift" %} 8146 ins_encode %{ 8147 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8148 %} 8149 ins_pipe(ialu_reg_reg); 8150 %} 8151 8152 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8153 %{ 8154 predicate(VM_Version::supports_bmi2()); 8155 match(Set dst (LShiftI (LoadI src) shift)); 8156 ins_cost(175); 8157 format %{ "shlxl $dst, $src, $shift" %} 8158 ins_encode %{ 8159 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8160 %} 8161 ins_pipe(ialu_reg_mem); 8162 %} 8163 8164 // Arithmetic Shift Right by 8-bit immediate 8165 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8166 %{ 8167 match(Set dst (RShiftI dst shift)); 8168 effect(KILL cr); 8169 8170 format %{ "sarl $dst, $shift" %} 8171 ins_encode %{ 8172 __ sarl($dst$$Register, $shift$$constant); 8173 %} 8174 ins_pipe(ialu_mem_imm); 8175 %} 8176 8177 // Arithmetic Shift Right by 8-bit immediate 8178 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8179 %{ 8180 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8181 effect(KILL cr); 8182 8183 format %{ "sarl $dst, $shift" %} 8184 ins_encode %{ 8185 __ sarl($dst$$Address, $shift$$constant); 8186 %} 8187 ins_pipe(ialu_mem_imm); 8188 %} 8189 8190 // Arithmetic Shift Right by variable 8191 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8192 %{ 8193 predicate(!VM_Version::supports_bmi2()); 8194 match(Set dst (RShiftI dst shift)); 8195 effect(KILL cr); 8196 8197 format %{ "sarl $dst, $shift" %} 8198 ins_encode %{ 8199 __ sarl($dst$$Register); 8200 %} 8201 ins_pipe(ialu_reg_reg); 8202 %} 8203 8204 // Arithmetic Shift Right by variable 8205 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8206 %{ 8207 predicate(!VM_Version::supports_bmi2()); 8208 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8209 effect(KILL cr); 8210 8211 format %{ "sarl $dst, $shift" %} 8212 ins_encode %{ 8213 __ sarl($dst$$Address); 8214 %} 8215 ins_pipe(ialu_mem_reg); 8216 %} 8217 8218 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8219 %{ 8220 predicate(VM_Version::supports_bmi2()); 8221 match(Set dst (RShiftI src shift)); 8222 8223 format %{ "sarxl $dst, $src, $shift" %} 8224 ins_encode %{ 8225 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8226 %} 8227 ins_pipe(ialu_reg_reg); 8228 %} 8229 8230 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8231 %{ 8232 predicate(VM_Version::supports_bmi2()); 8233 match(Set dst (RShiftI (LoadI src) shift)); 8234 ins_cost(175); 8235 format %{ "sarxl $dst, $src, $shift" %} 8236 ins_encode %{ 8237 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8238 %} 8239 ins_pipe(ialu_reg_mem); 8240 %} 8241 8242 // Logical Shift Right by 8-bit immediate 8243 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8244 %{ 8245 match(Set dst (URShiftI dst shift)); 8246 effect(KILL cr); 8247 8248 format %{ "shrl $dst, $shift" %} 8249 ins_encode %{ 8250 __ shrl($dst$$Register, $shift$$constant); 8251 %} 8252 ins_pipe(ialu_reg); 8253 %} 8254 8255 // Logical Shift Right by 8-bit immediate 8256 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8257 %{ 8258 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8259 effect(KILL cr); 8260 8261 format %{ "shrl $dst, $shift" %} 8262 ins_encode %{ 8263 __ shrl($dst$$Address, $shift$$constant); 8264 %} 8265 ins_pipe(ialu_mem_imm); 8266 %} 8267 8268 // Logical Shift Right by variable 8269 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8270 %{ 8271 predicate(!VM_Version::supports_bmi2()); 8272 match(Set dst (URShiftI dst shift)); 8273 effect(KILL cr); 8274 8275 format %{ "shrl $dst, $shift" %} 8276 ins_encode %{ 8277 __ shrl($dst$$Register); 8278 %} 8279 ins_pipe(ialu_reg_reg); 8280 %} 8281 8282 // Logical Shift Right by variable 8283 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8284 %{ 8285 predicate(!VM_Version::supports_bmi2()); 8286 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8287 effect(KILL cr); 8288 8289 format %{ "shrl $dst, $shift" %} 8290 ins_encode %{ 8291 __ shrl($dst$$Address); 8292 %} 8293 ins_pipe(ialu_mem_reg); 8294 %} 8295 8296 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8297 %{ 8298 predicate(VM_Version::supports_bmi2()); 8299 match(Set dst (URShiftI src shift)); 8300 8301 format %{ "shrxl $dst, $src, $shift" %} 8302 ins_encode %{ 8303 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8304 %} 8305 ins_pipe(ialu_reg_reg); 8306 %} 8307 8308 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8309 %{ 8310 predicate(VM_Version::supports_bmi2()); 8311 match(Set dst (URShiftI (LoadI src) shift)); 8312 ins_cost(175); 8313 format %{ "shrxl $dst, $src, $shift" %} 8314 ins_encode %{ 8315 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8316 %} 8317 ins_pipe(ialu_reg_mem); 8318 %} 8319 8320 // Long Shift Instructions 8321 // Shift Left by one, two, three 8322 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8323 %{ 8324 match(Set dst (LShiftL dst shift)); 8325 effect(KILL cr); 8326 8327 format %{ "salq $dst, $shift" %} 8328 ins_encode %{ 8329 __ salq($dst$$Register, $shift$$constant); 8330 %} 8331 ins_pipe(ialu_reg); 8332 %} 8333 8334 // Shift Left by 8-bit immediate 8335 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8336 %{ 8337 match(Set dst (LShiftL dst shift)); 8338 effect(KILL cr); 8339 8340 format %{ "salq $dst, $shift" %} 8341 ins_encode %{ 8342 __ salq($dst$$Register, $shift$$constant); 8343 %} 8344 ins_pipe(ialu_reg); 8345 %} 8346 8347 // Shift Left by 8-bit immediate 8348 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8349 %{ 8350 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8351 effect(KILL cr); 8352 8353 format %{ "salq $dst, $shift" %} 8354 ins_encode %{ 8355 __ salq($dst$$Address, $shift$$constant); 8356 %} 8357 ins_pipe(ialu_mem_imm); 8358 %} 8359 8360 // Shift Left by variable 8361 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8362 %{ 8363 predicate(!VM_Version::supports_bmi2()); 8364 match(Set dst (LShiftL dst shift)); 8365 effect(KILL cr); 8366 8367 format %{ "salq $dst, $shift" %} 8368 ins_encode %{ 8369 __ salq($dst$$Register); 8370 %} 8371 ins_pipe(ialu_reg_reg); 8372 %} 8373 8374 // Shift Left by variable 8375 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8376 %{ 8377 predicate(!VM_Version::supports_bmi2()); 8378 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8379 effect(KILL cr); 8380 8381 format %{ "salq $dst, $shift" %} 8382 ins_encode %{ 8383 __ salq($dst$$Address); 8384 %} 8385 ins_pipe(ialu_mem_reg); 8386 %} 8387 8388 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8389 %{ 8390 predicate(VM_Version::supports_bmi2()); 8391 match(Set dst (LShiftL src shift)); 8392 8393 format %{ "shlxq $dst, $src, $shift" %} 8394 ins_encode %{ 8395 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8396 %} 8397 ins_pipe(ialu_reg_reg); 8398 %} 8399 8400 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8401 %{ 8402 predicate(VM_Version::supports_bmi2()); 8403 match(Set dst (LShiftL (LoadL src) shift)); 8404 ins_cost(175); 8405 format %{ "shlxq $dst, $src, $shift" %} 8406 ins_encode %{ 8407 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8408 %} 8409 ins_pipe(ialu_reg_mem); 8410 %} 8411 8412 // Arithmetic Shift Right by 8-bit immediate 8413 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8414 %{ 8415 match(Set dst (RShiftL dst shift)); 8416 effect(KILL cr); 8417 8418 format %{ "sarq $dst, $shift" %} 8419 ins_encode %{ 8420 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8421 %} 8422 ins_pipe(ialu_mem_imm); 8423 %} 8424 8425 // Arithmetic Shift Right by 8-bit immediate 8426 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8427 %{ 8428 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8429 effect(KILL cr); 8430 8431 format %{ "sarq $dst, $shift" %} 8432 ins_encode %{ 8433 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8434 %} 8435 ins_pipe(ialu_mem_imm); 8436 %} 8437 8438 // Arithmetic Shift Right by variable 8439 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8440 %{ 8441 predicate(!VM_Version::supports_bmi2()); 8442 match(Set dst (RShiftL dst shift)); 8443 effect(KILL cr); 8444 8445 format %{ "sarq $dst, $shift" %} 8446 ins_encode %{ 8447 __ sarq($dst$$Register); 8448 %} 8449 ins_pipe(ialu_reg_reg); 8450 %} 8451 8452 // Arithmetic Shift Right by variable 8453 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8454 %{ 8455 predicate(!VM_Version::supports_bmi2()); 8456 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8457 effect(KILL cr); 8458 8459 format %{ "sarq $dst, $shift" %} 8460 ins_encode %{ 8461 __ sarq($dst$$Address); 8462 %} 8463 ins_pipe(ialu_mem_reg); 8464 %} 8465 8466 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8467 %{ 8468 predicate(VM_Version::supports_bmi2()); 8469 match(Set dst (RShiftL src shift)); 8470 8471 format %{ "sarxq $dst, $src, $shift" %} 8472 ins_encode %{ 8473 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8474 %} 8475 ins_pipe(ialu_reg_reg); 8476 %} 8477 8478 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8479 %{ 8480 predicate(VM_Version::supports_bmi2()); 8481 match(Set dst (RShiftL (LoadL src) shift)); 8482 ins_cost(175); 8483 format %{ "sarxq $dst, $src, $shift" %} 8484 ins_encode %{ 8485 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8486 %} 8487 ins_pipe(ialu_reg_mem); 8488 %} 8489 8490 // Logical Shift Right by 8-bit immediate 8491 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8492 %{ 8493 match(Set dst (URShiftL dst shift)); 8494 effect(KILL cr); 8495 8496 format %{ "shrq $dst, $shift" %} 8497 ins_encode %{ 8498 __ shrq($dst$$Register, $shift$$constant); 8499 %} 8500 ins_pipe(ialu_reg); 8501 %} 8502 8503 // Logical Shift Right by 8-bit immediate 8504 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8505 %{ 8506 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8507 effect(KILL cr); 8508 8509 format %{ "shrq $dst, $shift" %} 8510 ins_encode %{ 8511 __ shrq($dst$$Address, $shift$$constant); 8512 %} 8513 ins_pipe(ialu_mem_imm); 8514 %} 8515 8516 // Logical Shift Right by variable 8517 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8518 %{ 8519 predicate(!VM_Version::supports_bmi2()); 8520 match(Set dst (URShiftL dst shift)); 8521 effect(KILL cr); 8522 8523 format %{ "shrq $dst, $shift" %} 8524 ins_encode %{ 8525 __ shrq($dst$$Register); 8526 %} 8527 ins_pipe(ialu_reg_reg); 8528 %} 8529 8530 // Logical Shift Right by variable 8531 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8532 %{ 8533 predicate(!VM_Version::supports_bmi2()); 8534 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8535 effect(KILL cr); 8536 8537 format %{ "shrq $dst, $shift" %} 8538 ins_encode %{ 8539 __ shrq($dst$$Address); 8540 %} 8541 ins_pipe(ialu_mem_reg); 8542 %} 8543 8544 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8545 %{ 8546 predicate(VM_Version::supports_bmi2()); 8547 match(Set dst (URShiftL src shift)); 8548 8549 format %{ "shrxq $dst, $src, $shift" %} 8550 ins_encode %{ 8551 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8552 %} 8553 ins_pipe(ialu_reg_reg); 8554 %} 8555 8556 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8557 %{ 8558 predicate(VM_Version::supports_bmi2()); 8559 match(Set dst (URShiftL (LoadL src) shift)); 8560 ins_cost(175); 8561 format %{ "shrxq $dst, $src, $shift" %} 8562 ins_encode %{ 8563 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8564 %} 8565 ins_pipe(ialu_reg_mem); 8566 %} 8567 8568 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8569 // This idiom is used by the compiler for the i2b bytecode. 8570 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8571 %{ 8572 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8573 8574 format %{ "movsbl $dst, $src\t# i2b" %} 8575 ins_encode %{ 8576 __ movsbl($dst$$Register, $src$$Register); 8577 %} 8578 ins_pipe(ialu_reg_reg); 8579 %} 8580 8581 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8582 // This idiom is used by the compiler the i2s bytecode. 8583 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8584 %{ 8585 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8586 8587 format %{ "movswl $dst, $src\t# i2s" %} 8588 ins_encode %{ 8589 __ movswl($dst$$Register, $src$$Register); 8590 %} 8591 ins_pipe(ialu_reg_reg); 8592 %} 8593 8594 // ROL/ROR instructions 8595 8596 // Rotate left by constant. 8597 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8598 %{ 8599 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8600 match(Set dst (RotateLeft dst shift)); 8601 effect(KILL cr); 8602 format %{ "roll $dst, $shift" %} 8603 ins_encode %{ 8604 __ roll($dst$$Register, $shift$$constant); 8605 %} 8606 ins_pipe(ialu_reg); 8607 %} 8608 8609 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8610 %{ 8611 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8612 match(Set dst (RotateLeft src shift)); 8613 format %{ "rolxl $dst, $src, $shift" %} 8614 ins_encode %{ 8615 int shift = 32 - ($shift$$constant & 31); 8616 __ rorxl($dst$$Register, $src$$Register, shift); 8617 %} 8618 ins_pipe(ialu_reg_reg); 8619 %} 8620 8621 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8622 %{ 8623 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8624 match(Set dst (RotateLeft (LoadI src) shift)); 8625 ins_cost(175); 8626 format %{ "rolxl $dst, $src, $shift" %} 8627 ins_encode %{ 8628 int shift = 32 - ($shift$$constant & 31); 8629 __ rorxl($dst$$Register, $src$$Address, shift); 8630 %} 8631 ins_pipe(ialu_reg_mem); 8632 %} 8633 8634 // Rotate Left by variable 8635 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8636 %{ 8637 predicate(n->bottom_type()->basic_type() == T_INT); 8638 match(Set dst (RotateLeft dst shift)); 8639 effect(KILL cr); 8640 format %{ "roll $dst, $shift" %} 8641 ins_encode %{ 8642 __ roll($dst$$Register); 8643 %} 8644 ins_pipe(ialu_reg_reg); 8645 %} 8646 8647 // Rotate Right by constant. 8648 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8649 %{ 8650 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8651 match(Set dst (RotateRight dst shift)); 8652 effect(KILL cr); 8653 format %{ "rorl $dst, $shift" %} 8654 ins_encode %{ 8655 __ rorl($dst$$Register, $shift$$constant); 8656 %} 8657 ins_pipe(ialu_reg); 8658 %} 8659 8660 // Rotate Right by constant. 8661 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8662 %{ 8663 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8664 match(Set dst (RotateRight src shift)); 8665 format %{ "rorxl $dst, $src, $shift" %} 8666 ins_encode %{ 8667 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8668 %} 8669 ins_pipe(ialu_reg_reg); 8670 %} 8671 8672 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8673 %{ 8674 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8675 match(Set dst (RotateRight (LoadI src) shift)); 8676 ins_cost(175); 8677 format %{ "rorxl $dst, $src, $shift" %} 8678 ins_encode %{ 8679 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8680 %} 8681 ins_pipe(ialu_reg_mem); 8682 %} 8683 8684 // Rotate Right by variable 8685 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8686 %{ 8687 predicate(n->bottom_type()->basic_type() == T_INT); 8688 match(Set dst (RotateRight dst shift)); 8689 effect(KILL cr); 8690 format %{ "rorl $dst, $shift" %} 8691 ins_encode %{ 8692 __ rorl($dst$$Register); 8693 %} 8694 ins_pipe(ialu_reg_reg); 8695 %} 8696 8697 // Rotate Left by constant. 8698 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8699 %{ 8700 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8701 match(Set dst (RotateLeft dst shift)); 8702 effect(KILL cr); 8703 format %{ "rolq $dst, $shift" %} 8704 ins_encode %{ 8705 __ rolq($dst$$Register, $shift$$constant); 8706 %} 8707 ins_pipe(ialu_reg); 8708 %} 8709 8710 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8711 %{ 8712 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8713 match(Set dst (RotateLeft src shift)); 8714 format %{ "rolxq $dst, $src, $shift" %} 8715 ins_encode %{ 8716 int shift = 64 - ($shift$$constant & 63); 8717 __ rorxq($dst$$Register, $src$$Register, shift); 8718 %} 8719 ins_pipe(ialu_reg_reg); 8720 %} 8721 8722 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8723 %{ 8724 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8725 match(Set dst (RotateLeft (LoadL src) shift)); 8726 ins_cost(175); 8727 format %{ "rolxq $dst, $src, $shift" %} 8728 ins_encode %{ 8729 int shift = 64 - ($shift$$constant & 63); 8730 __ rorxq($dst$$Register, $src$$Address, shift); 8731 %} 8732 ins_pipe(ialu_reg_mem); 8733 %} 8734 8735 // Rotate Left by variable 8736 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8737 %{ 8738 predicate(n->bottom_type()->basic_type() == T_LONG); 8739 match(Set dst (RotateLeft dst shift)); 8740 effect(KILL cr); 8741 format %{ "rolq $dst, $shift" %} 8742 ins_encode %{ 8743 __ rolq($dst$$Register); 8744 %} 8745 ins_pipe(ialu_reg_reg); 8746 %} 8747 8748 // Rotate Right by constant. 8749 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8750 %{ 8751 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8752 match(Set dst (RotateRight dst shift)); 8753 effect(KILL cr); 8754 format %{ "rorq $dst, $shift" %} 8755 ins_encode %{ 8756 __ rorq($dst$$Register, $shift$$constant); 8757 %} 8758 ins_pipe(ialu_reg); 8759 %} 8760 8761 // Rotate Right by constant 8762 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8763 %{ 8764 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8765 match(Set dst (RotateRight src shift)); 8766 format %{ "rorxq $dst, $src, $shift" %} 8767 ins_encode %{ 8768 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8769 %} 8770 ins_pipe(ialu_reg_reg); 8771 %} 8772 8773 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8774 %{ 8775 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8776 match(Set dst (RotateRight (LoadL src) shift)); 8777 ins_cost(175); 8778 format %{ "rorxq $dst, $src, $shift" %} 8779 ins_encode %{ 8780 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8781 %} 8782 ins_pipe(ialu_reg_mem); 8783 %} 8784 8785 // Rotate Right by variable 8786 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8787 %{ 8788 predicate(n->bottom_type()->basic_type() == T_LONG); 8789 match(Set dst (RotateRight dst shift)); 8790 effect(KILL cr); 8791 format %{ "rorq $dst, $shift" %} 8792 ins_encode %{ 8793 __ rorq($dst$$Register); 8794 %} 8795 ins_pipe(ialu_reg_reg); 8796 %} 8797 8798 //----------------------------- CompressBits/ExpandBits ------------------------ 8799 8800 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8801 predicate(n->bottom_type()->isa_long()); 8802 match(Set dst (CompressBits src mask)); 8803 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8804 ins_encode %{ 8805 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8806 %} 8807 ins_pipe( pipe_slow ); 8808 %} 8809 8810 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8811 predicate(n->bottom_type()->isa_long()); 8812 match(Set dst (ExpandBits src mask)); 8813 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8814 ins_encode %{ 8815 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8816 %} 8817 ins_pipe( pipe_slow ); 8818 %} 8819 8820 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8821 predicate(n->bottom_type()->isa_long()); 8822 match(Set dst (CompressBits src (LoadL mask))); 8823 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8824 ins_encode %{ 8825 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8826 %} 8827 ins_pipe( pipe_slow ); 8828 %} 8829 8830 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8831 predicate(n->bottom_type()->isa_long()); 8832 match(Set dst (ExpandBits src (LoadL mask))); 8833 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8834 ins_encode %{ 8835 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8836 %} 8837 ins_pipe( pipe_slow ); 8838 %} 8839 8840 8841 // Logical Instructions 8842 8843 // Integer Logical Instructions 8844 8845 // And Instructions 8846 // And Register with Register 8847 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8848 %{ 8849 match(Set dst (AndI dst src)); 8850 effect(KILL cr); 8851 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); 8852 8853 format %{ "andl $dst, $src\t# int" %} 8854 ins_encode %{ 8855 __ andl($dst$$Register, $src$$Register); 8856 %} 8857 ins_pipe(ialu_reg_reg); 8858 %} 8859 8860 // And Register with Immediate 255 8861 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8862 %{ 8863 match(Set dst (AndI src mask)); 8864 8865 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8866 ins_encode %{ 8867 __ movzbl($dst$$Register, $src$$Register); 8868 %} 8869 ins_pipe(ialu_reg); 8870 %} 8871 8872 // And Register with Immediate 255 and promote to long 8873 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8874 %{ 8875 match(Set dst (ConvI2L (AndI src mask))); 8876 8877 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8878 ins_encode %{ 8879 __ movzbl($dst$$Register, $src$$Register); 8880 %} 8881 ins_pipe(ialu_reg); 8882 %} 8883 8884 // And Register with Immediate 65535 8885 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8886 %{ 8887 match(Set dst (AndI src mask)); 8888 8889 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8890 ins_encode %{ 8891 __ movzwl($dst$$Register, $src$$Register); 8892 %} 8893 ins_pipe(ialu_reg); 8894 %} 8895 8896 // And Register with Immediate 65535 and promote to long 8897 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8898 %{ 8899 match(Set dst (ConvI2L (AndI src mask))); 8900 8901 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8902 ins_encode %{ 8903 __ movzwl($dst$$Register, $src$$Register); 8904 %} 8905 ins_pipe(ialu_reg); 8906 %} 8907 8908 // Can skip int2long conversions after AND with small bitmask 8909 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8910 %{ 8911 predicate(VM_Version::supports_bmi2()); 8912 ins_cost(125); 8913 effect(TEMP tmp, KILL cr); 8914 match(Set dst (ConvI2L (AndI src mask))); 8915 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8916 ins_encode %{ 8917 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8918 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8919 %} 8920 ins_pipe(ialu_reg_reg); 8921 %} 8922 8923 // And Register with Immediate 8924 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8925 %{ 8926 match(Set dst (AndI dst src)); 8927 effect(KILL cr); 8928 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); 8929 8930 format %{ "andl $dst, $src\t# int" %} 8931 ins_encode %{ 8932 __ andl($dst$$Register, $src$$constant); 8933 %} 8934 ins_pipe(ialu_reg); 8935 %} 8936 8937 // And Register with Memory 8938 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8939 %{ 8940 match(Set dst (AndI dst (LoadI 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(150); 8945 format %{ "andl $dst, $src\t# int" %} 8946 ins_encode %{ 8947 __ andl($dst$$Register, $src$$Address); 8948 %} 8949 ins_pipe(ialu_reg_mem); 8950 %} 8951 8952 // And Memory with Register 8953 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8954 %{ 8955 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8956 effect(KILL cr); 8957 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); 8958 8959 ins_cost(150); 8960 format %{ "andb $dst, $src\t# byte" %} 8961 ins_encode %{ 8962 __ andb($dst$$Address, $src$$Register); 8963 %} 8964 ins_pipe(ialu_mem_reg); 8965 %} 8966 8967 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8968 %{ 8969 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8970 effect(KILL cr); 8971 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); 8972 8973 ins_cost(150); 8974 format %{ "andl $dst, $src\t# int" %} 8975 ins_encode %{ 8976 __ andl($dst$$Address, $src$$Register); 8977 %} 8978 ins_pipe(ialu_mem_reg); 8979 %} 8980 8981 // And Memory with Immediate 8982 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8983 %{ 8984 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8985 effect(KILL cr); 8986 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); 8987 8988 ins_cost(125); 8989 format %{ "andl $dst, $src\t# int" %} 8990 ins_encode %{ 8991 __ andl($dst$$Address, $src$$constant); 8992 %} 8993 ins_pipe(ialu_mem_imm); 8994 %} 8995 8996 // BMI1 instructions 8997 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8998 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8999 predicate(UseBMI1Instructions); 9000 effect(KILL cr); 9001 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9002 9003 ins_cost(125); 9004 format %{ "andnl $dst, $src1, $src2" %} 9005 9006 ins_encode %{ 9007 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9008 %} 9009 ins_pipe(ialu_reg_mem); 9010 %} 9011 9012 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9013 match(Set dst (AndI (XorI src1 minus_1) src2)); 9014 predicate(UseBMI1Instructions); 9015 effect(KILL cr); 9016 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9017 9018 format %{ "andnl $dst, $src1, $src2" %} 9019 9020 ins_encode %{ 9021 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9022 %} 9023 ins_pipe(ialu_reg); 9024 %} 9025 9026 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 9027 match(Set dst (AndI (SubI imm_zero src) src)); 9028 predicate(UseBMI1Instructions); 9029 effect(KILL cr); 9030 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9031 9032 format %{ "blsil $dst, $src" %} 9033 9034 ins_encode %{ 9035 __ blsil($dst$$Register, $src$$Register); 9036 %} 9037 ins_pipe(ialu_reg); 9038 %} 9039 9040 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 9041 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9042 predicate(UseBMI1Instructions); 9043 effect(KILL cr); 9044 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9045 9046 ins_cost(125); 9047 format %{ "blsil $dst, $src" %} 9048 9049 ins_encode %{ 9050 __ blsil($dst$$Register, $src$$Address); 9051 %} 9052 ins_pipe(ialu_reg_mem); 9053 %} 9054 9055 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9056 %{ 9057 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9058 predicate(UseBMI1Instructions); 9059 effect(KILL cr); 9060 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9061 9062 ins_cost(125); 9063 format %{ "blsmskl $dst, $src" %} 9064 9065 ins_encode %{ 9066 __ blsmskl($dst$$Register, $src$$Address); 9067 %} 9068 ins_pipe(ialu_reg_mem); 9069 %} 9070 9071 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9072 %{ 9073 match(Set dst (XorI (AddI src minus_1) src)); 9074 predicate(UseBMI1Instructions); 9075 effect(KILL cr); 9076 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9077 9078 format %{ "blsmskl $dst, $src" %} 9079 9080 ins_encode %{ 9081 __ blsmskl($dst$$Register, $src$$Register); 9082 %} 9083 9084 ins_pipe(ialu_reg); 9085 %} 9086 9087 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9088 %{ 9089 match(Set dst (AndI (AddI src minus_1) src) ); 9090 predicate(UseBMI1Instructions); 9091 effect(KILL cr); 9092 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9093 9094 format %{ "blsrl $dst, $src" %} 9095 9096 ins_encode %{ 9097 __ blsrl($dst$$Register, $src$$Register); 9098 %} 9099 9100 ins_pipe(ialu_reg_mem); 9101 %} 9102 9103 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9104 %{ 9105 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9106 predicate(UseBMI1Instructions); 9107 effect(KILL cr); 9108 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9109 9110 ins_cost(125); 9111 format %{ "blsrl $dst, $src" %} 9112 9113 ins_encode %{ 9114 __ blsrl($dst$$Register, $src$$Address); 9115 %} 9116 9117 ins_pipe(ialu_reg); 9118 %} 9119 9120 // Or Instructions 9121 // Or Register with Register 9122 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9123 %{ 9124 match(Set dst (OrI dst src)); 9125 effect(KILL cr); 9126 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); 9127 9128 format %{ "orl $dst, $src\t# int" %} 9129 ins_encode %{ 9130 __ orl($dst$$Register, $src$$Register); 9131 %} 9132 ins_pipe(ialu_reg_reg); 9133 %} 9134 9135 // Or Register with Immediate 9136 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9137 %{ 9138 match(Set dst (OrI dst src)); 9139 effect(KILL cr); 9140 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); 9141 9142 format %{ "orl $dst, $src\t# int" %} 9143 ins_encode %{ 9144 __ orl($dst$$Register, $src$$constant); 9145 %} 9146 ins_pipe(ialu_reg); 9147 %} 9148 9149 // Or Register with Memory 9150 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9151 %{ 9152 match(Set dst (OrI dst (LoadI 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(150); 9157 format %{ "orl $dst, $src\t# int" %} 9158 ins_encode %{ 9159 __ orl($dst$$Register, $src$$Address); 9160 %} 9161 ins_pipe(ialu_reg_mem); 9162 %} 9163 9164 // Or Memory with Register 9165 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9166 %{ 9167 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9168 effect(KILL cr); 9169 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); 9170 9171 ins_cost(150); 9172 format %{ "orb $dst, $src\t# byte" %} 9173 ins_encode %{ 9174 __ orb($dst$$Address, $src$$Register); 9175 %} 9176 ins_pipe(ialu_mem_reg); 9177 %} 9178 9179 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9180 %{ 9181 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9182 effect(KILL cr); 9183 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); 9184 9185 ins_cost(150); 9186 format %{ "orl $dst, $src\t# int" %} 9187 ins_encode %{ 9188 __ orl($dst$$Address, $src$$Register); 9189 %} 9190 ins_pipe(ialu_mem_reg); 9191 %} 9192 9193 // Or Memory with Immediate 9194 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9195 %{ 9196 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9197 effect(KILL cr); 9198 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9199 9200 ins_cost(125); 9201 format %{ "orl $dst, $src\t# int" %} 9202 ins_encode %{ 9203 __ orl($dst$$Address, $src$$constant); 9204 %} 9205 ins_pipe(ialu_mem_imm); 9206 %} 9207 9208 // Xor Instructions 9209 // Xor Register with Register 9210 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9211 %{ 9212 match(Set dst (XorI dst src)); 9213 effect(KILL cr); 9214 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); 9215 9216 format %{ "xorl $dst, $src\t# int" %} 9217 ins_encode %{ 9218 __ xorl($dst$$Register, $src$$Register); 9219 %} 9220 ins_pipe(ialu_reg_reg); 9221 %} 9222 9223 // Xor Register with Immediate -1 9224 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9225 match(Set dst (XorI dst imm)); 9226 9227 format %{ "not $dst" %} 9228 ins_encode %{ 9229 __ notl($dst$$Register); 9230 %} 9231 ins_pipe(ialu_reg); 9232 %} 9233 9234 // Xor Register with Immediate 9235 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9236 %{ 9237 match(Set dst (XorI dst src)); 9238 effect(KILL cr); 9239 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); 9240 9241 format %{ "xorl $dst, $src\t# int" %} 9242 ins_encode %{ 9243 __ xorl($dst$$Register, $src$$constant); 9244 %} 9245 ins_pipe(ialu_reg); 9246 %} 9247 9248 // Xor Register with Memory 9249 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9250 %{ 9251 match(Set dst (XorI dst (LoadI 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(150); 9256 format %{ "xorl $dst, $src\t# int" %} 9257 ins_encode %{ 9258 __ xorl($dst$$Register, $src$$Address); 9259 %} 9260 ins_pipe(ialu_reg_mem); 9261 %} 9262 9263 // Xor Memory with Register 9264 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9265 %{ 9266 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9267 effect(KILL cr); 9268 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); 9269 9270 ins_cost(150); 9271 format %{ "xorb $dst, $src\t# byte" %} 9272 ins_encode %{ 9273 __ xorb($dst$$Address, $src$$Register); 9274 %} 9275 ins_pipe(ialu_mem_reg); 9276 %} 9277 9278 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9279 %{ 9280 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9281 effect(KILL cr); 9282 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); 9283 9284 ins_cost(150); 9285 format %{ "xorl $dst, $src\t# int" %} 9286 ins_encode %{ 9287 __ xorl($dst$$Address, $src$$Register); 9288 %} 9289 ins_pipe(ialu_mem_reg); 9290 %} 9291 9292 // Xor Memory with Immediate 9293 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9294 %{ 9295 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9296 effect(KILL cr); 9297 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); 9298 9299 ins_cost(125); 9300 format %{ "xorl $dst, $src\t# int" %} 9301 ins_encode %{ 9302 __ xorl($dst$$Address, $src$$constant); 9303 %} 9304 ins_pipe(ialu_mem_imm); 9305 %} 9306 9307 9308 // Long Logical Instructions 9309 9310 // And Instructions 9311 // And Register with Register 9312 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9313 %{ 9314 match(Set dst (AndL dst src)); 9315 effect(KILL cr); 9316 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); 9317 9318 format %{ "andq $dst, $src\t# long" %} 9319 ins_encode %{ 9320 __ andq($dst$$Register, $src$$Register); 9321 %} 9322 ins_pipe(ialu_reg_reg); 9323 %} 9324 9325 // And Register with Immediate 255 9326 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9327 %{ 9328 match(Set dst (AndL src mask)); 9329 9330 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9331 ins_encode %{ 9332 // movzbl zeroes out the upper 32-bit and does not need REX.W 9333 __ movzbl($dst$$Register, $src$$Register); 9334 %} 9335 ins_pipe(ialu_reg); 9336 %} 9337 9338 // And Register with Immediate 65535 9339 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9340 %{ 9341 match(Set dst (AndL src mask)); 9342 9343 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9344 ins_encode %{ 9345 // movzwl zeroes out the upper 32-bit and does not need REX.W 9346 __ movzwl($dst$$Register, $src$$Register); 9347 %} 9348 ins_pipe(ialu_reg); 9349 %} 9350 9351 // And Register with Immediate 9352 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9353 %{ 9354 match(Set dst (AndL 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 format %{ "andq $dst, $src\t# long" %} 9359 ins_encode %{ 9360 __ andq($dst$$Register, $src$$constant); 9361 %} 9362 ins_pipe(ialu_reg); 9363 %} 9364 9365 // And Register with Memory 9366 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9367 %{ 9368 match(Set dst (AndL dst (LoadL src))); 9369 effect(KILL cr); 9370 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); 9371 9372 ins_cost(150); 9373 format %{ "andq $dst, $src\t# long" %} 9374 ins_encode %{ 9375 __ andq($dst$$Register, $src$$Address); 9376 %} 9377 ins_pipe(ialu_reg_mem); 9378 %} 9379 9380 // And Memory with Register 9381 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9382 %{ 9383 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9384 effect(KILL cr); 9385 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); 9386 9387 ins_cost(150); 9388 format %{ "andq $dst, $src\t# long" %} 9389 ins_encode %{ 9390 __ andq($dst$$Address, $src$$Register); 9391 %} 9392 ins_pipe(ialu_mem_reg); 9393 %} 9394 9395 // And Memory with Immediate 9396 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9397 %{ 9398 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9399 effect(KILL cr); 9400 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); 9401 9402 ins_cost(125); 9403 format %{ "andq $dst, $src\t# long" %} 9404 ins_encode %{ 9405 __ andq($dst$$Address, $src$$constant); 9406 %} 9407 ins_pipe(ialu_mem_imm); 9408 %} 9409 9410 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9411 %{ 9412 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9413 // because AND/OR works well enough for 8/32-bit values. 9414 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9415 9416 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9417 effect(KILL cr); 9418 9419 ins_cost(125); 9420 format %{ "btrq $dst, log2(not($con))\t# long" %} 9421 ins_encode %{ 9422 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9423 %} 9424 ins_pipe(ialu_mem_imm); 9425 %} 9426 9427 // BMI1 instructions 9428 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9429 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9430 predicate(UseBMI1Instructions); 9431 effect(KILL cr); 9432 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9433 9434 ins_cost(125); 9435 format %{ "andnq $dst, $src1, $src2" %} 9436 9437 ins_encode %{ 9438 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9439 %} 9440 ins_pipe(ialu_reg_mem); 9441 %} 9442 9443 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9444 match(Set dst (AndL (XorL src1 minus_1) src2)); 9445 predicate(UseBMI1Instructions); 9446 effect(KILL cr); 9447 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9448 9449 format %{ "andnq $dst, $src1, $src2" %} 9450 9451 ins_encode %{ 9452 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9453 %} 9454 ins_pipe(ialu_reg_mem); 9455 %} 9456 9457 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9458 match(Set dst (AndL (SubL imm_zero src) src)); 9459 predicate(UseBMI1Instructions); 9460 effect(KILL cr); 9461 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9462 9463 format %{ "blsiq $dst, $src" %} 9464 9465 ins_encode %{ 9466 __ blsiq($dst$$Register, $src$$Register); 9467 %} 9468 ins_pipe(ialu_reg); 9469 %} 9470 9471 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9472 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9473 predicate(UseBMI1Instructions); 9474 effect(KILL cr); 9475 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9476 9477 ins_cost(125); 9478 format %{ "blsiq $dst, $src" %} 9479 9480 ins_encode %{ 9481 __ blsiq($dst$$Register, $src$$Address); 9482 %} 9483 ins_pipe(ialu_reg_mem); 9484 %} 9485 9486 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9487 %{ 9488 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9489 predicate(UseBMI1Instructions); 9490 effect(KILL cr); 9491 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9492 9493 ins_cost(125); 9494 format %{ "blsmskq $dst, $src" %} 9495 9496 ins_encode %{ 9497 __ blsmskq($dst$$Register, $src$$Address); 9498 %} 9499 ins_pipe(ialu_reg_mem); 9500 %} 9501 9502 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9503 %{ 9504 match(Set dst (XorL (AddL src minus_1) src)); 9505 predicate(UseBMI1Instructions); 9506 effect(KILL cr); 9507 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9508 9509 format %{ "blsmskq $dst, $src" %} 9510 9511 ins_encode %{ 9512 __ blsmskq($dst$$Register, $src$$Register); 9513 %} 9514 9515 ins_pipe(ialu_reg); 9516 %} 9517 9518 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9519 %{ 9520 match(Set dst (AndL (AddL src minus_1) src) ); 9521 predicate(UseBMI1Instructions); 9522 effect(KILL cr); 9523 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9524 9525 format %{ "blsrq $dst, $src" %} 9526 9527 ins_encode %{ 9528 __ blsrq($dst$$Register, $src$$Register); 9529 %} 9530 9531 ins_pipe(ialu_reg); 9532 %} 9533 9534 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9535 %{ 9536 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9537 predicate(UseBMI1Instructions); 9538 effect(KILL cr); 9539 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9540 9541 ins_cost(125); 9542 format %{ "blsrq $dst, $src" %} 9543 9544 ins_encode %{ 9545 __ blsrq($dst$$Register, $src$$Address); 9546 %} 9547 9548 ins_pipe(ialu_reg); 9549 %} 9550 9551 // Or Instructions 9552 // Or Register with Register 9553 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9554 %{ 9555 match(Set dst (OrL dst src)); 9556 effect(KILL cr); 9557 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); 9558 9559 format %{ "orq $dst, $src\t# long" %} 9560 ins_encode %{ 9561 __ orq($dst$$Register, $src$$Register); 9562 %} 9563 ins_pipe(ialu_reg_reg); 9564 %} 9565 9566 // Use any_RegP to match R15 (TLS register) without spilling. 9567 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9568 match(Set dst (OrL dst (CastP2X 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 format %{ "orq $dst, $src\t# long" %} 9573 ins_encode %{ 9574 __ orq($dst$$Register, $src$$Register); 9575 %} 9576 ins_pipe(ialu_reg_reg); 9577 %} 9578 9579 9580 // Or Register with Immediate 9581 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9582 %{ 9583 match(Set dst (OrL 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 format %{ "orq $dst, $src\t# long" %} 9588 ins_encode %{ 9589 __ orq($dst$$Register, $src$$constant); 9590 %} 9591 ins_pipe(ialu_reg); 9592 %} 9593 9594 // Or Register with Memory 9595 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9596 %{ 9597 match(Set dst (OrL dst (LoadL src))); 9598 effect(KILL cr); 9599 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); 9600 9601 ins_cost(150); 9602 format %{ "orq $dst, $src\t# long" %} 9603 ins_encode %{ 9604 __ orq($dst$$Register, $src$$Address); 9605 %} 9606 ins_pipe(ialu_reg_mem); 9607 %} 9608 9609 // Or Memory with Register 9610 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9611 %{ 9612 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9613 effect(KILL cr); 9614 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); 9615 9616 ins_cost(150); 9617 format %{ "orq $dst, $src\t# long" %} 9618 ins_encode %{ 9619 __ orq($dst$$Address, $src$$Register); 9620 %} 9621 ins_pipe(ialu_mem_reg); 9622 %} 9623 9624 // Or Memory with Immediate 9625 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9626 %{ 9627 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9628 effect(KILL cr); 9629 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); 9630 9631 ins_cost(125); 9632 format %{ "orq $dst, $src\t# long" %} 9633 ins_encode %{ 9634 __ orq($dst$$Address, $src$$constant); 9635 %} 9636 ins_pipe(ialu_mem_imm); 9637 %} 9638 9639 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9640 %{ 9641 // con should be a pure 64-bit power of 2 immediate 9642 // because AND/OR works well enough for 8/32-bit values. 9643 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9644 9645 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9646 effect(KILL cr); 9647 9648 ins_cost(125); 9649 format %{ "btsq $dst, log2($con)\t# long" %} 9650 ins_encode %{ 9651 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9652 %} 9653 ins_pipe(ialu_mem_imm); 9654 %} 9655 9656 // Xor Instructions 9657 // Xor Register with Register 9658 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9659 %{ 9660 match(Set dst (XorL dst src)); 9661 effect(KILL cr); 9662 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); 9663 9664 format %{ "xorq $dst, $src\t# long" %} 9665 ins_encode %{ 9666 __ xorq($dst$$Register, $src$$Register); 9667 %} 9668 ins_pipe(ialu_reg_reg); 9669 %} 9670 9671 // Xor Register with Immediate -1 9672 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9673 match(Set dst (XorL dst imm)); 9674 9675 format %{ "notq $dst" %} 9676 ins_encode %{ 9677 __ notq($dst$$Register); 9678 %} 9679 ins_pipe(ialu_reg); 9680 %} 9681 9682 // Xor Register with Immediate 9683 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9684 %{ 9685 match(Set dst (XorL 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 format %{ "xorq $dst, $src\t# long" %} 9690 ins_encode %{ 9691 __ xorq($dst$$Register, $src$$constant); 9692 %} 9693 ins_pipe(ialu_reg); 9694 %} 9695 9696 // Xor Register with Memory 9697 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9698 %{ 9699 match(Set dst (XorL dst (LoadL src))); 9700 effect(KILL cr); 9701 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); 9702 9703 ins_cost(150); 9704 format %{ "xorq $dst, $src\t# long" %} 9705 ins_encode %{ 9706 __ xorq($dst$$Register, $src$$Address); 9707 %} 9708 ins_pipe(ialu_reg_mem); 9709 %} 9710 9711 // Xor Memory with Register 9712 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9713 %{ 9714 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9715 effect(KILL cr); 9716 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); 9717 9718 ins_cost(150); 9719 format %{ "xorq $dst, $src\t# long" %} 9720 ins_encode %{ 9721 __ xorq($dst$$Address, $src$$Register); 9722 %} 9723 ins_pipe(ialu_mem_reg); 9724 %} 9725 9726 // Xor Memory with Immediate 9727 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9728 %{ 9729 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9730 effect(KILL cr); 9731 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); 9732 9733 ins_cost(125); 9734 format %{ "xorq $dst, $src\t# long" %} 9735 ins_encode %{ 9736 __ xorq($dst$$Address, $src$$constant); 9737 %} 9738 ins_pipe(ialu_mem_imm); 9739 %} 9740 9741 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9742 %{ 9743 match(Set dst (CmpLTMask p q)); 9744 effect(KILL cr); 9745 9746 ins_cost(400); 9747 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9748 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 9749 "negl $dst" %} 9750 ins_encode %{ 9751 __ cmpl($p$$Register, $q$$Register); 9752 __ setcc(Assembler::less, $dst$$Register); 9753 __ negl($dst$$Register); 9754 %} 9755 ins_pipe(pipe_slow); 9756 %} 9757 9758 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9759 %{ 9760 match(Set dst (CmpLTMask dst zero)); 9761 effect(KILL cr); 9762 9763 ins_cost(100); 9764 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9765 ins_encode %{ 9766 __ sarl($dst$$Register, 31); 9767 %} 9768 ins_pipe(ialu_reg); 9769 %} 9770 9771 /* Better to save a register than avoid a branch */ 9772 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9773 %{ 9774 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9775 effect(KILL cr); 9776 ins_cost(300); 9777 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9778 "jge done\n\t" 9779 "addl $p,$y\n" 9780 "done: " %} 9781 ins_encode %{ 9782 Register Rp = $p$$Register; 9783 Register Rq = $q$$Register; 9784 Register Ry = $y$$Register; 9785 Label done; 9786 __ subl(Rp, Rq); 9787 __ jccb(Assembler::greaterEqual, done); 9788 __ addl(Rp, Ry); 9789 __ bind(done); 9790 %} 9791 ins_pipe(pipe_cmplt); 9792 %} 9793 9794 /* Better to save a register than avoid a branch */ 9795 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9796 %{ 9797 match(Set y (AndI (CmpLTMask p q) y)); 9798 effect(KILL cr); 9799 9800 ins_cost(300); 9801 9802 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9803 "jlt done\n\t" 9804 "xorl $y, $y\n" 9805 "done: " %} 9806 ins_encode %{ 9807 Register Rp = $p$$Register; 9808 Register Rq = $q$$Register; 9809 Register Ry = $y$$Register; 9810 Label done; 9811 __ cmpl(Rp, Rq); 9812 __ jccb(Assembler::less, done); 9813 __ xorl(Ry, Ry); 9814 __ bind(done); 9815 %} 9816 ins_pipe(pipe_cmplt); 9817 %} 9818 9819 9820 //---------- FP Instructions------------------------------------------------ 9821 9822 // Really expensive, avoid 9823 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9824 %{ 9825 match(Set cr (CmpF src1 src2)); 9826 9827 ins_cost(500); 9828 format %{ "ucomiss $src1, $src2\n\t" 9829 "jnp,s exit\n\t" 9830 "pushfq\t# saw NaN, set CF\n\t" 9831 "andq [rsp], #0xffffff2b\n\t" 9832 "popfq\n" 9833 "exit:" %} 9834 ins_encode %{ 9835 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9836 emit_cmpfp_fixup(masm); 9837 %} 9838 ins_pipe(pipe_slow); 9839 %} 9840 9841 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9842 match(Set cr (CmpF src1 src2)); 9843 9844 ins_cost(100); 9845 format %{ "ucomiss $src1, $src2" %} 9846 ins_encode %{ 9847 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9848 %} 9849 ins_pipe(pipe_slow); 9850 %} 9851 9852 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9853 match(Set cr (CmpF src1 (LoadF src2))); 9854 9855 ins_cost(100); 9856 format %{ "ucomiss $src1, $src2" %} 9857 ins_encode %{ 9858 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9859 %} 9860 ins_pipe(pipe_slow); 9861 %} 9862 9863 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9864 match(Set cr (CmpF src con)); 9865 ins_cost(100); 9866 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9867 ins_encode %{ 9868 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9869 %} 9870 ins_pipe(pipe_slow); 9871 %} 9872 9873 // Really expensive, avoid 9874 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9875 %{ 9876 match(Set cr (CmpD src1 src2)); 9877 9878 ins_cost(500); 9879 format %{ "ucomisd $src1, $src2\n\t" 9880 "jnp,s exit\n\t" 9881 "pushfq\t# saw NaN, set CF\n\t" 9882 "andq [rsp], #0xffffff2b\n\t" 9883 "popfq\n" 9884 "exit:" %} 9885 ins_encode %{ 9886 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9887 emit_cmpfp_fixup(masm); 9888 %} 9889 ins_pipe(pipe_slow); 9890 %} 9891 9892 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9893 match(Set cr (CmpD src1 src2)); 9894 9895 ins_cost(100); 9896 format %{ "ucomisd $src1, $src2 test" %} 9897 ins_encode %{ 9898 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9899 %} 9900 ins_pipe(pipe_slow); 9901 %} 9902 9903 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9904 match(Set cr (CmpD src1 (LoadD src2))); 9905 9906 ins_cost(100); 9907 format %{ "ucomisd $src1, $src2" %} 9908 ins_encode %{ 9909 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9910 %} 9911 ins_pipe(pipe_slow); 9912 %} 9913 9914 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9915 match(Set cr (CmpD src con)); 9916 ins_cost(100); 9917 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9918 ins_encode %{ 9919 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9920 %} 9921 ins_pipe(pipe_slow); 9922 %} 9923 9924 // Compare into -1,0,1 9925 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9926 %{ 9927 match(Set dst (CmpF3 src1 src2)); 9928 effect(KILL cr); 9929 9930 ins_cost(275); 9931 format %{ "ucomiss $src1, $src2\n\t" 9932 "movl $dst, #-1\n\t" 9933 "jp,s done\n\t" 9934 "jb,s done\n\t" 9935 "setne $dst\n\t" 9936 "movzbl $dst, $dst\n" 9937 "done:" %} 9938 ins_encode %{ 9939 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9940 emit_cmpfp3(masm, $dst$$Register); 9941 %} 9942 ins_pipe(pipe_slow); 9943 %} 9944 9945 // Compare into -1,0,1 9946 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9947 %{ 9948 match(Set dst (CmpF3 src1 (LoadF src2))); 9949 effect(KILL cr); 9950 9951 ins_cost(275); 9952 format %{ "ucomiss $src1, $src2\n\t" 9953 "movl $dst, #-1\n\t" 9954 "jp,s done\n\t" 9955 "jb,s done\n\t" 9956 "setne $dst\n\t" 9957 "movzbl $dst, $dst\n" 9958 "done:" %} 9959 ins_encode %{ 9960 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9961 emit_cmpfp3(masm, $dst$$Register); 9962 %} 9963 ins_pipe(pipe_slow); 9964 %} 9965 9966 // Compare into -1,0,1 9967 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9968 match(Set dst (CmpF3 src con)); 9969 effect(KILL cr); 9970 9971 ins_cost(275); 9972 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9973 "movl $dst, #-1\n\t" 9974 "jp,s done\n\t" 9975 "jb,s done\n\t" 9976 "setne $dst\n\t" 9977 "movzbl $dst, $dst\n" 9978 "done:" %} 9979 ins_encode %{ 9980 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9981 emit_cmpfp3(masm, $dst$$Register); 9982 %} 9983 ins_pipe(pipe_slow); 9984 %} 9985 9986 // Compare into -1,0,1 9987 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9988 %{ 9989 match(Set dst (CmpD3 src1 src2)); 9990 effect(KILL cr); 9991 9992 ins_cost(275); 9993 format %{ "ucomisd $src1, $src2\n\t" 9994 "movl $dst, #-1\n\t" 9995 "jp,s done\n\t" 9996 "jb,s done\n\t" 9997 "setne $dst\n\t" 9998 "movzbl $dst, $dst\n" 9999 "done:" %} 10000 ins_encode %{ 10001 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10002 emit_cmpfp3(masm, $dst$$Register); 10003 %} 10004 ins_pipe(pipe_slow); 10005 %} 10006 10007 // Compare into -1,0,1 10008 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10009 %{ 10010 match(Set dst (CmpD3 src1 (LoadD src2))); 10011 effect(KILL cr); 10012 10013 ins_cost(275); 10014 format %{ "ucomisd $src1, $src2\n\t" 10015 "movl $dst, #-1\n\t" 10016 "jp,s done\n\t" 10017 "jb,s done\n\t" 10018 "setne $dst\n\t" 10019 "movzbl $dst, $dst\n" 10020 "done:" %} 10021 ins_encode %{ 10022 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10023 emit_cmpfp3(masm, $dst$$Register); 10024 %} 10025 ins_pipe(pipe_slow); 10026 %} 10027 10028 // Compare into -1,0,1 10029 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10030 match(Set dst (CmpD3 src con)); 10031 effect(KILL cr); 10032 10033 ins_cost(275); 10034 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10035 "movl $dst, #-1\n\t" 10036 "jp,s done\n\t" 10037 "jb,s done\n\t" 10038 "setne $dst\n\t" 10039 "movzbl $dst, $dst\n" 10040 "done:" %} 10041 ins_encode %{ 10042 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10043 emit_cmpfp3(masm, $dst$$Register); 10044 %} 10045 ins_pipe(pipe_slow); 10046 %} 10047 10048 //----------Arithmetic Conversion Instructions--------------------------------- 10049 10050 instruct convF2D_reg_reg(regD dst, regF src) 10051 %{ 10052 match(Set dst (ConvF2D src)); 10053 10054 format %{ "cvtss2sd $dst, $src" %} 10055 ins_encode %{ 10056 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10057 %} 10058 ins_pipe(pipe_slow); // XXX 10059 %} 10060 10061 instruct convF2D_reg_mem(regD dst, memory src) 10062 %{ 10063 predicate(UseAVX == 0); 10064 match(Set dst (ConvF2D (LoadF src))); 10065 10066 format %{ "cvtss2sd $dst, $src" %} 10067 ins_encode %{ 10068 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10069 %} 10070 ins_pipe(pipe_slow); // XXX 10071 %} 10072 10073 instruct convD2F_reg_reg(regF dst, regD src) 10074 %{ 10075 match(Set dst (ConvD2F src)); 10076 10077 format %{ "cvtsd2ss $dst, $src" %} 10078 ins_encode %{ 10079 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10080 %} 10081 ins_pipe(pipe_slow); // XXX 10082 %} 10083 10084 instruct convD2F_reg_mem(regF dst, memory src) 10085 %{ 10086 predicate(UseAVX == 0); 10087 match(Set dst (ConvD2F (LoadD src))); 10088 10089 format %{ "cvtsd2ss $dst, $src" %} 10090 ins_encode %{ 10091 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10092 %} 10093 ins_pipe(pipe_slow); // XXX 10094 %} 10095 10096 // XXX do mem variants 10097 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10098 %{ 10099 match(Set dst (ConvF2I src)); 10100 effect(KILL cr); 10101 format %{ "convert_f2i $dst, $src" %} 10102 ins_encode %{ 10103 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10104 %} 10105 ins_pipe(pipe_slow); 10106 %} 10107 10108 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10109 %{ 10110 match(Set dst (ConvF2L src)); 10111 effect(KILL cr); 10112 format %{ "convert_f2l $dst, $src"%} 10113 ins_encode %{ 10114 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10115 %} 10116 ins_pipe(pipe_slow); 10117 %} 10118 10119 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10120 %{ 10121 match(Set dst (ConvD2I src)); 10122 effect(KILL cr); 10123 format %{ "convert_d2i $dst, $src"%} 10124 ins_encode %{ 10125 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10126 %} 10127 ins_pipe(pipe_slow); 10128 %} 10129 10130 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10131 %{ 10132 match(Set dst (ConvD2L src)); 10133 effect(KILL cr); 10134 format %{ "convert_d2l $dst, $src"%} 10135 ins_encode %{ 10136 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10137 %} 10138 ins_pipe(pipe_slow); 10139 %} 10140 10141 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10142 %{ 10143 match(Set dst (RoundD src)); 10144 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10145 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10146 ins_encode %{ 10147 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10148 %} 10149 ins_pipe(pipe_slow); 10150 %} 10151 10152 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10153 %{ 10154 match(Set dst (RoundF src)); 10155 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10156 format %{ "round_float $dst,$src" %} 10157 ins_encode %{ 10158 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10159 %} 10160 ins_pipe(pipe_slow); 10161 %} 10162 10163 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10164 %{ 10165 predicate(!UseXmmI2F); 10166 match(Set dst (ConvI2F src)); 10167 10168 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10169 ins_encode %{ 10170 if (UseAVX > 0) { 10171 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10172 } 10173 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10174 %} 10175 ins_pipe(pipe_slow); // XXX 10176 %} 10177 10178 instruct convI2F_reg_mem(regF dst, memory src) 10179 %{ 10180 predicate(UseAVX == 0); 10181 match(Set dst (ConvI2F (LoadI src))); 10182 10183 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10184 ins_encode %{ 10185 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10186 %} 10187 ins_pipe(pipe_slow); // XXX 10188 %} 10189 10190 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10191 %{ 10192 predicate(!UseXmmI2D); 10193 match(Set dst (ConvI2D src)); 10194 10195 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10196 ins_encode %{ 10197 if (UseAVX > 0) { 10198 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10199 } 10200 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10201 %} 10202 ins_pipe(pipe_slow); // XXX 10203 %} 10204 10205 instruct convI2D_reg_mem(regD dst, memory src) 10206 %{ 10207 predicate(UseAVX == 0); 10208 match(Set dst (ConvI2D (LoadI src))); 10209 10210 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10211 ins_encode %{ 10212 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10213 %} 10214 ins_pipe(pipe_slow); // XXX 10215 %} 10216 10217 instruct convXI2F_reg(regF dst, rRegI src) 10218 %{ 10219 predicate(UseXmmI2F); 10220 match(Set dst (ConvI2F src)); 10221 10222 format %{ "movdl $dst, $src\n\t" 10223 "cvtdq2psl $dst, $dst\t# i2f" %} 10224 ins_encode %{ 10225 __ movdl($dst$$XMMRegister, $src$$Register); 10226 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10227 %} 10228 ins_pipe(pipe_slow); // XXX 10229 %} 10230 10231 instruct convXI2D_reg(regD dst, rRegI src) 10232 %{ 10233 predicate(UseXmmI2D); 10234 match(Set dst (ConvI2D src)); 10235 10236 format %{ "movdl $dst, $src\n\t" 10237 "cvtdq2pdl $dst, $dst\t# i2d" %} 10238 ins_encode %{ 10239 __ movdl($dst$$XMMRegister, $src$$Register); 10240 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10241 %} 10242 ins_pipe(pipe_slow); // XXX 10243 %} 10244 10245 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10246 %{ 10247 match(Set dst (ConvL2F src)); 10248 10249 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10250 ins_encode %{ 10251 if (UseAVX > 0) { 10252 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10253 } 10254 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10255 %} 10256 ins_pipe(pipe_slow); // XXX 10257 %} 10258 10259 instruct convL2F_reg_mem(regF dst, memory src) 10260 %{ 10261 predicate(UseAVX == 0); 10262 match(Set dst (ConvL2F (LoadL src))); 10263 10264 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10265 ins_encode %{ 10266 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10267 %} 10268 ins_pipe(pipe_slow); // XXX 10269 %} 10270 10271 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10272 %{ 10273 match(Set dst (ConvL2D src)); 10274 10275 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10276 ins_encode %{ 10277 if (UseAVX > 0) { 10278 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10279 } 10280 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10281 %} 10282 ins_pipe(pipe_slow); // XXX 10283 %} 10284 10285 instruct convL2D_reg_mem(regD dst, memory src) 10286 %{ 10287 predicate(UseAVX == 0); 10288 match(Set dst (ConvL2D (LoadL src))); 10289 10290 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10291 ins_encode %{ 10292 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10293 %} 10294 ins_pipe(pipe_slow); // XXX 10295 %} 10296 10297 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10298 %{ 10299 match(Set dst (ConvI2L src)); 10300 10301 ins_cost(125); 10302 format %{ "movslq $dst, $src\t# i2l" %} 10303 ins_encode %{ 10304 __ movslq($dst$$Register, $src$$Register); 10305 %} 10306 ins_pipe(ialu_reg_reg); 10307 %} 10308 10309 // Zero-extend convert int to long 10310 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10311 %{ 10312 match(Set dst (AndL (ConvI2L src) mask)); 10313 10314 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10315 ins_encode %{ 10316 if ($dst$$reg != $src$$reg) { 10317 __ movl($dst$$Register, $src$$Register); 10318 } 10319 %} 10320 ins_pipe(ialu_reg_reg); 10321 %} 10322 10323 // Zero-extend convert int to long 10324 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10325 %{ 10326 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10327 10328 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10329 ins_encode %{ 10330 __ movl($dst$$Register, $src$$Address); 10331 %} 10332 ins_pipe(ialu_reg_mem); 10333 %} 10334 10335 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10336 %{ 10337 match(Set dst (AndL src mask)); 10338 10339 format %{ "movl $dst, $src\t# zero-extend long" %} 10340 ins_encode %{ 10341 __ movl($dst$$Register, $src$$Register); 10342 %} 10343 ins_pipe(ialu_reg_reg); 10344 %} 10345 10346 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10347 %{ 10348 match(Set dst (ConvL2I src)); 10349 10350 format %{ "movl $dst, $src\t# l2i" %} 10351 ins_encode %{ 10352 __ movl($dst$$Register, $src$$Register); 10353 %} 10354 ins_pipe(ialu_reg_reg); 10355 %} 10356 10357 10358 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10359 match(Set dst (MoveF2I src)); 10360 effect(DEF dst, USE src); 10361 10362 ins_cost(125); 10363 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10364 ins_encode %{ 10365 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10366 %} 10367 ins_pipe(ialu_reg_mem); 10368 %} 10369 10370 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10371 match(Set dst (MoveI2F src)); 10372 effect(DEF dst, USE src); 10373 10374 ins_cost(125); 10375 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10376 ins_encode %{ 10377 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10378 %} 10379 ins_pipe(pipe_slow); 10380 %} 10381 10382 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10383 match(Set dst (MoveD2L src)); 10384 effect(DEF dst, USE src); 10385 10386 ins_cost(125); 10387 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10388 ins_encode %{ 10389 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10390 %} 10391 ins_pipe(ialu_reg_mem); 10392 %} 10393 10394 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10395 predicate(!UseXmmLoadAndClearUpper); 10396 match(Set dst (MoveL2D src)); 10397 effect(DEF dst, USE src); 10398 10399 ins_cost(125); 10400 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10401 ins_encode %{ 10402 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10403 %} 10404 ins_pipe(pipe_slow); 10405 %} 10406 10407 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10408 predicate(UseXmmLoadAndClearUpper); 10409 match(Set dst (MoveL2D src)); 10410 effect(DEF dst, USE src); 10411 10412 ins_cost(125); 10413 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10414 ins_encode %{ 10415 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10416 %} 10417 ins_pipe(pipe_slow); 10418 %} 10419 10420 10421 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10422 match(Set dst (MoveF2I src)); 10423 effect(DEF dst, USE src); 10424 10425 ins_cost(95); // XXX 10426 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10427 ins_encode %{ 10428 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10429 %} 10430 ins_pipe(pipe_slow); 10431 %} 10432 10433 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10434 match(Set dst (MoveI2F src)); 10435 effect(DEF dst, USE src); 10436 10437 ins_cost(100); 10438 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10439 ins_encode %{ 10440 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10441 %} 10442 ins_pipe( ialu_mem_reg ); 10443 %} 10444 10445 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10446 match(Set dst (MoveD2L src)); 10447 effect(DEF dst, USE src); 10448 10449 ins_cost(95); // XXX 10450 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10451 ins_encode %{ 10452 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10453 %} 10454 ins_pipe(pipe_slow); 10455 %} 10456 10457 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10458 match(Set dst (MoveL2D src)); 10459 effect(DEF dst, USE src); 10460 10461 ins_cost(100); 10462 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10463 ins_encode %{ 10464 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10465 %} 10466 ins_pipe(ialu_mem_reg); 10467 %} 10468 10469 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10470 match(Set dst (MoveF2I src)); 10471 effect(DEF dst, USE src); 10472 ins_cost(85); 10473 format %{ "movd $dst,$src\t# MoveF2I" %} 10474 ins_encode %{ 10475 __ movdl($dst$$Register, $src$$XMMRegister); 10476 %} 10477 ins_pipe( pipe_slow ); 10478 %} 10479 10480 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10481 match(Set dst (MoveD2L src)); 10482 effect(DEF dst, USE src); 10483 ins_cost(85); 10484 format %{ "movd $dst,$src\t# MoveD2L" %} 10485 ins_encode %{ 10486 __ movdq($dst$$Register, $src$$XMMRegister); 10487 %} 10488 ins_pipe( pipe_slow ); 10489 %} 10490 10491 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10492 match(Set dst (MoveI2F src)); 10493 effect(DEF dst, USE src); 10494 ins_cost(100); 10495 format %{ "movd $dst,$src\t# MoveI2F" %} 10496 ins_encode %{ 10497 __ movdl($dst$$XMMRegister, $src$$Register); 10498 %} 10499 ins_pipe( pipe_slow ); 10500 %} 10501 10502 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10503 match(Set dst (MoveL2D src)); 10504 effect(DEF dst, USE src); 10505 ins_cost(100); 10506 format %{ "movd $dst,$src\t# MoveL2D" %} 10507 ins_encode %{ 10508 __ movdq($dst$$XMMRegister, $src$$Register); 10509 %} 10510 ins_pipe( pipe_slow ); 10511 %} 10512 10513 // Fast clearing of an array 10514 // Small non-constant lenght ClearArray for non-AVX512 targets. 10515 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10516 Universe dummy, rFlagsReg cr) 10517 %{ 10518 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 10519 match(Set dummy (ClearArray cnt base)); 10520 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10521 10522 format %{ $$template 10523 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10524 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10525 $$emit$$"jg LARGE\n\t" 10526 $$emit$$"dec rcx\n\t" 10527 $$emit$$"js DONE\t# Zero length\n\t" 10528 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10529 $$emit$$"dec rcx\n\t" 10530 $$emit$$"jge LOOP\n\t" 10531 $$emit$$"jmp DONE\n\t" 10532 $$emit$$"# LARGE:\n\t" 10533 if (UseFastStosb) { 10534 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10535 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10536 } else if (UseXMMForObjInit) { 10537 $$emit$$"mov rdi,rax\n\t" 10538 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10539 $$emit$$"jmpq L_zero_64_bytes\n\t" 10540 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10541 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10542 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10543 $$emit$$"add 0x40,rax\n\t" 10544 $$emit$$"# L_zero_64_bytes:\n\t" 10545 $$emit$$"sub 0x8,rcx\n\t" 10546 $$emit$$"jge L_loop\n\t" 10547 $$emit$$"add 0x4,rcx\n\t" 10548 $$emit$$"jl L_tail\n\t" 10549 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10550 $$emit$$"add 0x20,rax\n\t" 10551 $$emit$$"sub 0x4,rcx\n\t" 10552 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10553 $$emit$$"add 0x4,rcx\n\t" 10554 $$emit$$"jle L_end\n\t" 10555 $$emit$$"dec rcx\n\t" 10556 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10557 $$emit$$"vmovq xmm0,(rax)\n\t" 10558 $$emit$$"add 0x8,rax\n\t" 10559 $$emit$$"dec rcx\n\t" 10560 $$emit$$"jge L_sloop\n\t" 10561 $$emit$$"# L_end:\n\t" 10562 } else { 10563 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10564 } 10565 $$emit$$"# DONE" 10566 %} 10567 ins_encode %{ 10568 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10569 $tmp$$XMMRegister, false, knoreg); 10570 %} 10571 ins_pipe(pipe_slow); 10572 %} 10573 10574 // Small non-constant length ClearArray for AVX512 targets. 10575 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10576 Universe dummy, rFlagsReg cr) 10577 %{ 10578 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 10579 match(Set dummy (ClearArray cnt base)); 10580 ins_cost(125); 10581 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10582 10583 format %{ $$template 10584 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10585 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10586 $$emit$$"jg LARGE\n\t" 10587 $$emit$$"dec rcx\n\t" 10588 $$emit$$"js DONE\t# Zero length\n\t" 10589 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10590 $$emit$$"dec rcx\n\t" 10591 $$emit$$"jge LOOP\n\t" 10592 $$emit$$"jmp DONE\n\t" 10593 $$emit$$"# LARGE:\n\t" 10594 if (UseFastStosb) { 10595 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10596 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10597 } else if (UseXMMForObjInit) { 10598 $$emit$$"mov rdi,rax\n\t" 10599 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10600 $$emit$$"jmpq L_zero_64_bytes\n\t" 10601 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10602 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10603 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10604 $$emit$$"add 0x40,rax\n\t" 10605 $$emit$$"# L_zero_64_bytes:\n\t" 10606 $$emit$$"sub 0x8,rcx\n\t" 10607 $$emit$$"jge L_loop\n\t" 10608 $$emit$$"add 0x4,rcx\n\t" 10609 $$emit$$"jl L_tail\n\t" 10610 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10611 $$emit$$"add 0x20,rax\n\t" 10612 $$emit$$"sub 0x4,rcx\n\t" 10613 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10614 $$emit$$"add 0x4,rcx\n\t" 10615 $$emit$$"jle L_end\n\t" 10616 $$emit$$"dec rcx\n\t" 10617 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10618 $$emit$$"vmovq xmm0,(rax)\n\t" 10619 $$emit$$"add 0x8,rax\n\t" 10620 $$emit$$"dec rcx\n\t" 10621 $$emit$$"jge L_sloop\n\t" 10622 $$emit$$"# L_end:\n\t" 10623 } else { 10624 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10625 } 10626 $$emit$$"# DONE" 10627 %} 10628 ins_encode %{ 10629 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10630 $tmp$$XMMRegister, false, $ktmp$$KRegister); 10631 %} 10632 ins_pipe(pipe_slow); 10633 %} 10634 10635 // Large non-constant length ClearArray for non-AVX512 targets. 10636 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10637 Universe dummy, rFlagsReg cr) 10638 %{ 10639 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 10640 match(Set dummy (ClearArray cnt base)); 10641 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10642 10643 format %{ $$template 10644 if (UseFastStosb) { 10645 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10646 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10647 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10648 } else if (UseXMMForObjInit) { 10649 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10650 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10651 $$emit$$"jmpq L_zero_64_bytes\n\t" 10652 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10653 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10654 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10655 $$emit$$"add 0x40,rax\n\t" 10656 $$emit$$"# L_zero_64_bytes:\n\t" 10657 $$emit$$"sub 0x8,rcx\n\t" 10658 $$emit$$"jge L_loop\n\t" 10659 $$emit$$"add 0x4,rcx\n\t" 10660 $$emit$$"jl L_tail\n\t" 10661 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10662 $$emit$$"add 0x20,rax\n\t" 10663 $$emit$$"sub 0x4,rcx\n\t" 10664 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10665 $$emit$$"add 0x4,rcx\n\t" 10666 $$emit$$"jle L_end\n\t" 10667 $$emit$$"dec rcx\n\t" 10668 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10669 $$emit$$"vmovq xmm0,(rax)\n\t" 10670 $$emit$$"add 0x8,rax\n\t" 10671 $$emit$$"dec rcx\n\t" 10672 $$emit$$"jge L_sloop\n\t" 10673 $$emit$$"# L_end:\n\t" 10674 } else { 10675 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10676 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10677 } 10678 %} 10679 ins_encode %{ 10680 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10681 $tmp$$XMMRegister, true, knoreg); 10682 %} 10683 ins_pipe(pipe_slow); 10684 %} 10685 10686 // Large non-constant length ClearArray for AVX512 targets. 10687 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10688 Universe dummy, rFlagsReg cr) 10689 %{ 10690 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 10691 match(Set dummy (ClearArray cnt base)); 10692 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10693 10694 format %{ $$template 10695 if (UseFastStosb) { 10696 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10697 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10698 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10699 } else if (UseXMMForObjInit) { 10700 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10701 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10702 $$emit$$"jmpq L_zero_64_bytes\n\t" 10703 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10704 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10705 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10706 $$emit$$"add 0x40,rax\n\t" 10707 $$emit$$"# L_zero_64_bytes:\n\t" 10708 $$emit$$"sub 0x8,rcx\n\t" 10709 $$emit$$"jge L_loop\n\t" 10710 $$emit$$"add 0x4,rcx\n\t" 10711 $$emit$$"jl L_tail\n\t" 10712 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10713 $$emit$$"add 0x20,rax\n\t" 10714 $$emit$$"sub 0x4,rcx\n\t" 10715 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10716 $$emit$$"add 0x4,rcx\n\t" 10717 $$emit$$"jle L_end\n\t" 10718 $$emit$$"dec rcx\n\t" 10719 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10720 $$emit$$"vmovq xmm0,(rax)\n\t" 10721 $$emit$$"add 0x8,rax\n\t" 10722 $$emit$$"dec rcx\n\t" 10723 $$emit$$"jge L_sloop\n\t" 10724 $$emit$$"# L_end:\n\t" 10725 } else { 10726 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10727 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10728 } 10729 %} 10730 ins_encode %{ 10731 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10732 $tmp$$XMMRegister, true, $ktmp$$KRegister); 10733 %} 10734 ins_pipe(pipe_slow); 10735 %} 10736 10737 // Small constant length ClearArray for AVX512 targets. 10738 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 10739 %{ 10740 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 10741 match(Set dummy (ClearArray cnt base)); 10742 ins_cost(100); 10743 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 10744 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10745 ins_encode %{ 10746 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10747 %} 10748 ins_pipe(pipe_slow); 10749 %} 10750 10751 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10752 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10753 %{ 10754 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10755 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10756 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10757 10758 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10759 ins_encode %{ 10760 __ string_compare($str1$$Register, $str2$$Register, 10761 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10762 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10763 %} 10764 ins_pipe( pipe_slow ); 10765 %} 10766 10767 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10768 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10769 %{ 10770 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10771 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10772 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10773 10774 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10775 ins_encode %{ 10776 __ string_compare($str1$$Register, $str2$$Register, 10777 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10778 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10779 %} 10780 ins_pipe( pipe_slow ); 10781 %} 10782 10783 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10784 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10785 %{ 10786 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10787 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10788 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10789 10790 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10791 ins_encode %{ 10792 __ string_compare($str1$$Register, $str2$$Register, 10793 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10794 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10795 %} 10796 ins_pipe( pipe_slow ); 10797 %} 10798 10799 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10800 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10801 %{ 10802 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10803 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10804 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10805 10806 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10807 ins_encode %{ 10808 __ string_compare($str1$$Register, $str2$$Register, 10809 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10810 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10811 %} 10812 ins_pipe( pipe_slow ); 10813 %} 10814 10815 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10816 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10817 %{ 10818 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10819 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10820 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10821 10822 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10823 ins_encode %{ 10824 __ string_compare($str1$$Register, $str2$$Register, 10825 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10826 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 10827 %} 10828 ins_pipe( pipe_slow ); 10829 %} 10830 10831 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10832 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10833 %{ 10834 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10835 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10836 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10837 10838 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10839 ins_encode %{ 10840 __ string_compare($str1$$Register, $str2$$Register, 10841 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10842 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 10843 %} 10844 ins_pipe( pipe_slow ); 10845 %} 10846 10847 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10848 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10849 %{ 10850 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10851 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10852 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10853 10854 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10855 ins_encode %{ 10856 __ string_compare($str2$$Register, $str1$$Register, 10857 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10858 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 10859 %} 10860 ins_pipe( pipe_slow ); 10861 %} 10862 10863 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10864 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10865 %{ 10866 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10867 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10868 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10869 10870 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10871 ins_encode %{ 10872 __ string_compare($str2$$Register, $str1$$Register, 10873 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10874 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 10875 %} 10876 ins_pipe( pipe_slow ); 10877 %} 10878 10879 // fast search of substring with known size. 10880 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10881 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10882 %{ 10883 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10884 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10885 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10886 10887 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10888 ins_encode %{ 10889 int icnt2 = (int)$int_cnt2$$constant; 10890 if (icnt2 >= 16) { 10891 // IndexOf for constant substrings with size >= 16 elements 10892 // which don't need to be loaded through stack. 10893 __ string_indexofC8($str1$$Register, $str2$$Register, 10894 $cnt1$$Register, $cnt2$$Register, 10895 icnt2, $result$$Register, 10896 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10897 } else { 10898 // Small strings are loaded through stack if they cross page boundary. 10899 __ string_indexof($str1$$Register, $str2$$Register, 10900 $cnt1$$Register, $cnt2$$Register, 10901 icnt2, $result$$Register, 10902 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10903 } 10904 %} 10905 ins_pipe( pipe_slow ); 10906 %} 10907 10908 // fast search of substring with known size. 10909 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10910 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10911 %{ 10912 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10913 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10914 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10915 10916 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10917 ins_encode %{ 10918 int icnt2 = (int)$int_cnt2$$constant; 10919 if (icnt2 >= 8) { 10920 // IndexOf for constant substrings with size >= 8 elements 10921 // which don't need to be loaded through stack. 10922 __ string_indexofC8($str1$$Register, $str2$$Register, 10923 $cnt1$$Register, $cnt2$$Register, 10924 icnt2, $result$$Register, 10925 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10926 } else { 10927 // Small strings are loaded through stack if they cross page boundary. 10928 __ string_indexof($str1$$Register, $str2$$Register, 10929 $cnt1$$Register, $cnt2$$Register, 10930 icnt2, $result$$Register, 10931 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10932 } 10933 %} 10934 ins_pipe( pipe_slow ); 10935 %} 10936 10937 // fast search of substring with known size. 10938 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10939 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10940 %{ 10941 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10942 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10943 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10944 10945 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10946 ins_encode %{ 10947 int icnt2 = (int)$int_cnt2$$constant; 10948 if (icnt2 >= 8) { 10949 // IndexOf for constant substrings with size >= 8 elements 10950 // which don't need to be loaded through stack. 10951 __ string_indexofC8($str1$$Register, $str2$$Register, 10952 $cnt1$$Register, $cnt2$$Register, 10953 icnt2, $result$$Register, 10954 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10955 } else { 10956 // Small strings are loaded through stack if they cross page boundary. 10957 __ string_indexof($str1$$Register, $str2$$Register, 10958 $cnt1$$Register, $cnt2$$Register, 10959 icnt2, $result$$Register, 10960 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10961 } 10962 %} 10963 ins_pipe( pipe_slow ); 10964 %} 10965 10966 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10967 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10968 %{ 10969 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10970 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10971 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10972 10973 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10974 ins_encode %{ 10975 __ string_indexof($str1$$Register, $str2$$Register, 10976 $cnt1$$Register, $cnt2$$Register, 10977 (-1), $result$$Register, 10978 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10979 %} 10980 ins_pipe( pipe_slow ); 10981 %} 10982 10983 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10984 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10985 %{ 10986 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10987 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10988 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10989 10990 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10991 ins_encode %{ 10992 __ string_indexof($str1$$Register, $str2$$Register, 10993 $cnt1$$Register, $cnt2$$Register, 10994 (-1), $result$$Register, 10995 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10996 %} 10997 ins_pipe( pipe_slow ); 10998 %} 10999 11000 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11001 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11002 %{ 11003 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11004 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11005 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11006 11007 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11008 ins_encode %{ 11009 __ string_indexof($str1$$Register, $str2$$Register, 11010 $cnt1$$Register, $cnt2$$Register, 11011 (-1), $result$$Register, 11012 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11013 %} 11014 ins_pipe( pipe_slow ); 11015 %} 11016 11017 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11018 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11019 %{ 11020 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 11021 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11022 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11023 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11024 ins_encode %{ 11025 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11026 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11027 %} 11028 ins_pipe( pipe_slow ); 11029 %} 11030 11031 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11032 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11033 %{ 11034 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 11035 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11036 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11037 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11038 ins_encode %{ 11039 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11040 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11041 %} 11042 ins_pipe( pipe_slow ); 11043 %} 11044 11045 // fast string equals 11046 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11047 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11048 %{ 11049 predicate(!VM_Version::supports_avx512vlbw()); 11050 match(Set result (StrEquals (Binary str1 str2) cnt)); 11051 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11052 11053 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11054 ins_encode %{ 11055 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11056 $cnt$$Register, $result$$Register, $tmp3$$Register, 11057 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11058 %} 11059 ins_pipe( pipe_slow ); 11060 %} 11061 11062 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11063 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11064 %{ 11065 predicate(VM_Version::supports_avx512vlbw()); 11066 match(Set result (StrEquals (Binary str1 str2) cnt)); 11067 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11068 11069 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11070 ins_encode %{ 11071 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11072 $cnt$$Register, $result$$Register, $tmp3$$Register, 11073 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11074 %} 11075 ins_pipe( pipe_slow ); 11076 %} 11077 11078 // fast array equals 11079 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11080 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11081 %{ 11082 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11083 match(Set result (AryEq ary1 ary2)); 11084 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11085 11086 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11087 ins_encode %{ 11088 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11089 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11090 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11091 %} 11092 ins_pipe( pipe_slow ); 11093 %} 11094 11095 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11096 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11097 %{ 11098 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11099 match(Set result (AryEq ary1 ary2)); 11100 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11101 11102 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11103 ins_encode %{ 11104 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11105 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11106 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11107 %} 11108 ins_pipe( pipe_slow ); 11109 %} 11110 11111 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11112 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11113 %{ 11114 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11115 match(Set result (AryEq ary1 ary2)); 11116 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11117 11118 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11119 ins_encode %{ 11120 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11121 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11122 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11123 %} 11124 ins_pipe( pipe_slow ); 11125 %} 11126 11127 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11128 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11129 %{ 11130 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11131 match(Set result (AryEq ary1 ary2)); 11132 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11133 11134 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11135 ins_encode %{ 11136 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11137 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11138 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11139 %} 11140 ins_pipe( pipe_slow ); 11141 %} 11142 11143 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11144 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11145 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11146 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11147 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11148 %{ 11149 predicate(UseAVX >= 2); 11150 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11151 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11152 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11153 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11154 USE basic_type, KILL cr); 11155 11156 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11157 ins_encode %{ 11158 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11159 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11160 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11161 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11162 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11163 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11164 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11165 %} 11166 ins_pipe( pipe_slow ); 11167 %} 11168 11169 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11170 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11171 %{ 11172 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11173 match(Set result (CountPositives ary1 len)); 11174 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11175 11176 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11177 ins_encode %{ 11178 __ count_positives($ary1$$Register, $len$$Register, 11179 $result$$Register, $tmp3$$Register, 11180 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11181 %} 11182 ins_pipe( pipe_slow ); 11183 %} 11184 11185 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11186 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11187 %{ 11188 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11189 match(Set result (CountPositives ary1 len)); 11190 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11191 11192 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11193 ins_encode %{ 11194 __ count_positives($ary1$$Register, $len$$Register, 11195 $result$$Register, $tmp3$$Register, 11196 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11197 %} 11198 ins_pipe( pipe_slow ); 11199 %} 11200 11201 // fast char[] to byte[] compression 11202 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11203 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11204 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11205 match(Set result (StrCompressedCopy src (Binary dst len))); 11206 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11207 USE_KILL len, KILL tmp5, KILL cr); 11208 11209 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11210 ins_encode %{ 11211 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11212 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11213 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11214 knoreg, knoreg); 11215 %} 11216 ins_pipe( pipe_slow ); 11217 %} 11218 11219 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11220 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11221 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11222 match(Set result (StrCompressedCopy src (Binary dst len))); 11223 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11224 USE_KILL len, KILL tmp5, KILL cr); 11225 11226 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11227 ins_encode %{ 11228 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11229 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11230 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11231 $ktmp1$$KRegister, $ktmp2$$KRegister); 11232 %} 11233 ins_pipe( pipe_slow ); 11234 %} 11235 // fast byte[] to char[] inflation 11236 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11237 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11238 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11239 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11240 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11241 11242 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11243 ins_encode %{ 11244 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11245 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11246 %} 11247 ins_pipe( pipe_slow ); 11248 %} 11249 11250 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11251 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11252 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11253 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11254 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11255 11256 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11257 ins_encode %{ 11258 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11259 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11260 %} 11261 ins_pipe( pipe_slow ); 11262 %} 11263 11264 // encode char[] to byte[] in ISO_8859_1 11265 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11266 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11267 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11268 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11269 match(Set result (EncodeISOArray src (Binary dst len))); 11270 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11271 11272 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11273 ins_encode %{ 11274 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11275 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11276 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11277 %} 11278 ins_pipe( pipe_slow ); 11279 %} 11280 11281 // encode char[] to byte[] in ASCII 11282 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11283 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11284 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11285 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11286 match(Set result (EncodeISOArray src (Binary dst len))); 11287 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11288 11289 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11290 ins_encode %{ 11291 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11292 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11293 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11294 %} 11295 ins_pipe( pipe_slow ); 11296 %} 11297 11298 //----------Overflow Math Instructions----------------------------------------- 11299 11300 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11301 %{ 11302 match(Set cr (OverflowAddI op1 op2)); 11303 effect(DEF cr, USE_KILL op1, USE op2); 11304 11305 format %{ "addl $op1, $op2\t# overflow check int" %} 11306 11307 ins_encode %{ 11308 __ addl($op1$$Register, $op2$$Register); 11309 %} 11310 ins_pipe(ialu_reg_reg); 11311 %} 11312 11313 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11314 %{ 11315 match(Set cr (OverflowAddI op1 op2)); 11316 effect(DEF cr, USE_KILL op1, USE op2); 11317 11318 format %{ "addl $op1, $op2\t# overflow check int" %} 11319 11320 ins_encode %{ 11321 __ addl($op1$$Register, $op2$$constant); 11322 %} 11323 ins_pipe(ialu_reg_reg); 11324 %} 11325 11326 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11327 %{ 11328 match(Set cr (OverflowAddL op1 op2)); 11329 effect(DEF cr, USE_KILL op1, USE op2); 11330 11331 format %{ "addq $op1, $op2\t# overflow check long" %} 11332 ins_encode %{ 11333 __ addq($op1$$Register, $op2$$Register); 11334 %} 11335 ins_pipe(ialu_reg_reg); 11336 %} 11337 11338 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11339 %{ 11340 match(Set cr (OverflowAddL op1 op2)); 11341 effect(DEF cr, USE_KILL op1, USE op2); 11342 11343 format %{ "addq $op1, $op2\t# overflow check long" %} 11344 ins_encode %{ 11345 __ addq($op1$$Register, $op2$$constant); 11346 %} 11347 ins_pipe(ialu_reg_reg); 11348 %} 11349 11350 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11351 %{ 11352 match(Set cr (OverflowSubI op1 op2)); 11353 11354 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11355 ins_encode %{ 11356 __ cmpl($op1$$Register, $op2$$Register); 11357 %} 11358 ins_pipe(ialu_reg_reg); 11359 %} 11360 11361 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11362 %{ 11363 match(Set cr (OverflowSubI op1 op2)); 11364 11365 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11366 ins_encode %{ 11367 __ cmpl($op1$$Register, $op2$$constant); 11368 %} 11369 ins_pipe(ialu_reg_reg); 11370 %} 11371 11372 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11373 %{ 11374 match(Set cr (OverflowSubL op1 op2)); 11375 11376 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11377 ins_encode %{ 11378 __ cmpq($op1$$Register, $op2$$Register); 11379 %} 11380 ins_pipe(ialu_reg_reg); 11381 %} 11382 11383 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11384 %{ 11385 match(Set cr (OverflowSubL op1 op2)); 11386 11387 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11388 ins_encode %{ 11389 __ cmpq($op1$$Register, $op2$$constant); 11390 %} 11391 ins_pipe(ialu_reg_reg); 11392 %} 11393 11394 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11395 %{ 11396 match(Set cr (OverflowSubI zero op2)); 11397 effect(DEF cr, USE_KILL op2); 11398 11399 format %{ "negl $op2\t# overflow check int" %} 11400 ins_encode %{ 11401 __ negl($op2$$Register); 11402 %} 11403 ins_pipe(ialu_reg_reg); 11404 %} 11405 11406 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11407 %{ 11408 match(Set cr (OverflowSubL zero op2)); 11409 effect(DEF cr, USE_KILL op2); 11410 11411 format %{ "negq $op2\t# overflow check long" %} 11412 ins_encode %{ 11413 __ negq($op2$$Register); 11414 %} 11415 ins_pipe(ialu_reg_reg); 11416 %} 11417 11418 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11419 %{ 11420 match(Set cr (OverflowMulI op1 op2)); 11421 effect(DEF cr, USE_KILL op1, USE op2); 11422 11423 format %{ "imull $op1, $op2\t# overflow check int" %} 11424 ins_encode %{ 11425 __ imull($op1$$Register, $op2$$Register); 11426 %} 11427 ins_pipe(ialu_reg_reg_alu0); 11428 %} 11429 11430 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11431 %{ 11432 match(Set cr (OverflowMulI op1 op2)); 11433 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11434 11435 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11436 ins_encode %{ 11437 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11438 %} 11439 ins_pipe(ialu_reg_reg_alu0); 11440 %} 11441 11442 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11443 %{ 11444 match(Set cr (OverflowMulL op1 op2)); 11445 effect(DEF cr, USE_KILL op1, USE op2); 11446 11447 format %{ "imulq $op1, $op2\t# overflow check long" %} 11448 ins_encode %{ 11449 __ imulq($op1$$Register, $op2$$Register); 11450 %} 11451 ins_pipe(ialu_reg_reg_alu0); 11452 %} 11453 11454 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11455 %{ 11456 match(Set cr (OverflowMulL op1 op2)); 11457 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11458 11459 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11460 ins_encode %{ 11461 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11462 %} 11463 ins_pipe(ialu_reg_reg_alu0); 11464 %} 11465 11466 11467 //----------Control Flow Instructions------------------------------------------ 11468 // Signed compare Instructions 11469 11470 // XXX more variants!! 11471 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11472 %{ 11473 match(Set cr (CmpI op1 op2)); 11474 effect(DEF cr, USE op1, USE op2); 11475 11476 format %{ "cmpl $op1, $op2" %} 11477 ins_encode %{ 11478 __ cmpl($op1$$Register, $op2$$Register); 11479 %} 11480 ins_pipe(ialu_cr_reg_reg); 11481 %} 11482 11483 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11484 %{ 11485 match(Set cr (CmpI op1 op2)); 11486 11487 format %{ "cmpl $op1, $op2" %} 11488 ins_encode %{ 11489 __ cmpl($op1$$Register, $op2$$constant); 11490 %} 11491 ins_pipe(ialu_cr_reg_imm); 11492 %} 11493 11494 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11495 %{ 11496 match(Set cr (CmpI op1 (LoadI op2))); 11497 11498 ins_cost(500); // XXX 11499 format %{ "cmpl $op1, $op2" %} 11500 ins_encode %{ 11501 __ cmpl($op1$$Register, $op2$$Address); 11502 %} 11503 ins_pipe(ialu_cr_reg_mem); 11504 %} 11505 11506 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11507 %{ 11508 match(Set cr (CmpI src zero)); 11509 11510 format %{ "testl $src, $src" %} 11511 ins_encode %{ 11512 __ testl($src$$Register, $src$$Register); 11513 %} 11514 ins_pipe(ialu_cr_reg_imm); 11515 %} 11516 11517 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11518 %{ 11519 match(Set cr (CmpI (AndI src con) zero)); 11520 11521 format %{ "testl $src, $con" %} 11522 ins_encode %{ 11523 __ testl($src$$Register, $con$$constant); 11524 %} 11525 ins_pipe(ialu_cr_reg_imm); 11526 %} 11527 11528 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11529 %{ 11530 match(Set cr (CmpI (AndI src1 src2) zero)); 11531 11532 format %{ "testl $src1, $src2" %} 11533 ins_encode %{ 11534 __ testl($src1$$Register, $src2$$Register); 11535 %} 11536 ins_pipe(ialu_cr_reg_imm); 11537 %} 11538 11539 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11540 %{ 11541 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11542 11543 format %{ "testl $src, $mem" %} 11544 ins_encode %{ 11545 __ testl($src$$Register, $mem$$Address); 11546 %} 11547 ins_pipe(ialu_cr_reg_mem); 11548 %} 11549 11550 // Unsigned compare Instructions; really, same as signed except they 11551 // produce an rFlagsRegU instead of rFlagsReg. 11552 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11553 %{ 11554 match(Set cr (CmpU op1 op2)); 11555 11556 format %{ "cmpl $op1, $op2\t# unsigned" %} 11557 ins_encode %{ 11558 __ cmpl($op1$$Register, $op2$$Register); 11559 %} 11560 ins_pipe(ialu_cr_reg_reg); 11561 %} 11562 11563 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11564 %{ 11565 match(Set cr (CmpU op1 op2)); 11566 11567 format %{ "cmpl $op1, $op2\t# unsigned" %} 11568 ins_encode %{ 11569 __ cmpl($op1$$Register, $op2$$constant); 11570 %} 11571 ins_pipe(ialu_cr_reg_imm); 11572 %} 11573 11574 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11575 %{ 11576 match(Set cr (CmpU op1 (LoadI op2))); 11577 11578 ins_cost(500); // XXX 11579 format %{ "cmpl $op1, $op2\t# unsigned" %} 11580 ins_encode %{ 11581 __ cmpl($op1$$Register, $op2$$Address); 11582 %} 11583 ins_pipe(ialu_cr_reg_mem); 11584 %} 11585 11586 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11587 %{ 11588 match(Set cr (CmpU src zero)); 11589 11590 format %{ "testl $src, $src\t# unsigned" %} 11591 ins_encode %{ 11592 __ testl($src$$Register, $src$$Register); 11593 %} 11594 ins_pipe(ialu_cr_reg_imm); 11595 %} 11596 11597 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11598 %{ 11599 match(Set cr (CmpP op1 op2)); 11600 11601 format %{ "cmpq $op1, $op2\t# ptr" %} 11602 ins_encode %{ 11603 __ cmpq($op1$$Register, $op2$$Register); 11604 %} 11605 ins_pipe(ialu_cr_reg_reg); 11606 %} 11607 11608 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11609 %{ 11610 match(Set cr (CmpP op1 (LoadP op2))); 11611 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11612 11613 ins_cost(500); // XXX 11614 format %{ "cmpq $op1, $op2\t# ptr" %} 11615 ins_encode %{ 11616 __ cmpq($op1$$Register, $op2$$Address); 11617 %} 11618 ins_pipe(ialu_cr_reg_mem); 11619 %} 11620 11621 // XXX this is generalized by compP_rReg_mem??? 11622 // Compare raw pointer (used in out-of-heap check). 11623 // Only works because non-oop pointers must be raw pointers 11624 // and raw pointers have no anti-dependencies. 11625 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11626 %{ 11627 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11628 n->in(2)->as_Load()->barrier_data() == 0); 11629 match(Set cr (CmpP op1 (LoadP op2))); 11630 11631 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11632 ins_encode %{ 11633 __ cmpq($op1$$Register, $op2$$Address); 11634 %} 11635 ins_pipe(ialu_cr_reg_mem); 11636 %} 11637 11638 // This will generate a signed flags result. This should be OK since 11639 // any compare to a zero should be eq/neq. 11640 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11641 %{ 11642 match(Set cr (CmpP src zero)); 11643 11644 format %{ "testq $src, $src\t# ptr" %} 11645 ins_encode %{ 11646 __ testq($src$$Register, $src$$Register); 11647 %} 11648 ins_pipe(ialu_cr_reg_imm); 11649 %} 11650 11651 // This will generate a signed flags result. This should be OK since 11652 // any compare to a zero should be eq/neq. 11653 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11654 %{ 11655 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11656 n->in(1)->as_Load()->barrier_data() == 0); 11657 match(Set cr (CmpP (LoadP op) zero)); 11658 11659 ins_cost(500); // XXX 11660 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11661 ins_encode %{ 11662 __ testq($op$$Address, 0xFFFFFFFF); 11663 %} 11664 ins_pipe(ialu_cr_reg_imm); 11665 %} 11666 11667 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11668 %{ 11669 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11670 n->in(1)->as_Load()->barrier_data() == 0); 11671 match(Set cr (CmpP (LoadP mem) zero)); 11672 11673 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11674 ins_encode %{ 11675 __ cmpq(r12, $mem$$Address); 11676 %} 11677 ins_pipe(ialu_cr_reg_mem); 11678 %} 11679 11680 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11681 %{ 11682 match(Set cr (CmpN op1 op2)); 11683 11684 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11685 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11686 ins_pipe(ialu_cr_reg_reg); 11687 %} 11688 11689 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11690 %{ 11691 match(Set cr (CmpN src (LoadN mem))); 11692 11693 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11694 ins_encode %{ 11695 __ cmpl($src$$Register, $mem$$Address); 11696 %} 11697 ins_pipe(ialu_cr_reg_mem); 11698 %} 11699 11700 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11701 match(Set cr (CmpN op1 op2)); 11702 11703 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11704 ins_encode %{ 11705 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11706 %} 11707 ins_pipe(ialu_cr_reg_imm); 11708 %} 11709 11710 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11711 %{ 11712 match(Set cr (CmpN src (LoadN mem))); 11713 11714 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11715 ins_encode %{ 11716 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11717 %} 11718 ins_pipe(ialu_cr_reg_mem); 11719 %} 11720 11721 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11722 match(Set cr (CmpN op1 op2)); 11723 11724 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11725 ins_encode %{ 11726 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11727 %} 11728 ins_pipe(ialu_cr_reg_imm); 11729 %} 11730 11731 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11732 %{ 11733 match(Set cr (CmpN src (LoadNKlass mem))); 11734 11735 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11736 ins_encode %{ 11737 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11738 %} 11739 ins_pipe(ialu_cr_reg_mem); 11740 %} 11741 11742 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11743 match(Set cr (CmpN src zero)); 11744 11745 format %{ "testl $src, $src\t# compressed ptr" %} 11746 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11747 ins_pipe(ialu_cr_reg_imm); 11748 %} 11749 11750 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11751 %{ 11752 predicate(CompressedOops::base() != nullptr); 11753 match(Set cr (CmpN (LoadN mem) zero)); 11754 11755 ins_cost(500); // XXX 11756 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11757 ins_encode %{ 11758 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11759 %} 11760 ins_pipe(ialu_cr_reg_mem); 11761 %} 11762 11763 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11764 %{ 11765 predicate(CompressedOops::base() == nullptr); 11766 match(Set cr (CmpN (LoadN mem) zero)); 11767 11768 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11769 ins_encode %{ 11770 __ cmpl(r12, $mem$$Address); 11771 %} 11772 ins_pipe(ialu_cr_reg_mem); 11773 %} 11774 11775 // Yanked all unsigned pointer compare operations. 11776 // Pointer compares are done with CmpP which is already unsigned. 11777 11778 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11779 %{ 11780 match(Set cr (CmpL op1 op2)); 11781 11782 format %{ "cmpq $op1, $op2" %} 11783 ins_encode %{ 11784 __ cmpq($op1$$Register, $op2$$Register); 11785 %} 11786 ins_pipe(ialu_cr_reg_reg); 11787 %} 11788 11789 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11790 %{ 11791 match(Set cr (CmpL op1 op2)); 11792 11793 format %{ "cmpq $op1, $op2" %} 11794 ins_encode %{ 11795 __ cmpq($op1$$Register, $op2$$constant); 11796 %} 11797 ins_pipe(ialu_cr_reg_imm); 11798 %} 11799 11800 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11801 %{ 11802 match(Set cr (CmpL op1 (LoadL op2))); 11803 11804 format %{ "cmpq $op1, $op2" %} 11805 ins_encode %{ 11806 __ cmpq($op1$$Register, $op2$$Address); 11807 %} 11808 ins_pipe(ialu_cr_reg_mem); 11809 %} 11810 11811 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11812 %{ 11813 match(Set cr (CmpL src zero)); 11814 11815 format %{ "testq $src, $src" %} 11816 ins_encode %{ 11817 __ testq($src$$Register, $src$$Register); 11818 %} 11819 ins_pipe(ialu_cr_reg_imm); 11820 %} 11821 11822 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11823 %{ 11824 match(Set cr (CmpL (AndL src con) zero)); 11825 11826 format %{ "testq $src, $con\t# long" %} 11827 ins_encode %{ 11828 __ testq($src$$Register, $con$$constant); 11829 %} 11830 ins_pipe(ialu_cr_reg_imm); 11831 %} 11832 11833 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 11834 %{ 11835 match(Set cr (CmpL (AndL src1 src2) zero)); 11836 11837 format %{ "testq $src1, $src2\t# long" %} 11838 ins_encode %{ 11839 __ testq($src1$$Register, $src2$$Register); 11840 %} 11841 ins_pipe(ialu_cr_reg_imm); 11842 %} 11843 11844 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11845 %{ 11846 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11847 11848 format %{ "testq $src, $mem" %} 11849 ins_encode %{ 11850 __ testq($src$$Register, $mem$$Address); 11851 %} 11852 ins_pipe(ialu_cr_reg_mem); 11853 %} 11854 11855 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11856 %{ 11857 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11858 11859 format %{ "testq $src, $mem" %} 11860 ins_encode %{ 11861 __ testq($src$$Register, $mem$$Address); 11862 %} 11863 ins_pipe(ialu_cr_reg_mem); 11864 %} 11865 11866 // Manifest a CmpU result in an integer register. Very painful. 11867 // This is the test to avoid. 11868 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 11869 %{ 11870 match(Set dst (CmpU3 src1 src2)); 11871 effect(KILL flags); 11872 11873 ins_cost(275); // XXX 11874 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 11875 "movl $dst, -1\n\t" 11876 "jb,u done\n\t" 11877 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11878 "done:" %} 11879 ins_encode %{ 11880 Label done; 11881 __ cmpl($src1$$Register, $src2$$Register); 11882 __ movl($dst$$Register, -1); 11883 __ jccb(Assembler::below, done); 11884 __ setcc(Assembler::notZero, $dst$$Register); 11885 __ bind(done); 11886 %} 11887 ins_pipe(pipe_slow); 11888 %} 11889 11890 // Manifest a CmpL result in an integer register. Very painful. 11891 // This is the test to avoid. 11892 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11893 %{ 11894 match(Set dst (CmpL3 src1 src2)); 11895 effect(KILL flags); 11896 11897 ins_cost(275); // XXX 11898 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11899 "movl $dst, -1\n\t" 11900 "jl,s done\n\t" 11901 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11902 "done:" %} 11903 ins_encode %{ 11904 Label done; 11905 __ cmpq($src1$$Register, $src2$$Register); 11906 __ movl($dst$$Register, -1); 11907 __ jccb(Assembler::less, done); 11908 __ setcc(Assembler::notZero, $dst$$Register); 11909 __ bind(done); 11910 %} 11911 ins_pipe(pipe_slow); 11912 %} 11913 11914 // Manifest a CmpUL result in an integer register. Very painful. 11915 // This is the test to avoid. 11916 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11917 %{ 11918 match(Set dst (CmpUL3 src1 src2)); 11919 effect(KILL flags); 11920 11921 ins_cost(275); // XXX 11922 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11923 "movl $dst, -1\n\t" 11924 "jb,u done\n\t" 11925 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11926 "done:" %} 11927 ins_encode %{ 11928 Label done; 11929 __ cmpq($src1$$Register, $src2$$Register); 11930 __ movl($dst$$Register, -1); 11931 __ jccb(Assembler::below, done); 11932 __ setcc(Assembler::notZero, $dst$$Register); 11933 __ bind(done); 11934 %} 11935 ins_pipe(pipe_slow); 11936 %} 11937 11938 // Unsigned long compare Instructions; really, same as signed long except they 11939 // produce an rFlagsRegU instead of rFlagsReg. 11940 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11941 %{ 11942 match(Set cr (CmpUL op1 op2)); 11943 11944 format %{ "cmpq $op1, $op2\t# unsigned" %} 11945 ins_encode %{ 11946 __ cmpq($op1$$Register, $op2$$Register); 11947 %} 11948 ins_pipe(ialu_cr_reg_reg); 11949 %} 11950 11951 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11952 %{ 11953 match(Set cr (CmpUL op1 op2)); 11954 11955 format %{ "cmpq $op1, $op2\t# unsigned" %} 11956 ins_encode %{ 11957 __ cmpq($op1$$Register, $op2$$constant); 11958 %} 11959 ins_pipe(ialu_cr_reg_imm); 11960 %} 11961 11962 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11963 %{ 11964 match(Set cr (CmpUL op1 (LoadL op2))); 11965 11966 format %{ "cmpq $op1, $op2\t# unsigned" %} 11967 ins_encode %{ 11968 __ cmpq($op1$$Register, $op2$$Address); 11969 %} 11970 ins_pipe(ialu_cr_reg_mem); 11971 %} 11972 11973 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11974 %{ 11975 match(Set cr (CmpUL src zero)); 11976 11977 format %{ "testq $src, $src\t# unsigned" %} 11978 ins_encode %{ 11979 __ testq($src$$Register, $src$$Register); 11980 %} 11981 ins_pipe(ialu_cr_reg_imm); 11982 %} 11983 11984 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11985 %{ 11986 match(Set cr (CmpI (LoadB mem) imm)); 11987 11988 ins_cost(125); 11989 format %{ "cmpb $mem, $imm" %} 11990 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11991 ins_pipe(ialu_cr_reg_mem); 11992 %} 11993 11994 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 11995 %{ 11996 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11997 11998 ins_cost(125); 11999 format %{ "testb $mem, $imm\t# ubyte" %} 12000 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12001 ins_pipe(ialu_cr_reg_mem); 12002 %} 12003 12004 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 12005 %{ 12006 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12007 12008 ins_cost(125); 12009 format %{ "testb $mem, $imm\t# byte" %} 12010 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12011 ins_pipe(ialu_cr_reg_mem); 12012 %} 12013 12014 //----------Max and Min-------------------------------------------------------- 12015 // Min Instructions 12016 12017 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12018 %{ 12019 effect(USE_DEF dst, USE src, USE cr); 12020 12021 format %{ "cmovlgt $dst, $src\t# min" %} 12022 ins_encode %{ 12023 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 12024 %} 12025 ins_pipe(pipe_cmov_reg); 12026 %} 12027 12028 12029 instruct minI_rReg(rRegI dst, rRegI src) 12030 %{ 12031 match(Set dst (MinI dst src)); 12032 12033 ins_cost(200); 12034 expand %{ 12035 rFlagsReg cr; 12036 compI_rReg(cr, dst, src); 12037 cmovI_reg_g(dst, src, cr); 12038 %} 12039 %} 12040 12041 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12042 %{ 12043 effect(USE_DEF dst, USE src, USE cr); 12044 12045 format %{ "cmovllt $dst, $src\t# max" %} 12046 ins_encode %{ 12047 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12048 %} 12049 ins_pipe(pipe_cmov_reg); 12050 %} 12051 12052 12053 instruct maxI_rReg(rRegI dst, rRegI src) 12054 %{ 12055 match(Set dst (MaxI dst src)); 12056 12057 ins_cost(200); 12058 expand %{ 12059 rFlagsReg cr; 12060 compI_rReg(cr, dst, src); 12061 cmovI_reg_l(dst, src, cr); 12062 %} 12063 %} 12064 12065 // ============================================================================ 12066 // Branch Instructions 12067 12068 // Jump Direct - Label defines a relative address from JMP+1 12069 instruct jmpDir(label labl) 12070 %{ 12071 match(Goto); 12072 effect(USE labl); 12073 12074 ins_cost(300); 12075 format %{ "jmp $labl" %} 12076 size(5); 12077 ins_encode %{ 12078 Label* L = $labl$$label; 12079 __ jmp(*L, false); // Always long jump 12080 %} 12081 ins_pipe(pipe_jmp); 12082 %} 12083 12084 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12085 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12086 %{ 12087 match(If cop cr); 12088 effect(USE labl); 12089 12090 ins_cost(300); 12091 format %{ "j$cop $labl" %} 12092 size(6); 12093 ins_encode %{ 12094 Label* L = $labl$$label; 12095 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12096 %} 12097 ins_pipe(pipe_jcc); 12098 %} 12099 12100 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12101 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12102 %{ 12103 match(CountedLoopEnd cop cr); 12104 effect(USE labl); 12105 12106 ins_cost(300); 12107 format %{ "j$cop $labl\t# loop end" %} 12108 size(6); 12109 ins_encode %{ 12110 Label* L = $labl$$label; 12111 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12112 %} 12113 ins_pipe(pipe_jcc); 12114 %} 12115 12116 // Jump Direct Conditional - using unsigned comparison 12117 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12118 match(If cop cmp); 12119 effect(USE labl); 12120 12121 ins_cost(300); 12122 format %{ "j$cop,u $labl" %} 12123 size(6); 12124 ins_encode %{ 12125 Label* L = $labl$$label; 12126 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12127 %} 12128 ins_pipe(pipe_jcc); 12129 %} 12130 12131 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12132 match(If cop cmp); 12133 effect(USE labl); 12134 12135 ins_cost(200); 12136 format %{ "j$cop,u $labl" %} 12137 size(6); 12138 ins_encode %{ 12139 Label* L = $labl$$label; 12140 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12141 %} 12142 ins_pipe(pipe_jcc); 12143 %} 12144 12145 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12146 match(If cop cmp); 12147 effect(USE labl); 12148 12149 ins_cost(200); 12150 format %{ $$template 12151 if ($cop$$cmpcode == Assembler::notEqual) { 12152 $$emit$$"jp,u $labl\n\t" 12153 $$emit$$"j$cop,u $labl" 12154 } else { 12155 $$emit$$"jp,u done\n\t" 12156 $$emit$$"j$cop,u $labl\n\t" 12157 $$emit$$"done:" 12158 } 12159 %} 12160 ins_encode %{ 12161 Label* l = $labl$$label; 12162 if ($cop$$cmpcode == Assembler::notEqual) { 12163 __ jcc(Assembler::parity, *l, false); 12164 __ jcc(Assembler::notEqual, *l, false); 12165 } else if ($cop$$cmpcode == Assembler::equal) { 12166 Label done; 12167 __ jccb(Assembler::parity, done); 12168 __ jcc(Assembler::equal, *l, false); 12169 __ bind(done); 12170 } else { 12171 ShouldNotReachHere(); 12172 } 12173 %} 12174 ins_pipe(pipe_jcc); 12175 %} 12176 12177 // ============================================================================ 12178 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12179 // superklass array for an instance of the superklass. Set a hidden 12180 // internal cache on a hit (cache is checked with exposed code in 12181 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12182 // encoding ALSO sets flags. 12183 12184 instruct partialSubtypeCheck(rdi_RegP result, 12185 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12186 rFlagsReg cr) 12187 %{ 12188 match(Set result (PartialSubtypeCheck sub super)); 12189 effect(KILL rcx, KILL cr); 12190 12191 ins_cost(1100); // slightly larger than the next version 12192 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12193 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12194 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12195 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12196 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12197 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12198 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12199 "miss:\t" %} 12200 12201 opcode(0x1); // Force a XOR of RDI 12202 ins_encode(enc_PartialSubtypeCheck()); 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($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 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12232 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12233 immP0 zero, 12234 rdi_RegP result) 12235 %{ 12236 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12237 effect(KILL rcx, KILL result); 12238 12239 ins_cost(1000); 12240 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12241 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12242 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12243 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12244 "jne,s miss\t\t# Missed: flags nz\n\t" 12245 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12246 "miss:\t" %} 12247 12248 opcode(0x0); // No need to XOR RDI 12249 ins_encode(enc_PartialSubtypeCheck()); 12250 ins_pipe(pipe_slow); 12251 %} 12252 12253 // ============================================================================ 12254 // Branch Instructions -- short offset versions 12255 // 12256 // These instructions are used to replace jumps of a long offset (the default 12257 // match) with jumps of a shorter offset. These instructions are all tagged 12258 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12259 // match rules in general matching. Instead, the ADLC generates a conversion 12260 // method in the MachNode which can be used to do in-place replacement of the 12261 // long variant with the shorter variant. The compiler will determine if a 12262 // branch can be taken by the is_short_branch_offset() predicate in the machine 12263 // specific code section of the file. 12264 12265 // Jump Direct - Label defines a relative address from JMP+1 12266 instruct jmpDir_short(label labl) %{ 12267 match(Goto); 12268 effect(USE labl); 12269 12270 ins_cost(300); 12271 format %{ "jmp,s $labl" %} 12272 size(2); 12273 ins_encode %{ 12274 Label* L = $labl$$label; 12275 __ jmpb(*L); 12276 %} 12277 ins_pipe(pipe_jmp); 12278 ins_short_branch(1); 12279 %} 12280 12281 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12282 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12283 match(If cop cr); 12284 effect(USE labl); 12285 12286 ins_cost(300); 12287 format %{ "j$cop,s $labl" %} 12288 size(2); 12289 ins_encode %{ 12290 Label* L = $labl$$label; 12291 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12292 %} 12293 ins_pipe(pipe_jcc); 12294 ins_short_branch(1); 12295 %} 12296 12297 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12298 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12299 match(CountedLoopEnd cop cr); 12300 effect(USE labl); 12301 12302 ins_cost(300); 12303 format %{ "j$cop,s $labl\t# loop end" %} 12304 size(2); 12305 ins_encode %{ 12306 Label* L = $labl$$label; 12307 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12308 %} 12309 ins_pipe(pipe_jcc); 12310 ins_short_branch(1); 12311 %} 12312 12313 // Jump Direct Conditional - using unsigned comparison 12314 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12315 match(If cop cmp); 12316 effect(USE labl); 12317 12318 ins_cost(300); 12319 format %{ "j$cop,us $labl" %} 12320 size(2); 12321 ins_encode %{ 12322 Label* L = $labl$$label; 12323 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12324 %} 12325 ins_pipe(pipe_jcc); 12326 ins_short_branch(1); 12327 %} 12328 12329 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12330 match(If cop cmp); 12331 effect(USE labl); 12332 12333 ins_cost(300); 12334 format %{ "j$cop,us $labl" %} 12335 size(2); 12336 ins_encode %{ 12337 Label* L = $labl$$label; 12338 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12339 %} 12340 ins_pipe(pipe_jcc); 12341 ins_short_branch(1); 12342 %} 12343 12344 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12345 match(If cop cmp); 12346 effect(USE labl); 12347 12348 ins_cost(300); 12349 format %{ $$template 12350 if ($cop$$cmpcode == Assembler::notEqual) { 12351 $$emit$$"jp,u,s $labl\n\t" 12352 $$emit$$"j$cop,u,s $labl" 12353 } else { 12354 $$emit$$"jp,u,s done\n\t" 12355 $$emit$$"j$cop,u,s $labl\n\t" 12356 $$emit$$"done:" 12357 } 12358 %} 12359 size(4); 12360 ins_encode %{ 12361 Label* l = $labl$$label; 12362 if ($cop$$cmpcode == Assembler::notEqual) { 12363 __ jccb(Assembler::parity, *l); 12364 __ jccb(Assembler::notEqual, *l); 12365 } else if ($cop$$cmpcode == Assembler::equal) { 12366 Label done; 12367 __ jccb(Assembler::parity, done); 12368 __ jccb(Assembler::equal, *l); 12369 __ bind(done); 12370 } else { 12371 ShouldNotReachHere(); 12372 } 12373 %} 12374 ins_pipe(pipe_jcc); 12375 ins_short_branch(1); 12376 %} 12377 12378 // ============================================================================ 12379 // inlined locking and unlocking 12380 12381 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12382 predicate(LockingMode != LM_LIGHTWEIGHT); 12383 match(Set cr (FastLock object box)); 12384 effect(TEMP tmp, TEMP scr, USE_KILL box); 12385 ins_cost(300); 12386 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12387 ins_encode %{ 12388 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12389 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12390 %} 12391 ins_pipe(pipe_slow); 12392 %} 12393 12394 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12395 predicate(LockingMode != LM_LIGHTWEIGHT); 12396 match(Set cr (FastUnlock object box)); 12397 effect(TEMP tmp, USE_KILL box); 12398 ins_cost(300); 12399 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12400 ins_encode %{ 12401 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12402 %} 12403 ins_pipe(pipe_slow); 12404 %} 12405 12406 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12407 predicate(LockingMode == LM_LIGHTWEIGHT); 12408 match(Set cr (FastLock object box)); 12409 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12410 ins_cost(300); 12411 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12412 ins_encode %{ 12413 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12414 %} 12415 ins_pipe(pipe_slow); 12416 %} 12417 12418 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12419 predicate(LockingMode == LM_LIGHTWEIGHT); 12420 match(Set cr (FastUnlock object rax_reg)); 12421 effect(TEMP tmp, USE_KILL rax_reg); 12422 ins_cost(300); 12423 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12424 ins_encode %{ 12425 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12426 %} 12427 ins_pipe(pipe_slow); 12428 %} 12429 12430 12431 // ============================================================================ 12432 // Safepoint Instructions 12433 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12434 %{ 12435 match(SafePoint poll); 12436 effect(KILL cr, USE poll); 12437 12438 format %{ "testl rax, [$poll]\t" 12439 "# Safepoint: poll for GC" %} 12440 ins_cost(125); 12441 ins_encode %{ 12442 __ relocate(relocInfo::poll_type); 12443 address pre_pc = __ pc(); 12444 __ testl(rax, Address($poll$$Register, 0)); 12445 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12446 %} 12447 ins_pipe(ialu_reg_mem); 12448 %} 12449 12450 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12451 match(Set dst (MaskAll src)); 12452 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12453 ins_encode %{ 12454 int mask_len = Matcher::vector_length(this); 12455 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12456 %} 12457 ins_pipe( pipe_slow ); 12458 %} 12459 12460 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12461 predicate(Matcher::vector_length(n) > 32); 12462 match(Set dst (MaskAll src)); 12463 effect(TEMP tmp); 12464 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12465 ins_encode %{ 12466 int mask_len = Matcher::vector_length(this); 12467 __ movslq($tmp$$Register, $src$$Register); 12468 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12469 %} 12470 ins_pipe( pipe_slow ); 12471 %} 12472 12473 // ============================================================================ 12474 // Procedure Call/Return Instructions 12475 // Call Java Static Instruction 12476 // Note: If this code changes, the corresponding ret_addr_offset() and 12477 // compute_padding() functions will have to be adjusted. 12478 instruct CallStaticJavaDirect(method meth) %{ 12479 match(CallStaticJava); 12480 effect(USE meth); 12481 12482 ins_cost(300); 12483 format %{ "call,static " %} 12484 opcode(0xE8); /* E8 cd */ 12485 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12486 ins_pipe(pipe_slow); 12487 ins_alignment(4); 12488 %} 12489 12490 // Call Java Dynamic Instruction 12491 // Note: If this code changes, the corresponding ret_addr_offset() and 12492 // compute_padding() functions will have to be adjusted. 12493 instruct CallDynamicJavaDirect(method meth) 12494 %{ 12495 match(CallDynamicJava); 12496 effect(USE meth); 12497 12498 ins_cost(300); 12499 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12500 "call,dynamic " %} 12501 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12502 ins_pipe(pipe_slow); 12503 ins_alignment(4); 12504 %} 12505 12506 // Call Runtime Instruction 12507 instruct CallRuntimeDirect(method meth) 12508 %{ 12509 match(CallRuntime); 12510 effect(USE meth); 12511 12512 ins_cost(300); 12513 format %{ "call,runtime " %} 12514 ins_encode(clear_avx, Java_To_Runtime(meth)); 12515 ins_pipe(pipe_slow); 12516 %} 12517 12518 // Call runtime without safepoint 12519 instruct CallLeafDirect(method meth) 12520 %{ 12521 match(CallLeaf); 12522 effect(USE meth); 12523 12524 ins_cost(300); 12525 format %{ "call_leaf,runtime " %} 12526 ins_encode(clear_avx, Java_To_Runtime(meth)); 12527 ins_pipe(pipe_slow); 12528 %} 12529 12530 // Call runtime without safepoint and with vector arguments 12531 instruct CallLeafDirectVector(method meth) 12532 %{ 12533 match(CallLeafVector); 12534 effect(USE meth); 12535 12536 ins_cost(300); 12537 format %{ "call_leaf,vector " %} 12538 ins_encode(Java_To_Runtime(meth)); 12539 ins_pipe(pipe_slow); 12540 %} 12541 12542 // Call runtime without safepoint 12543 instruct CallLeafNoFPDirect(method meth) 12544 %{ 12545 match(CallLeafNoFP); 12546 effect(USE meth); 12547 12548 ins_cost(300); 12549 format %{ "call_leaf_nofp,runtime " %} 12550 ins_encode(clear_avx, Java_To_Runtime(meth)); 12551 ins_pipe(pipe_slow); 12552 %} 12553 12554 // Return Instruction 12555 // Remove the return address & jump to it. 12556 // Notice: We always emit a nop after a ret to make sure there is room 12557 // for safepoint patching 12558 instruct Ret() 12559 %{ 12560 match(Return); 12561 12562 format %{ "ret" %} 12563 ins_encode %{ 12564 __ ret(0); 12565 %} 12566 ins_pipe(pipe_jmp); 12567 %} 12568 12569 // Tail Call; Jump from runtime stub to Java code. 12570 // Also known as an 'interprocedural jump'. 12571 // Target of jump will eventually return to caller. 12572 // TailJump below removes the return address. 12573 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12574 // emitted just above the TailCall which has reset rbp to the caller state. 12575 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12576 %{ 12577 match(TailCall jump_target method_ptr); 12578 12579 ins_cost(300); 12580 format %{ "jmp $jump_target\t# rbx holds method" %} 12581 ins_encode %{ 12582 __ jmp($jump_target$$Register); 12583 %} 12584 ins_pipe(pipe_jmp); 12585 %} 12586 12587 // Tail Jump; remove the return address; jump to target. 12588 // TailCall above leaves the return address around. 12589 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12590 %{ 12591 match(TailJump jump_target ex_oop); 12592 12593 ins_cost(300); 12594 format %{ "popq rdx\t# pop return address\n\t" 12595 "jmp $jump_target" %} 12596 ins_encode %{ 12597 __ popq(as_Register(RDX_enc)); 12598 __ jmp($jump_target$$Register); 12599 %} 12600 ins_pipe(pipe_jmp); 12601 %} 12602 12603 // Forward exception. 12604 instruct ForwardExceptionjmp() 12605 %{ 12606 match(ForwardException); 12607 12608 format %{ "jmp forward_exception_stub" %} 12609 ins_encode %{ 12610 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 12611 %} 12612 ins_pipe(pipe_jmp); 12613 %} 12614 12615 // Create exception oop: created by stack-crawling runtime code. 12616 // Created exception is now available to this handler, and is setup 12617 // just prior to jumping to this handler. No code emitted. 12618 instruct CreateException(rax_RegP ex_oop) 12619 %{ 12620 match(Set ex_oop (CreateEx)); 12621 12622 size(0); 12623 // use the following format syntax 12624 format %{ "# exception oop is in rax; no code emitted" %} 12625 ins_encode(); 12626 ins_pipe(empty); 12627 %} 12628 12629 // Rethrow exception: 12630 // The exception oop will come in the first argument position. 12631 // Then JUMP (not call) to the rethrow stub code. 12632 instruct RethrowException() 12633 %{ 12634 match(Rethrow); 12635 12636 // use the following format syntax 12637 format %{ "jmp rethrow_stub" %} 12638 ins_encode %{ 12639 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12640 %} 12641 ins_pipe(pipe_jmp); 12642 %} 12643 12644 // ============================================================================ 12645 // This name is KNOWN by the ADLC and cannot be changed. 12646 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12647 // for this guy. 12648 instruct tlsLoadP(r15_RegP dst) %{ 12649 match(Set dst (ThreadLocal)); 12650 effect(DEF dst); 12651 12652 size(0); 12653 format %{ "# TLS is in R15" %} 12654 ins_encode( /*empty encoding*/ ); 12655 ins_pipe(ialu_reg_reg); 12656 %} 12657 12658 12659 //----------PEEPHOLE RULES----------------------------------------------------- 12660 // These must follow all instruction definitions as they use the names 12661 // defined in the instructions definitions. 12662 // 12663 // peeppredicate ( rule_predicate ); 12664 // // the predicate unless which the peephole rule will be ignored 12665 // 12666 // peepmatch ( root_instr_name [preceding_instruction]* ); 12667 // 12668 // peepprocedure ( procedure_name ); 12669 // // provide a procedure name to perform the optimization, the procedure should 12670 // // reside in the architecture dependent peephole file, the method has the 12671 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12672 // // with the arguments being the basic block, the current node index inside the 12673 // // block, the register allocator, the functions upon invoked return a new node 12674 // // defined in peepreplace, and the rules of the nodes appearing in the 12675 // // corresponding peepmatch, the function return true if successful, else 12676 // // return false 12677 // 12678 // peepconstraint %{ 12679 // (instruction_number.operand_name relational_op instruction_number.operand_name 12680 // [, ...] ); 12681 // // instruction numbers are zero-based using left to right order in peepmatch 12682 // 12683 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12684 // // provide an instruction_number.operand_name for each operand that appears 12685 // // in the replacement instruction's match rule 12686 // 12687 // ---------VM FLAGS--------------------------------------------------------- 12688 // 12689 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12690 // 12691 // Each peephole rule is given an identifying number starting with zero and 12692 // increasing by one in the order seen by the parser. An individual peephole 12693 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12694 // on the command-line. 12695 // 12696 // ---------CURRENT LIMITATIONS---------------------------------------------- 12697 // 12698 // Only transformations inside a basic block (do we need more for peephole) 12699 // 12700 // ---------EXAMPLE---------------------------------------------------------- 12701 // 12702 // // pertinent parts of existing instructions in architecture description 12703 // instruct movI(rRegI dst, rRegI src) 12704 // %{ 12705 // match(Set dst (CopyI src)); 12706 // %} 12707 // 12708 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12709 // %{ 12710 // match(Set dst (AddI dst src)); 12711 // effect(KILL cr); 12712 // %} 12713 // 12714 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12715 // %{ 12716 // match(Set dst (AddI dst src)); 12717 // %} 12718 // 12719 // 1. Simple replacement 12720 // - Only match adjacent instructions in same basic block 12721 // - Only equality constraints 12722 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12723 // - Only one replacement instruction 12724 // 12725 // // Change (inc mov) to lea 12726 // peephole %{ 12727 // // lea should only be emitted when beneficial 12728 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12729 // // increment preceded by register-register move 12730 // peepmatch ( incI_rReg movI ); 12731 // // require that the destination register of the increment 12732 // // match the destination register of the move 12733 // peepconstraint ( 0.dst == 1.dst ); 12734 // // construct a replacement instruction that sets 12735 // // the destination to ( move's source register + one ) 12736 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12737 // %} 12738 // 12739 // 2. Procedural replacement 12740 // - More flexible finding relevent nodes 12741 // - More flexible constraints 12742 // - More flexible transformations 12743 // - May utilise architecture-dependent API more effectively 12744 // - Currently only one replacement instruction due to adlc parsing capabilities 12745 // 12746 // // Change (inc mov) to lea 12747 // peephole %{ 12748 // // lea should only be emitted when beneficial 12749 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12750 // // the rule numbers of these nodes inside are passed into the function below 12751 // peepmatch ( incI_rReg movI ); 12752 // // the method that takes the responsibility of transformation 12753 // peepprocedure ( inc_mov_to_lea ); 12754 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12755 // // node is passed into the function above 12756 // peepreplace ( leaI_rReg_immI() ); 12757 // %} 12758 12759 // These instructions is not matched by the matcher but used by the peephole 12760 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12761 %{ 12762 predicate(false); 12763 match(Set dst (AddI src1 src2)); 12764 format %{ "leal $dst, [$src1 + $src2]" %} 12765 ins_encode %{ 12766 Register dst = $dst$$Register; 12767 Register src1 = $src1$$Register; 12768 Register src2 = $src2$$Register; 12769 if (src1 != rbp && src1 != r13) { 12770 __ leal(dst, Address(src1, src2, Address::times_1)); 12771 } else { 12772 assert(src2 != rbp && src2 != r13, ""); 12773 __ leal(dst, Address(src2, src1, Address::times_1)); 12774 } 12775 %} 12776 ins_pipe(ialu_reg_reg); 12777 %} 12778 12779 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 12780 %{ 12781 predicate(false); 12782 match(Set dst (AddI src1 src2)); 12783 format %{ "leal $dst, [$src1 + $src2]" %} 12784 ins_encode %{ 12785 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 12786 %} 12787 ins_pipe(ialu_reg_reg); 12788 %} 12789 12790 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 12791 %{ 12792 predicate(false); 12793 match(Set dst (LShiftI src shift)); 12794 format %{ "leal $dst, [$src << $shift]" %} 12795 ins_encode %{ 12796 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12797 Register src = $src$$Register; 12798 if (scale == Address::times_2 && src != rbp && src != r13) { 12799 __ leal($dst$$Register, Address(src, src, Address::times_1)); 12800 } else { 12801 __ leal($dst$$Register, Address(noreg, src, scale)); 12802 } 12803 %} 12804 ins_pipe(ialu_reg_reg); 12805 %} 12806 12807 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 12808 %{ 12809 predicate(false); 12810 match(Set dst (AddL src1 src2)); 12811 format %{ "leaq $dst, [$src1 + $src2]" %} 12812 ins_encode %{ 12813 Register dst = $dst$$Register; 12814 Register src1 = $src1$$Register; 12815 Register src2 = $src2$$Register; 12816 if (src1 != rbp && src1 != r13) { 12817 __ leaq(dst, Address(src1, src2, Address::times_1)); 12818 } else { 12819 assert(src2 != rbp && src2 != r13, ""); 12820 __ leaq(dst, Address(src2, src1, Address::times_1)); 12821 } 12822 %} 12823 ins_pipe(ialu_reg_reg); 12824 %} 12825 12826 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 12827 %{ 12828 predicate(false); 12829 match(Set dst (AddL src1 src2)); 12830 format %{ "leaq $dst, [$src1 + $src2]" %} 12831 ins_encode %{ 12832 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 12833 %} 12834 ins_pipe(ialu_reg_reg); 12835 %} 12836 12837 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 12838 %{ 12839 predicate(false); 12840 match(Set dst (LShiftL src shift)); 12841 format %{ "leaq $dst, [$src << $shift]" %} 12842 ins_encode %{ 12843 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12844 Register src = $src$$Register; 12845 if (scale == Address::times_2 && src != rbp && src != r13) { 12846 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 12847 } else { 12848 __ leaq($dst$$Register, Address(noreg, src, scale)); 12849 } 12850 %} 12851 ins_pipe(ialu_reg_reg); 12852 %} 12853 12854 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 12855 // sal}) with lea instructions. The {add, sal} rules are beneficial in 12856 // processors with at least partial ALU support for lea 12857 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 12858 // beneficial for processors with full ALU support 12859 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 12860 12861 peephole 12862 %{ 12863 peeppredicate(VM_Version::supports_fast_2op_lea()); 12864 peepmatch (addI_rReg); 12865 peepprocedure (lea_coalesce_reg); 12866 peepreplace (leaI_rReg_rReg_peep()); 12867 %} 12868 12869 peephole 12870 %{ 12871 peeppredicate(VM_Version::supports_fast_2op_lea()); 12872 peepmatch (addI_rReg_imm); 12873 peepprocedure (lea_coalesce_imm); 12874 peepreplace (leaI_rReg_immI_peep()); 12875 %} 12876 12877 peephole 12878 %{ 12879 peeppredicate(VM_Version::supports_fast_3op_lea() || 12880 VM_Version::is_intel_cascade_lake()); 12881 peepmatch (incI_rReg); 12882 peepprocedure (lea_coalesce_imm); 12883 peepreplace (leaI_rReg_immI_peep()); 12884 %} 12885 12886 peephole 12887 %{ 12888 peeppredicate(VM_Version::supports_fast_3op_lea() || 12889 VM_Version::is_intel_cascade_lake()); 12890 peepmatch (decI_rReg); 12891 peepprocedure (lea_coalesce_imm); 12892 peepreplace (leaI_rReg_immI_peep()); 12893 %} 12894 12895 peephole 12896 %{ 12897 peeppredicate(VM_Version::supports_fast_2op_lea()); 12898 peepmatch (salI_rReg_immI2); 12899 peepprocedure (lea_coalesce_imm); 12900 peepreplace (leaI_rReg_immI2_peep()); 12901 %} 12902 12903 peephole 12904 %{ 12905 peeppredicate(VM_Version::supports_fast_2op_lea()); 12906 peepmatch (addL_rReg); 12907 peepprocedure (lea_coalesce_reg); 12908 peepreplace (leaL_rReg_rReg_peep()); 12909 %} 12910 12911 peephole 12912 %{ 12913 peeppredicate(VM_Version::supports_fast_2op_lea()); 12914 peepmatch (addL_rReg_imm); 12915 peepprocedure (lea_coalesce_imm); 12916 peepreplace (leaL_rReg_immL32_peep()); 12917 %} 12918 12919 peephole 12920 %{ 12921 peeppredicate(VM_Version::supports_fast_3op_lea() || 12922 VM_Version::is_intel_cascade_lake()); 12923 peepmatch (incL_rReg); 12924 peepprocedure (lea_coalesce_imm); 12925 peepreplace (leaL_rReg_immL32_peep()); 12926 %} 12927 12928 peephole 12929 %{ 12930 peeppredicate(VM_Version::supports_fast_3op_lea() || 12931 VM_Version::is_intel_cascade_lake()); 12932 peepmatch (decL_rReg); 12933 peepprocedure (lea_coalesce_imm); 12934 peepreplace (leaL_rReg_immL32_peep()); 12935 %} 12936 12937 peephole 12938 %{ 12939 peeppredicate(VM_Version::supports_fast_2op_lea()); 12940 peepmatch (salL_rReg_immI2); 12941 peepprocedure (lea_coalesce_imm); 12942 peepreplace (leaL_rReg_immI2_peep()); 12943 %} 12944 12945 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 12946 // 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 12947 12948 //int variant 12949 peephole 12950 %{ 12951 peepmatch (testI_reg); 12952 peepprocedure (test_may_remove); 12953 %} 12954 12955 //long variant 12956 peephole 12957 %{ 12958 peepmatch (testL_reg); 12959 peepprocedure (test_may_remove); 12960 %} 12961 12962 12963 //----------SMARTSPILL RULES--------------------------------------------------- 12964 // These must follow all instruction definitions as they use the names 12965 // defined in the instructions definitions.