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