1 // 2 // Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // architecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 reg_def R16 (SOC, SOC, Op_RegI, 16, r16->as_VMReg()); 132 reg_def R16_H(SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 133 134 reg_def R17 (SOC, SOC, Op_RegI, 17, r17->as_VMReg()); 135 reg_def R17_H(SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 136 137 reg_def R18 (SOC, SOC, Op_RegI, 18, r18->as_VMReg()); 138 reg_def R18_H(SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 139 140 reg_def R19 (SOC, SOC, Op_RegI, 19, r19->as_VMReg()); 141 reg_def R19_H(SOC, SOC, Op_RegI, 19, r19->as_VMReg()->next()); 142 143 reg_def R20 (SOC, SOC, Op_RegI, 20, r20->as_VMReg()); 144 reg_def R20_H(SOC, SOC, Op_RegI, 20, r20->as_VMReg()->next()); 145 146 reg_def R21 (SOC, SOC, Op_RegI, 21, r21->as_VMReg()); 147 reg_def R21_H(SOC, SOC, Op_RegI, 21, r21->as_VMReg()->next()); 148 149 reg_def R22 (SOC, SOC, Op_RegI, 22, r22->as_VMReg()); 150 reg_def R22_H(SOC, SOC, Op_RegI, 22, r22->as_VMReg()->next()); 151 152 reg_def R23 (SOC, SOC, Op_RegI, 23, r23->as_VMReg()); 153 reg_def R23_H(SOC, SOC, Op_RegI, 23, r23->as_VMReg()->next()); 154 155 reg_def R24 (SOC, SOC, Op_RegI, 24, r24->as_VMReg()); 156 reg_def R24_H(SOC, SOC, Op_RegI, 24, r24->as_VMReg()->next()); 157 158 reg_def R25 (SOC, SOC, Op_RegI, 25, r25->as_VMReg()); 159 reg_def R25_H(SOC, SOC, Op_RegI, 25, r25->as_VMReg()->next()); 160 161 reg_def R26 (SOC, SOC, Op_RegI, 26, r26->as_VMReg()); 162 reg_def R26_H(SOC, SOC, Op_RegI, 26, r26->as_VMReg()->next()); 163 164 reg_def R27 (SOC, SOC, Op_RegI, 27, r27->as_VMReg()); 165 reg_def R27_H(SOC, SOC, Op_RegI, 27, r27->as_VMReg()->next()); 166 167 reg_def R28 (SOC, SOC, Op_RegI, 28, r28->as_VMReg()); 168 reg_def R28_H(SOC, SOC, Op_RegI, 28, r28->as_VMReg()->next()); 169 170 reg_def R29 (SOC, SOC, Op_RegI, 29, r29->as_VMReg()); 171 reg_def R29_H(SOC, SOC, Op_RegI, 29, r29->as_VMReg()->next()); 172 173 reg_def R30 (SOC, SOC, Op_RegI, 30, r30->as_VMReg()); 174 reg_def R30_H(SOC, SOC, Op_RegI, 30, r30->as_VMReg()->next()); 175 176 reg_def R31 (SOC, SOC, Op_RegI, 31, r31->as_VMReg()); 177 reg_def R31_H(SOC, SOC, Op_RegI, 31, r31->as_VMReg()->next()); 178 179 // Floating Point Registers 180 181 // Specify priority of register selection within phases of register 182 // allocation. Highest priority is first. A useful heuristic is to 183 // give registers a low priority when they are required by machine 184 // instructions, like EAX and EDX on I486, and choose no-save registers 185 // before save-on-call, & save-on-call before save-on-entry. Registers 186 // which participate in fixed calling sequences should come last. 187 // Registers which are used as pairs must fall on an even boundary. 188 189 alloc_class chunk0(R10, R10_H, 190 R11, R11_H, 191 R8, R8_H, 192 R9, R9_H, 193 R12, R12_H, 194 RCX, RCX_H, 195 RBX, RBX_H, 196 RDI, RDI_H, 197 RDX, RDX_H, 198 RSI, RSI_H, 199 RAX, RAX_H, 200 RBP, RBP_H, 201 R13, R13_H, 202 R14, R14_H, 203 R15, R15_H, 204 R16, R16_H, 205 R17, R17_H, 206 R18, R18_H, 207 R19, R19_H, 208 R20, R20_H, 209 R21, R21_H, 210 R22, R22_H, 211 R23, R23_H, 212 R24, R24_H, 213 R25, R25_H, 214 R26, R26_H, 215 R27, R27_H, 216 R28, R28_H, 217 R29, R29_H, 218 R30, R30_H, 219 R31, R31_H, 220 RSP, RSP_H); 221 222 223 //----------Architecture Description Register Classes-------------------------- 224 // Several register classes are automatically defined based upon information in 225 // this architecture description. 226 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 227 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 228 // 229 230 // Empty register class. 231 reg_class no_reg(); 232 233 // Class for all pointer/long registers including APX extended GPRs. 234 reg_class all_reg(RAX, RAX_H, 235 RDX, RDX_H, 236 RBP, RBP_H, 237 RDI, RDI_H, 238 RSI, RSI_H, 239 RCX, RCX_H, 240 RBX, RBX_H, 241 RSP, RSP_H, 242 R8, R8_H, 243 R9, R9_H, 244 R10, R10_H, 245 R11, R11_H, 246 R12, R12_H, 247 R13, R13_H, 248 R14, R14_H, 249 R15, R15_H, 250 R16, R16_H, 251 R17, R17_H, 252 R18, R18_H, 253 R19, R19_H, 254 R20, R20_H, 255 R21, R21_H, 256 R22, R22_H, 257 R23, R23_H, 258 R24, R24_H, 259 R25, R25_H, 260 R26, R26_H, 261 R27, R27_H, 262 R28, R28_H, 263 R29, R29_H, 264 R30, R30_H, 265 R31, R31_H); 266 267 // Class for all int registers including APX extended GPRs. 268 reg_class all_int_reg(RAX 269 RDX, 270 RBP, 271 RDI, 272 RSI, 273 RCX, 274 RBX, 275 R8, 276 R9, 277 R10, 278 R11, 279 R12, 280 R13, 281 R14, 282 R16, 283 R17, 284 R18, 285 R19, 286 R20, 287 R21, 288 R22, 289 R23, 290 R24, 291 R25, 292 R26, 293 R27, 294 R28, 295 R29, 296 R30, 297 R31); 298 299 // Class for all pointer registers 300 reg_class any_reg %{ 301 return _ANY_REG_mask; 302 %} 303 304 // Class for all pointer registers (excluding RSP) 305 reg_class ptr_reg %{ 306 return _PTR_REG_mask; 307 %} 308 309 // Class for all pointer registers (excluding RSP and RBP) 310 reg_class ptr_reg_no_rbp %{ 311 return _PTR_REG_NO_RBP_mask; 312 %} 313 314 // Class for all pointer registers (excluding RAX and RSP) 315 reg_class ptr_no_rax_reg %{ 316 return _PTR_NO_RAX_REG_mask; 317 %} 318 319 // Class for all pointer registers (excluding RAX, RBX, and RSP) 320 reg_class ptr_no_rax_rbx_reg %{ 321 return _PTR_NO_RAX_RBX_REG_mask; 322 %} 323 324 // Class for all long registers (excluding RSP) 325 reg_class long_reg %{ 326 return _LONG_REG_mask; 327 %} 328 329 // Class for all long registers (excluding RAX, RDX and RSP) 330 reg_class long_no_rax_rdx_reg %{ 331 return _LONG_NO_RAX_RDX_REG_mask; 332 %} 333 334 // Class for all long registers (excluding RCX and RSP) 335 reg_class long_no_rcx_reg %{ 336 return _LONG_NO_RCX_REG_mask; 337 %} 338 339 // Class for all long registers (excluding RBP and R13) 340 reg_class long_no_rbp_r13_reg %{ 341 return _LONG_NO_RBP_R13_REG_mask; 342 %} 343 344 // Class for all int registers (excluding RSP) 345 reg_class int_reg %{ 346 return _INT_REG_mask; 347 %} 348 349 // Class for all int registers (excluding RAX, RDX, and RSP) 350 reg_class int_no_rax_rdx_reg %{ 351 return _INT_NO_RAX_RDX_REG_mask; 352 %} 353 354 // Class for all int registers (excluding RCX and RSP) 355 reg_class int_no_rcx_reg %{ 356 return _INT_NO_RCX_REG_mask; 357 %} 358 359 // Class for all int registers (excluding RBP and R13) 360 reg_class int_no_rbp_r13_reg %{ 361 return _INT_NO_RBP_R13_REG_mask; 362 %} 363 364 // Singleton class for RAX pointer register 365 reg_class ptr_rax_reg(RAX, RAX_H); 366 367 // Singleton class for RBX pointer register 368 reg_class ptr_rbx_reg(RBX, RBX_H); 369 370 // Singleton class for RSI pointer register 371 reg_class ptr_rsi_reg(RSI, RSI_H); 372 373 // Singleton class for RBP pointer register 374 reg_class ptr_rbp_reg(RBP, RBP_H); 375 376 // Singleton class for RDI pointer register 377 reg_class ptr_rdi_reg(RDI, RDI_H); 378 379 // Singleton class for stack pointer 380 reg_class ptr_rsp_reg(RSP, RSP_H); 381 382 // Singleton class for TLS pointer 383 reg_class ptr_r15_reg(R15, R15_H); 384 385 // Singleton class for RAX long register 386 reg_class long_rax_reg(RAX, RAX_H); 387 388 // Singleton class for RCX long register 389 reg_class long_rcx_reg(RCX, RCX_H); 390 391 // Singleton class for RDX long register 392 reg_class long_rdx_reg(RDX, RDX_H); 393 394 // Singleton class for R11 long register 395 reg_class long_r11_reg(R11, R11_H); 396 397 // Singleton class for RAX int register 398 reg_class int_rax_reg(RAX); 399 400 // Singleton class for RBX int register 401 reg_class int_rbx_reg(RBX); 402 403 // Singleton class for RCX int register 404 reg_class int_rcx_reg(RCX); 405 406 // Singleton class for RDX int register 407 reg_class int_rdx_reg(RDX); 408 409 // Singleton class for RDI int register 410 reg_class int_rdi_reg(RDI); 411 412 // Singleton class for instruction pointer 413 // reg_class ip_reg(RIP); 414 415 %} 416 417 //----------SOURCE BLOCK------------------------------------------------------- 418 // This is a block of C++ code which provides values, functions, and 419 // definitions necessary in the rest of the architecture description 420 421 source_hpp %{ 422 423 #include "peephole_x86_64.hpp" 424 425 %} 426 427 // Register masks 428 source_hpp %{ 429 430 extern RegMask _ANY_REG_mask; 431 extern RegMask _PTR_REG_mask; 432 extern RegMask _PTR_REG_NO_RBP_mask; 433 extern RegMask _PTR_NO_RAX_REG_mask; 434 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 435 extern RegMask _LONG_REG_mask; 436 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 437 extern RegMask _LONG_NO_RCX_REG_mask; 438 extern RegMask _LONG_NO_RBP_R13_REG_mask; 439 extern RegMask _INT_REG_mask; 440 extern RegMask _INT_NO_RAX_RDX_REG_mask; 441 extern RegMask _INT_NO_RCX_REG_mask; 442 extern RegMask _INT_NO_RBP_R13_REG_mask; 443 extern RegMask _FLOAT_REG_mask; 444 445 extern RegMask _STACK_OR_PTR_REG_mask; 446 extern RegMask _STACK_OR_LONG_REG_mask; 447 extern RegMask _STACK_OR_INT_REG_mask; 448 449 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 450 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 451 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 452 453 %} 454 455 source %{ 456 #define RELOC_IMM64 Assembler::imm_operand 457 #define RELOC_DISP32 Assembler::disp32_operand 458 459 #define __ masm-> 460 461 RegMask _ANY_REG_mask; 462 RegMask _PTR_REG_mask; 463 RegMask _PTR_REG_NO_RBP_mask; 464 RegMask _PTR_NO_RAX_REG_mask; 465 RegMask _PTR_NO_RAX_RBX_REG_mask; 466 RegMask _LONG_REG_mask; 467 RegMask _LONG_NO_RAX_RDX_REG_mask; 468 RegMask _LONG_NO_RCX_REG_mask; 469 RegMask _LONG_NO_RBP_R13_REG_mask; 470 RegMask _INT_REG_mask; 471 RegMask _INT_NO_RAX_RDX_REG_mask; 472 RegMask _INT_NO_RCX_REG_mask; 473 RegMask _INT_NO_RBP_R13_REG_mask; 474 RegMask _FLOAT_REG_mask; 475 RegMask _STACK_OR_PTR_REG_mask; 476 RegMask _STACK_OR_LONG_REG_mask; 477 RegMask _STACK_OR_INT_REG_mask; 478 479 static bool need_r12_heapbase() { 480 return UseCompressedOops; 481 } 482 483 void reg_mask_init() { 484 constexpr Register egprs[] = {r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31}; 485 486 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 487 // We derive a number of subsets from it. 488 _ANY_REG_mask = _ALL_REG_mask; 489 490 if (PreserveFramePointer) { 491 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 492 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 493 } 494 if (need_r12_heapbase()) { 495 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 496 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 497 } 498 499 _PTR_REG_mask = _ANY_REG_mask; 500 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 501 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 502 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 503 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 504 if (!UseAPX) { 505 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 506 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 507 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg()->next())); 508 } 509 } 510 511 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 512 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 513 514 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 515 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 516 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 517 518 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 519 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 520 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 521 522 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 523 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 524 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 525 526 527 _LONG_REG_mask = _PTR_REG_mask; 528 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 529 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 530 531 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 532 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 533 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 534 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 535 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 536 537 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 538 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 539 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 540 541 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 542 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 543 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 544 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 545 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 546 547 _INT_REG_mask = _ALL_INT_REG_mask; 548 if (!UseAPX) { 549 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 550 _INT_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 551 } 552 } 553 554 if (PreserveFramePointer) { 555 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 556 } 557 if (need_r12_heapbase()) { 558 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 559 } 560 561 _STACK_OR_INT_REG_mask = _INT_REG_mask; 562 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 563 564 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 565 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 566 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 567 568 _INT_NO_RCX_REG_mask = _INT_REG_mask; 569 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 570 571 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 572 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 573 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 574 575 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 576 // from the float_reg_legacy/float_reg_evex register class. 577 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 578 } 579 580 static bool generate_vzeroupper(Compile* C) { 581 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 582 } 583 584 static int clear_avx_size() { 585 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 586 } 587 588 // !!!!! Special hack to get all types of calls to specify the byte offset 589 // from the start of the call to the point where the return address 590 // will point. 591 int MachCallStaticJavaNode::ret_addr_offset() 592 { 593 int offset = 5; // 5 bytes from start of call to where return address points 594 offset += clear_avx_size(); 595 return offset; 596 } 597 598 int MachCallDynamicJavaNode::ret_addr_offset() 599 { 600 int offset = 15; // 15 bytes from start of call to where return address points 601 offset += clear_avx_size(); 602 return offset; 603 } 604 605 int MachCallRuntimeNode::ret_addr_offset() { 606 int offset = 13; // movq r10,#addr; callq (r10) 607 if (this->ideal_Opcode() != Op_CallLeafVector) { 608 offset += clear_avx_size(); 609 } 610 return offset; 611 } 612 // 613 // Compute padding required for nodes which need alignment 614 // 615 616 // The address of the call instruction needs to be 4-byte aligned to 617 // ensure that it does not span a cache line so that it can be patched. 618 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 619 { 620 current_offset += clear_avx_size(); // skip vzeroupper 621 current_offset += 1; // skip call opcode byte 622 return align_up(current_offset, alignment_required()) - current_offset; 623 } 624 625 // The address of the call instruction needs to be 4-byte aligned to 626 // ensure that it does not span a cache line so that it can be patched. 627 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 628 { 629 current_offset += clear_avx_size(); // skip vzeroupper 630 current_offset += 11; // skip movq instruction + call opcode byte 631 return align_up(current_offset, alignment_required()) - current_offset; 632 } 633 634 // This could be in MacroAssembler but it's fairly C2 specific 635 static void emit_cmpfp_fixup(MacroAssembler* masm) { 636 Label exit; 637 __ jccb(Assembler::noParity, exit); 638 __ pushf(); 639 // 640 // comiss/ucomiss instructions set ZF,PF,CF flags and 641 // zero OF,AF,SF for NaN values. 642 // Fixup flags by zeroing ZF,PF so that compare of NaN 643 // values returns 'less than' result (CF is set). 644 // Leave the rest of flags unchanged. 645 // 646 // 7 6 5 4 3 2 1 0 647 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 648 // 0 0 1 0 1 0 1 1 (0x2B) 649 // 650 __ andq(Address(rsp, 0), 0xffffff2b); 651 __ popf(); 652 __ bind(exit); 653 } 654 655 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 656 Label done; 657 __ movl(dst, -1); 658 __ jcc(Assembler::parity, done); 659 __ jcc(Assembler::below, done); 660 __ setcc(Assembler::notEqual, dst); 661 __ bind(done); 662 } 663 664 // Math.min() # Math.max() 665 // -------------------------- 666 // ucomis[s/d] # 667 // ja -> b # a 668 // jp -> NaN # NaN 669 // jb -> a # b 670 // je # 671 // |-jz -> a | b # a & b 672 // | -> a # 673 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 674 XMMRegister a, XMMRegister b, 675 XMMRegister xmmt, Register rt, 676 bool min, bool single) { 677 678 Label nan, zero, below, above, done; 679 680 if (single) 681 __ ucomiss(a, b); 682 else 683 __ ucomisd(a, b); 684 685 if (dst->encoding() != (min ? b : a)->encoding()) 686 __ jccb(Assembler::above, above); // CF=0 & ZF=0 687 else 688 __ jccb(Assembler::above, done); 689 690 __ jccb(Assembler::parity, nan); // PF=1 691 __ jccb(Assembler::below, below); // CF=1 692 693 // equal 694 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 695 if (single) { 696 __ ucomiss(a, xmmt); 697 __ jccb(Assembler::equal, zero); 698 699 __ movflt(dst, a); 700 __ jmp(done); 701 } 702 else { 703 __ ucomisd(a, xmmt); 704 __ jccb(Assembler::equal, zero); 705 706 __ movdbl(dst, a); 707 __ jmp(done); 708 } 709 710 __ bind(zero); 711 if (min) 712 __ vpor(dst, a, b, Assembler::AVX_128bit); 713 else 714 __ vpand(dst, a, b, Assembler::AVX_128bit); 715 716 __ jmp(done); 717 718 __ bind(above); 719 if (single) 720 __ movflt(dst, min ? b : a); 721 else 722 __ movdbl(dst, min ? b : a); 723 724 __ jmp(done); 725 726 __ bind(nan); 727 if (single) { 728 __ movl(rt, 0x7fc00000); // Float.NaN 729 __ movdl(dst, rt); 730 } 731 else { 732 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 733 __ movdq(dst, rt); 734 } 735 __ jmp(done); 736 737 __ bind(below); 738 if (single) 739 __ movflt(dst, min ? a : b); 740 else 741 __ movdbl(dst, min ? a : b); 742 743 __ bind(done); 744 } 745 746 //============================================================================= 747 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 748 749 int ConstantTable::calculate_table_base_offset() const { 750 return 0; // absolute addressing, no offset 751 } 752 753 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 754 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 755 ShouldNotReachHere(); 756 } 757 758 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 759 // Empty encoding 760 } 761 762 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 763 return 0; 764 } 765 766 #ifndef PRODUCT 767 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 768 st->print("# MachConstantBaseNode (empty encoding)"); 769 } 770 #endif 771 772 773 //============================================================================= 774 #ifndef PRODUCT 775 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 776 Compile* C = ra_->C; 777 778 int framesize = C->output()->frame_size_in_bytes(); 779 int bangsize = C->output()->bang_size_in_bytes(); 780 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 781 // Remove wordSize for return addr which is already pushed. 782 framesize -= wordSize; 783 784 if (C->output()->need_stack_bang(bangsize)) { 785 framesize -= wordSize; 786 st->print("# stack bang (%d bytes)", bangsize); 787 st->print("\n\t"); 788 st->print("pushq rbp\t# Save rbp"); 789 if (PreserveFramePointer) { 790 st->print("\n\t"); 791 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 792 } 793 if (framesize) { 794 st->print("\n\t"); 795 st->print("subq rsp, #%d\t# Create frame",framesize); 796 } 797 } else { 798 st->print("subq rsp, #%d\t# Create frame",framesize); 799 st->print("\n\t"); 800 framesize -= wordSize; 801 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 802 if (PreserveFramePointer) { 803 st->print("\n\t"); 804 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 805 if (framesize > 0) { 806 st->print("\n\t"); 807 st->print("addq rbp, #%d", framesize); 808 } 809 } 810 } 811 812 if (VerifyStackAtCalls) { 813 st->print("\n\t"); 814 framesize -= wordSize; 815 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 816 #ifdef ASSERT 817 st->print("\n\t"); 818 st->print("# stack alignment check"); 819 #endif 820 } 821 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 822 st->print("\n\t"); 823 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 824 st->print("\n\t"); 825 st->print("je fast_entry\t"); 826 st->print("\n\t"); 827 st->print("call #nmethod_entry_barrier_stub\t"); 828 st->print("\n\tfast_entry:"); 829 } 830 st->cr(); 831 } 832 #endif 833 834 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 835 Compile* C = ra_->C; 836 837 int framesize = C->output()->frame_size_in_bytes(); 838 int bangsize = C->output()->bang_size_in_bytes(); 839 840 if (C->clinit_barrier_on_entry()) { 841 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 842 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 843 844 Label L_skip_barrier; 845 Register klass = rscratch1; 846 847 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 848 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 849 850 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 851 852 __ bind(L_skip_barrier); 853 } 854 855 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 856 857 C->output()->set_frame_complete(__ offset()); 858 859 if (C->has_mach_constant_base_node()) { 860 // NOTE: We set the table base offset here because users might be 861 // emitted before MachConstantBaseNode. 862 ConstantTable& constant_table = C->output()->constant_table(); 863 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 864 } 865 } 866 867 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 868 { 869 return MachNode::size(ra_); // too many variables; just compute it 870 // the hard way 871 } 872 873 int MachPrologNode::reloc() const 874 { 875 return 0; // a large enough number 876 } 877 878 //============================================================================= 879 #ifndef PRODUCT 880 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 881 { 882 Compile* C = ra_->C; 883 if (generate_vzeroupper(C)) { 884 st->print("vzeroupper"); 885 st->cr(); st->print("\t"); 886 } 887 888 int framesize = C->output()->frame_size_in_bytes(); 889 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 890 // Remove word for return adr already pushed 891 // and RBP 892 framesize -= 2*wordSize; 893 894 if (framesize) { 895 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 896 st->print("\t"); 897 } 898 899 st->print_cr("popq rbp"); 900 if (do_polling() && C->is_method_compilation()) { 901 st->print("\t"); 902 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 903 "ja #safepoint_stub\t" 904 "# Safepoint: poll for GC"); 905 } 906 } 907 #endif 908 909 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 910 { 911 Compile* C = ra_->C; 912 913 if (generate_vzeroupper(C)) { 914 // Clear upper bits of YMM registers when current compiled code uses 915 // wide vectors to avoid AVX <-> SSE transition penalty during call. 916 __ vzeroupper(); 917 } 918 919 int framesize = C->output()->frame_size_in_bytes(); 920 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 921 // Remove word for return adr already pushed 922 // and RBP 923 framesize -= 2*wordSize; 924 925 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 926 927 if (framesize) { 928 __ addq(rsp, framesize); 929 } 930 931 __ popq(rbp); 932 933 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 934 __ reserved_stack_check(); 935 } 936 937 if (do_polling() && C->is_method_compilation()) { 938 Label dummy_label; 939 Label* code_stub = &dummy_label; 940 if (!C->output()->in_scratch_emit_size()) { 941 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 942 C->output()->add_stub(stub); 943 code_stub = &stub->entry(); 944 } 945 __ relocate(relocInfo::poll_return_type); 946 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 947 } 948 } 949 950 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 951 { 952 return MachNode::size(ra_); // too many variables; just compute it 953 // the hard way 954 } 955 956 int MachEpilogNode::reloc() const 957 { 958 return 2; // a large enough number 959 } 960 961 const Pipeline* MachEpilogNode::pipeline() const 962 { 963 return MachNode::pipeline_class(); 964 } 965 966 //============================================================================= 967 968 enum RC { 969 rc_bad, 970 rc_int, 971 rc_kreg, 972 rc_float, 973 rc_stack 974 }; 975 976 static enum RC rc_class(OptoReg::Name reg) 977 { 978 if( !OptoReg::is_valid(reg) ) return rc_bad; 979 980 if (OptoReg::is_stack(reg)) return rc_stack; 981 982 VMReg r = OptoReg::as_VMReg(reg); 983 984 if (r->is_Register()) return rc_int; 985 986 if (r->is_KRegister()) return rc_kreg; 987 988 assert(r->is_XMMRegister(), "must be"); 989 return rc_float; 990 } 991 992 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 993 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 994 int src_hi, int dst_hi, uint ireg, outputStream* st); 995 996 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 997 int stack_offset, int reg, uint ireg, outputStream* st); 998 999 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 1000 int dst_offset, uint ireg, outputStream* st) { 1001 if (masm) { 1002 switch (ireg) { 1003 case Op_VecS: 1004 __ movq(Address(rsp, -8), rax); 1005 __ movl(rax, Address(rsp, src_offset)); 1006 __ movl(Address(rsp, dst_offset), rax); 1007 __ movq(rax, Address(rsp, -8)); 1008 break; 1009 case Op_VecD: 1010 __ pushq(Address(rsp, src_offset)); 1011 __ popq (Address(rsp, dst_offset)); 1012 break; 1013 case Op_VecX: 1014 __ pushq(Address(rsp, src_offset)); 1015 __ popq (Address(rsp, dst_offset)); 1016 __ pushq(Address(rsp, src_offset+8)); 1017 __ popq (Address(rsp, dst_offset+8)); 1018 break; 1019 case Op_VecY: 1020 __ vmovdqu(Address(rsp, -32), xmm0); 1021 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1022 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1023 __ vmovdqu(xmm0, Address(rsp, -32)); 1024 break; 1025 case Op_VecZ: 1026 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1027 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1028 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1029 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1030 break; 1031 default: 1032 ShouldNotReachHere(); 1033 } 1034 #ifndef PRODUCT 1035 } else { 1036 switch (ireg) { 1037 case Op_VecS: 1038 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1039 "movl rax, [rsp + #%d]\n\t" 1040 "movl [rsp + #%d], rax\n\t" 1041 "movq rax, [rsp - #8]", 1042 src_offset, dst_offset); 1043 break; 1044 case Op_VecD: 1045 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1046 "popq [rsp + #%d]", 1047 src_offset, dst_offset); 1048 break; 1049 case Op_VecX: 1050 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1051 "popq [rsp + #%d]\n\t" 1052 "pushq [rsp + #%d]\n\t" 1053 "popq [rsp + #%d]", 1054 src_offset, dst_offset, src_offset+8, dst_offset+8); 1055 break; 1056 case Op_VecY: 1057 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1058 "vmovdqu xmm0, [rsp + #%d]\n\t" 1059 "vmovdqu [rsp + #%d], xmm0\n\t" 1060 "vmovdqu xmm0, [rsp - #32]", 1061 src_offset, dst_offset); 1062 break; 1063 case Op_VecZ: 1064 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1065 "vmovdqu xmm0, [rsp + #%d]\n\t" 1066 "vmovdqu [rsp + #%d], xmm0\n\t" 1067 "vmovdqu xmm0, [rsp - #64]", 1068 src_offset, dst_offset); 1069 break; 1070 default: 1071 ShouldNotReachHere(); 1072 } 1073 #endif 1074 } 1075 } 1076 1077 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1078 PhaseRegAlloc* ra_, 1079 bool do_size, 1080 outputStream* st) const { 1081 assert(masm != nullptr || st != nullptr, "sanity"); 1082 // Get registers to move 1083 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1084 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1085 OptoReg::Name dst_second = ra_->get_reg_second(this); 1086 OptoReg::Name dst_first = ra_->get_reg_first(this); 1087 1088 enum RC src_second_rc = rc_class(src_second); 1089 enum RC src_first_rc = rc_class(src_first); 1090 enum RC dst_second_rc = rc_class(dst_second); 1091 enum RC dst_first_rc = rc_class(dst_first); 1092 1093 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1094 "must move at least 1 register" ); 1095 1096 if (src_first == dst_first && src_second == dst_second) { 1097 // Self copy, no move 1098 return 0; 1099 } 1100 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1101 uint ireg = ideal_reg(); 1102 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1103 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1104 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1105 // mem -> mem 1106 int src_offset = ra_->reg2offset(src_first); 1107 int dst_offset = ra_->reg2offset(dst_first); 1108 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1109 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1110 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1111 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1112 int stack_offset = ra_->reg2offset(dst_first); 1113 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1114 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1115 int stack_offset = ra_->reg2offset(src_first); 1116 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1117 } else { 1118 ShouldNotReachHere(); 1119 } 1120 return 0; 1121 } 1122 if (src_first_rc == rc_stack) { 1123 // mem -> 1124 if (dst_first_rc == rc_stack) { 1125 // mem -> mem 1126 assert(src_second != dst_first, "overlap"); 1127 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1128 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1129 // 64-bit 1130 int src_offset = ra_->reg2offset(src_first); 1131 int dst_offset = ra_->reg2offset(dst_first); 1132 if (masm) { 1133 __ pushq(Address(rsp, src_offset)); 1134 __ popq (Address(rsp, dst_offset)); 1135 #ifndef PRODUCT 1136 } else { 1137 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1138 "popq [rsp + #%d]", 1139 src_offset, dst_offset); 1140 #endif 1141 } 1142 } else { 1143 // 32-bit 1144 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1145 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1146 // No pushl/popl, so: 1147 int src_offset = ra_->reg2offset(src_first); 1148 int dst_offset = ra_->reg2offset(dst_first); 1149 if (masm) { 1150 __ movq(Address(rsp, -8), rax); 1151 __ movl(rax, Address(rsp, src_offset)); 1152 __ movl(Address(rsp, dst_offset), rax); 1153 __ movq(rax, Address(rsp, -8)); 1154 #ifndef PRODUCT 1155 } else { 1156 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1157 "movl rax, [rsp + #%d]\n\t" 1158 "movl [rsp + #%d], rax\n\t" 1159 "movq rax, [rsp - #8]", 1160 src_offset, dst_offset); 1161 #endif 1162 } 1163 } 1164 return 0; 1165 } else if (dst_first_rc == rc_int) { 1166 // mem -> gpr 1167 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1168 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1169 // 64-bit 1170 int offset = ra_->reg2offset(src_first); 1171 if (masm) { 1172 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1173 #ifndef PRODUCT 1174 } else { 1175 st->print("movq %s, [rsp + #%d]\t# spill", 1176 Matcher::regName[dst_first], 1177 offset); 1178 #endif 1179 } 1180 } else { 1181 // 32-bit 1182 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1183 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1184 int offset = ra_->reg2offset(src_first); 1185 if (masm) { 1186 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1187 #ifndef PRODUCT 1188 } else { 1189 st->print("movl %s, [rsp + #%d]\t# spill", 1190 Matcher::regName[dst_first], 1191 offset); 1192 #endif 1193 } 1194 } 1195 return 0; 1196 } else if (dst_first_rc == rc_float) { 1197 // mem-> xmm 1198 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1199 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1200 // 64-bit 1201 int offset = ra_->reg2offset(src_first); 1202 if (masm) { 1203 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1204 #ifndef PRODUCT 1205 } else { 1206 st->print("%s %s, [rsp + #%d]\t# spill", 1207 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1208 Matcher::regName[dst_first], 1209 offset); 1210 #endif 1211 } 1212 } else { 1213 // 32-bit 1214 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1215 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1216 int offset = ra_->reg2offset(src_first); 1217 if (masm) { 1218 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1219 #ifndef PRODUCT 1220 } else { 1221 st->print("movss %s, [rsp + #%d]\t# spill", 1222 Matcher::regName[dst_first], 1223 offset); 1224 #endif 1225 } 1226 } 1227 return 0; 1228 } else if (dst_first_rc == rc_kreg) { 1229 // mem -> kreg 1230 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1231 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1232 // 64-bit 1233 int offset = ra_->reg2offset(src_first); 1234 if (masm) { 1235 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1236 #ifndef PRODUCT 1237 } else { 1238 st->print("kmovq %s, [rsp + #%d]\t# spill", 1239 Matcher::regName[dst_first], 1240 offset); 1241 #endif 1242 } 1243 } 1244 return 0; 1245 } 1246 } else if (src_first_rc == rc_int) { 1247 // gpr -> 1248 if (dst_first_rc == rc_stack) { 1249 // gpr -> mem 1250 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1251 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1252 // 64-bit 1253 int offset = ra_->reg2offset(dst_first); 1254 if (masm) { 1255 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1256 #ifndef PRODUCT 1257 } else { 1258 st->print("movq [rsp + #%d], %s\t# spill", 1259 offset, 1260 Matcher::regName[src_first]); 1261 #endif 1262 } 1263 } else { 1264 // 32-bit 1265 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1266 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1267 int offset = ra_->reg2offset(dst_first); 1268 if (masm) { 1269 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1270 #ifndef PRODUCT 1271 } else { 1272 st->print("movl [rsp + #%d], %s\t# spill", 1273 offset, 1274 Matcher::regName[src_first]); 1275 #endif 1276 } 1277 } 1278 return 0; 1279 } else if (dst_first_rc == rc_int) { 1280 // gpr -> gpr 1281 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1282 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1283 // 64-bit 1284 if (masm) { 1285 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1286 as_Register(Matcher::_regEncode[src_first])); 1287 #ifndef PRODUCT 1288 } else { 1289 st->print("movq %s, %s\t# spill", 1290 Matcher::regName[dst_first], 1291 Matcher::regName[src_first]); 1292 #endif 1293 } 1294 return 0; 1295 } else { 1296 // 32-bit 1297 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1298 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1299 if (masm) { 1300 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1301 as_Register(Matcher::_regEncode[src_first])); 1302 #ifndef PRODUCT 1303 } else { 1304 st->print("movl %s, %s\t# spill", 1305 Matcher::regName[dst_first], 1306 Matcher::regName[src_first]); 1307 #endif 1308 } 1309 return 0; 1310 } 1311 } else if (dst_first_rc == rc_float) { 1312 // gpr -> xmm 1313 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1314 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1315 // 64-bit 1316 if (masm) { 1317 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1318 #ifndef PRODUCT 1319 } else { 1320 st->print("movdq %s, %s\t# spill", 1321 Matcher::regName[dst_first], 1322 Matcher::regName[src_first]); 1323 #endif 1324 } 1325 } else { 1326 // 32-bit 1327 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1328 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1329 if (masm) { 1330 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1331 #ifndef PRODUCT 1332 } else { 1333 st->print("movdl %s, %s\t# spill", 1334 Matcher::regName[dst_first], 1335 Matcher::regName[src_first]); 1336 #endif 1337 } 1338 } 1339 return 0; 1340 } else if (dst_first_rc == rc_kreg) { 1341 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1342 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1343 // 64-bit 1344 if (masm) { 1345 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1346 #ifndef PRODUCT 1347 } else { 1348 st->print("kmovq %s, %s\t# spill", 1349 Matcher::regName[dst_first], 1350 Matcher::regName[src_first]); 1351 #endif 1352 } 1353 } 1354 Unimplemented(); 1355 return 0; 1356 } 1357 } else if (src_first_rc == rc_float) { 1358 // xmm -> 1359 if (dst_first_rc == rc_stack) { 1360 // xmm -> mem 1361 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1362 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1363 // 64-bit 1364 int offset = ra_->reg2offset(dst_first); 1365 if (masm) { 1366 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1367 #ifndef PRODUCT 1368 } else { 1369 st->print("movsd [rsp + #%d], %s\t# spill", 1370 offset, 1371 Matcher::regName[src_first]); 1372 #endif 1373 } 1374 } else { 1375 // 32-bit 1376 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1377 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1378 int offset = ra_->reg2offset(dst_first); 1379 if (masm) { 1380 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1381 #ifndef PRODUCT 1382 } else { 1383 st->print("movss [rsp + #%d], %s\t# spill", 1384 offset, 1385 Matcher::regName[src_first]); 1386 #endif 1387 } 1388 } 1389 return 0; 1390 } else if (dst_first_rc == rc_int) { 1391 // xmm -> gpr 1392 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1393 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1394 // 64-bit 1395 if (masm) { 1396 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1397 #ifndef PRODUCT 1398 } else { 1399 st->print("movdq %s, %s\t# spill", 1400 Matcher::regName[dst_first], 1401 Matcher::regName[src_first]); 1402 #endif 1403 } 1404 } else { 1405 // 32-bit 1406 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1407 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1408 if (masm) { 1409 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1410 #ifndef PRODUCT 1411 } else { 1412 st->print("movdl %s, %s\t# spill", 1413 Matcher::regName[dst_first], 1414 Matcher::regName[src_first]); 1415 #endif 1416 } 1417 } 1418 return 0; 1419 } else if (dst_first_rc == rc_float) { 1420 // xmm -> xmm 1421 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1422 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1423 // 64-bit 1424 if (masm) { 1425 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1426 #ifndef PRODUCT 1427 } else { 1428 st->print("%s %s, %s\t# spill", 1429 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1430 Matcher::regName[dst_first], 1431 Matcher::regName[src_first]); 1432 #endif 1433 } 1434 } else { 1435 // 32-bit 1436 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1437 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1438 if (masm) { 1439 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1440 #ifndef PRODUCT 1441 } else { 1442 st->print("%s %s, %s\t# spill", 1443 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1444 Matcher::regName[dst_first], 1445 Matcher::regName[src_first]); 1446 #endif 1447 } 1448 } 1449 return 0; 1450 } else if (dst_first_rc == rc_kreg) { 1451 assert(false, "Illegal spilling"); 1452 return 0; 1453 } 1454 } else if (src_first_rc == rc_kreg) { 1455 if (dst_first_rc == rc_stack) { 1456 // mem -> kreg 1457 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1458 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1459 // 64-bit 1460 int offset = ra_->reg2offset(dst_first); 1461 if (masm) { 1462 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1463 #ifndef PRODUCT 1464 } else { 1465 st->print("kmovq [rsp + #%d] , %s\t# spill", 1466 offset, 1467 Matcher::regName[src_first]); 1468 #endif 1469 } 1470 } 1471 return 0; 1472 } else if (dst_first_rc == rc_int) { 1473 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1474 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1475 // 64-bit 1476 if (masm) { 1477 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1478 #ifndef PRODUCT 1479 } else { 1480 st->print("kmovq %s, %s\t# spill", 1481 Matcher::regName[dst_first], 1482 Matcher::regName[src_first]); 1483 #endif 1484 } 1485 } 1486 Unimplemented(); 1487 return 0; 1488 } else if (dst_first_rc == rc_kreg) { 1489 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1490 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1491 // 64-bit 1492 if (masm) { 1493 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1494 #ifndef PRODUCT 1495 } else { 1496 st->print("kmovq %s, %s\t# spill", 1497 Matcher::regName[dst_first], 1498 Matcher::regName[src_first]); 1499 #endif 1500 } 1501 } 1502 return 0; 1503 } else if (dst_first_rc == rc_float) { 1504 assert(false, "Illegal spill"); 1505 return 0; 1506 } 1507 } 1508 1509 assert(0," foo "); 1510 Unimplemented(); 1511 return 0; 1512 } 1513 1514 #ifndef PRODUCT 1515 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1516 implementation(nullptr, ra_, false, st); 1517 } 1518 #endif 1519 1520 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1521 implementation(masm, ra_, false, nullptr); 1522 } 1523 1524 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1525 return MachNode::size(ra_); 1526 } 1527 1528 //============================================================================= 1529 #ifndef PRODUCT 1530 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1531 { 1532 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1533 int reg = ra_->get_reg_first(this); 1534 st->print("leaq %s, [rsp + #%d]\t# box lock", 1535 Matcher::regName[reg], offset); 1536 } 1537 #endif 1538 1539 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1540 { 1541 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1542 int reg = ra_->get_encode(this); 1543 1544 __ lea(as_Register(reg), Address(rsp, offset)); 1545 } 1546 1547 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1548 { 1549 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1550 return (offset < 0x80) ? 5 : 8; // REX 1551 } 1552 1553 //============================================================================= 1554 #ifndef PRODUCT 1555 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1556 { 1557 if (UseCompressedClassPointers) { 1558 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1559 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1560 } else { 1561 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1562 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1563 } 1564 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1565 } 1566 #endif 1567 1568 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1569 { 1570 __ ic_check(InteriorEntryAlignment); 1571 } 1572 1573 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1574 { 1575 return MachNode::size(ra_); // too many variables; just compute it 1576 // the hard way 1577 } 1578 1579 1580 //============================================================================= 1581 1582 bool Matcher::supports_vector_calling_convention(void) { 1583 if (EnableVectorSupport && UseVectorStubs) { 1584 return true; 1585 } 1586 return false; 1587 } 1588 1589 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1590 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1591 int lo = XMM0_num; 1592 int hi = XMM0b_num; 1593 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1594 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1595 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1596 return OptoRegPair(hi, lo); 1597 } 1598 1599 // Is this branch offset short enough that a short branch can be used? 1600 // 1601 // NOTE: If the platform does not provide any short branch variants, then 1602 // this method should return false for offset 0. 1603 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1604 // The passed offset is relative to address of the branch. 1605 // On 86 a branch displacement is calculated relative to address 1606 // of a next instruction. 1607 offset -= br_size; 1608 1609 // the short version of jmpConUCF2 contains multiple branches, 1610 // making the reach slightly less 1611 if (rule == jmpConUCF2_rule) 1612 return (-126 <= offset && offset <= 125); 1613 return (-128 <= offset && offset <= 127); 1614 } 1615 1616 // Return whether or not this register is ever used as an argument. 1617 // This function is used on startup to build the trampoline stubs in 1618 // generateOptoStub. Registers not mentioned will be killed by the VM 1619 // call in the trampoline, and arguments in those registers not be 1620 // available to the callee. 1621 bool Matcher::can_be_java_arg(int reg) 1622 { 1623 return 1624 reg == RDI_num || reg == RDI_H_num || 1625 reg == RSI_num || reg == RSI_H_num || 1626 reg == RDX_num || reg == RDX_H_num || 1627 reg == RCX_num || reg == RCX_H_num || 1628 reg == R8_num || reg == R8_H_num || 1629 reg == R9_num || reg == R9_H_num || 1630 reg == R12_num || reg == R12_H_num || 1631 reg == XMM0_num || reg == XMM0b_num || 1632 reg == XMM1_num || reg == XMM1b_num || 1633 reg == XMM2_num || reg == XMM2b_num || 1634 reg == XMM3_num || reg == XMM3b_num || 1635 reg == XMM4_num || reg == XMM4b_num || 1636 reg == XMM5_num || reg == XMM5b_num || 1637 reg == XMM6_num || reg == XMM6b_num || 1638 reg == XMM7_num || reg == XMM7b_num; 1639 } 1640 1641 bool Matcher::is_spillable_arg(int reg) 1642 { 1643 return can_be_java_arg(reg); 1644 } 1645 1646 uint Matcher::int_pressure_limit() 1647 { 1648 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1649 } 1650 1651 uint Matcher::float_pressure_limit() 1652 { 1653 // After experiment around with different values, the following default threshold 1654 // works best for LCM's register pressure scheduling on x64. 1655 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1656 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1657 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1658 } 1659 1660 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1661 // In 64 bit mode a code which use multiply when 1662 // devisor is constant is faster than hardware 1663 // DIV instruction (it uses MulHiL). 1664 return false; 1665 } 1666 1667 // Register for DIVI projection of divmodI 1668 RegMask Matcher::divI_proj_mask() { 1669 return INT_RAX_REG_mask(); 1670 } 1671 1672 // Register for MODI projection of divmodI 1673 RegMask Matcher::modI_proj_mask() { 1674 return INT_RDX_REG_mask(); 1675 } 1676 1677 // Register for DIVL projection of divmodL 1678 RegMask Matcher::divL_proj_mask() { 1679 return LONG_RAX_REG_mask(); 1680 } 1681 1682 // Register for MODL projection of divmodL 1683 RegMask Matcher::modL_proj_mask() { 1684 return LONG_RDX_REG_mask(); 1685 } 1686 1687 // Register for saving SP into on method handle invokes. Not used on x86_64. 1688 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1689 return NO_REG_mask(); 1690 } 1691 1692 %} 1693 1694 //----------ENCODING BLOCK----------------------------------------------------- 1695 // This block specifies the encoding classes used by the compiler to 1696 // output byte streams. Encoding classes are parameterized macros 1697 // used by Machine Instruction Nodes in order to generate the bit 1698 // encoding of the instruction. Operands specify their base encoding 1699 // interface with the interface keyword. There are currently 1700 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1701 // COND_INTER. REG_INTER causes an operand to generate a function 1702 // which returns its register number when queried. CONST_INTER causes 1703 // an operand to generate a function which returns the value of the 1704 // constant when queried. MEMORY_INTER causes an operand to generate 1705 // four functions which return the Base Register, the Index Register, 1706 // the Scale Value, and the Offset Value of the operand when queried. 1707 // COND_INTER causes an operand to generate six functions which return 1708 // the encoding code (ie - encoding bits for the instruction) 1709 // associated with each basic boolean condition for a conditional 1710 // instruction. 1711 // 1712 // Instructions specify two basic values for encoding. Again, a 1713 // function is available to check if the constant displacement is an 1714 // oop. They use the ins_encode keyword to specify their encoding 1715 // classes (which must be a sequence of enc_class names, and their 1716 // parameters, specified in the encoding block), and they use the 1717 // opcode keyword to specify, in order, their primary, secondary, and 1718 // tertiary opcode. Only the opcode sections which a particular 1719 // instruction needs for encoding need to be specified. 1720 encode %{ 1721 enc_class cdql_enc(no_rax_rdx_RegI div) 1722 %{ 1723 // Full implementation of Java idiv and irem; checks for 1724 // special case as described in JVM spec., p.243 & p.271. 1725 // 1726 // normal case special case 1727 // 1728 // input : rax: dividend min_int 1729 // reg: divisor -1 1730 // 1731 // output: rax: quotient (= rax idiv reg) min_int 1732 // rdx: remainder (= rax irem reg) 0 1733 // 1734 // Code sequnce: 1735 // 1736 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1737 // 5: 75 07/08 jne e <normal> 1738 // 7: 33 d2 xor %edx,%edx 1739 // [div >= 8 -> offset + 1] 1740 // [REX_B] 1741 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1742 // c: 74 03/04 je 11 <done> 1743 // 000000000000000e <normal>: 1744 // e: 99 cltd 1745 // [div >= 8 -> offset + 1] 1746 // [REX_B] 1747 // f: f7 f9 idiv $div 1748 // 0000000000000011 <done>: 1749 Label normal; 1750 Label done; 1751 1752 // cmp $0x80000000,%eax 1753 __ cmpl(as_Register(RAX_enc), 0x80000000); 1754 1755 // jne e <normal> 1756 __ jccb(Assembler::notEqual, normal); 1757 1758 // xor %edx,%edx 1759 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1760 1761 // cmp $0xffffffffffffffff,%ecx 1762 __ cmpl($div$$Register, -1); 1763 1764 // je 11 <done> 1765 __ jccb(Assembler::equal, done); 1766 1767 // <normal> 1768 // cltd 1769 __ bind(normal); 1770 __ cdql(); 1771 1772 // idivl 1773 // <done> 1774 __ idivl($div$$Register); 1775 __ bind(done); 1776 %} 1777 1778 enc_class cdqq_enc(no_rax_rdx_RegL div) 1779 %{ 1780 // Full implementation of Java ldiv and lrem; checks for 1781 // special case as described in JVM spec., p.243 & p.271. 1782 // 1783 // normal case special case 1784 // 1785 // input : rax: dividend min_long 1786 // reg: divisor -1 1787 // 1788 // output: rax: quotient (= rax idiv reg) min_long 1789 // rdx: remainder (= rax irem reg) 0 1790 // 1791 // Code sequnce: 1792 // 1793 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1794 // 7: 00 00 80 1795 // a: 48 39 d0 cmp %rdx,%rax 1796 // d: 75 08 jne 17 <normal> 1797 // f: 33 d2 xor %edx,%edx 1798 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1799 // 15: 74 05 je 1c <done> 1800 // 0000000000000017 <normal>: 1801 // 17: 48 99 cqto 1802 // 19: 48 f7 f9 idiv $div 1803 // 000000000000001c <done>: 1804 Label normal; 1805 Label done; 1806 1807 // mov $0x8000000000000000,%rdx 1808 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1809 1810 // cmp %rdx,%rax 1811 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1812 1813 // jne 17 <normal> 1814 __ jccb(Assembler::notEqual, normal); 1815 1816 // xor %edx,%edx 1817 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1818 1819 // cmp $0xffffffffffffffff,$div 1820 __ cmpq($div$$Register, -1); 1821 1822 // je 1e <done> 1823 __ jccb(Assembler::equal, done); 1824 1825 // <normal> 1826 // cqto 1827 __ bind(normal); 1828 __ cdqq(); 1829 1830 // idivq (note: must be emitted by the user of this rule) 1831 // <done> 1832 __ idivq($div$$Register); 1833 __ bind(done); 1834 %} 1835 1836 enc_class clear_avx %{ 1837 debug_only(int off0 = __ offset()); 1838 if (generate_vzeroupper(Compile::current())) { 1839 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1840 // Clear upper bits of YMM registers when current compiled code uses 1841 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1842 __ vzeroupper(); 1843 } 1844 debug_only(int off1 = __ offset()); 1845 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1846 %} 1847 1848 enc_class Java_To_Runtime(method meth) %{ 1849 // No relocation needed 1850 __ mov64(r10, (int64_t) $meth$$method); 1851 __ call(r10); 1852 __ post_call_nop(); 1853 %} 1854 1855 enc_class Java_Static_Call(method meth) 1856 %{ 1857 // JAVA STATIC CALL 1858 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1859 // determine who we intended to call. 1860 if (!_method) { 1861 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1862 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1863 // The NOP here is purely to ensure that eliding a call to 1864 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1865 __ addr_nop_5(); 1866 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1867 } else { 1868 int method_index = resolved_method_index(masm); 1869 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1870 : static_call_Relocation::spec(method_index); 1871 address mark = __ pc(); 1872 int call_offset = __ offset(); 1873 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1874 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1875 // Calls of the same statically bound method can share 1876 // a stub to the interpreter. 1877 __ code()->shared_stub_to_interp_for(_method, call_offset); 1878 } else { 1879 // Emit stubs for static call. 1880 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1881 __ clear_inst_mark(); 1882 if (stub == nullptr) { 1883 ciEnv::current()->record_failure("CodeCache is full"); 1884 return; 1885 } 1886 } 1887 } 1888 __ post_call_nop(); 1889 %} 1890 1891 enc_class Java_Dynamic_Call(method meth) %{ 1892 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1893 __ post_call_nop(); 1894 %} 1895 1896 %} 1897 1898 1899 1900 //----------FRAME-------------------------------------------------------------- 1901 // Definition of frame structure and management information. 1902 // 1903 // S T A C K L A Y O U T Allocators stack-slot number 1904 // | (to get allocators register number 1905 // G Owned by | | v add OptoReg::stack0()) 1906 // r CALLER | | 1907 // o | +--------+ pad to even-align allocators stack-slot 1908 // w V | pad0 | numbers; owned by CALLER 1909 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1910 // h ^ | in | 5 1911 // | | args | 4 Holes in incoming args owned by SELF 1912 // | | | | 3 1913 // | | +--------+ 1914 // V | | old out| Empty on Intel, window on Sparc 1915 // | old |preserve| Must be even aligned. 1916 // | SP-+--------+----> Matcher::_old_SP, even aligned 1917 // | | in | 3 area for Intel ret address 1918 // Owned by |preserve| Empty on Sparc. 1919 // SELF +--------+ 1920 // | | pad2 | 2 pad to align old SP 1921 // | +--------+ 1 1922 // | | locks | 0 1923 // | +--------+----> OptoReg::stack0(), even aligned 1924 // | | pad1 | 11 pad to align new SP 1925 // | +--------+ 1926 // | | | 10 1927 // | | spills | 9 spills 1928 // V | | 8 (pad0 slot for callee) 1929 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1930 // ^ | out | 7 1931 // | | args | 6 Holes in outgoing args owned by CALLEE 1932 // Owned by +--------+ 1933 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1934 // | new |preserve| Must be even-aligned. 1935 // | SP-+--------+----> Matcher::_new_SP, even aligned 1936 // | | | 1937 // 1938 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1939 // known from SELF's arguments and the Java calling convention. 1940 // Region 6-7 is determined per call site. 1941 // Note 2: If the calling convention leaves holes in the incoming argument 1942 // area, those holes are owned by SELF. Holes in the outgoing area 1943 // are owned by the CALLEE. Holes should not be necessary in the 1944 // incoming area, as the Java calling convention is completely under 1945 // the control of the AD file. Doubles can be sorted and packed to 1946 // avoid holes. Holes in the outgoing arguments may be necessary for 1947 // varargs C calling conventions. 1948 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1949 // even aligned with pad0 as needed. 1950 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1951 // region 6-11 is even aligned; it may be padded out more so that 1952 // the region from SP to FP meets the minimum stack alignment. 1953 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1954 // alignment. Region 11, pad1, may be dynamically extended so that 1955 // SP meets the minimum alignment. 1956 1957 frame 1958 %{ 1959 // These three registers define part of the calling convention 1960 // between compiled code and the interpreter. 1961 inline_cache_reg(RAX); // Inline Cache Register 1962 1963 // Optional: name the operand used by cisc-spilling to access 1964 // [stack_pointer + offset] 1965 cisc_spilling_operand_name(indOffset32); 1966 1967 // Number of stack slots consumed by locking an object 1968 sync_stack_slots(2); 1969 1970 // Compiled code's Frame Pointer 1971 frame_pointer(RSP); 1972 1973 // Interpreter stores its frame pointer in a register which is 1974 // stored to the stack by I2CAdaptors. 1975 // I2CAdaptors convert from interpreted java to compiled java. 1976 interpreter_frame_pointer(RBP); 1977 1978 // Stack alignment requirement 1979 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1980 1981 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1982 // for calls to C. Supports the var-args backing area for register parms. 1983 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1984 1985 // The after-PROLOG location of the return address. Location of 1986 // return address specifies a type (REG or STACK) and a number 1987 // representing the register number (i.e. - use a register name) or 1988 // stack slot. 1989 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 1990 // Otherwise, it is above the locks and verification slot and alignment word 1991 return_addr(STACK - 2 + 1992 align_up((Compile::current()->in_preserve_stack_slots() + 1993 Compile::current()->fixed_slots()), 1994 stack_alignment_in_slots())); 1995 1996 // Location of compiled Java return values. Same as C for now. 1997 return_value 1998 %{ 1999 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2000 "only return normal values"); 2001 2002 static const int lo[Op_RegL + 1] = { 2003 0, 2004 0, 2005 RAX_num, // Op_RegN 2006 RAX_num, // Op_RegI 2007 RAX_num, // Op_RegP 2008 XMM0_num, // Op_RegF 2009 XMM0_num, // Op_RegD 2010 RAX_num // Op_RegL 2011 }; 2012 static const int hi[Op_RegL + 1] = { 2013 0, 2014 0, 2015 OptoReg::Bad, // Op_RegN 2016 OptoReg::Bad, // Op_RegI 2017 RAX_H_num, // Op_RegP 2018 OptoReg::Bad, // Op_RegF 2019 XMM0b_num, // Op_RegD 2020 RAX_H_num // Op_RegL 2021 }; 2022 // Excluded flags and vector registers. 2023 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2024 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2025 %} 2026 %} 2027 2028 //----------ATTRIBUTES--------------------------------------------------------- 2029 //----------Operand Attributes------------------------------------------------- 2030 op_attrib op_cost(0); // Required cost attribute 2031 2032 //----------Instruction Attributes--------------------------------------------- 2033 ins_attrib ins_cost(100); // Required cost attribute 2034 ins_attrib ins_size(8); // Required size attribute (in bits) 2035 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2036 // a non-matching short branch variant 2037 // of some long branch? 2038 ins_attrib ins_alignment(1); // Required alignment attribute (must 2039 // be a power of 2) specifies the 2040 // alignment that some part of the 2041 // instruction (not necessarily the 2042 // start) requires. If > 1, a 2043 // compute_padding() function must be 2044 // provided for the instruction 2045 2046 //----------OPERANDS----------------------------------------------------------- 2047 // Operand definitions must precede instruction definitions for correct parsing 2048 // in the ADLC because operands constitute user defined types which are used in 2049 // instruction definitions. 2050 2051 //----------Simple Operands---------------------------------------------------- 2052 // Immediate Operands 2053 // Integer Immediate 2054 operand immI() 2055 %{ 2056 match(ConI); 2057 2058 op_cost(10); 2059 format %{ %} 2060 interface(CONST_INTER); 2061 %} 2062 2063 // Constant for test vs zero 2064 operand immI_0() 2065 %{ 2066 predicate(n->get_int() == 0); 2067 match(ConI); 2068 2069 op_cost(0); 2070 format %{ %} 2071 interface(CONST_INTER); 2072 %} 2073 2074 // Constant for increment 2075 operand immI_1() 2076 %{ 2077 predicate(n->get_int() == 1); 2078 match(ConI); 2079 2080 op_cost(0); 2081 format %{ %} 2082 interface(CONST_INTER); 2083 %} 2084 2085 // Constant for decrement 2086 operand immI_M1() 2087 %{ 2088 predicate(n->get_int() == -1); 2089 match(ConI); 2090 2091 op_cost(0); 2092 format %{ %} 2093 interface(CONST_INTER); 2094 %} 2095 2096 operand immI_2() 2097 %{ 2098 predicate(n->get_int() == 2); 2099 match(ConI); 2100 2101 op_cost(0); 2102 format %{ %} 2103 interface(CONST_INTER); 2104 %} 2105 2106 operand immI_4() 2107 %{ 2108 predicate(n->get_int() == 4); 2109 match(ConI); 2110 2111 op_cost(0); 2112 format %{ %} 2113 interface(CONST_INTER); 2114 %} 2115 2116 operand immI_8() 2117 %{ 2118 predicate(n->get_int() == 8); 2119 match(ConI); 2120 2121 op_cost(0); 2122 format %{ %} 2123 interface(CONST_INTER); 2124 %} 2125 2126 // Valid scale values for addressing modes 2127 operand immI2() 2128 %{ 2129 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2130 match(ConI); 2131 2132 format %{ %} 2133 interface(CONST_INTER); 2134 %} 2135 2136 operand immU7() 2137 %{ 2138 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2139 match(ConI); 2140 2141 op_cost(5); 2142 format %{ %} 2143 interface(CONST_INTER); 2144 %} 2145 2146 operand immI8() 2147 %{ 2148 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2149 match(ConI); 2150 2151 op_cost(5); 2152 format %{ %} 2153 interface(CONST_INTER); 2154 %} 2155 2156 operand immU8() 2157 %{ 2158 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2159 match(ConI); 2160 2161 op_cost(5); 2162 format %{ %} 2163 interface(CONST_INTER); 2164 %} 2165 2166 operand immI16() 2167 %{ 2168 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2169 match(ConI); 2170 2171 op_cost(10); 2172 format %{ %} 2173 interface(CONST_INTER); 2174 %} 2175 2176 // Int Immediate non-negative 2177 operand immU31() 2178 %{ 2179 predicate(n->get_int() >= 0); 2180 match(ConI); 2181 2182 op_cost(0); 2183 format %{ %} 2184 interface(CONST_INTER); 2185 %} 2186 2187 // Pointer Immediate 2188 operand immP() 2189 %{ 2190 match(ConP); 2191 2192 op_cost(10); 2193 format %{ %} 2194 interface(CONST_INTER); 2195 %} 2196 2197 // Null Pointer Immediate 2198 operand immP0() 2199 %{ 2200 predicate(n->get_ptr() == 0); 2201 match(ConP); 2202 2203 op_cost(5); 2204 format %{ %} 2205 interface(CONST_INTER); 2206 %} 2207 2208 // Pointer Immediate 2209 operand immN() %{ 2210 match(ConN); 2211 2212 op_cost(10); 2213 format %{ %} 2214 interface(CONST_INTER); 2215 %} 2216 2217 operand immNKlass() %{ 2218 match(ConNKlass); 2219 2220 op_cost(10); 2221 format %{ %} 2222 interface(CONST_INTER); 2223 %} 2224 2225 // Null Pointer Immediate 2226 operand immN0() %{ 2227 predicate(n->get_narrowcon() == 0); 2228 match(ConN); 2229 2230 op_cost(5); 2231 format %{ %} 2232 interface(CONST_INTER); 2233 %} 2234 2235 operand immP31() 2236 %{ 2237 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2238 && (n->get_ptr() >> 31) == 0); 2239 match(ConP); 2240 2241 op_cost(5); 2242 format %{ %} 2243 interface(CONST_INTER); 2244 %} 2245 2246 2247 // Long Immediate 2248 operand immL() 2249 %{ 2250 match(ConL); 2251 2252 op_cost(20); 2253 format %{ %} 2254 interface(CONST_INTER); 2255 %} 2256 2257 // Long Immediate 8-bit 2258 operand immL8() 2259 %{ 2260 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2261 match(ConL); 2262 2263 op_cost(5); 2264 format %{ %} 2265 interface(CONST_INTER); 2266 %} 2267 2268 // Long Immediate 32-bit unsigned 2269 operand immUL32() 2270 %{ 2271 predicate(n->get_long() == (unsigned int) (n->get_long())); 2272 match(ConL); 2273 2274 op_cost(10); 2275 format %{ %} 2276 interface(CONST_INTER); 2277 %} 2278 2279 // Long Immediate 32-bit signed 2280 operand immL32() 2281 %{ 2282 predicate(n->get_long() == (int) (n->get_long())); 2283 match(ConL); 2284 2285 op_cost(15); 2286 format %{ %} 2287 interface(CONST_INTER); 2288 %} 2289 2290 operand immL_Pow2() 2291 %{ 2292 predicate(is_power_of_2((julong)n->get_long())); 2293 match(ConL); 2294 2295 op_cost(15); 2296 format %{ %} 2297 interface(CONST_INTER); 2298 %} 2299 2300 operand immL_NotPow2() 2301 %{ 2302 predicate(is_power_of_2((julong)~n->get_long())); 2303 match(ConL); 2304 2305 op_cost(15); 2306 format %{ %} 2307 interface(CONST_INTER); 2308 %} 2309 2310 // Long Immediate zero 2311 operand immL0() 2312 %{ 2313 predicate(n->get_long() == 0L); 2314 match(ConL); 2315 2316 op_cost(10); 2317 format %{ %} 2318 interface(CONST_INTER); 2319 %} 2320 2321 // Constant for increment 2322 operand immL1() 2323 %{ 2324 predicate(n->get_long() == 1); 2325 match(ConL); 2326 2327 format %{ %} 2328 interface(CONST_INTER); 2329 %} 2330 2331 // Constant for decrement 2332 operand immL_M1() 2333 %{ 2334 predicate(n->get_long() == -1); 2335 match(ConL); 2336 2337 format %{ %} 2338 interface(CONST_INTER); 2339 %} 2340 2341 // Long Immediate: low 32-bit mask 2342 operand immL_32bits() 2343 %{ 2344 predicate(n->get_long() == 0xFFFFFFFFL); 2345 match(ConL); 2346 op_cost(20); 2347 2348 format %{ %} 2349 interface(CONST_INTER); 2350 %} 2351 2352 // Int Immediate: 2^n-1, positive 2353 operand immI_Pow2M1() 2354 %{ 2355 predicate((n->get_int() > 0) 2356 && is_power_of_2((juint)n->get_int() + 1)); 2357 match(ConI); 2358 2359 op_cost(20); 2360 format %{ %} 2361 interface(CONST_INTER); 2362 %} 2363 2364 // Float Immediate zero 2365 operand immF0() 2366 %{ 2367 predicate(jint_cast(n->getf()) == 0); 2368 match(ConF); 2369 2370 op_cost(5); 2371 format %{ %} 2372 interface(CONST_INTER); 2373 %} 2374 2375 // Float Immediate 2376 operand immF() 2377 %{ 2378 match(ConF); 2379 2380 op_cost(15); 2381 format %{ %} 2382 interface(CONST_INTER); 2383 %} 2384 2385 // Half Float Immediate 2386 operand immH() 2387 %{ 2388 match(ConH); 2389 2390 op_cost(15); 2391 format %{ %} 2392 interface(CONST_INTER); 2393 %} 2394 2395 // Double Immediate zero 2396 operand immD0() 2397 %{ 2398 predicate(jlong_cast(n->getd()) == 0); 2399 match(ConD); 2400 2401 op_cost(5); 2402 format %{ %} 2403 interface(CONST_INTER); 2404 %} 2405 2406 // Double Immediate 2407 operand immD() 2408 %{ 2409 match(ConD); 2410 2411 op_cost(15); 2412 format %{ %} 2413 interface(CONST_INTER); 2414 %} 2415 2416 // Immediates for special shifts (sign extend) 2417 2418 // Constants for increment 2419 operand immI_16() 2420 %{ 2421 predicate(n->get_int() == 16); 2422 match(ConI); 2423 2424 format %{ %} 2425 interface(CONST_INTER); 2426 %} 2427 2428 operand immI_24() 2429 %{ 2430 predicate(n->get_int() == 24); 2431 match(ConI); 2432 2433 format %{ %} 2434 interface(CONST_INTER); 2435 %} 2436 2437 // Constant for byte-wide masking 2438 operand immI_255() 2439 %{ 2440 predicate(n->get_int() == 255); 2441 match(ConI); 2442 2443 format %{ %} 2444 interface(CONST_INTER); 2445 %} 2446 2447 // Constant for short-wide masking 2448 operand immI_65535() 2449 %{ 2450 predicate(n->get_int() == 65535); 2451 match(ConI); 2452 2453 format %{ %} 2454 interface(CONST_INTER); 2455 %} 2456 2457 // Constant for byte-wide masking 2458 operand immL_255() 2459 %{ 2460 predicate(n->get_long() == 255); 2461 match(ConL); 2462 2463 format %{ %} 2464 interface(CONST_INTER); 2465 %} 2466 2467 // Constant for short-wide masking 2468 operand immL_65535() 2469 %{ 2470 predicate(n->get_long() == 65535); 2471 match(ConL); 2472 2473 format %{ %} 2474 interface(CONST_INTER); 2475 %} 2476 2477 operand kReg() 2478 %{ 2479 constraint(ALLOC_IN_RC(vectmask_reg)); 2480 match(RegVectMask); 2481 format %{%} 2482 interface(REG_INTER); 2483 %} 2484 2485 // Register Operands 2486 // Integer Register 2487 operand rRegI() 2488 %{ 2489 constraint(ALLOC_IN_RC(int_reg)); 2490 match(RegI); 2491 2492 match(rax_RegI); 2493 match(rbx_RegI); 2494 match(rcx_RegI); 2495 match(rdx_RegI); 2496 match(rdi_RegI); 2497 2498 format %{ %} 2499 interface(REG_INTER); 2500 %} 2501 2502 // Special Registers 2503 operand rax_RegI() 2504 %{ 2505 constraint(ALLOC_IN_RC(int_rax_reg)); 2506 match(RegI); 2507 match(rRegI); 2508 2509 format %{ "RAX" %} 2510 interface(REG_INTER); 2511 %} 2512 2513 // Special Registers 2514 operand rbx_RegI() 2515 %{ 2516 constraint(ALLOC_IN_RC(int_rbx_reg)); 2517 match(RegI); 2518 match(rRegI); 2519 2520 format %{ "RBX" %} 2521 interface(REG_INTER); 2522 %} 2523 2524 operand rcx_RegI() 2525 %{ 2526 constraint(ALLOC_IN_RC(int_rcx_reg)); 2527 match(RegI); 2528 match(rRegI); 2529 2530 format %{ "RCX" %} 2531 interface(REG_INTER); 2532 %} 2533 2534 operand rdx_RegI() 2535 %{ 2536 constraint(ALLOC_IN_RC(int_rdx_reg)); 2537 match(RegI); 2538 match(rRegI); 2539 2540 format %{ "RDX" %} 2541 interface(REG_INTER); 2542 %} 2543 2544 operand rdi_RegI() 2545 %{ 2546 constraint(ALLOC_IN_RC(int_rdi_reg)); 2547 match(RegI); 2548 match(rRegI); 2549 2550 format %{ "RDI" %} 2551 interface(REG_INTER); 2552 %} 2553 2554 operand no_rax_rdx_RegI() 2555 %{ 2556 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2557 match(RegI); 2558 match(rbx_RegI); 2559 match(rcx_RegI); 2560 match(rdi_RegI); 2561 2562 format %{ %} 2563 interface(REG_INTER); 2564 %} 2565 2566 operand no_rbp_r13_RegI() 2567 %{ 2568 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2569 match(RegI); 2570 match(rRegI); 2571 match(rax_RegI); 2572 match(rbx_RegI); 2573 match(rcx_RegI); 2574 match(rdx_RegI); 2575 match(rdi_RegI); 2576 2577 format %{ %} 2578 interface(REG_INTER); 2579 %} 2580 2581 // Pointer Register 2582 operand any_RegP() 2583 %{ 2584 constraint(ALLOC_IN_RC(any_reg)); 2585 match(RegP); 2586 match(rax_RegP); 2587 match(rbx_RegP); 2588 match(rdi_RegP); 2589 match(rsi_RegP); 2590 match(rbp_RegP); 2591 match(r15_RegP); 2592 match(rRegP); 2593 2594 format %{ %} 2595 interface(REG_INTER); 2596 %} 2597 2598 operand rRegP() 2599 %{ 2600 constraint(ALLOC_IN_RC(ptr_reg)); 2601 match(RegP); 2602 match(rax_RegP); 2603 match(rbx_RegP); 2604 match(rdi_RegP); 2605 match(rsi_RegP); 2606 match(rbp_RegP); // See Q&A below about 2607 match(r15_RegP); // r15_RegP and rbp_RegP. 2608 2609 format %{ %} 2610 interface(REG_INTER); 2611 %} 2612 2613 operand rRegN() %{ 2614 constraint(ALLOC_IN_RC(int_reg)); 2615 match(RegN); 2616 2617 format %{ %} 2618 interface(REG_INTER); 2619 %} 2620 2621 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2622 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2623 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2624 // The output of an instruction is controlled by the allocator, which respects 2625 // register class masks, not match rules. Unless an instruction mentions 2626 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2627 // by the allocator as an input. 2628 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2629 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2630 // result, RBP is not included in the output of the instruction either. 2631 2632 // This operand is not allowed to use RBP even if 2633 // RBP is not used to hold the frame pointer. 2634 operand no_rbp_RegP() 2635 %{ 2636 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2637 match(RegP); 2638 match(rbx_RegP); 2639 match(rsi_RegP); 2640 match(rdi_RegP); 2641 2642 format %{ %} 2643 interface(REG_INTER); 2644 %} 2645 2646 // Special Registers 2647 // Return a pointer value 2648 operand rax_RegP() 2649 %{ 2650 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2651 match(RegP); 2652 match(rRegP); 2653 2654 format %{ %} 2655 interface(REG_INTER); 2656 %} 2657 2658 // Special Registers 2659 // Return a compressed pointer value 2660 operand rax_RegN() 2661 %{ 2662 constraint(ALLOC_IN_RC(int_rax_reg)); 2663 match(RegN); 2664 match(rRegN); 2665 2666 format %{ %} 2667 interface(REG_INTER); 2668 %} 2669 2670 // Used in AtomicAdd 2671 operand rbx_RegP() 2672 %{ 2673 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2674 match(RegP); 2675 match(rRegP); 2676 2677 format %{ %} 2678 interface(REG_INTER); 2679 %} 2680 2681 operand rsi_RegP() 2682 %{ 2683 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2684 match(RegP); 2685 match(rRegP); 2686 2687 format %{ %} 2688 interface(REG_INTER); 2689 %} 2690 2691 operand rbp_RegP() 2692 %{ 2693 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2694 match(RegP); 2695 match(rRegP); 2696 2697 format %{ %} 2698 interface(REG_INTER); 2699 %} 2700 2701 // Used in rep stosq 2702 operand rdi_RegP() 2703 %{ 2704 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2705 match(RegP); 2706 match(rRegP); 2707 2708 format %{ %} 2709 interface(REG_INTER); 2710 %} 2711 2712 operand r15_RegP() 2713 %{ 2714 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2715 match(RegP); 2716 match(rRegP); 2717 2718 format %{ %} 2719 interface(REG_INTER); 2720 %} 2721 2722 operand rRegL() 2723 %{ 2724 constraint(ALLOC_IN_RC(long_reg)); 2725 match(RegL); 2726 match(rax_RegL); 2727 match(rdx_RegL); 2728 2729 format %{ %} 2730 interface(REG_INTER); 2731 %} 2732 2733 // Special Registers 2734 operand no_rax_rdx_RegL() 2735 %{ 2736 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2737 match(RegL); 2738 match(rRegL); 2739 2740 format %{ %} 2741 interface(REG_INTER); 2742 %} 2743 2744 operand rax_RegL() 2745 %{ 2746 constraint(ALLOC_IN_RC(long_rax_reg)); 2747 match(RegL); 2748 match(rRegL); 2749 2750 format %{ "RAX" %} 2751 interface(REG_INTER); 2752 %} 2753 2754 operand rcx_RegL() 2755 %{ 2756 constraint(ALLOC_IN_RC(long_rcx_reg)); 2757 match(RegL); 2758 match(rRegL); 2759 2760 format %{ %} 2761 interface(REG_INTER); 2762 %} 2763 2764 operand rdx_RegL() 2765 %{ 2766 constraint(ALLOC_IN_RC(long_rdx_reg)); 2767 match(RegL); 2768 match(rRegL); 2769 2770 format %{ %} 2771 interface(REG_INTER); 2772 %} 2773 2774 operand r11_RegL() 2775 %{ 2776 constraint(ALLOC_IN_RC(long_r11_reg)); 2777 match(RegL); 2778 match(rRegL); 2779 2780 format %{ %} 2781 interface(REG_INTER); 2782 %} 2783 2784 operand no_rbp_r13_RegL() 2785 %{ 2786 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2787 match(RegL); 2788 match(rRegL); 2789 match(rax_RegL); 2790 match(rcx_RegL); 2791 match(rdx_RegL); 2792 2793 format %{ %} 2794 interface(REG_INTER); 2795 %} 2796 2797 // Flags register, used as output of compare instructions 2798 operand rFlagsReg() 2799 %{ 2800 constraint(ALLOC_IN_RC(int_flags)); 2801 match(RegFlags); 2802 2803 format %{ "RFLAGS" %} 2804 interface(REG_INTER); 2805 %} 2806 2807 // Flags register, used as output of FLOATING POINT compare instructions 2808 operand rFlagsRegU() 2809 %{ 2810 constraint(ALLOC_IN_RC(int_flags)); 2811 match(RegFlags); 2812 2813 format %{ "RFLAGS_U" %} 2814 interface(REG_INTER); 2815 %} 2816 2817 operand rFlagsRegUCF() %{ 2818 constraint(ALLOC_IN_RC(int_flags)); 2819 match(RegFlags); 2820 predicate(false); 2821 2822 format %{ "RFLAGS_U_CF" %} 2823 interface(REG_INTER); 2824 %} 2825 2826 // Float register operands 2827 operand regF() %{ 2828 constraint(ALLOC_IN_RC(float_reg)); 2829 match(RegF); 2830 2831 format %{ %} 2832 interface(REG_INTER); 2833 %} 2834 2835 // Float register operands 2836 operand legRegF() %{ 2837 constraint(ALLOC_IN_RC(float_reg_legacy)); 2838 match(RegF); 2839 2840 format %{ %} 2841 interface(REG_INTER); 2842 %} 2843 2844 // Float register operands 2845 operand vlRegF() %{ 2846 constraint(ALLOC_IN_RC(float_reg_vl)); 2847 match(RegF); 2848 2849 format %{ %} 2850 interface(REG_INTER); 2851 %} 2852 2853 // Double register operands 2854 operand regD() %{ 2855 constraint(ALLOC_IN_RC(double_reg)); 2856 match(RegD); 2857 2858 format %{ %} 2859 interface(REG_INTER); 2860 %} 2861 2862 // Double register operands 2863 operand legRegD() %{ 2864 constraint(ALLOC_IN_RC(double_reg_legacy)); 2865 match(RegD); 2866 2867 format %{ %} 2868 interface(REG_INTER); 2869 %} 2870 2871 // Double register operands 2872 operand vlRegD() %{ 2873 constraint(ALLOC_IN_RC(double_reg_vl)); 2874 match(RegD); 2875 2876 format %{ %} 2877 interface(REG_INTER); 2878 %} 2879 2880 //----------Memory Operands---------------------------------------------------- 2881 // Direct Memory Operand 2882 // operand direct(immP addr) 2883 // %{ 2884 // match(addr); 2885 2886 // format %{ "[$addr]" %} 2887 // interface(MEMORY_INTER) %{ 2888 // base(0xFFFFFFFF); 2889 // index(0x4); 2890 // scale(0x0); 2891 // disp($addr); 2892 // %} 2893 // %} 2894 2895 // Indirect Memory Operand 2896 operand indirect(any_RegP reg) 2897 %{ 2898 constraint(ALLOC_IN_RC(ptr_reg)); 2899 match(reg); 2900 2901 format %{ "[$reg]" %} 2902 interface(MEMORY_INTER) %{ 2903 base($reg); 2904 index(0x4); 2905 scale(0x0); 2906 disp(0x0); 2907 %} 2908 %} 2909 2910 // Indirect Memory Plus Short Offset Operand 2911 operand indOffset8(any_RegP reg, immL8 off) 2912 %{ 2913 constraint(ALLOC_IN_RC(ptr_reg)); 2914 match(AddP reg off); 2915 2916 format %{ "[$reg + $off (8-bit)]" %} 2917 interface(MEMORY_INTER) %{ 2918 base($reg); 2919 index(0x4); 2920 scale(0x0); 2921 disp($off); 2922 %} 2923 %} 2924 2925 // Indirect Memory Plus Long Offset Operand 2926 operand indOffset32(any_RegP reg, immL32 off) 2927 %{ 2928 constraint(ALLOC_IN_RC(ptr_reg)); 2929 match(AddP reg off); 2930 2931 format %{ "[$reg + $off (32-bit)]" %} 2932 interface(MEMORY_INTER) %{ 2933 base($reg); 2934 index(0x4); 2935 scale(0x0); 2936 disp($off); 2937 %} 2938 %} 2939 2940 // Indirect Memory Plus Index Register Plus Offset Operand 2941 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2942 %{ 2943 constraint(ALLOC_IN_RC(ptr_reg)); 2944 match(AddP (AddP reg lreg) off); 2945 2946 op_cost(10); 2947 format %{"[$reg + $off + $lreg]" %} 2948 interface(MEMORY_INTER) %{ 2949 base($reg); 2950 index($lreg); 2951 scale(0x0); 2952 disp($off); 2953 %} 2954 %} 2955 2956 // Indirect Memory Plus Index Register Plus Offset Operand 2957 operand indIndex(any_RegP reg, rRegL lreg) 2958 %{ 2959 constraint(ALLOC_IN_RC(ptr_reg)); 2960 match(AddP reg lreg); 2961 2962 op_cost(10); 2963 format %{"[$reg + $lreg]" %} 2964 interface(MEMORY_INTER) %{ 2965 base($reg); 2966 index($lreg); 2967 scale(0x0); 2968 disp(0x0); 2969 %} 2970 %} 2971 2972 // Indirect Memory Times Scale Plus Index Register 2973 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2974 %{ 2975 constraint(ALLOC_IN_RC(ptr_reg)); 2976 match(AddP reg (LShiftL lreg scale)); 2977 2978 op_cost(10); 2979 format %{"[$reg + $lreg << $scale]" %} 2980 interface(MEMORY_INTER) %{ 2981 base($reg); 2982 index($lreg); 2983 scale($scale); 2984 disp(0x0); 2985 %} 2986 %} 2987 2988 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 2989 %{ 2990 constraint(ALLOC_IN_RC(ptr_reg)); 2991 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 2992 match(AddP reg (LShiftL (ConvI2L idx) scale)); 2993 2994 op_cost(10); 2995 format %{"[$reg + pos $idx << $scale]" %} 2996 interface(MEMORY_INTER) %{ 2997 base($reg); 2998 index($idx); 2999 scale($scale); 3000 disp(0x0); 3001 %} 3002 %} 3003 3004 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3005 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3006 %{ 3007 constraint(ALLOC_IN_RC(ptr_reg)); 3008 match(AddP (AddP reg (LShiftL lreg scale)) off); 3009 3010 op_cost(10); 3011 format %{"[$reg + $off + $lreg << $scale]" %} 3012 interface(MEMORY_INTER) %{ 3013 base($reg); 3014 index($lreg); 3015 scale($scale); 3016 disp($off); 3017 %} 3018 %} 3019 3020 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3021 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3022 %{ 3023 constraint(ALLOC_IN_RC(ptr_reg)); 3024 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3025 match(AddP (AddP reg (ConvI2L idx)) off); 3026 3027 op_cost(10); 3028 format %{"[$reg + $off + $idx]" %} 3029 interface(MEMORY_INTER) %{ 3030 base($reg); 3031 index($idx); 3032 scale(0x0); 3033 disp($off); 3034 %} 3035 %} 3036 3037 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3038 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3039 %{ 3040 constraint(ALLOC_IN_RC(ptr_reg)); 3041 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3042 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3043 3044 op_cost(10); 3045 format %{"[$reg + $off + $idx << $scale]" %} 3046 interface(MEMORY_INTER) %{ 3047 base($reg); 3048 index($idx); 3049 scale($scale); 3050 disp($off); 3051 %} 3052 %} 3053 3054 // Indirect Narrow Oop Plus Offset Operand 3055 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3056 // we can't free r12 even with CompressedOops::base() == nullptr. 3057 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3058 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3059 constraint(ALLOC_IN_RC(ptr_reg)); 3060 match(AddP (DecodeN reg) off); 3061 3062 op_cost(10); 3063 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3064 interface(MEMORY_INTER) %{ 3065 base(0xc); // R12 3066 index($reg); 3067 scale(0x3); 3068 disp($off); 3069 %} 3070 %} 3071 3072 // Indirect Memory Operand 3073 operand indirectNarrow(rRegN reg) 3074 %{ 3075 predicate(CompressedOops::shift() == 0); 3076 constraint(ALLOC_IN_RC(ptr_reg)); 3077 match(DecodeN reg); 3078 3079 format %{ "[$reg]" %} 3080 interface(MEMORY_INTER) %{ 3081 base($reg); 3082 index(0x4); 3083 scale(0x0); 3084 disp(0x0); 3085 %} 3086 %} 3087 3088 // Indirect Memory Plus Short Offset Operand 3089 operand indOffset8Narrow(rRegN reg, immL8 off) 3090 %{ 3091 predicate(CompressedOops::shift() == 0); 3092 constraint(ALLOC_IN_RC(ptr_reg)); 3093 match(AddP (DecodeN reg) off); 3094 3095 format %{ "[$reg + $off (8-bit)]" %} 3096 interface(MEMORY_INTER) %{ 3097 base($reg); 3098 index(0x4); 3099 scale(0x0); 3100 disp($off); 3101 %} 3102 %} 3103 3104 // Indirect Memory Plus Long Offset Operand 3105 operand indOffset32Narrow(rRegN reg, immL32 off) 3106 %{ 3107 predicate(CompressedOops::shift() == 0); 3108 constraint(ALLOC_IN_RC(ptr_reg)); 3109 match(AddP (DecodeN reg) off); 3110 3111 format %{ "[$reg + $off (32-bit)]" %} 3112 interface(MEMORY_INTER) %{ 3113 base($reg); 3114 index(0x4); 3115 scale(0x0); 3116 disp($off); 3117 %} 3118 %} 3119 3120 // Indirect Memory Plus Index Register Plus Offset Operand 3121 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3122 %{ 3123 predicate(CompressedOops::shift() == 0); 3124 constraint(ALLOC_IN_RC(ptr_reg)); 3125 match(AddP (AddP (DecodeN reg) lreg) off); 3126 3127 op_cost(10); 3128 format %{"[$reg + $off + $lreg]" %} 3129 interface(MEMORY_INTER) %{ 3130 base($reg); 3131 index($lreg); 3132 scale(0x0); 3133 disp($off); 3134 %} 3135 %} 3136 3137 // Indirect Memory Plus Index Register Plus Offset Operand 3138 operand indIndexNarrow(rRegN reg, rRegL lreg) 3139 %{ 3140 predicate(CompressedOops::shift() == 0); 3141 constraint(ALLOC_IN_RC(ptr_reg)); 3142 match(AddP (DecodeN reg) lreg); 3143 3144 op_cost(10); 3145 format %{"[$reg + $lreg]" %} 3146 interface(MEMORY_INTER) %{ 3147 base($reg); 3148 index($lreg); 3149 scale(0x0); 3150 disp(0x0); 3151 %} 3152 %} 3153 3154 // Indirect Memory Times Scale Plus Index Register 3155 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3156 %{ 3157 predicate(CompressedOops::shift() == 0); 3158 constraint(ALLOC_IN_RC(ptr_reg)); 3159 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3160 3161 op_cost(10); 3162 format %{"[$reg + $lreg << $scale]" %} 3163 interface(MEMORY_INTER) %{ 3164 base($reg); 3165 index($lreg); 3166 scale($scale); 3167 disp(0x0); 3168 %} 3169 %} 3170 3171 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3172 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3173 %{ 3174 predicate(CompressedOops::shift() == 0); 3175 constraint(ALLOC_IN_RC(ptr_reg)); 3176 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3177 3178 op_cost(10); 3179 format %{"[$reg + $off + $lreg << $scale]" %} 3180 interface(MEMORY_INTER) %{ 3181 base($reg); 3182 index($lreg); 3183 scale($scale); 3184 disp($off); 3185 %} 3186 %} 3187 3188 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3189 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3190 %{ 3191 constraint(ALLOC_IN_RC(ptr_reg)); 3192 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3193 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3194 3195 op_cost(10); 3196 format %{"[$reg + $off + $idx]" %} 3197 interface(MEMORY_INTER) %{ 3198 base($reg); 3199 index($idx); 3200 scale(0x0); 3201 disp($off); 3202 %} 3203 %} 3204 3205 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3206 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3207 %{ 3208 constraint(ALLOC_IN_RC(ptr_reg)); 3209 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3210 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3211 3212 op_cost(10); 3213 format %{"[$reg + $off + $idx << $scale]" %} 3214 interface(MEMORY_INTER) %{ 3215 base($reg); 3216 index($idx); 3217 scale($scale); 3218 disp($off); 3219 %} 3220 %} 3221 3222 //----------Special Memory Operands-------------------------------------------- 3223 // Stack Slot Operand - This operand is used for loading and storing temporary 3224 // values on the stack where a match requires a value to 3225 // flow through memory. 3226 operand stackSlotP(sRegP reg) 3227 %{ 3228 constraint(ALLOC_IN_RC(stack_slots)); 3229 // No match rule because this operand is only generated in matching 3230 3231 format %{ "[$reg]" %} 3232 interface(MEMORY_INTER) %{ 3233 base(0x4); // RSP 3234 index(0x4); // No Index 3235 scale(0x0); // No Scale 3236 disp($reg); // Stack Offset 3237 %} 3238 %} 3239 3240 operand stackSlotI(sRegI reg) 3241 %{ 3242 constraint(ALLOC_IN_RC(stack_slots)); 3243 // No match rule because this operand is only generated in matching 3244 3245 format %{ "[$reg]" %} 3246 interface(MEMORY_INTER) %{ 3247 base(0x4); // RSP 3248 index(0x4); // No Index 3249 scale(0x0); // No Scale 3250 disp($reg); // Stack Offset 3251 %} 3252 %} 3253 3254 operand stackSlotF(sRegF reg) 3255 %{ 3256 constraint(ALLOC_IN_RC(stack_slots)); 3257 // No match rule because this operand is only generated in matching 3258 3259 format %{ "[$reg]" %} 3260 interface(MEMORY_INTER) %{ 3261 base(0x4); // RSP 3262 index(0x4); // No Index 3263 scale(0x0); // No Scale 3264 disp($reg); // Stack Offset 3265 %} 3266 %} 3267 3268 operand stackSlotD(sRegD reg) 3269 %{ 3270 constraint(ALLOC_IN_RC(stack_slots)); 3271 // No match rule because this operand is only generated in matching 3272 3273 format %{ "[$reg]" %} 3274 interface(MEMORY_INTER) %{ 3275 base(0x4); // RSP 3276 index(0x4); // No Index 3277 scale(0x0); // No Scale 3278 disp($reg); // Stack Offset 3279 %} 3280 %} 3281 operand stackSlotL(sRegL reg) 3282 %{ 3283 constraint(ALLOC_IN_RC(stack_slots)); 3284 // No match rule because this operand is only generated in matching 3285 3286 format %{ "[$reg]" %} 3287 interface(MEMORY_INTER) %{ 3288 base(0x4); // RSP 3289 index(0x4); // No Index 3290 scale(0x0); // No Scale 3291 disp($reg); // Stack Offset 3292 %} 3293 %} 3294 3295 //----------Conditional Branch Operands---------------------------------------- 3296 // Comparison Op - This is the operation of the comparison, and is limited to 3297 // the following set of codes: 3298 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3299 // 3300 // Other attributes of the comparison, such as unsignedness, are specified 3301 // by the comparison instruction that sets a condition code flags register. 3302 // That result is represented by a flags operand whose subtype is appropriate 3303 // to the unsignedness (etc.) of the comparison. 3304 // 3305 // Later, the instruction which matches both the Comparison Op (a Bool) and 3306 // the flags (produced by the Cmp) specifies the coding of the comparison op 3307 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3308 3309 // Comparison Code 3310 operand cmpOp() 3311 %{ 3312 match(Bool); 3313 3314 format %{ "" %} 3315 interface(COND_INTER) %{ 3316 equal(0x4, "e"); 3317 not_equal(0x5, "ne"); 3318 less(0xC, "l"); 3319 greater_equal(0xD, "ge"); 3320 less_equal(0xE, "le"); 3321 greater(0xF, "g"); 3322 overflow(0x0, "o"); 3323 no_overflow(0x1, "no"); 3324 %} 3325 %} 3326 3327 // Comparison Code, unsigned compare. Used by FP also, with 3328 // C2 (unordered) turned into GT or LT already. The other bits 3329 // C0 and C3 are turned into Carry & Zero flags. 3330 operand cmpOpU() 3331 %{ 3332 match(Bool); 3333 3334 format %{ "" %} 3335 interface(COND_INTER) %{ 3336 equal(0x4, "e"); 3337 not_equal(0x5, "ne"); 3338 less(0x2, "b"); 3339 greater_equal(0x3, "ae"); 3340 less_equal(0x6, "be"); 3341 greater(0x7, "a"); 3342 overflow(0x0, "o"); 3343 no_overflow(0x1, "no"); 3344 %} 3345 %} 3346 3347 3348 // Floating comparisons that don't require any fixup for the unordered case, 3349 // If both inputs of the comparison are the same, ZF is always set so we 3350 // don't need to use cmpOpUCF2 for eq/ne 3351 operand cmpOpUCF() %{ 3352 match(Bool); 3353 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3354 n->as_Bool()->_test._test == BoolTest::ge || 3355 n->as_Bool()->_test._test == BoolTest::le || 3356 n->as_Bool()->_test._test == BoolTest::gt || 3357 n->in(1)->in(1) == n->in(1)->in(2)); 3358 format %{ "" %} 3359 interface(COND_INTER) %{ 3360 equal(0xb, "np"); 3361 not_equal(0xa, "p"); 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 can be fixed up with extra conditional jumps 3373 operand cmpOpUCF2() %{ 3374 match(Bool); 3375 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3376 n->as_Bool()->_test._test == BoolTest::eq) && 3377 n->in(1)->in(1) != n->in(1)->in(2)); 3378 format %{ "" %} 3379 interface(COND_INTER) %{ 3380 equal(0x4, "e"); 3381 not_equal(0x5, "ne"); 3382 less(0x2, "b"); 3383 greater_equal(0x3, "ae"); 3384 less_equal(0x6, "be"); 3385 greater(0x7, "a"); 3386 overflow(0x0, "o"); 3387 no_overflow(0x1, "no"); 3388 %} 3389 %} 3390 3391 //----------OPERAND CLASSES---------------------------------------------------- 3392 // Operand Classes are groups of operands that are used as to simplify 3393 // instruction definitions by not requiring the AD writer to specify separate 3394 // instructions for every form of operand when the instruction accepts 3395 // multiple operand types with the same basic encoding and format. The classic 3396 // case of this is memory operands. 3397 3398 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3399 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3400 indCompressedOopOffset, 3401 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3402 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3403 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3404 3405 //----------PIPELINE----------------------------------------------------------- 3406 // Rules which define the behavior of the target architectures pipeline. 3407 pipeline %{ 3408 3409 //----------ATTRIBUTES--------------------------------------------------------- 3410 attributes %{ 3411 variable_size_instructions; // Fixed size instructions 3412 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3413 instruction_unit_size = 1; // An instruction is 1 bytes long 3414 instruction_fetch_unit_size = 16; // The processor fetches one line 3415 instruction_fetch_units = 1; // of 16 bytes 3416 3417 // List of nop instructions 3418 nops( MachNop ); 3419 %} 3420 3421 //----------RESOURCES---------------------------------------------------------- 3422 // Resources are the functional units available to the machine 3423 3424 // Generic P2/P3 pipeline 3425 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3426 // 3 instructions decoded per cycle. 3427 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3428 // 3 ALU op, only ALU0 handles mul instructions. 3429 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3430 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3431 BR, FPU, 3432 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3433 3434 //----------PIPELINE DESCRIPTION----------------------------------------------- 3435 // Pipeline Description specifies the stages in the machine's pipeline 3436 3437 // Generic P2/P3 pipeline 3438 pipe_desc(S0, S1, S2, S3, S4, S5); 3439 3440 //----------PIPELINE CLASSES--------------------------------------------------- 3441 // Pipeline Classes describe the stages in which input and output are 3442 // referenced by the hardware pipeline. 3443 3444 // Naming convention: ialu or fpu 3445 // Then: _reg 3446 // Then: _reg if there is a 2nd register 3447 // Then: _long if it's a pair of instructions implementing a long 3448 // Then: _fat if it requires the big decoder 3449 // Or: _mem if it requires the big decoder and a memory unit. 3450 3451 // Integer ALU reg operation 3452 pipe_class ialu_reg(rRegI dst) 3453 %{ 3454 single_instruction; 3455 dst : S4(write); 3456 dst : S3(read); 3457 DECODE : S0; // any decoder 3458 ALU : S3; // any alu 3459 %} 3460 3461 // Long ALU reg operation 3462 pipe_class ialu_reg_long(rRegL dst) 3463 %{ 3464 instruction_count(2); 3465 dst : S4(write); 3466 dst : S3(read); 3467 DECODE : S0(2); // any 2 decoders 3468 ALU : S3(2); // both alus 3469 %} 3470 3471 // Integer ALU reg operation using big decoder 3472 pipe_class ialu_reg_fat(rRegI dst) 3473 %{ 3474 single_instruction; 3475 dst : S4(write); 3476 dst : S3(read); 3477 D0 : S0; // big decoder only 3478 ALU : S3; // any alu 3479 %} 3480 3481 // Integer ALU reg-reg operation 3482 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3483 %{ 3484 single_instruction; 3485 dst : S4(write); 3486 src : S3(read); 3487 DECODE : S0; // any decoder 3488 ALU : S3; // any alu 3489 %} 3490 3491 // Integer ALU reg-reg operation 3492 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3493 %{ 3494 single_instruction; 3495 dst : S4(write); 3496 src : S3(read); 3497 D0 : S0; // big decoder only 3498 ALU : S3; // any alu 3499 %} 3500 3501 // Integer ALU reg-mem operation 3502 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3503 %{ 3504 single_instruction; 3505 dst : S5(write); 3506 mem : S3(read); 3507 D0 : S0; // big decoder only 3508 ALU : S4; // any alu 3509 MEM : S3; // any mem 3510 %} 3511 3512 // Integer mem operation (prefetch) 3513 pipe_class ialu_mem(memory mem) 3514 %{ 3515 single_instruction; 3516 mem : S3(read); 3517 D0 : S0; // big decoder only 3518 MEM : S3; // any mem 3519 %} 3520 3521 // Integer Store to Memory 3522 pipe_class ialu_mem_reg(memory mem, rRegI src) 3523 %{ 3524 single_instruction; 3525 mem : S3(read); 3526 src : S5(read); 3527 D0 : S0; // big decoder only 3528 ALU : S4; // any alu 3529 MEM : S3; 3530 %} 3531 3532 // // Long Store to Memory 3533 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3534 // %{ 3535 // instruction_count(2); 3536 // mem : S3(read); 3537 // src : S5(read); 3538 // D0 : S0(2); // big decoder only; twice 3539 // ALU : S4(2); // any 2 alus 3540 // MEM : S3(2); // Both mems 3541 // %} 3542 3543 // Integer Store to Memory 3544 pipe_class ialu_mem_imm(memory mem) 3545 %{ 3546 single_instruction; 3547 mem : S3(read); 3548 D0 : S0; // big decoder only 3549 ALU : S4; // any alu 3550 MEM : S3; 3551 %} 3552 3553 // Integer ALU0 reg-reg operation 3554 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3555 %{ 3556 single_instruction; 3557 dst : S4(write); 3558 src : S3(read); 3559 D0 : S0; // Big decoder only 3560 ALU0 : S3; // only alu0 3561 %} 3562 3563 // Integer ALU0 reg-mem operation 3564 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3565 %{ 3566 single_instruction; 3567 dst : S5(write); 3568 mem : S3(read); 3569 D0 : S0; // big decoder only 3570 ALU0 : S4; // ALU0 only 3571 MEM : S3; // any mem 3572 %} 3573 3574 // Integer ALU reg-reg operation 3575 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3576 %{ 3577 single_instruction; 3578 cr : S4(write); 3579 src1 : S3(read); 3580 src2 : S3(read); 3581 DECODE : S0; // any decoder 3582 ALU : S3; // any alu 3583 %} 3584 3585 // Integer ALU reg-imm operation 3586 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3587 %{ 3588 single_instruction; 3589 cr : S4(write); 3590 src1 : S3(read); 3591 DECODE : S0; // any decoder 3592 ALU : S3; // any alu 3593 %} 3594 3595 // Integer ALU reg-mem operation 3596 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3597 %{ 3598 single_instruction; 3599 cr : S4(write); 3600 src1 : S3(read); 3601 src2 : S3(read); 3602 D0 : S0; // big decoder only 3603 ALU : S4; // any alu 3604 MEM : S3; 3605 %} 3606 3607 // Conditional move reg-reg 3608 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3609 %{ 3610 instruction_count(4); 3611 y : S4(read); 3612 q : S3(read); 3613 p : S3(read); 3614 DECODE : S0(4); // any decoder 3615 %} 3616 3617 // Conditional move reg-reg 3618 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3619 %{ 3620 single_instruction; 3621 dst : S4(write); 3622 src : S3(read); 3623 cr : S3(read); 3624 DECODE : S0; // any decoder 3625 %} 3626 3627 // Conditional move reg-mem 3628 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3629 %{ 3630 single_instruction; 3631 dst : S4(write); 3632 src : S3(read); 3633 cr : S3(read); 3634 DECODE : S0; // any decoder 3635 MEM : S3; 3636 %} 3637 3638 // Conditional move reg-reg long 3639 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3640 %{ 3641 single_instruction; 3642 dst : S4(write); 3643 src : S3(read); 3644 cr : S3(read); 3645 DECODE : S0(2); // any 2 decoders 3646 %} 3647 3648 // Float reg-reg operation 3649 pipe_class fpu_reg(regD dst) 3650 %{ 3651 instruction_count(2); 3652 dst : S3(read); 3653 DECODE : S0(2); // any 2 decoders 3654 FPU : S3; 3655 %} 3656 3657 // Float reg-reg operation 3658 pipe_class fpu_reg_reg(regD dst, regD src) 3659 %{ 3660 instruction_count(2); 3661 dst : S4(write); 3662 src : S3(read); 3663 DECODE : S0(2); // any 2 decoders 3664 FPU : S3; 3665 %} 3666 3667 // Float reg-reg operation 3668 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3669 %{ 3670 instruction_count(3); 3671 dst : S4(write); 3672 src1 : S3(read); 3673 src2 : S3(read); 3674 DECODE : S0(3); // any 3 decoders 3675 FPU : S3(2); 3676 %} 3677 3678 // Float reg-reg operation 3679 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3680 %{ 3681 instruction_count(4); 3682 dst : S4(write); 3683 src1 : S3(read); 3684 src2 : S3(read); 3685 src3 : S3(read); 3686 DECODE : S0(4); // any 3 decoders 3687 FPU : S3(2); 3688 %} 3689 3690 // Float reg-reg operation 3691 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3692 %{ 3693 instruction_count(4); 3694 dst : S4(write); 3695 src1 : S3(read); 3696 src2 : S3(read); 3697 src3 : S3(read); 3698 DECODE : S1(3); // any 3 decoders 3699 D0 : S0; // Big decoder only 3700 FPU : S3(2); 3701 MEM : S3; 3702 %} 3703 3704 // Float reg-mem operation 3705 pipe_class fpu_reg_mem(regD dst, memory mem) 3706 %{ 3707 instruction_count(2); 3708 dst : S5(write); 3709 mem : S3(read); 3710 D0 : S0; // big decoder only 3711 DECODE : S1; // any decoder for FPU POP 3712 FPU : S4; 3713 MEM : S3; // any mem 3714 %} 3715 3716 // Float reg-mem operation 3717 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3718 %{ 3719 instruction_count(3); 3720 dst : S5(write); 3721 src1 : S3(read); 3722 mem : S3(read); 3723 D0 : S0; // big decoder only 3724 DECODE : S1(2); // any decoder for FPU POP 3725 FPU : S4; 3726 MEM : S3; // any mem 3727 %} 3728 3729 // Float mem-reg operation 3730 pipe_class fpu_mem_reg(memory mem, regD src) 3731 %{ 3732 instruction_count(2); 3733 src : S5(read); 3734 mem : S3(read); 3735 DECODE : S0; // any decoder for FPU PUSH 3736 D0 : S1; // big decoder only 3737 FPU : S4; 3738 MEM : S3; // any mem 3739 %} 3740 3741 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3742 %{ 3743 instruction_count(3); 3744 src1 : S3(read); 3745 src2 : S3(read); 3746 mem : S3(read); 3747 DECODE : S0(2); // any decoder for FPU PUSH 3748 D0 : S1; // big decoder only 3749 FPU : S4; 3750 MEM : S3; // any mem 3751 %} 3752 3753 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3754 %{ 3755 instruction_count(3); 3756 src1 : S3(read); 3757 src2 : S3(read); 3758 mem : S4(read); 3759 DECODE : S0; // any decoder for FPU PUSH 3760 D0 : S0(2); // big decoder only 3761 FPU : S4; 3762 MEM : S3(2); // any mem 3763 %} 3764 3765 pipe_class fpu_mem_mem(memory dst, memory src1) 3766 %{ 3767 instruction_count(2); 3768 src1 : S3(read); 3769 dst : S4(read); 3770 D0 : S0(2); // big decoder only 3771 MEM : S3(2); // any mem 3772 %} 3773 3774 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3775 %{ 3776 instruction_count(3); 3777 src1 : S3(read); 3778 src2 : S3(read); 3779 dst : S4(read); 3780 D0 : S0(3); // big decoder only 3781 FPU : S4; 3782 MEM : S3(3); // any mem 3783 %} 3784 3785 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3786 %{ 3787 instruction_count(3); 3788 src1 : S4(read); 3789 mem : S4(read); 3790 DECODE : S0; // any decoder for FPU PUSH 3791 D0 : S0(2); // big decoder only 3792 FPU : S4; 3793 MEM : S3(2); // any mem 3794 %} 3795 3796 // Float load constant 3797 pipe_class fpu_reg_con(regD dst) 3798 %{ 3799 instruction_count(2); 3800 dst : S5(write); 3801 D0 : S0; // big decoder only for the load 3802 DECODE : S1; // any decoder for FPU POP 3803 FPU : S4; 3804 MEM : S3; // any mem 3805 %} 3806 3807 // Float load constant 3808 pipe_class fpu_reg_reg_con(regD dst, regD src) 3809 %{ 3810 instruction_count(3); 3811 dst : S5(write); 3812 src : S3(read); 3813 D0 : S0; // big decoder only for the load 3814 DECODE : S1(2); // any decoder for FPU POP 3815 FPU : S4; 3816 MEM : S3; // any mem 3817 %} 3818 3819 // UnConditional branch 3820 pipe_class pipe_jmp(label labl) 3821 %{ 3822 single_instruction; 3823 BR : S3; 3824 %} 3825 3826 // Conditional branch 3827 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3828 %{ 3829 single_instruction; 3830 cr : S1(read); 3831 BR : S3; 3832 %} 3833 3834 // Allocation idiom 3835 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3836 %{ 3837 instruction_count(1); force_serialization; 3838 fixed_latency(6); 3839 heap_ptr : S3(read); 3840 DECODE : S0(3); 3841 D0 : S2; 3842 MEM : S3; 3843 ALU : S3(2); 3844 dst : S5(write); 3845 BR : S5; 3846 %} 3847 3848 // Generic big/slow expanded idiom 3849 pipe_class pipe_slow() 3850 %{ 3851 instruction_count(10); multiple_bundles; force_serialization; 3852 fixed_latency(100); 3853 D0 : S0(2); 3854 MEM : S3(2); 3855 %} 3856 3857 // The real do-nothing guy 3858 pipe_class empty() 3859 %{ 3860 instruction_count(0); 3861 %} 3862 3863 // Define the class for the Nop node 3864 define 3865 %{ 3866 MachNop = empty; 3867 %} 3868 3869 %} 3870 3871 //----------INSTRUCTIONS------------------------------------------------------- 3872 // 3873 // match -- States which machine-independent subtree may be replaced 3874 // by this instruction. 3875 // ins_cost -- The estimated cost of this instruction is used by instruction 3876 // selection to identify a minimum cost tree of machine 3877 // instructions that matches a tree of machine-independent 3878 // instructions. 3879 // format -- A string providing the disassembly for this instruction. 3880 // The value of an instruction's operand may be inserted 3881 // by referring to it with a '$' prefix. 3882 // opcode -- Three instruction opcodes may be provided. These are referred 3883 // to within an encode class as $primary, $secondary, and $tertiary 3884 // rrspectively. The primary opcode is commonly used to 3885 // indicate the type of machine instruction, while secondary 3886 // and tertiary are often used for prefix options or addressing 3887 // modes. 3888 // ins_encode -- A list of encode classes with parameters. The encode class 3889 // name must have been defined in an 'enc_class' specification 3890 // in the encode section of the architecture description. 3891 3892 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3893 // Load Float 3894 instruct MoveF2VL(vlRegF dst, regF src) %{ 3895 match(Set dst src); 3896 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3897 ins_encode %{ 3898 ShouldNotReachHere(); 3899 %} 3900 ins_pipe( fpu_reg_reg ); 3901 %} 3902 3903 // Load Float 3904 instruct MoveF2LEG(legRegF dst, regF src) %{ 3905 match(Set dst src); 3906 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3907 ins_encode %{ 3908 ShouldNotReachHere(); 3909 %} 3910 ins_pipe( fpu_reg_reg ); 3911 %} 3912 3913 // Load Float 3914 instruct MoveVL2F(regF dst, vlRegF src) %{ 3915 match(Set dst src); 3916 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3917 ins_encode %{ 3918 ShouldNotReachHere(); 3919 %} 3920 ins_pipe( fpu_reg_reg ); 3921 %} 3922 3923 // Load Float 3924 instruct MoveLEG2F(regF dst, legRegF src) %{ 3925 match(Set dst src); 3926 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3927 ins_encode %{ 3928 ShouldNotReachHere(); 3929 %} 3930 ins_pipe( fpu_reg_reg ); 3931 %} 3932 3933 // Load Double 3934 instruct MoveD2VL(vlRegD dst, regD src) %{ 3935 match(Set dst src); 3936 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3937 ins_encode %{ 3938 ShouldNotReachHere(); 3939 %} 3940 ins_pipe( fpu_reg_reg ); 3941 %} 3942 3943 // Load Double 3944 instruct MoveD2LEG(legRegD dst, regD src) %{ 3945 match(Set dst src); 3946 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3947 ins_encode %{ 3948 ShouldNotReachHere(); 3949 %} 3950 ins_pipe( fpu_reg_reg ); 3951 %} 3952 3953 // Load Double 3954 instruct MoveVL2D(regD dst, vlRegD src) %{ 3955 match(Set dst src); 3956 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3957 ins_encode %{ 3958 ShouldNotReachHere(); 3959 %} 3960 ins_pipe( fpu_reg_reg ); 3961 %} 3962 3963 // Load Double 3964 instruct MoveLEG2D(regD dst, legRegD src) %{ 3965 match(Set dst src); 3966 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3967 ins_encode %{ 3968 ShouldNotReachHere(); 3969 %} 3970 ins_pipe( fpu_reg_reg ); 3971 %} 3972 3973 //----------Load/Store/Move Instructions--------------------------------------- 3974 //----------Load Instructions-------------------------------------------------- 3975 3976 // Load Byte (8 bit signed) 3977 instruct loadB(rRegI dst, memory mem) 3978 %{ 3979 match(Set dst (LoadB mem)); 3980 3981 ins_cost(125); 3982 format %{ "movsbl $dst, $mem\t# byte" %} 3983 3984 ins_encode %{ 3985 __ movsbl($dst$$Register, $mem$$Address); 3986 %} 3987 3988 ins_pipe(ialu_reg_mem); 3989 %} 3990 3991 // Load Byte (8 bit signed) into Long Register 3992 instruct loadB2L(rRegL dst, memory mem) 3993 %{ 3994 match(Set dst (ConvI2L (LoadB mem))); 3995 3996 ins_cost(125); 3997 format %{ "movsbq $dst, $mem\t# byte -> long" %} 3998 3999 ins_encode %{ 4000 __ movsbq($dst$$Register, $mem$$Address); 4001 %} 4002 4003 ins_pipe(ialu_reg_mem); 4004 %} 4005 4006 // Load Unsigned Byte (8 bit UNsigned) 4007 instruct loadUB(rRegI dst, memory mem) 4008 %{ 4009 match(Set dst (LoadUB mem)); 4010 4011 ins_cost(125); 4012 format %{ "movzbl $dst, $mem\t# ubyte" %} 4013 4014 ins_encode %{ 4015 __ movzbl($dst$$Register, $mem$$Address); 4016 %} 4017 4018 ins_pipe(ialu_reg_mem); 4019 %} 4020 4021 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4022 instruct loadUB2L(rRegL dst, memory mem) 4023 %{ 4024 match(Set dst (ConvI2L (LoadUB mem))); 4025 4026 ins_cost(125); 4027 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4028 4029 ins_encode %{ 4030 __ movzbq($dst$$Register, $mem$$Address); 4031 %} 4032 4033 ins_pipe(ialu_reg_mem); 4034 %} 4035 4036 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4037 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4038 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4039 effect(KILL cr); 4040 4041 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4042 "andl $dst, right_n_bits($mask, 8)" %} 4043 ins_encode %{ 4044 Register Rdst = $dst$$Register; 4045 __ movzbq(Rdst, $mem$$Address); 4046 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4047 %} 4048 ins_pipe(ialu_reg_mem); 4049 %} 4050 4051 // Load Short (16 bit signed) 4052 instruct loadS(rRegI dst, memory mem) 4053 %{ 4054 match(Set dst (LoadS mem)); 4055 4056 ins_cost(125); 4057 format %{ "movswl $dst, $mem\t# short" %} 4058 4059 ins_encode %{ 4060 __ movswl($dst$$Register, $mem$$Address); 4061 %} 4062 4063 ins_pipe(ialu_reg_mem); 4064 %} 4065 4066 // Load Short (16 bit signed) to Byte (8 bit signed) 4067 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4068 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4069 4070 ins_cost(125); 4071 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4072 ins_encode %{ 4073 __ movsbl($dst$$Register, $mem$$Address); 4074 %} 4075 ins_pipe(ialu_reg_mem); 4076 %} 4077 4078 // Load Short (16 bit signed) into Long Register 4079 instruct loadS2L(rRegL dst, memory mem) 4080 %{ 4081 match(Set dst (ConvI2L (LoadS mem))); 4082 4083 ins_cost(125); 4084 format %{ "movswq $dst, $mem\t# short -> long" %} 4085 4086 ins_encode %{ 4087 __ movswq($dst$$Register, $mem$$Address); 4088 %} 4089 4090 ins_pipe(ialu_reg_mem); 4091 %} 4092 4093 // Load Unsigned Short/Char (16 bit UNsigned) 4094 instruct loadUS(rRegI dst, memory mem) 4095 %{ 4096 match(Set dst (LoadUS mem)); 4097 4098 ins_cost(125); 4099 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4100 4101 ins_encode %{ 4102 __ movzwl($dst$$Register, $mem$$Address); 4103 %} 4104 4105 ins_pipe(ialu_reg_mem); 4106 %} 4107 4108 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4109 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4110 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4111 4112 ins_cost(125); 4113 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4114 ins_encode %{ 4115 __ movsbl($dst$$Register, $mem$$Address); 4116 %} 4117 ins_pipe(ialu_reg_mem); 4118 %} 4119 4120 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4121 instruct loadUS2L(rRegL dst, memory mem) 4122 %{ 4123 match(Set dst (ConvI2L (LoadUS mem))); 4124 4125 ins_cost(125); 4126 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4127 4128 ins_encode %{ 4129 __ movzwq($dst$$Register, $mem$$Address); 4130 %} 4131 4132 ins_pipe(ialu_reg_mem); 4133 %} 4134 4135 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4136 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4137 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4138 4139 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4140 ins_encode %{ 4141 __ movzbq($dst$$Register, $mem$$Address); 4142 %} 4143 ins_pipe(ialu_reg_mem); 4144 %} 4145 4146 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4147 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4148 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4149 effect(KILL cr); 4150 4151 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4152 "andl $dst, right_n_bits($mask, 16)" %} 4153 ins_encode %{ 4154 Register Rdst = $dst$$Register; 4155 __ movzwq(Rdst, $mem$$Address); 4156 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4157 %} 4158 ins_pipe(ialu_reg_mem); 4159 %} 4160 4161 // Load Integer 4162 instruct loadI(rRegI dst, memory mem) 4163 %{ 4164 match(Set dst (LoadI mem)); 4165 4166 ins_cost(125); 4167 format %{ "movl $dst, $mem\t# int" %} 4168 4169 ins_encode %{ 4170 __ movl($dst$$Register, $mem$$Address); 4171 %} 4172 4173 ins_pipe(ialu_reg_mem); 4174 %} 4175 4176 // Load Integer (32 bit signed) to Byte (8 bit signed) 4177 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4178 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4179 4180 ins_cost(125); 4181 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4182 ins_encode %{ 4183 __ movsbl($dst$$Register, $mem$$Address); 4184 %} 4185 ins_pipe(ialu_reg_mem); 4186 %} 4187 4188 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4189 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4190 match(Set dst (AndI (LoadI mem) mask)); 4191 4192 ins_cost(125); 4193 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4194 ins_encode %{ 4195 __ movzbl($dst$$Register, $mem$$Address); 4196 %} 4197 ins_pipe(ialu_reg_mem); 4198 %} 4199 4200 // Load Integer (32 bit signed) to Short (16 bit signed) 4201 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4202 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4203 4204 ins_cost(125); 4205 format %{ "movswl $dst, $mem\t# int -> short" %} 4206 ins_encode %{ 4207 __ movswl($dst$$Register, $mem$$Address); 4208 %} 4209 ins_pipe(ialu_reg_mem); 4210 %} 4211 4212 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4213 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4214 match(Set dst (AndI (LoadI mem) mask)); 4215 4216 ins_cost(125); 4217 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4218 ins_encode %{ 4219 __ movzwl($dst$$Register, $mem$$Address); 4220 %} 4221 ins_pipe(ialu_reg_mem); 4222 %} 4223 4224 // Load Integer into Long Register 4225 instruct loadI2L(rRegL dst, memory mem) 4226 %{ 4227 match(Set dst (ConvI2L (LoadI mem))); 4228 4229 ins_cost(125); 4230 format %{ "movslq $dst, $mem\t# int -> long" %} 4231 4232 ins_encode %{ 4233 __ movslq($dst$$Register, $mem$$Address); 4234 %} 4235 4236 ins_pipe(ialu_reg_mem); 4237 %} 4238 4239 // Load Integer with mask 0xFF into Long Register 4240 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4241 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4242 4243 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4244 ins_encode %{ 4245 __ movzbq($dst$$Register, $mem$$Address); 4246 %} 4247 ins_pipe(ialu_reg_mem); 4248 %} 4249 4250 // Load Integer with mask 0xFFFF into Long Register 4251 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4252 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4253 4254 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4255 ins_encode %{ 4256 __ movzwq($dst$$Register, $mem$$Address); 4257 %} 4258 ins_pipe(ialu_reg_mem); 4259 %} 4260 4261 // Load Integer with a 31-bit mask into Long Register 4262 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4263 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4264 effect(KILL cr); 4265 4266 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4267 "andl $dst, $mask" %} 4268 ins_encode %{ 4269 Register Rdst = $dst$$Register; 4270 __ movl(Rdst, $mem$$Address); 4271 __ andl(Rdst, $mask$$constant); 4272 %} 4273 ins_pipe(ialu_reg_mem); 4274 %} 4275 4276 // Load Unsigned Integer into Long Register 4277 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4278 %{ 4279 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4280 4281 ins_cost(125); 4282 format %{ "movl $dst, $mem\t# uint -> long" %} 4283 4284 ins_encode %{ 4285 __ movl($dst$$Register, $mem$$Address); 4286 %} 4287 4288 ins_pipe(ialu_reg_mem); 4289 %} 4290 4291 // Load Long 4292 instruct loadL(rRegL dst, memory mem) 4293 %{ 4294 match(Set dst (LoadL mem)); 4295 4296 ins_cost(125); 4297 format %{ "movq $dst, $mem\t# long" %} 4298 4299 ins_encode %{ 4300 __ movq($dst$$Register, $mem$$Address); 4301 %} 4302 4303 ins_pipe(ialu_reg_mem); // XXX 4304 %} 4305 4306 // Load Range 4307 instruct loadRange(rRegI dst, memory mem) 4308 %{ 4309 match(Set dst (LoadRange mem)); 4310 4311 ins_cost(125); // XXX 4312 format %{ "movl $dst, $mem\t# range" %} 4313 ins_encode %{ 4314 __ movl($dst$$Register, $mem$$Address); 4315 %} 4316 ins_pipe(ialu_reg_mem); 4317 %} 4318 4319 // Load Pointer 4320 instruct loadP(rRegP dst, memory mem) 4321 %{ 4322 match(Set dst (LoadP mem)); 4323 predicate(n->as_Load()->barrier_data() == 0); 4324 4325 ins_cost(125); // XXX 4326 format %{ "movq $dst, $mem\t# ptr" %} 4327 ins_encode %{ 4328 __ movq($dst$$Register, $mem$$Address); 4329 %} 4330 ins_pipe(ialu_reg_mem); // XXX 4331 %} 4332 4333 // Load Compressed Pointer 4334 instruct loadN(rRegN dst, memory mem) 4335 %{ 4336 predicate(n->as_Load()->barrier_data() == 0); 4337 match(Set dst (LoadN mem)); 4338 4339 ins_cost(125); // XXX 4340 format %{ "movl $dst, $mem\t# compressed ptr" %} 4341 ins_encode %{ 4342 __ movl($dst$$Register, $mem$$Address); 4343 %} 4344 ins_pipe(ialu_reg_mem); // XXX 4345 %} 4346 4347 4348 // Load Klass Pointer 4349 instruct loadKlass(rRegP dst, memory mem) 4350 %{ 4351 match(Set dst (LoadKlass mem)); 4352 4353 ins_cost(125); // XXX 4354 format %{ "movq $dst, $mem\t# class" %} 4355 ins_encode %{ 4356 __ movq($dst$$Register, $mem$$Address); 4357 %} 4358 ins_pipe(ialu_reg_mem); // XXX 4359 %} 4360 4361 // Load narrow Klass Pointer 4362 instruct loadNKlass(rRegN dst, memory mem) 4363 %{ 4364 predicate(!UseCompactObjectHeaders); 4365 match(Set dst (LoadNKlass mem)); 4366 4367 ins_cost(125); // XXX 4368 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4369 ins_encode %{ 4370 __ movl($dst$$Register, $mem$$Address); 4371 %} 4372 ins_pipe(ialu_reg_mem); // XXX 4373 %} 4374 4375 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4376 %{ 4377 predicate(UseCompactObjectHeaders); 4378 match(Set dst (LoadNKlass mem)); 4379 effect(KILL cr); 4380 ins_cost(125); // XXX 4381 format %{ 4382 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4383 "shrl $dst, markWord::klass_shift_at_offset" 4384 %} 4385 ins_encode %{ 4386 __ movl($dst$$Register, $mem$$Address); 4387 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4388 %} 4389 ins_pipe(ialu_reg_mem); // XXX 4390 %} 4391 4392 // Load Float 4393 instruct loadF(regF dst, memory mem) 4394 %{ 4395 match(Set dst (LoadF mem)); 4396 4397 ins_cost(145); // XXX 4398 format %{ "movss $dst, $mem\t# float" %} 4399 ins_encode %{ 4400 __ movflt($dst$$XMMRegister, $mem$$Address); 4401 %} 4402 ins_pipe(pipe_slow); // XXX 4403 %} 4404 4405 // Load Double 4406 instruct loadD_partial(regD dst, memory mem) 4407 %{ 4408 predicate(!UseXmmLoadAndClearUpper); 4409 match(Set dst (LoadD mem)); 4410 4411 ins_cost(145); // XXX 4412 format %{ "movlpd $dst, $mem\t# double" %} 4413 ins_encode %{ 4414 __ movdbl($dst$$XMMRegister, $mem$$Address); 4415 %} 4416 ins_pipe(pipe_slow); // XXX 4417 %} 4418 4419 instruct loadD(regD dst, memory mem) 4420 %{ 4421 predicate(UseXmmLoadAndClearUpper); 4422 match(Set dst (LoadD mem)); 4423 4424 ins_cost(145); // XXX 4425 format %{ "movsd $dst, $mem\t# double" %} 4426 ins_encode %{ 4427 __ movdbl($dst$$XMMRegister, $mem$$Address); 4428 %} 4429 ins_pipe(pipe_slow); // XXX 4430 %} 4431 4432 // max = java.lang.Math.max(float a, float b) 4433 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4434 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4435 match(Set dst (MaxF a b)); 4436 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4437 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4438 ins_encode %{ 4439 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4440 %} 4441 ins_pipe( pipe_slow ); 4442 %} 4443 4444 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4445 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4446 match(Set dst (MaxF a b)); 4447 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4448 4449 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4450 ins_encode %{ 4451 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4452 false /*min*/, true /*single*/); 4453 %} 4454 ins_pipe( pipe_slow ); 4455 %} 4456 4457 // max = java.lang.Math.max(double a, double b) 4458 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4459 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4460 match(Set dst (MaxD a b)); 4461 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4462 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4463 ins_encode %{ 4464 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4465 %} 4466 ins_pipe( pipe_slow ); 4467 %} 4468 4469 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4470 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4471 match(Set dst (MaxD a b)); 4472 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4473 4474 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4475 ins_encode %{ 4476 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4477 false /*min*/, false /*single*/); 4478 %} 4479 ins_pipe( pipe_slow ); 4480 %} 4481 4482 // min = java.lang.Math.min(float a, float b) 4483 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4484 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4485 match(Set dst (MinF a b)); 4486 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4487 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4488 ins_encode %{ 4489 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4490 %} 4491 ins_pipe( pipe_slow ); 4492 %} 4493 4494 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4495 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4496 match(Set dst (MinF a b)); 4497 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4498 4499 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4500 ins_encode %{ 4501 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4502 true /*min*/, true /*single*/); 4503 %} 4504 ins_pipe( pipe_slow ); 4505 %} 4506 4507 // min = java.lang.Math.min(double a, double b) 4508 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4509 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4510 match(Set dst (MinD a b)); 4511 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4512 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4513 ins_encode %{ 4514 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4515 %} 4516 ins_pipe( pipe_slow ); 4517 %} 4518 4519 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4520 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4521 match(Set dst (MinD a b)); 4522 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4523 4524 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4525 ins_encode %{ 4526 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4527 true /*min*/, false /*single*/); 4528 %} 4529 ins_pipe( pipe_slow ); 4530 %} 4531 4532 // Load Effective Address 4533 instruct leaP8(rRegP dst, indOffset8 mem) 4534 %{ 4535 match(Set dst mem); 4536 4537 ins_cost(110); // XXX 4538 format %{ "leaq $dst, $mem\t# ptr 8" %} 4539 ins_encode %{ 4540 __ leaq($dst$$Register, $mem$$Address); 4541 %} 4542 ins_pipe(ialu_reg_reg_fat); 4543 %} 4544 4545 instruct leaP32(rRegP dst, indOffset32 mem) 4546 %{ 4547 match(Set dst mem); 4548 4549 ins_cost(110); 4550 format %{ "leaq $dst, $mem\t# ptr 32" %} 4551 ins_encode %{ 4552 __ leaq($dst$$Register, $mem$$Address); 4553 %} 4554 ins_pipe(ialu_reg_reg_fat); 4555 %} 4556 4557 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4558 %{ 4559 match(Set dst mem); 4560 4561 ins_cost(110); 4562 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4563 ins_encode %{ 4564 __ leaq($dst$$Register, $mem$$Address); 4565 %} 4566 ins_pipe(ialu_reg_reg_fat); 4567 %} 4568 4569 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4570 %{ 4571 match(Set dst mem); 4572 4573 ins_cost(110); 4574 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4575 ins_encode %{ 4576 __ leaq($dst$$Register, $mem$$Address); 4577 %} 4578 ins_pipe(ialu_reg_reg_fat); 4579 %} 4580 4581 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4582 %{ 4583 match(Set dst mem); 4584 4585 ins_cost(110); 4586 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4587 ins_encode %{ 4588 __ leaq($dst$$Register, $mem$$Address); 4589 %} 4590 ins_pipe(ialu_reg_reg_fat); 4591 %} 4592 4593 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4594 %{ 4595 match(Set dst mem); 4596 4597 ins_cost(110); 4598 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4599 ins_encode %{ 4600 __ leaq($dst$$Register, $mem$$Address); 4601 %} 4602 ins_pipe(ialu_reg_reg_fat); 4603 %} 4604 4605 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4606 %{ 4607 match(Set dst mem); 4608 4609 ins_cost(110); 4610 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4611 ins_encode %{ 4612 __ leaq($dst$$Register, $mem$$Address); 4613 %} 4614 ins_pipe(ialu_reg_reg_fat); 4615 %} 4616 4617 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4618 %{ 4619 match(Set dst mem); 4620 4621 ins_cost(110); 4622 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4623 ins_encode %{ 4624 __ leaq($dst$$Register, $mem$$Address); 4625 %} 4626 ins_pipe(ialu_reg_reg_fat); 4627 %} 4628 4629 // Load Effective Address which uses Narrow (32-bits) oop 4630 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4631 %{ 4632 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4633 match(Set dst mem); 4634 4635 ins_cost(110); 4636 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4637 ins_encode %{ 4638 __ leaq($dst$$Register, $mem$$Address); 4639 %} 4640 ins_pipe(ialu_reg_reg_fat); 4641 %} 4642 4643 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4644 %{ 4645 predicate(CompressedOops::shift() == 0); 4646 match(Set dst mem); 4647 4648 ins_cost(110); // XXX 4649 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4650 ins_encode %{ 4651 __ leaq($dst$$Register, $mem$$Address); 4652 %} 4653 ins_pipe(ialu_reg_reg_fat); 4654 %} 4655 4656 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4657 %{ 4658 predicate(CompressedOops::shift() == 0); 4659 match(Set dst mem); 4660 4661 ins_cost(110); 4662 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4663 ins_encode %{ 4664 __ leaq($dst$$Register, $mem$$Address); 4665 %} 4666 ins_pipe(ialu_reg_reg_fat); 4667 %} 4668 4669 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4670 %{ 4671 predicate(CompressedOops::shift() == 0); 4672 match(Set dst mem); 4673 4674 ins_cost(110); 4675 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4676 ins_encode %{ 4677 __ leaq($dst$$Register, $mem$$Address); 4678 %} 4679 ins_pipe(ialu_reg_reg_fat); 4680 %} 4681 4682 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4683 %{ 4684 predicate(CompressedOops::shift() == 0); 4685 match(Set dst mem); 4686 4687 ins_cost(110); 4688 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4689 ins_encode %{ 4690 __ leaq($dst$$Register, $mem$$Address); 4691 %} 4692 ins_pipe(ialu_reg_reg_fat); 4693 %} 4694 4695 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4696 %{ 4697 predicate(CompressedOops::shift() == 0); 4698 match(Set dst mem); 4699 4700 ins_cost(110); 4701 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4702 ins_encode %{ 4703 __ leaq($dst$$Register, $mem$$Address); 4704 %} 4705 ins_pipe(ialu_reg_reg_fat); 4706 %} 4707 4708 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4709 %{ 4710 predicate(CompressedOops::shift() == 0); 4711 match(Set dst mem); 4712 4713 ins_cost(110); 4714 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4715 ins_encode %{ 4716 __ leaq($dst$$Register, $mem$$Address); 4717 %} 4718 ins_pipe(ialu_reg_reg_fat); 4719 %} 4720 4721 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4722 %{ 4723 predicate(CompressedOops::shift() == 0); 4724 match(Set dst mem); 4725 4726 ins_cost(110); 4727 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4728 ins_encode %{ 4729 __ leaq($dst$$Register, $mem$$Address); 4730 %} 4731 ins_pipe(ialu_reg_reg_fat); 4732 %} 4733 4734 instruct loadConI(rRegI dst, immI src) 4735 %{ 4736 match(Set dst src); 4737 4738 format %{ "movl $dst, $src\t# int" %} 4739 ins_encode %{ 4740 __ movl($dst$$Register, $src$$constant); 4741 %} 4742 ins_pipe(ialu_reg_fat); // XXX 4743 %} 4744 4745 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4746 %{ 4747 match(Set dst src); 4748 effect(KILL cr); 4749 4750 ins_cost(50); 4751 format %{ "xorl $dst, $dst\t# int" %} 4752 ins_encode %{ 4753 __ xorl($dst$$Register, $dst$$Register); 4754 %} 4755 ins_pipe(ialu_reg); 4756 %} 4757 4758 instruct loadConL(rRegL dst, immL src) 4759 %{ 4760 match(Set dst src); 4761 4762 ins_cost(150); 4763 format %{ "movq $dst, $src\t# long" %} 4764 ins_encode %{ 4765 __ mov64($dst$$Register, $src$$constant); 4766 %} 4767 ins_pipe(ialu_reg); 4768 %} 4769 4770 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4771 %{ 4772 match(Set dst src); 4773 effect(KILL cr); 4774 4775 ins_cost(50); 4776 format %{ "xorl $dst, $dst\t# long" %} 4777 ins_encode %{ 4778 __ xorl($dst$$Register, $dst$$Register); 4779 %} 4780 ins_pipe(ialu_reg); // XXX 4781 %} 4782 4783 instruct loadConUL32(rRegL dst, immUL32 src) 4784 %{ 4785 match(Set dst src); 4786 4787 ins_cost(60); 4788 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4789 ins_encode %{ 4790 __ movl($dst$$Register, $src$$constant); 4791 %} 4792 ins_pipe(ialu_reg); 4793 %} 4794 4795 instruct loadConL32(rRegL dst, immL32 src) 4796 %{ 4797 match(Set dst src); 4798 4799 ins_cost(70); 4800 format %{ "movq $dst, $src\t# long (32-bit)" %} 4801 ins_encode %{ 4802 __ movq($dst$$Register, $src$$constant); 4803 %} 4804 ins_pipe(ialu_reg); 4805 %} 4806 4807 instruct loadConP(rRegP dst, immP con) %{ 4808 match(Set dst con); 4809 4810 format %{ "movq $dst, $con\t# ptr" %} 4811 ins_encode %{ 4812 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4813 %} 4814 ins_pipe(ialu_reg_fat); // XXX 4815 %} 4816 4817 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4818 %{ 4819 match(Set dst src); 4820 effect(KILL cr); 4821 4822 ins_cost(50); 4823 format %{ "xorl $dst, $dst\t# ptr" %} 4824 ins_encode %{ 4825 __ xorl($dst$$Register, $dst$$Register); 4826 %} 4827 ins_pipe(ialu_reg); 4828 %} 4829 4830 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4831 %{ 4832 match(Set dst src); 4833 effect(KILL cr); 4834 4835 ins_cost(60); 4836 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4837 ins_encode %{ 4838 __ movl($dst$$Register, $src$$constant); 4839 %} 4840 ins_pipe(ialu_reg); 4841 %} 4842 4843 instruct loadConF(regF dst, immF con) %{ 4844 match(Set dst con); 4845 ins_cost(125); 4846 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4847 ins_encode %{ 4848 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4849 %} 4850 ins_pipe(pipe_slow); 4851 %} 4852 4853 instruct loadConH(regF dst, immH con) %{ 4854 match(Set dst con); 4855 ins_cost(125); 4856 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4857 ins_encode %{ 4858 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4859 %} 4860 ins_pipe(pipe_slow); 4861 %} 4862 4863 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4864 match(Set dst src); 4865 effect(KILL cr); 4866 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4867 ins_encode %{ 4868 __ xorq($dst$$Register, $dst$$Register); 4869 %} 4870 ins_pipe(ialu_reg); 4871 %} 4872 4873 instruct loadConN(rRegN dst, immN src) %{ 4874 match(Set dst src); 4875 4876 ins_cost(125); 4877 format %{ "movl $dst, $src\t# compressed ptr" %} 4878 ins_encode %{ 4879 address con = (address)$src$$constant; 4880 if (con == nullptr) { 4881 ShouldNotReachHere(); 4882 } else { 4883 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4884 } 4885 %} 4886 ins_pipe(ialu_reg_fat); // XXX 4887 %} 4888 4889 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4890 match(Set dst src); 4891 4892 ins_cost(125); 4893 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4894 ins_encode %{ 4895 address con = (address)$src$$constant; 4896 if (con == nullptr) { 4897 ShouldNotReachHere(); 4898 } else { 4899 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4900 } 4901 %} 4902 ins_pipe(ialu_reg_fat); // XXX 4903 %} 4904 4905 instruct loadConF0(regF dst, immF0 src) 4906 %{ 4907 match(Set dst src); 4908 ins_cost(100); 4909 4910 format %{ "xorps $dst, $dst\t# float 0.0" %} 4911 ins_encode %{ 4912 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4913 %} 4914 ins_pipe(pipe_slow); 4915 %} 4916 4917 // Use the same format since predicate() can not be used here. 4918 instruct loadConD(regD dst, immD con) %{ 4919 match(Set dst con); 4920 ins_cost(125); 4921 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4922 ins_encode %{ 4923 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4924 %} 4925 ins_pipe(pipe_slow); 4926 %} 4927 4928 instruct loadConD0(regD dst, immD0 src) 4929 %{ 4930 match(Set dst src); 4931 ins_cost(100); 4932 4933 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4934 ins_encode %{ 4935 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4936 %} 4937 ins_pipe(pipe_slow); 4938 %} 4939 4940 instruct loadSSI(rRegI dst, stackSlotI src) 4941 %{ 4942 match(Set dst src); 4943 4944 ins_cost(125); 4945 format %{ "movl $dst, $src\t# int stk" %} 4946 ins_encode %{ 4947 __ movl($dst$$Register, $src$$Address); 4948 %} 4949 ins_pipe(ialu_reg_mem); 4950 %} 4951 4952 instruct loadSSL(rRegL dst, stackSlotL src) 4953 %{ 4954 match(Set dst src); 4955 4956 ins_cost(125); 4957 format %{ "movq $dst, $src\t# long stk" %} 4958 ins_encode %{ 4959 __ movq($dst$$Register, $src$$Address); 4960 %} 4961 ins_pipe(ialu_reg_mem); 4962 %} 4963 4964 instruct loadSSP(rRegP dst, stackSlotP src) 4965 %{ 4966 match(Set dst src); 4967 4968 ins_cost(125); 4969 format %{ "movq $dst, $src\t# ptr stk" %} 4970 ins_encode %{ 4971 __ movq($dst$$Register, $src$$Address); 4972 %} 4973 ins_pipe(ialu_reg_mem); 4974 %} 4975 4976 instruct loadSSF(regF dst, stackSlotF src) 4977 %{ 4978 match(Set dst src); 4979 4980 ins_cost(125); 4981 format %{ "movss $dst, $src\t# float stk" %} 4982 ins_encode %{ 4983 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 4984 %} 4985 ins_pipe(pipe_slow); // XXX 4986 %} 4987 4988 // Use the same format since predicate() can not be used here. 4989 instruct loadSSD(regD dst, stackSlotD src) 4990 %{ 4991 match(Set dst src); 4992 4993 ins_cost(125); 4994 format %{ "movsd $dst, $src\t# double stk" %} 4995 ins_encode %{ 4996 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 4997 %} 4998 ins_pipe(pipe_slow); // XXX 4999 %} 5000 5001 // Prefetch instructions for allocation. 5002 // Must be safe to execute with invalid address (cannot fault). 5003 5004 instruct prefetchAlloc( memory mem ) %{ 5005 predicate(AllocatePrefetchInstr==3); 5006 match(PrefetchAllocation mem); 5007 ins_cost(125); 5008 5009 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5010 ins_encode %{ 5011 __ prefetchw($mem$$Address); 5012 %} 5013 ins_pipe(ialu_mem); 5014 %} 5015 5016 instruct prefetchAllocNTA( memory mem ) %{ 5017 predicate(AllocatePrefetchInstr==0); 5018 match(PrefetchAllocation mem); 5019 ins_cost(125); 5020 5021 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5022 ins_encode %{ 5023 __ prefetchnta($mem$$Address); 5024 %} 5025 ins_pipe(ialu_mem); 5026 %} 5027 5028 instruct prefetchAllocT0( memory mem ) %{ 5029 predicate(AllocatePrefetchInstr==1); 5030 match(PrefetchAllocation mem); 5031 ins_cost(125); 5032 5033 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5034 ins_encode %{ 5035 __ prefetcht0($mem$$Address); 5036 %} 5037 ins_pipe(ialu_mem); 5038 %} 5039 5040 instruct prefetchAllocT2( memory mem ) %{ 5041 predicate(AllocatePrefetchInstr==2); 5042 match(PrefetchAllocation mem); 5043 ins_cost(125); 5044 5045 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5046 ins_encode %{ 5047 __ prefetcht2($mem$$Address); 5048 %} 5049 ins_pipe(ialu_mem); 5050 %} 5051 5052 //----------Store Instructions------------------------------------------------- 5053 5054 // Store Byte 5055 instruct storeB(memory mem, rRegI src) 5056 %{ 5057 match(Set mem (StoreB mem src)); 5058 5059 ins_cost(125); // XXX 5060 format %{ "movb $mem, $src\t# byte" %} 5061 ins_encode %{ 5062 __ movb($mem$$Address, $src$$Register); 5063 %} 5064 ins_pipe(ialu_mem_reg); 5065 %} 5066 5067 // Store Char/Short 5068 instruct storeC(memory mem, rRegI src) 5069 %{ 5070 match(Set mem (StoreC mem src)); 5071 5072 ins_cost(125); // XXX 5073 format %{ "movw $mem, $src\t# char/short" %} 5074 ins_encode %{ 5075 __ movw($mem$$Address, $src$$Register); 5076 %} 5077 ins_pipe(ialu_mem_reg); 5078 %} 5079 5080 // Store Integer 5081 instruct storeI(memory mem, rRegI src) 5082 %{ 5083 match(Set mem (StoreI mem src)); 5084 5085 ins_cost(125); // XXX 5086 format %{ "movl $mem, $src\t# int" %} 5087 ins_encode %{ 5088 __ movl($mem$$Address, $src$$Register); 5089 %} 5090 ins_pipe(ialu_mem_reg); 5091 %} 5092 5093 // Store Long 5094 instruct storeL(memory mem, rRegL src) 5095 %{ 5096 match(Set mem (StoreL mem src)); 5097 5098 ins_cost(125); // XXX 5099 format %{ "movq $mem, $src\t# long" %} 5100 ins_encode %{ 5101 __ movq($mem$$Address, $src$$Register); 5102 %} 5103 ins_pipe(ialu_mem_reg); // XXX 5104 %} 5105 5106 // Store Pointer 5107 instruct storeP(memory mem, any_RegP src) 5108 %{ 5109 predicate(n->as_Store()->barrier_data() == 0); 5110 match(Set mem (StoreP mem src)); 5111 5112 ins_cost(125); // XXX 5113 format %{ "movq $mem, $src\t# ptr" %} 5114 ins_encode %{ 5115 __ movq($mem$$Address, $src$$Register); 5116 %} 5117 ins_pipe(ialu_mem_reg); 5118 %} 5119 5120 instruct storeImmP0(memory mem, immP0 zero) 5121 %{ 5122 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5123 match(Set mem (StoreP mem zero)); 5124 5125 ins_cost(125); // XXX 5126 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5127 ins_encode %{ 5128 __ movq($mem$$Address, r12); 5129 %} 5130 ins_pipe(ialu_mem_reg); 5131 %} 5132 5133 // Store Null Pointer, mark word, or other simple pointer constant. 5134 instruct storeImmP(memory mem, immP31 src) 5135 %{ 5136 predicate(n->as_Store()->barrier_data() == 0); 5137 match(Set mem (StoreP mem src)); 5138 5139 ins_cost(150); // XXX 5140 format %{ "movq $mem, $src\t# ptr" %} 5141 ins_encode %{ 5142 __ movq($mem$$Address, $src$$constant); 5143 %} 5144 ins_pipe(ialu_mem_imm); 5145 %} 5146 5147 // Store Compressed Pointer 5148 instruct storeN(memory mem, rRegN src) 5149 %{ 5150 predicate(n->as_Store()->barrier_data() == 0); 5151 match(Set mem (StoreN mem src)); 5152 5153 ins_cost(125); // XXX 5154 format %{ "movl $mem, $src\t# compressed ptr" %} 5155 ins_encode %{ 5156 __ movl($mem$$Address, $src$$Register); 5157 %} 5158 ins_pipe(ialu_mem_reg); 5159 %} 5160 5161 instruct storeNKlass(memory mem, rRegN src) 5162 %{ 5163 match(Set mem (StoreNKlass mem src)); 5164 5165 ins_cost(125); // XXX 5166 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5167 ins_encode %{ 5168 __ movl($mem$$Address, $src$$Register); 5169 %} 5170 ins_pipe(ialu_mem_reg); 5171 %} 5172 5173 instruct storeImmN0(memory mem, immN0 zero) 5174 %{ 5175 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5176 match(Set mem (StoreN mem zero)); 5177 5178 ins_cost(125); // XXX 5179 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5180 ins_encode %{ 5181 __ movl($mem$$Address, r12); 5182 %} 5183 ins_pipe(ialu_mem_reg); 5184 %} 5185 5186 instruct storeImmN(memory mem, immN src) 5187 %{ 5188 predicate(n->as_Store()->barrier_data() == 0); 5189 match(Set mem (StoreN mem src)); 5190 5191 ins_cost(150); // XXX 5192 format %{ "movl $mem, $src\t# compressed ptr" %} 5193 ins_encode %{ 5194 address con = (address)$src$$constant; 5195 if (con == nullptr) { 5196 __ movl($mem$$Address, 0); 5197 } else { 5198 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5199 } 5200 %} 5201 ins_pipe(ialu_mem_imm); 5202 %} 5203 5204 instruct storeImmNKlass(memory mem, immNKlass src) 5205 %{ 5206 match(Set mem (StoreNKlass mem src)); 5207 5208 ins_cost(150); // XXX 5209 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5210 ins_encode %{ 5211 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5212 %} 5213 ins_pipe(ialu_mem_imm); 5214 %} 5215 5216 // Store Integer Immediate 5217 instruct storeImmI0(memory mem, immI_0 zero) 5218 %{ 5219 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5220 match(Set mem (StoreI mem zero)); 5221 5222 ins_cost(125); // XXX 5223 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5224 ins_encode %{ 5225 __ movl($mem$$Address, r12); 5226 %} 5227 ins_pipe(ialu_mem_reg); 5228 %} 5229 5230 instruct storeImmI(memory mem, immI src) 5231 %{ 5232 match(Set mem (StoreI mem src)); 5233 5234 ins_cost(150); 5235 format %{ "movl $mem, $src\t# int" %} 5236 ins_encode %{ 5237 __ movl($mem$$Address, $src$$constant); 5238 %} 5239 ins_pipe(ialu_mem_imm); 5240 %} 5241 5242 // Store Long Immediate 5243 instruct storeImmL0(memory mem, immL0 zero) 5244 %{ 5245 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5246 match(Set mem (StoreL mem zero)); 5247 5248 ins_cost(125); // XXX 5249 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5250 ins_encode %{ 5251 __ movq($mem$$Address, r12); 5252 %} 5253 ins_pipe(ialu_mem_reg); 5254 %} 5255 5256 instruct storeImmL(memory mem, immL32 src) 5257 %{ 5258 match(Set mem (StoreL mem src)); 5259 5260 ins_cost(150); 5261 format %{ "movq $mem, $src\t# long" %} 5262 ins_encode %{ 5263 __ movq($mem$$Address, $src$$constant); 5264 %} 5265 ins_pipe(ialu_mem_imm); 5266 %} 5267 5268 // Store Short/Char Immediate 5269 instruct storeImmC0(memory mem, immI_0 zero) 5270 %{ 5271 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5272 match(Set mem (StoreC mem zero)); 5273 5274 ins_cost(125); // XXX 5275 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5276 ins_encode %{ 5277 __ movw($mem$$Address, r12); 5278 %} 5279 ins_pipe(ialu_mem_reg); 5280 %} 5281 5282 instruct storeImmI16(memory mem, immI16 src) 5283 %{ 5284 predicate(UseStoreImmI16); 5285 match(Set mem (StoreC mem src)); 5286 5287 ins_cost(150); 5288 format %{ "movw $mem, $src\t# short/char" %} 5289 ins_encode %{ 5290 __ movw($mem$$Address, $src$$constant); 5291 %} 5292 ins_pipe(ialu_mem_imm); 5293 %} 5294 5295 // Store Byte Immediate 5296 instruct storeImmB0(memory mem, immI_0 zero) 5297 %{ 5298 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5299 match(Set mem (StoreB mem zero)); 5300 5301 ins_cost(125); // XXX 5302 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5303 ins_encode %{ 5304 __ movb($mem$$Address, r12); 5305 %} 5306 ins_pipe(ialu_mem_reg); 5307 %} 5308 5309 instruct storeImmB(memory mem, immI8 src) 5310 %{ 5311 match(Set mem (StoreB mem src)); 5312 5313 ins_cost(150); // XXX 5314 format %{ "movb $mem, $src\t# byte" %} 5315 ins_encode %{ 5316 __ movb($mem$$Address, $src$$constant); 5317 %} 5318 ins_pipe(ialu_mem_imm); 5319 %} 5320 5321 // Store Float 5322 instruct storeF(memory mem, regF src) 5323 %{ 5324 match(Set mem (StoreF mem src)); 5325 5326 ins_cost(95); // XXX 5327 format %{ "movss $mem, $src\t# float" %} 5328 ins_encode %{ 5329 __ movflt($mem$$Address, $src$$XMMRegister); 5330 %} 5331 ins_pipe(pipe_slow); // XXX 5332 %} 5333 5334 // Store immediate Float value (it is faster than store from XMM register) 5335 instruct storeF0(memory mem, immF0 zero) 5336 %{ 5337 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5338 match(Set mem (StoreF mem zero)); 5339 5340 ins_cost(25); // XXX 5341 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5342 ins_encode %{ 5343 __ movl($mem$$Address, r12); 5344 %} 5345 ins_pipe(ialu_mem_reg); 5346 %} 5347 5348 instruct storeF_imm(memory mem, immF src) 5349 %{ 5350 match(Set mem (StoreF mem src)); 5351 5352 ins_cost(50); 5353 format %{ "movl $mem, $src\t# float" %} 5354 ins_encode %{ 5355 __ movl($mem$$Address, jint_cast($src$$constant)); 5356 %} 5357 ins_pipe(ialu_mem_imm); 5358 %} 5359 5360 // Store Double 5361 instruct storeD(memory mem, regD src) 5362 %{ 5363 match(Set mem (StoreD mem src)); 5364 5365 ins_cost(95); // XXX 5366 format %{ "movsd $mem, $src\t# double" %} 5367 ins_encode %{ 5368 __ movdbl($mem$$Address, $src$$XMMRegister); 5369 %} 5370 ins_pipe(pipe_slow); // XXX 5371 %} 5372 5373 // Store immediate double 0.0 (it is faster than store from XMM register) 5374 instruct storeD0_imm(memory mem, immD0 src) 5375 %{ 5376 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5377 match(Set mem (StoreD mem src)); 5378 5379 ins_cost(50); 5380 format %{ "movq $mem, $src\t# double 0." %} 5381 ins_encode %{ 5382 __ movq($mem$$Address, $src$$constant); 5383 %} 5384 ins_pipe(ialu_mem_imm); 5385 %} 5386 5387 instruct storeD0(memory mem, immD0 zero) 5388 %{ 5389 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5390 match(Set mem (StoreD mem zero)); 5391 5392 ins_cost(25); // XXX 5393 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5394 ins_encode %{ 5395 __ movq($mem$$Address, r12); 5396 %} 5397 ins_pipe(ialu_mem_reg); 5398 %} 5399 5400 instruct storeSSI(stackSlotI dst, rRegI src) 5401 %{ 5402 match(Set dst src); 5403 5404 ins_cost(100); 5405 format %{ "movl $dst, $src\t# int stk" %} 5406 ins_encode %{ 5407 __ movl($dst$$Address, $src$$Register); 5408 %} 5409 ins_pipe( ialu_mem_reg ); 5410 %} 5411 5412 instruct storeSSL(stackSlotL dst, rRegL src) 5413 %{ 5414 match(Set dst src); 5415 5416 ins_cost(100); 5417 format %{ "movq $dst, $src\t# long stk" %} 5418 ins_encode %{ 5419 __ movq($dst$$Address, $src$$Register); 5420 %} 5421 ins_pipe(ialu_mem_reg); 5422 %} 5423 5424 instruct storeSSP(stackSlotP dst, rRegP src) 5425 %{ 5426 match(Set dst src); 5427 5428 ins_cost(100); 5429 format %{ "movq $dst, $src\t# ptr stk" %} 5430 ins_encode %{ 5431 __ movq($dst$$Address, $src$$Register); 5432 %} 5433 ins_pipe(ialu_mem_reg); 5434 %} 5435 5436 instruct storeSSF(stackSlotF dst, regF src) 5437 %{ 5438 match(Set dst src); 5439 5440 ins_cost(95); // XXX 5441 format %{ "movss $dst, $src\t# float stk" %} 5442 ins_encode %{ 5443 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5444 %} 5445 ins_pipe(pipe_slow); // XXX 5446 %} 5447 5448 instruct storeSSD(stackSlotD dst, regD src) 5449 %{ 5450 match(Set dst src); 5451 5452 ins_cost(95); // XXX 5453 format %{ "movsd $dst, $src\t# double stk" %} 5454 ins_encode %{ 5455 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5456 %} 5457 ins_pipe(pipe_slow); // XXX 5458 %} 5459 5460 instruct cacheWB(indirect addr) 5461 %{ 5462 predicate(VM_Version::supports_data_cache_line_flush()); 5463 match(CacheWB addr); 5464 5465 ins_cost(100); 5466 format %{"cache wb $addr" %} 5467 ins_encode %{ 5468 assert($addr->index_position() < 0, "should be"); 5469 assert($addr$$disp == 0, "should be"); 5470 __ cache_wb(Address($addr$$base$$Register, 0)); 5471 %} 5472 ins_pipe(pipe_slow); // XXX 5473 %} 5474 5475 instruct cacheWBPreSync() 5476 %{ 5477 predicate(VM_Version::supports_data_cache_line_flush()); 5478 match(CacheWBPreSync); 5479 5480 ins_cost(100); 5481 format %{"cache wb presync" %} 5482 ins_encode %{ 5483 __ cache_wbsync(true); 5484 %} 5485 ins_pipe(pipe_slow); // XXX 5486 %} 5487 5488 instruct cacheWBPostSync() 5489 %{ 5490 predicate(VM_Version::supports_data_cache_line_flush()); 5491 match(CacheWBPostSync); 5492 5493 ins_cost(100); 5494 format %{"cache wb postsync" %} 5495 ins_encode %{ 5496 __ cache_wbsync(false); 5497 %} 5498 ins_pipe(pipe_slow); // XXX 5499 %} 5500 5501 //----------BSWAP Instructions------------------------------------------------- 5502 instruct bytes_reverse_int(rRegI dst) %{ 5503 match(Set dst (ReverseBytesI dst)); 5504 5505 format %{ "bswapl $dst" %} 5506 ins_encode %{ 5507 __ bswapl($dst$$Register); 5508 %} 5509 ins_pipe( ialu_reg ); 5510 %} 5511 5512 instruct bytes_reverse_long(rRegL dst) %{ 5513 match(Set dst (ReverseBytesL dst)); 5514 5515 format %{ "bswapq $dst" %} 5516 ins_encode %{ 5517 __ bswapq($dst$$Register); 5518 %} 5519 ins_pipe( ialu_reg); 5520 %} 5521 5522 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5523 match(Set dst (ReverseBytesUS dst)); 5524 effect(KILL cr); 5525 5526 format %{ "bswapl $dst\n\t" 5527 "shrl $dst,16\n\t" %} 5528 ins_encode %{ 5529 __ bswapl($dst$$Register); 5530 __ shrl($dst$$Register, 16); 5531 %} 5532 ins_pipe( ialu_reg ); 5533 %} 5534 5535 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5536 match(Set dst (ReverseBytesS dst)); 5537 effect(KILL cr); 5538 5539 format %{ "bswapl $dst\n\t" 5540 "sar $dst,16\n\t" %} 5541 ins_encode %{ 5542 __ bswapl($dst$$Register); 5543 __ sarl($dst$$Register, 16); 5544 %} 5545 ins_pipe( ialu_reg ); 5546 %} 5547 5548 //---------- Zeros Count Instructions ------------------------------------------ 5549 5550 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5551 predicate(UseCountLeadingZerosInstruction); 5552 match(Set dst (CountLeadingZerosI src)); 5553 effect(KILL cr); 5554 5555 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5556 ins_encode %{ 5557 __ lzcntl($dst$$Register, $src$$Register); 5558 %} 5559 ins_pipe(ialu_reg); 5560 %} 5561 5562 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5563 predicate(UseCountLeadingZerosInstruction); 5564 match(Set dst (CountLeadingZerosI (LoadI src))); 5565 effect(KILL cr); 5566 ins_cost(175); 5567 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5568 ins_encode %{ 5569 __ lzcntl($dst$$Register, $src$$Address); 5570 %} 5571 ins_pipe(ialu_reg_mem); 5572 %} 5573 5574 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5575 predicate(!UseCountLeadingZerosInstruction); 5576 match(Set dst (CountLeadingZerosI src)); 5577 effect(KILL cr); 5578 5579 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5580 "jnz skip\n\t" 5581 "movl $dst, -1\n" 5582 "skip:\n\t" 5583 "negl $dst\n\t" 5584 "addl $dst, 31" %} 5585 ins_encode %{ 5586 Register Rdst = $dst$$Register; 5587 Register Rsrc = $src$$Register; 5588 Label skip; 5589 __ bsrl(Rdst, Rsrc); 5590 __ jccb(Assembler::notZero, skip); 5591 __ movl(Rdst, -1); 5592 __ bind(skip); 5593 __ negl(Rdst); 5594 __ addl(Rdst, BitsPerInt - 1); 5595 %} 5596 ins_pipe(ialu_reg); 5597 %} 5598 5599 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5600 predicate(UseCountLeadingZerosInstruction); 5601 match(Set dst (CountLeadingZerosL src)); 5602 effect(KILL cr); 5603 5604 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5605 ins_encode %{ 5606 __ lzcntq($dst$$Register, $src$$Register); 5607 %} 5608 ins_pipe(ialu_reg); 5609 %} 5610 5611 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5612 predicate(UseCountLeadingZerosInstruction); 5613 match(Set dst (CountLeadingZerosL (LoadL src))); 5614 effect(KILL cr); 5615 ins_cost(175); 5616 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5617 ins_encode %{ 5618 __ lzcntq($dst$$Register, $src$$Address); 5619 %} 5620 ins_pipe(ialu_reg_mem); 5621 %} 5622 5623 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5624 predicate(!UseCountLeadingZerosInstruction); 5625 match(Set dst (CountLeadingZerosL src)); 5626 effect(KILL cr); 5627 5628 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5629 "jnz skip\n\t" 5630 "movl $dst, -1\n" 5631 "skip:\n\t" 5632 "negl $dst\n\t" 5633 "addl $dst, 63" %} 5634 ins_encode %{ 5635 Register Rdst = $dst$$Register; 5636 Register Rsrc = $src$$Register; 5637 Label skip; 5638 __ bsrq(Rdst, Rsrc); 5639 __ jccb(Assembler::notZero, skip); 5640 __ movl(Rdst, -1); 5641 __ bind(skip); 5642 __ negl(Rdst); 5643 __ addl(Rdst, BitsPerLong - 1); 5644 %} 5645 ins_pipe(ialu_reg); 5646 %} 5647 5648 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5649 predicate(UseCountTrailingZerosInstruction); 5650 match(Set dst (CountTrailingZerosI src)); 5651 effect(KILL cr); 5652 5653 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5654 ins_encode %{ 5655 __ tzcntl($dst$$Register, $src$$Register); 5656 %} 5657 ins_pipe(ialu_reg); 5658 %} 5659 5660 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5661 predicate(UseCountTrailingZerosInstruction); 5662 match(Set dst (CountTrailingZerosI (LoadI src))); 5663 effect(KILL cr); 5664 ins_cost(175); 5665 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5666 ins_encode %{ 5667 __ tzcntl($dst$$Register, $src$$Address); 5668 %} 5669 ins_pipe(ialu_reg_mem); 5670 %} 5671 5672 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5673 predicate(!UseCountTrailingZerosInstruction); 5674 match(Set dst (CountTrailingZerosI src)); 5675 effect(KILL cr); 5676 5677 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5678 "jnz done\n\t" 5679 "movl $dst, 32\n" 5680 "done:" %} 5681 ins_encode %{ 5682 Register Rdst = $dst$$Register; 5683 Label done; 5684 __ bsfl(Rdst, $src$$Register); 5685 __ jccb(Assembler::notZero, done); 5686 __ movl(Rdst, BitsPerInt); 5687 __ bind(done); 5688 %} 5689 ins_pipe(ialu_reg); 5690 %} 5691 5692 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5693 predicate(UseCountTrailingZerosInstruction); 5694 match(Set dst (CountTrailingZerosL src)); 5695 effect(KILL cr); 5696 5697 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5698 ins_encode %{ 5699 __ tzcntq($dst$$Register, $src$$Register); 5700 %} 5701 ins_pipe(ialu_reg); 5702 %} 5703 5704 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5705 predicate(UseCountTrailingZerosInstruction); 5706 match(Set dst (CountTrailingZerosL (LoadL src))); 5707 effect(KILL cr); 5708 ins_cost(175); 5709 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5710 ins_encode %{ 5711 __ tzcntq($dst$$Register, $src$$Address); 5712 %} 5713 ins_pipe(ialu_reg_mem); 5714 %} 5715 5716 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5717 predicate(!UseCountTrailingZerosInstruction); 5718 match(Set dst (CountTrailingZerosL src)); 5719 effect(KILL cr); 5720 5721 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5722 "jnz done\n\t" 5723 "movl $dst, 64\n" 5724 "done:" %} 5725 ins_encode %{ 5726 Register Rdst = $dst$$Register; 5727 Label done; 5728 __ bsfq(Rdst, $src$$Register); 5729 __ jccb(Assembler::notZero, done); 5730 __ movl(Rdst, BitsPerLong); 5731 __ bind(done); 5732 %} 5733 ins_pipe(ialu_reg); 5734 %} 5735 5736 //--------------- Reverse Operation Instructions ---------------- 5737 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5738 predicate(!VM_Version::supports_gfni()); 5739 match(Set dst (ReverseI src)); 5740 effect(TEMP dst, TEMP rtmp, KILL cr); 5741 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5742 ins_encode %{ 5743 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5744 %} 5745 ins_pipe( ialu_reg ); 5746 %} 5747 5748 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5749 predicate(VM_Version::supports_gfni()); 5750 match(Set dst (ReverseI src)); 5751 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5752 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5753 ins_encode %{ 5754 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5755 %} 5756 ins_pipe( ialu_reg ); 5757 %} 5758 5759 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5760 predicate(!VM_Version::supports_gfni()); 5761 match(Set dst (ReverseL src)); 5762 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5763 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5764 ins_encode %{ 5765 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5766 %} 5767 ins_pipe( ialu_reg ); 5768 %} 5769 5770 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5771 predicate(VM_Version::supports_gfni()); 5772 match(Set dst (ReverseL src)); 5773 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5774 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5775 ins_encode %{ 5776 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5777 %} 5778 ins_pipe( ialu_reg ); 5779 %} 5780 5781 //---------- Population Count Instructions ------------------------------------- 5782 5783 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5784 predicate(UsePopCountInstruction); 5785 match(Set dst (PopCountI src)); 5786 effect(KILL cr); 5787 5788 format %{ "popcnt $dst, $src" %} 5789 ins_encode %{ 5790 __ popcntl($dst$$Register, $src$$Register); 5791 %} 5792 ins_pipe(ialu_reg); 5793 %} 5794 5795 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5796 predicate(UsePopCountInstruction); 5797 match(Set dst (PopCountI (LoadI mem))); 5798 effect(KILL cr); 5799 5800 format %{ "popcnt $dst, $mem" %} 5801 ins_encode %{ 5802 __ popcntl($dst$$Register, $mem$$Address); 5803 %} 5804 ins_pipe(ialu_reg); 5805 %} 5806 5807 // Note: Long.bitCount(long) returns an int. 5808 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5809 predicate(UsePopCountInstruction); 5810 match(Set dst (PopCountL src)); 5811 effect(KILL cr); 5812 5813 format %{ "popcnt $dst, $src" %} 5814 ins_encode %{ 5815 __ popcntq($dst$$Register, $src$$Register); 5816 %} 5817 ins_pipe(ialu_reg); 5818 %} 5819 5820 // Note: Long.bitCount(long) returns an int. 5821 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5822 predicate(UsePopCountInstruction); 5823 match(Set dst (PopCountL (LoadL mem))); 5824 effect(KILL cr); 5825 5826 format %{ "popcnt $dst, $mem" %} 5827 ins_encode %{ 5828 __ popcntq($dst$$Register, $mem$$Address); 5829 %} 5830 ins_pipe(ialu_reg); 5831 %} 5832 5833 5834 //----------MemBar Instructions----------------------------------------------- 5835 // Memory barrier flavors 5836 5837 instruct membar_acquire() 5838 %{ 5839 match(MemBarAcquire); 5840 match(LoadFence); 5841 ins_cost(0); 5842 5843 size(0); 5844 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5845 ins_encode(); 5846 ins_pipe(empty); 5847 %} 5848 5849 instruct membar_acquire_lock() 5850 %{ 5851 match(MemBarAcquireLock); 5852 ins_cost(0); 5853 5854 size(0); 5855 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5856 ins_encode(); 5857 ins_pipe(empty); 5858 %} 5859 5860 instruct membar_release() 5861 %{ 5862 match(MemBarRelease); 5863 match(StoreFence); 5864 ins_cost(0); 5865 5866 size(0); 5867 format %{ "MEMBAR-release ! (empty encoding)" %} 5868 ins_encode(); 5869 ins_pipe(empty); 5870 %} 5871 5872 instruct membar_release_lock() 5873 %{ 5874 match(MemBarReleaseLock); 5875 ins_cost(0); 5876 5877 size(0); 5878 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5879 ins_encode(); 5880 ins_pipe(empty); 5881 %} 5882 5883 instruct membar_volatile(rFlagsReg cr) %{ 5884 match(MemBarVolatile); 5885 effect(KILL cr); 5886 ins_cost(400); 5887 5888 format %{ 5889 $$template 5890 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5891 %} 5892 ins_encode %{ 5893 __ membar(Assembler::StoreLoad); 5894 %} 5895 ins_pipe(pipe_slow); 5896 %} 5897 5898 instruct unnecessary_membar_volatile() 5899 %{ 5900 match(MemBarVolatile); 5901 predicate(Matcher::post_store_load_barrier(n)); 5902 ins_cost(0); 5903 5904 size(0); 5905 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5906 ins_encode(); 5907 ins_pipe(empty); 5908 %} 5909 5910 instruct membar_storestore() %{ 5911 match(MemBarStoreStore); 5912 match(StoreStoreFence); 5913 ins_cost(0); 5914 5915 size(0); 5916 format %{ "MEMBAR-storestore (empty encoding)" %} 5917 ins_encode( ); 5918 ins_pipe(empty); 5919 %} 5920 5921 //----------Move Instructions-------------------------------------------------- 5922 5923 instruct castX2P(rRegP dst, rRegL src) 5924 %{ 5925 match(Set dst (CastX2P src)); 5926 5927 format %{ "movq $dst, $src\t# long->ptr" %} 5928 ins_encode %{ 5929 if ($dst$$reg != $src$$reg) { 5930 __ movptr($dst$$Register, $src$$Register); 5931 } 5932 %} 5933 ins_pipe(ialu_reg_reg); // XXX 5934 %} 5935 5936 instruct castP2X(rRegL dst, rRegP src) 5937 %{ 5938 match(Set dst (CastP2X src)); 5939 5940 format %{ "movq $dst, $src\t# ptr -> long" %} 5941 ins_encode %{ 5942 if ($dst$$reg != $src$$reg) { 5943 __ movptr($dst$$Register, $src$$Register); 5944 } 5945 %} 5946 ins_pipe(ialu_reg_reg); // XXX 5947 %} 5948 5949 // Convert oop into int for vectors alignment masking 5950 instruct convP2I(rRegI dst, rRegP src) 5951 %{ 5952 match(Set dst (ConvL2I (CastP2X src))); 5953 5954 format %{ "movl $dst, $src\t# ptr -> int" %} 5955 ins_encode %{ 5956 __ movl($dst$$Register, $src$$Register); 5957 %} 5958 ins_pipe(ialu_reg_reg); // XXX 5959 %} 5960 5961 // Convert compressed oop into int for vectors alignment masking 5962 // in case of 32bit oops (heap < 4Gb). 5963 instruct convN2I(rRegI dst, rRegN src) 5964 %{ 5965 predicate(CompressedOops::shift() == 0); 5966 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5967 5968 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5969 ins_encode %{ 5970 __ movl($dst$$Register, $src$$Register); 5971 %} 5972 ins_pipe(ialu_reg_reg); // XXX 5973 %} 5974 5975 // Convert oop pointer into compressed form 5976 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5977 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5978 match(Set dst (EncodeP src)); 5979 effect(KILL cr); 5980 format %{ "encode_heap_oop $dst,$src" %} 5981 ins_encode %{ 5982 Register s = $src$$Register; 5983 Register d = $dst$$Register; 5984 if (s != d) { 5985 __ movq(d, s); 5986 } 5987 __ encode_heap_oop(d); 5988 %} 5989 ins_pipe(ialu_reg_long); 5990 %} 5991 5992 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5993 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 5994 match(Set dst (EncodeP src)); 5995 effect(KILL cr); 5996 format %{ "encode_heap_oop_not_null $dst,$src" %} 5997 ins_encode %{ 5998 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 5999 %} 6000 ins_pipe(ialu_reg_long); 6001 %} 6002 6003 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6004 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6005 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6006 match(Set dst (DecodeN src)); 6007 effect(KILL cr); 6008 format %{ "decode_heap_oop $dst,$src" %} 6009 ins_encode %{ 6010 Register s = $src$$Register; 6011 Register d = $dst$$Register; 6012 if (s != d) { 6013 __ movq(d, s); 6014 } 6015 __ decode_heap_oop(d); 6016 %} 6017 ins_pipe(ialu_reg_long); 6018 %} 6019 6020 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6021 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6022 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6023 match(Set dst (DecodeN src)); 6024 effect(KILL cr); 6025 format %{ "decode_heap_oop_not_null $dst,$src" %} 6026 ins_encode %{ 6027 Register s = $src$$Register; 6028 Register d = $dst$$Register; 6029 if (s != d) { 6030 __ decode_heap_oop_not_null(d, s); 6031 } else { 6032 __ decode_heap_oop_not_null(d); 6033 } 6034 %} 6035 ins_pipe(ialu_reg_long); 6036 %} 6037 6038 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6039 match(Set dst (EncodePKlass src)); 6040 effect(TEMP dst, KILL cr); 6041 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6042 ins_encode %{ 6043 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6044 %} 6045 ins_pipe(ialu_reg_long); 6046 %} 6047 6048 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6049 match(Set dst (DecodeNKlass src)); 6050 effect(TEMP dst, KILL cr); 6051 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6052 ins_encode %{ 6053 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6054 %} 6055 ins_pipe(ialu_reg_long); 6056 %} 6057 6058 //----------Conditional Move--------------------------------------------------- 6059 // Jump 6060 // dummy instruction for generating temp registers 6061 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6062 match(Jump (LShiftL switch_val shift)); 6063 ins_cost(350); 6064 predicate(false); 6065 effect(TEMP dest); 6066 6067 format %{ "leaq $dest, [$constantaddress]\n\t" 6068 "jmp [$dest + $switch_val << $shift]\n\t" %} 6069 ins_encode %{ 6070 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6071 // to do that and the compiler is using that register as one it can allocate. 6072 // So we build it all by hand. 6073 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6074 // ArrayAddress dispatch(table, index); 6075 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6076 __ lea($dest$$Register, $constantaddress); 6077 __ jmp(dispatch); 6078 %} 6079 ins_pipe(pipe_jmp); 6080 %} 6081 6082 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6083 match(Jump (AddL (LShiftL switch_val shift) offset)); 6084 ins_cost(350); 6085 effect(TEMP dest); 6086 6087 format %{ "leaq $dest, [$constantaddress]\n\t" 6088 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6089 ins_encode %{ 6090 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6091 // to do that and the compiler is using that register as one it can allocate. 6092 // So we build it all by hand. 6093 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6094 // ArrayAddress dispatch(table, index); 6095 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6096 __ lea($dest$$Register, $constantaddress); 6097 __ jmp(dispatch); 6098 %} 6099 ins_pipe(pipe_jmp); 6100 %} 6101 6102 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6103 match(Jump switch_val); 6104 ins_cost(350); 6105 effect(TEMP dest); 6106 6107 format %{ "leaq $dest, [$constantaddress]\n\t" 6108 "jmp [$dest + $switch_val]\n\t" %} 6109 ins_encode %{ 6110 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6111 // to do that and the compiler is using that register as one it can allocate. 6112 // So we build it all by hand. 6113 // Address index(noreg, switch_reg, Address::times_1); 6114 // ArrayAddress dispatch(table, index); 6115 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6116 __ lea($dest$$Register, $constantaddress); 6117 __ jmp(dispatch); 6118 %} 6119 ins_pipe(pipe_jmp); 6120 %} 6121 6122 // Conditional move 6123 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6124 %{ 6125 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6126 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6127 6128 ins_cost(100); // XXX 6129 format %{ "setbn$cop $dst\t# signed, int" %} 6130 ins_encode %{ 6131 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6132 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6133 %} 6134 ins_pipe(ialu_reg); 6135 %} 6136 6137 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6138 %{ 6139 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6140 6141 ins_cost(200); // XXX 6142 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6143 ins_encode %{ 6144 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6145 %} 6146 ins_pipe(pipe_cmov_reg); 6147 %} 6148 6149 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6150 %{ 6151 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6152 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6153 6154 ins_cost(100); // XXX 6155 format %{ "setbn$cop $dst\t# unsigned, int" %} 6156 ins_encode %{ 6157 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6158 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6159 %} 6160 ins_pipe(ialu_reg); 6161 %} 6162 6163 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6164 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6165 6166 ins_cost(200); // XXX 6167 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6168 ins_encode %{ 6169 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6170 %} 6171 ins_pipe(pipe_cmov_reg); 6172 %} 6173 6174 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6175 %{ 6176 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6177 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6178 6179 ins_cost(100); // XXX 6180 format %{ "setbn$cop $dst\t# unsigned, int" %} 6181 ins_encode %{ 6182 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6183 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6184 %} 6185 ins_pipe(ialu_reg); 6186 %} 6187 6188 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6189 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6190 ins_cost(200); 6191 expand %{ 6192 cmovI_regU(cop, cr, dst, src); 6193 %} 6194 %} 6195 6196 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6197 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6198 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6199 6200 ins_cost(200); // XXX 6201 format %{ "cmovpl $dst, $src\n\t" 6202 "cmovnel $dst, $src" %} 6203 ins_encode %{ 6204 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6205 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6206 %} 6207 ins_pipe(pipe_cmov_reg); 6208 %} 6209 6210 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6211 // inputs of the CMove 6212 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6213 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6214 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6215 6216 ins_cost(200); // XXX 6217 format %{ "cmovpl $dst, $src\n\t" 6218 "cmovnel $dst, $src" %} 6219 ins_encode %{ 6220 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6221 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6222 %} 6223 ins_pipe(pipe_cmov_reg); 6224 %} 6225 6226 // Conditional move 6227 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6228 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6229 6230 ins_cost(250); // XXX 6231 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6232 ins_encode %{ 6233 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6234 %} 6235 ins_pipe(pipe_cmov_mem); 6236 %} 6237 6238 // Conditional move 6239 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6240 %{ 6241 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6242 6243 ins_cost(250); // XXX 6244 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6245 ins_encode %{ 6246 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6247 %} 6248 ins_pipe(pipe_cmov_mem); 6249 %} 6250 6251 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6252 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6253 ins_cost(250); 6254 expand %{ 6255 cmovI_memU(cop, cr, dst, src); 6256 %} 6257 %} 6258 6259 // Conditional move 6260 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6261 %{ 6262 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6263 6264 ins_cost(200); // XXX 6265 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6266 ins_encode %{ 6267 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6268 %} 6269 ins_pipe(pipe_cmov_reg); 6270 %} 6271 6272 // Conditional move 6273 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6274 %{ 6275 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6276 6277 ins_cost(200); // XXX 6278 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6279 ins_encode %{ 6280 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6281 %} 6282 ins_pipe(pipe_cmov_reg); 6283 %} 6284 6285 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6286 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6287 ins_cost(200); 6288 expand %{ 6289 cmovN_regU(cop, cr, dst, src); 6290 %} 6291 %} 6292 6293 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6294 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6295 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6296 6297 ins_cost(200); // XXX 6298 format %{ "cmovpl $dst, $src\n\t" 6299 "cmovnel $dst, $src" %} 6300 ins_encode %{ 6301 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6302 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6303 %} 6304 ins_pipe(pipe_cmov_reg); 6305 %} 6306 6307 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6308 // inputs of the CMove 6309 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6310 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6311 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6312 6313 ins_cost(200); // XXX 6314 format %{ "cmovpl $dst, $src\n\t" 6315 "cmovnel $dst, $src" %} 6316 ins_encode %{ 6317 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6318 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6319 %} 6320 ins_pipe(pipe_cmov_reg); 6321 %} 6322 6323 // Conditional move 6324 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6325 %{ 6326 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6327 6328 ins_cost(200); // XXX 6329 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6330 ins_encode %{ 6331 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6332 %} 6333 ins_pipe(pipe_cmov_reg); // XXX 6334 %} 6335 6336 // Conditional move 6337 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6338 %{ 6339 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6340 6341 ins_cost(200); // XXX 6342 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6343 ins_encode %{ 6344 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6345 %} 6346 ins_pipe(pipe_cmov_reg); // XXX 6347 %} 6348 6349 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6350 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6351 ins_cost(200); 6352 expand %{ 6353 cmovP_regU(cop, cr, dst, src); 6354 %} 6355 %} 6356 6357 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6358 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6359 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6360 6361 ins_cost(200); // XXX 6362 format %{ "cmovpq $dst, $src\n\t" 6363 "cmovneq $dst, $src" %} 6364 ins_encode %{ 6365 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6366 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6367 %} 6368 ins_pipe(pipe_cmov_reg); 6369 %} 6370 6371 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6372 // inputs of the CMove 6373 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6374 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6375 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6376 6377 ins_cost(200); // XXX 6378 format %{ "cmovpq $dst, $src\n\t" 6379 "cmovneq $dst, $src" %} 6380 ins_encode %{ 6381 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6382 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6383 %} 6384 ins_pipe(pipe_cmov_reg); 6385 %} 6386 6387 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6388 %{ 6389 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6390 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6391 6392 ins_cost(100); // XXX 6393 format %{ "setbn$cop $dst\t# signed, long" %} 6394 ins_encode %{ 6395 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6396 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6397 %} 6398 ins_pipe(ialu_reg); 6399 %} 6400 6401 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6402 %{ 6403 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6404 6405 ins_cost(200); // XXX 6406 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6407 ins_encode %{ 6408 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6409 %} 6410 ins_pipe(pipe_cmov_reg); // XXX 6411 %} 6412 6413 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6414 %{ 6415 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6416 6417 ins_cost(200); // XXX 6418 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6419 ins_encode %{ 6420 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6421 %} 6422 ins_pipe(pipe_cmov_mem); // XXX 6423 %} 6424 6425 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6426 %{ 6427 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6428 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6429 6430 ins_cost(100); // XXX 6431 format %{ "setbn$cop $dst\t# unsigned, long" %} 6432 ins_encode %{ 6433 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6434 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6435 %} 6436 ins_pipe(ialu_reg); 6437 %} 6438 6439 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6440 %{ 6441 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6442 6443 ins_cost(200); // XXX 6444 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6445 ins_encode %{ 6446 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6447 %} 6448 ins_pipe(pipe_cmov_reg); // XXX 6449 %} 6450 6451 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6452 %{ 6453 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6454 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6455 6456 ins_cost(100); // XXX 6457 format %{ "setbn$cop $dst\t# unsigned, long" %} 6458 ins_encode %{ 6459 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6460 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6461 %} 6462 ins_pipe(ialu_reg); 6463 %} 6464 6465 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6466 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6467 ins_cost(200); 6468 expand %{ 6469 cmovL_regU(cop, cr, dst, src); 6470 %} 6471 %} 6472 6473 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6474 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6475 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6476 6477 ins_cost(200); // XXX 6478 format %{ "cmovpq $dst, $src\n\t" 6479 "cmovneq $dst, $src" %} 6480 ins_encode %{ 6481 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6482 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6483 %} 6484 ins_pipe(pipe_cmov_reg); 6485 %} 6486 6487 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6488 // inputs of the CMove 6489 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6490 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6491 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6492 6493 ins_cost(200); // XXX 6494 format %{ "cmovpq $dst, $src\n\t" 6495 "cmovneq $dst, $src" %} 6496 ins_encode %{ 6497 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6498 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6499 %} 6500 ins_pipe(pipe_cmov_reg); 6501 %} 6502 6503 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6504 %{ 6505 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6506 6507 ins_cost(200); // XXX 6508 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6509 ins_encode %{ 6510 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6511 %} 6512 ins_pipe(pipe_cmov_mem); // XXX 6513 %} 6514 6515 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6516 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6517 ins_cost(200); 6518 expand %{ 6519 cmovL_memU(cop, cr, dst, src); 6520 %} 6521 %} 6522 6523 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6524 %{ 6525 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6526 6527 ins_cost(200); // XXX 6528 format %{ "jn$cop skip\t# signed cmove float\n\t" 6529 "movss $dst, $src\n" 6530 "skip:" %} 6531 ins_encode %{ 6532 Label Lskip; 6533 // Invert sense of branch from sense of CMOV 6534 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6535 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6536 __ bind(Lskip); 6537 %} 6538 ins_pipe(pipe_slow); 6539 %} 6540 6541 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6542 %{ 6543 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6544 6545 ins_cost(200); // XXX 6546 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6547 "movss $dst, $src\n" 6548 "skip:" %} 6549 ins_encode %{ 6550 Label Lskip; 6551 // Invert sense of branch from sense of CMOV 6552 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6553 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6554 __ bind(Lskip); 6555 %} 6556 ins_pipe(pipe_slow); 6557 %} 6558 6559 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6560 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6561 ins_cost(200); 6562 expand %{ 6563 cmovF_regU(cop, cr, dst, src); 6564 %} 6565 %} 6566 6567 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6568 %{ 6569 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6570 6571 ins_cost(200); // XXX 6572 format %{ "jn$cop skip\t# signed cmove double\n\t" 6573 "movsd $dst, $src\n" 6574 "skip:" %} 6575 ins_encode %{ 6576 Label Lskip; 6577 // Invert sense of branch from sense of CMOV 6578 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6579 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6580 __ bind(Lskip); 6581 %} 6582 ins_pipe(pipe_slow); 6583 %} 6584 6585 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6586 %{ 6587 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6588 6589 ins_cost(200); // XXX 6590 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6591 "movsd $dst, $src\n" 6592 "skip:" %} 6593 ins_encode %{ 6594 Label Lskip; 6595 // Invert sense of branch from sense of CMOV 6596 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6597 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6598 __ bind(Lskip); 6599 %} 6600 ins_pipe(pipe_slow); 6601 %} 6602 6603 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6604 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6605 ins_cost(200); 6606 expand %{ 6607 cmovD_regU(cop, cr, dst, src); 6608 %} 6609 %} 6610 6611 //----------Arithmetic Instructions-------------------------------------------- 6612 //----------Addition Instructions---------------------------------------------- 6613 6614 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6615 %{ 6616 match(Set dst (AddI dst src)); 6617 effect(KILL cr); 6618 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); 6619 format %{ "addl $dst, $src\t# int" %} 6620 ins_encode %{ 6621 __ addl($dst$$Register, $src$$Register); 6622 %} 6623 ins_pipe(ialu_reg_reg); 6624 %} 6625 6626 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6627 %{ 6628 match(Set dst (AddI dst src)); 6629 effect(KILL cr); 6630 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); 6631 6632 format %{ "addl $dst, $src\t# int" %} 6633 ins_encode %{ 6634 __ addl($dst$$Register, $src$$constant); 6635 %} 6636 ins_pipe( ialu_reg ); 6637 %} 6638 6639 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6640 %{ 6641 match(Set dst (AddI dst (LoadI src))); 6642 effect(KILL cr); 6643 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); 6644 6645 ins_cost(150); // XXX 6646 format %{ "addl $dst, $src\t# int" %} 6647 ins_encode %{ 6648 __ addl($dst$$Register, $src$$Address); 6649 %} 6650 ins_pipe(ialu_reg_mem); 6651 %} 6652 6653 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6654 %{ 6655 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6656 effect(KILL cr); 6657 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); 6658 6659 ins_cost(150); // XXX 6660 format %{ "addl $dst, $src\t# int" %} 6661 ins_encode %{ 6662 __ addl($dst$$Address, $src$$Register); 6663 %} 6664 ins_pipe(ialu_mem_reg); 6665 %} 6666 6667 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6668 %{ 6669 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6670 effect(KILL cr); 6671 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); 6672 6673 6674 ins_cost(125); // XXX 6675 format %{ "addl $dst, $src\t# int" %} 6676 ins_encode %{ 6677 __ addl($dst$$Address, $src$$constant); 6678 %} 6679 ins_pipe(ialu_mem_imm); 6680 %} 6681 6682 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6683 %{ 6684 predicate(UseIncDec); 6685 match(Set dst (AddI dst src)); 6686 effect(KILL cr); 6687 6688 format %{ "incl $dst\t# int" %} 6689 ins_encode %{ 6690 __ incrementl($dst$$Register); 6691 %} 6692 ins_pipe(ialu_reg); 6693 %} 6694 6695 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6696 %{ 6697 predicate(UseIncDec); 6698 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6699 effect(KILL cr); 6700 6701 ins_cost(125); // XXX 6702 format %{ "incl $dst\t# int" %} 6703 ins_encode %{ 6704 __ incrementl($dst$$Address); 6705 %} 6706 ins_pipe(ialu_mem_imm); 6707 %} 6708 6709 // XXX why does that use AddI 6710 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6711 %{ 6712 predicate(UseIncDec); 6713 match(Set dst (AddI dst src)); 6714 effect(KILL cr); 6715 6716 format %{ "decl $dst\t# int" %} 6717 ins_encode %{ 6718 __ decrementl($dst$$Register); 6719 %} 6720 ins_pipe(ialu_reg); 6721 %} 6722 6723 // XXX why does that use AddI 6724 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6725 %{ 6726 predicate(UseIncDec); 6727 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6728 effect(KILL cr); 6729 6730 ins_cost(125); // XXX 6731 format %{ "decl $dst\t# int" %} 6732 ins_encode %{ 6733 __ decrementl($dst$$Address); 6734 %} 6735 ins_pipe(ialu_mem_imm); 6736 %} 6737 6738 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6739 %{ 6740 predicate(VM_Version::supports_fast_2op_lea()); 6741 match(Set dst (AddI (LShiftI index scale) disp)); 6742 6743 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6744 ins_encode %{ 6745 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6746 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6747 %} 6748 ins_pipe(ialu_reg_reg); 6749 %} 6750 6751 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6752 %{ 6753 predicate(VM_Version::supports_fast_3op_lea()); 6754 match(Set dst (AddI (AddI base index) disp)); 6755 6756 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6757 ins_encode %{ 6758 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6759 %} 6760 ins_pipe(ialu_reg_reg); 6761 %} 6762 6763 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6764 %{ 6765 predicate(VM_Version::supports_fast_2op_lea()); 6766 match(Set dst (AddI base (LShiftI index scale))); 6767 6768 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6769 ins_encode %{ 6770 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6771 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6772 %} 6773 ins_pipe(ialu_reg_reg); 6774 %} 6775 6776 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6777 %{ 6778 predicate(VM_Version::supports_fast_3op_lea()); 6779 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6780 6781 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6782 ins_encode %{ 6783 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6784 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6785 %} 6786 ins_pipe(ialu_reg_reg); 6787 %} 6788 6789 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6790 %{ 6791 match(Set dst (AddL dst src)); 6792 effect(KILL cr); 6793 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); 6794 6795 format %{ "addq $dst, $src\t# long" %} 6796 ins_encode %{ 6797 __ addq($dst$$Register, $src$$Register); 6798 %} 6799 ins_pipe(ialu_reg_reg); 6800 %} 6801 6802 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6803 %{ 6804 match(Set dst (AddL dst src)); 6805 effect(KILL cr); 6806 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); 6807 6808 format %{ "addq $dst, $src\t# long" %} 6809 ins_encode %{ 6810 __ addq($dst$$Register, $src$$constant); 6811 %} 6812 ins_pipe( ialu_reg ); 6813 %} 6814 6815 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6816 %{ 6817 match(Set dst (AddL dst (LoadL src))); 6818 effect(KILL cr); 6819 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); 6820 6821 ins_cost(150); // XXX 6822 format %{ "addq $dst, $src\t# long" %} 6823 ins_encode %{ 6824 __ addq($dst$$Register, $src$$Address); 6825 %} 6826 ins_pipe(ialu_reg_mem); 6827 %} 6828 6829 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6830 %{ 6831 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6832 effect(KILL cr); 6833 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); 6834 6835 ins_cost(150); // XXX 6836 format %{ "addq $dst, $src\t# long" %} 6837 ins_encode %{ 6838 __ addq($dst$$Address, $src$$Register); 6839 %} 6840 ins_pipe(ialu_mem_reg); 6841 %} 6842 6843 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6844 %{ 6845 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6846 effect(KILL cr); 6847 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); 6848 6849 ins_cost(125); // XXX 6850 format %{ "addq $dst, $src\t# long" %} 6851 ins_encode %{ 6852 __ addq($dst$$Address, $src$$constant); 6853 %} 6854 ins_pipe(ialu_mem_imm); 6855 %} 6856 6857 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6858 %{ 6859 predicate(UseIncDec); 6860 match(Set dst (AddL dst src)); 6861 effect(KILL cr); 6862 6863 format %{ "incq $dst\t# long" %} 6864 ins_encode %{ 6865 __ incrementq($dst$$Register); 6866 %} 6867 ins_pipe(ialu_reg); 6868 %} 6869 6870 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6871 %{ 6872 predicate(UseIncDec); 6873 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6874 effect(KILL cr); 6875 6876 ins_cost(125); // XXX 6877 format %{ "incq $dst\t# long" %} 6878 ins_encode %{ 6879 __ incrementq($dst$$Address); 6880 %} 6881 ins_pipe(ialu_mem_imm); 6882 %} 6883 6884 // XXX why does that use AddL 6885 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6886 %{ 6887 predicate(UseIncDec); 6888 match(Set dst (AddL dst src)); 6889 effect(KILL cr); 6890 6891 format %{ "decq $dst\t# long" %} 6892 ins_encode %{ 6893 __ decrementq($dst$$Register); 6894 %} 6895 ins_pipe(ialu_reg); 6896 %} 6897 6898 // XXX why does that use AddL 6899 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6900 %{ 6901 predicate(UseIncDec); 6902 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6903 effect(KILL cr); 6904 6905 ins_cost(125); // XXX 6906 format %{ "decq $dst\t# long" %} 6907 ins_encode %{ 6908 __ decrementq($dst$$Address); 6909 %} 6910 ins_pipe(ialu_mem_imm); 6911 %} 6912 6913 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6914 %{ 6915 predicate(VM_Version::supports_fast_2op_lea()); 6916 match(Set dst (AddL (LShiftL index scale) disp)); 6917 6918 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6919 ins_encode %{ 6920 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6921 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6922 %} 6923 ins_pipe(ialu_reg_reg); 6924 %} 6925 6926 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6927 %{ 6928 predicate(VM_Version::supports_fast_3op_lea()); 6929 match(Set dst (AddL (AddL base index) disp)); 6930 6931 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6932 ins_encode %{ 6933 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6934 %} 6935 ins_pipe(ialu_reg_reg); 6936 %} 6937 6938 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6939 %{ 6940 predicate(VM_Version::supports_fast_2op_lea()); 6941 match(Set dst (AddL base (LShiftL index scale))); 6942 6943 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6944 ins_encode %{ 6945 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6946 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6947 %} 6948 ins_pipe(ialu_reg_reg); 6949 %} 6950 6951 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6952 %{ 6953 predicate(VM_Version::supports_fast_3op_lea()); 6954 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6955 6956 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6957 ins_encode %{ 6958 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6959 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6960 %} 6961 ins_pipe(ialu_reg_reg); 6962 %} 6963 6964 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6965 %{ 6966 match(Set dst (AddP dst src)); 6967 effect(KILL cr); 6968 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); 6969 6970 format %{ "addq $dst, $src\t# ptr" %} 6971 ins_encode %{ 6972 __ addq($dst$$Register, $src$$Register); 6973 %} 6974 ins_pipe(ialu_reg_reg); 6975 %} 6976 6977 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6978 %{ 6979 match(Set dst (AddP dst src)); 6980 effect(KILL cr); 6981 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); 6982 6983 format %{ "addq $dst, $src\t# ptr" %} 6984 ins_encode %{ 6985 __ addq($dst$$Register, $src$$constant); 6986 %} 6987 ins_pipe( ialu_reg ); 6988 %} 6989 6990 // XXX addP mem ops ???? 6991 6992 instruct checkCastPP(rRegP dst) 6993 %{ 6994 match(Set dst (CheckCastPP dst)); 6995 6996 size(0); 6997 format %{ "# checkcastPP of $dst" %} 6998 ins_encode(/* empty encoding */); 6999 ins_pipe(empty); 7000 %} 7001 7002 instruct castPP(rRegP dst) 7003 %{ 7004 match(Set dst (CastPP dst)); 7005 7006 size(0); 7007 format %{ "# castPP of $dst" %} 7008 ins_encode(/* empty encoding */); 7009 ins_pipe(empty); 7010 %} 7011 7012 instruct castII(rRegI dst) 7013 %{ 7014 match(Set dst (CastII dst)); 7015 7016 size(0); 7017 format %{ "# castII of $dst" %} 7018 ins_encode(/* empty encoding */); 7019 ins_cost(0); 7020 ins_pipe(empty); 7021 %} 7022 7023 instruct castLL(rRegL dst) 7024 %{ 7025 match(Set dst (CastLL dst)); 7026 7027 size(0); 7028 format %{ "# castLL of $dst" %} 7029 ins_encode(/* empty encoding */); 7030 ins_cost(0); 7031 ins_pipe(empty); 7032 %} 7033 7034 instruct castFF(regF dst) 7035 %{ 7036 match(Set dst (CastFF dst)); 7037 7038 size(0); 7039 format %{ "# castFF of $dst" %} 7040 ins_encode(/* empty encoding */); 7041 ins_cost(0); 7042 ins_pipe(empty); 7043 %} 7044 7045 instruct castHH(regF dst) 7046 %{ 7047 match(Set dst (CastHH dst)); 7048 7049 size(0); 7050 format %{ "# castHH of $dst" %} 7051 ins_encode(/* empty encoding */); 7052 ins_cost(0); 7053 ins_pipe(empty); 7054 %} 7055 7056 instruct castDD(regD dst) 7057 %{ 7058 match(Set dst (CastDD dst)); 7059 7060 size(0); 7061 format %{ "# castDD of $dst" %} 7062 ins_encode(/* empty encoding */); 7063 ins_cost(0); 7064 ins_pipe(empty); 7065 %} 7066 7067 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7068 instruct compareAndSwapP(rRegI res, 7069 memory mem_ptr, 7070 rax_RegP oldval, rRegP newval, 7071 rFlagsReg cr) 7072 %{ 7073 predicate(n->as_LoadStore()->barrier_data() == 0); 7074 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7075 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7076 effect(KILL cr, KILL oldval); 7077 7078 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7079 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7080 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7081 ins_encode %{ 7082 __ lock(); 7083 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7084 __ setcc(Assembler::equal, $res$$Register); 7085 %} 7086 ins_pipe( pipe_cmpxchg ); 7087 %} 7088 7089 instruct compareAndSwapL(rRegI res, 7090 memory mem_ptr, 7091 rax_RegL oldval, rRegL newval, 7092 rFlagsReg cr) 7093 %{ 7094 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7095 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7096 effect(KILL cr, KILL oldval); 7097 7098 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7099 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7100 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7101 ins_encode %{ 7102 __ lock(); 7103 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7104 __ setcc(Assembler::equal, $res$$Register); 7105 %} 7106 ins_pipe( pipe_cmpxchg ); 7107 %} 7108 7109 instruct compareAndSwapI(rRegI res, 7110 memory mem_ptr, 7111 rax_RegI oldval, rRegI newval, 7112 rFlagsReg cr) 7113 %{ 7114 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7115 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7116 effect(KILL cr, KILL oldval); 7117 7118 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7119 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7120 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7121 ins_encode %{ 7122 __ lock(); 7123 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7124 __ setcc(Assembler::equal, $res$$Register); 7125 %} 7126 ins_pipe( pipe_cmpxchg ); 7127 %} 7128 7129 instruct compareAndSwapB(rRegI res, 7130 memory mem_ptr, 7131 rax_RegI oldval, rRegI newval, 7132 rFlagsReg cr) 7133 %{ 7134 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7135 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7136 effect(KILL cr, KILL oldval); 7137 7138 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7139 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7140 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7141 ins_encode %{ 7142 __ lock(); 7143 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7144 __ setcc(Assembler::equal, $res$$Register); 7145 %} 7146 ins_pipe( pipe_cmpxchg ); 7147 %} 7148 7149 instruct compareAndSwapS(rRegI res, 7150 memory mem_ptr, 7151 rax_RegI oldval, rRegI newval, 7152 rFlagsReg cr) 7153 %{ 7154 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7155 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7156 effect(KILL cr, KILL oldval); 7157 7158 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7159 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7160 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7161 ins_encode %{ 7162 __ lock(); 7163 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7164 __ setcc(Assembler::equal, $res$$Register); 7165 %} 7166 ins_pipe( pipe_cmpxchg ); 7167 %} 7168 7169 instruct compareAndSwapN(rRegI res, 7170 memory mem_ptr, 7171 rax_RegN oldval, rRegN newval, 7172 rFlagsReg cr) %{ 7173 predicate(n->as_LoadStore()->barrier_data() == 0); 7174 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7175 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7176 effect(KILL cr, KILL oldval); 7177 7178 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7179 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7180 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7181 ins_encode %{ 7182 __ lock(); 7183 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7184 __ setcc(Assembler::equal, $res$$Register); 7185 %} 7186 ins_pipe( pipe_cmpxchg ); 7187 %} 7188 7189 instruct compareAndExchangeB( 7190 memory mem_ptr, 7191 rax_RegI oldval, rRegI newval, 7192 rFlagsReg cr) 7193 %{ 7194 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7195 effect(KILL cr); 7196 7197 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7198 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7199 ins_encode %{ 7200 __ lock(); 7201 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7202 %} 7203 ins_pipe( pipe_cmpxchg ); 7204 %} 7205 7206 instruct compareAndExchangeS( 7207 memory mem_ptr, 7208 rax_RegI oldval, rRegI newval, 7209 rFlagsReg cr) 7210 %{ 7211 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7212 effect(KILL cr); 7213 7214 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7215 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7216 ins_encode %{ 7217 __ lock(); 7218 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7219 %} 7220 ins_pipe( pipe_cmpxchg ); 7221 %} 7222 7223 instruct compareAndExchangeI( 7224 memory mem_ptr, 7225 rax_RegI oldval, rRegI newval, 7226 rFlagsReg cr) 7227 %{ 7228 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7229 effect(KILL cr); 7230 7231 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7232 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7233 ins_encode %{ 7234 __ lock(); 7235 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7236 %} 7237 ins_pipe( pipe_cmpxchg ); 7238 %} 7239 7240 instruct compareAndExchangeL( 7241 memory mem_ptr, 7242 rax_RegL oldval, rRegL newval, 7243 rFlagsReg cr) 7244 %{ 7245 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7246 effect(KILL cr); 7247 7248 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7249 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7250 ins_encode %{ 7251 __ lock(); 7252 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7253 %} 7254 ins_pipe( pipe_cmpxchg ); 7255 %} 7256 7257 instruct compareAndExchangeN( 7258 memory mem_ptr, 7259 rax_RegN oldval, rRegN newval, 7260 rFlagsReg cr) %{ 7261 predicate(n->as_LoadStore()->barrier_data() == 0); 7262 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7263 effect(KILL cr); 7264 7265 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7266 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7267 ins_encode %{ 7268 __ lock(); 7269 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7270 %} 7271 ins_pipe( pipe_cmpxchg ); 7272 %} 7273 7274 instruct compareAndExchangeP( 7275 memory mem_ptr, 7276 rax_RegP oldval, rRegP newval, 7277 rFlagsReg cr) 7278 %{ 7279 predicate(n->as_LoadStore()->barrier_data() == 0); 7280 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7281 effect(KILL cr); 7282 7283 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7284 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7285 ins_encode %{ 7286 __ lock(); 7287 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7288 %} 7289 ins_pipe( pipe_cmpxchg ); 7290 %} 7291 7292 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7293 predicate(n->as_LoadStore()->result_not_used()); 7294 match(Set dummy (GetAndAddB mem add)); 7295 effect(KILL cr); 7296 format %{ "addb_lock $mem, $add" %} 7297 ins_encode %{ 7298 __ lock(); 7299 __ addb($mem$$Address, $add$$Register); 7300 %} 7301 ins_pipe(pipe_cmpxchg); 7302 %} 7303 7304 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7305 predicate(n->as_LoadStore()->result_not_used()); 7306 match(Set dummy (GetAndAddB mem add)); 7307 effect(KILL cr); 7308 format %{ "addb_lock $mem, $add" %} 7309 ins_encode %{ 7310 __ lock(); 7311 __ addb($mem$$Address, $add$$constant); 7312 %} 7313 ins_pipe(pipe_cmpxchg); 7314 %} 7315 7316 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7317 predicate(!n->as_LoadStore()->result_not_used()); 7318 match(Set newval (GetAndAddB mem newval)); 7319 effect(KILL cr); 7320 format %{ "xaddb_lock $mem, $newval" %} 7321 ins_encode %{ 7322 __ lock(); 7323 __ xaddb($mem$$Address, $newval$$Register); 7324 %} 7325 ins_pipe(pipe_cmpxchg); 7326 %} 7327 7328 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7329 predicate(n->as_LoadStore()->result_not_used()); 7330 match(Set dummy (GetAndAddS mem add)); 7331 effect(KILL cr); 7332 format %{ "addw_lock $mem, $add" %} 7333 ins_encode %{ 7334 __ lock(); 7335 __ addw($mem$$Address, $add$$Register); 7336 %} 7337 ins_pipe(pipe_cmpxchg); 7338 %} 7339 7340 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7341 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7342 match(Set dummy (GetAndAddS mem add)); 7343 effect(KILL cr); 7344 format %{ "addw_lock $mem, $add" %} 7345 ins_encode %{ 7346 __ lock(); 7347 __ addw($mem$$Address, $add$$constant); 7348 %} 7349 ins_pipe(pipe_cmpxchg); 7350 %} 7351 7352 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7353 predicate(!n->as_LoadStore()->result_not_used()); 7354 match(Set newval (GetAndAddS mem newval)); 7355 effect(KILL cr); 7356 format %{ "xaddw_lock $mem, $newval" %} 7357 ins_encode %{ 7358 __ lock(); 7359 __ xaddw($mem$$Address, $newval$$Register); 7360 %} 7361 ins_pipe(pipe_cmpxchg); 7362 %} 7363 7364 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7365 predicate(n->as_LoadStore()->result_not_used()); 7366 match(Set dummy (GetAndAddI mem add)); 7367 effect(KILL cr); 7368 format %{ "addl_lock $mem, $add" %} 7369 ins_encode %{ 7370 __ lock(); 7371 __ addl($mem$$Address, $add$$Register); 7372 %} 7373 ins_pipe(pipe_cmpxchg); 7374 %} 7375 7376 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7377 predicate(n->as_LoadStore()->result_not_used()); 7378 match(Set dummy (GetAndAddI mem add)); 7379 effect(KILL cr); 7380 format %{ "addl_lock $mem, $add" %} 7381 ins_encode %{ 7382 __ lock(); 7383 __ addl($mem$$Address, $add$$constant); 7384 %} 7385 ins_pipe(pipe_cmpxchg); 7386 %} 7387 7388 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7389 predicate(!n->as_LoadStore()->result_not_used()); 7390 match(Set newval (GetAndAddI mem newval)); 7391 effect(KILL cr); 7392 format %{ "xaddl_lock $mem, $newval" %} 7393 ins_encode %{ 7394 __ lock(); 7395 __ xaddl($mem$$Address, $newval$$Register); 7396 %} 7397 ins_pipe(pipe_cmpxchg); 7398 %} 7399 7400 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7401 predicate(n->as_LoadStore()->result_not_used()); 7402 match(Set dummy (GetAndAddL mem add)); 7403 effect(KILL cr); 7404 format %{ "addq_lock $mem, $add" %} 7405 ins_encode %{ 7406 __ lock(); 7407 __ addq($mem$$Address, $add$$Register); 7408 %} 7409 ins_pipe(pipe_cmpxchg); 7410 %} 7411 7412 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7413 predicate(n->as_LoadStore()->result_not_used()); 7414 match(Set dummy (GetAndAddL mem add)); 7415 effect(KILL cr); 7416 format %{ "addq_lock $mem, $add" %} 7417 ins_encode %{ 7418 __ lock(); 7419 __ addq($mem$$Address, $add$$constant); 7420 %} 7421 ins_pipe(pipe_cmpxchg); 7422 %} 7423 7424 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7425 predicate(!n->as_LoadStore()->result_not_used()); 7426 match(Set newval (GetAndAddL mem newval)); 7427 effect(KILL cr); 7428 format %{ "xaddq_lock $mem, $newval" %} 7429 ins_encode %{ 7430 __ lock(); 7431 __ xaddq($mem$$Address, $newval$$Register); 7432 %} 7433 ins_pipe(pipe_cmpxchg); 7434 %} 7435 7436 instruct xchgB( memory mem, rRegI newval) %{ 7437 match(Set newval (GetAndSetB mem newval)); 7438 format %{ "XCHGB $newval,[$mem]" %} 7439 ins_encode %{ 7440 __ xchgb($newval$$Register, $mem$$Address); 7441 %} 7442 ins_pipe( pipe_cmpxchg ); 7443 %} 7444 7445 instruct xchgS( memory mem, rRegI newval) %{ 7446 match(Set newval (GetAndSetS mem newval)); 7447 format %{ "XCHGW $newval,[$mem]" %} 7448 ins_encode %{ 7449 __ xchgw($newval$$Register, $mem$$Address); 7450 %} 7451 ins_pipe( pipe_cmpxchg ); 7452 %} 7453 7454 instruct xchgI( memory mem, rRegI newval) %{ 7455 match(Set newval (GetAndSetI mem newval)); 7456 format %{ "XCHGL $newval,[$mem]" %} 7457 ins_encode %{ 7458 __ xchgl($newval$$Register, $mem$$Address); 7459 %} 7460 ins_pipe( pipe_cmpxchg ); 7461 %} 7462 7463 instruct xchgL( memory mem, rRegL newval) %{ 7464 match(Set newval (GetAndSetL mem newval)); 7465 format %{ "XCHGL $newval,[$mem]" %} 7466 ins_encode %{ 7467 __ xchgq($newval$$Register, $mem$$Address); 7468 %} 7469 ins_pipe( pipe_cmpxchg ); 7470 %} 7471 7472 instruct xchgP( memory mem, rRegP newval) %{ 7473 match(Set newval (GetAndSetP mem newval)); 7474 predicate(n->as_LoadStore()->barrier_data() == 0); 7475 format %{ "XCHGQ $newval,[$mem]" %} 7476 ins_encode %{ 7477 __ xchgq($newval$$Register, $mem$$Address); 7478 %} 7479 ins_pipe( pipe_cmpxchg ); 7480 %} 7481 7482 instruct xchgN( memory mem, rRegN newval) %{ 7483 predicate(n->as_LoadStore()->barrier_data() == 0); 7484 match(Set newval (GetAndSetN mem newval)); 7485 format %{ "XCHGL $newval,$mem]" %} 7486 ins_encode %{ 7487 __ xchgl($newval$$Register, $mem$$Address); 7488 %} 7489 ins_pipe( pipe_cmpxchg ); 7490 %} 7491 7492 //----------Abs Instructions------------------------------------------- 7493 7494 // Integer Absolute Instructions 7495 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7496 %{ 7497 match(Set dst (AbsI src)); 7498 effect(TEMP dst, KILL cr); 7499 format %{ "xorl $dst, $dst\t# abs int\n\t" 7500 "subl $dst, $src\n\t" 7501 "cmovll $dst, $src" %} 7502 ins_encode %{ 7503 __ xorl($dst$$Register, $dst$$Register); 7504 __ subl($dst$$Register, $src$$Register); 7505 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7506 %} 7507 7508 ins_pipe(ialu_reg_reg); 7509 %} 7510 7511 // Long Absolute Instructions 7512 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7513 %{ 7514 match(Set dst (AbsL src)); 7515 effect(TEMP dst, KILL cr); 7516 format %{ "xorl $dst, $dst\t# abs long\n\t" 7517 "subq $dst, $src\n\t" 7518 "cmovlq $dst, $src" %} 7519 ins_encode %{ 7520 __ xorl($dst$$Register, $dst$$Register); 7521 __ subq($dst$$Register, $src$$Register); 7522 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7523 %} 7524 7525 ins_pipe(ialu_reg_reg); 7526 %} 7527 7528 //----------Subtraction Instructions------------------------------------------- 7529 7530 // Integer Subtraction Instructions 7531 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7532 %{ 7533 match(Set dst (SubI dst src)); 7534 effect(KILL cr); 7535 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); 7536 7537 format %{ "subl $dst, $src\t# int" %} 7538 ins_encode %{ 7539 __ subl($dst$$Register, $src$$Register); 7540 %} 7541 ins_pipe(ialu_reg_reg); 7542 %} 7543 7544 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7545 %{ 7546 match(Set dst (SubI dst (LoadI src))); 7547 effect(KILL cr); 7548 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); 7549 7550 ins_cost(150); 7551 format %{ "subl $dst, $src\t# int" %} 7552 ins_encode %{ 7553 __ subl($dst$$Register, $src$$Address); 7554 %} 7555 ins_pipe(ialu_reg_mem); 7556 %} 7557 7558 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7559 %{ 7560 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7561 effect(KILL cr); 7562 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); 7563 7564 ins_cost(150); 7565 format %{ "subl $dst, $src\t# int" %} 7566 ins_encode %{ 7567 __ subl($dst$$Address, $src$$Register); 7568 %} 7569 ins_pipe(ialu_mem_reg); 7570 %} 7571 7572 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7573 %{ 7574 match(Set dst (SubL dst src)); 7575 effect(KILL cr); 7576 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); 7577 7578 format %{ "subq $dst, $src\t# long" %} 7579 ins_encode %{ 7580 __ subq($dst$$Register, $src$$Register); 7581 %} 7582 ins_pipe(ialu_reg_reg); 7583 %} 7584 7585 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7586 %{ 7587 match(Set dst (SubL dst (LoadL src))); 7588 effect(KILL cr); 7589 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); 7590 7591 ins_cost(150); 7592 format %{ "subq $dst, $src\t# long" %} 7593 ins_encode %{ 7594 __ subq($dst$$Register, $src$$Address); 7595 %} 7596 ins_pipe(ialu_reg_mem); 7597 %} 7598 7599 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7600 %{ 7601 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7602 effect(KILL cr); 7603 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); 7604 7605 ins_cost(150); 7606 format %{ "subq $dst, $src\t# long" %} 7607 ins_encode %{ 7608 __ subq($dst$$Address, $src$$Register); 7609 %} 7610 ins_pipe(ialu_mem_reg); 7611 %} 7612 7613 // Subtract from a pointer 7614 // XXX hmpf??? 7615 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7616 %{ 7617 match(Set dst (AddP dst (SubI zero src))); 7618 effect(KILL cr); 7619 7620 format %{ "subq $dst, $src\t# ptr - int" %} 7621 ins_encode %{ 7622 __ subq($dst$$Register, $src$$Register); 7623 %} 7624 ins_pipe(ialu_reg_reg); 7625 %} 7626 7627 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7628 %{ 7629 match(Set dst (SubI zero dst)); 7630 effect(KILL cr); 7631 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7632 7633 format %{ "negl $dst\t# int" %} 7634 ins_encode %{ 7635 __ negl($dst$$Register); 7636 %} 7637 ins_pipe(ialu_reg); 7638 %} 7639 7640 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7641 %{ 7642 match(Set dst (NegI dst)); 7643 effect(KILL cr); 7644 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7645 7646 format %{ "negl $dst\t# int" %} 7647 ins_encode %{ 7648 __ negl($dst$$Register); 7649 %} 7650 ins_pipe(ialu_reg); 7651 %} 7652 7653 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7654 %{ 7655 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7656 effect(KILL cr); 7657 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7658 7659 format %{ "negl $dst\t# int" %} 7660 ins_encode %{ 7661 __ negl($dst$$Address); 7662 %} 7663 ins_pipe(ialu_reg); 7664 %} 7665 7666 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7667 %{ 7668 match(Set dst (SubL zero dst)); 7669 effect(KILL cr); 7670 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7671 7672 format %{ "negq $dst\t# long" %} 7673 ins_encode %{ 7674 __ negq($dst$$Register); 7675 %} 7676 ins_pipe(ialu_reg); 7677 %} 7678 7679 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7680 %{ 7681 match(Set dst (NegL dst)); 7682 effect(KILL cr); 7683 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7684 7685 format %{ "negq $dst\t# int" %} 7686 ins_encode %{ 7687 __ negq($dst$$Register); 7688 %} 7689 ins_pipe(ialu_reg); 7690 %} 7691 7692 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7693 %{ 7694 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7695 effect(KILL cr); 7696 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7697 7698 format %{ "negq $dst\t# long" %} 7699 ins_encode %{ 7700 __ negq($dst$$Address); 7701 %} 7702 ins_pipe(ialu_reg); 7703 %} 7704 7705 //----------Multiplication/Division Instructions------------------------------- 7706 // Integer Multiplication Instructions 7707 // Multiply Register 7708 7709 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7710 %{ 7711 match(Set dst (MulI dst src)); 7712 effect(KILL cr); 7713 7714 ins_cost(300); 7715 format %{ "imull $dst, $src\t# int" %} 7716 ins_encode %{ 7717 __ imull($dst$$Register, $src$$Register); 7718 %} 7719 ins_pipe(ialu_reg_reg_alu0); 7720 %} 7721 7722 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7723 %{ 7724 match(Set dst (MulI src imm)); 7725 effect(KILL cr); 7726 7727 ins_cost(300); 7728 format %{ "imull $dst, $src, $imm\t# int" %} 7729 ins_encode %{ 7730 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7731 %} 7732 ins_pipe(ialu_reg_reg_alu0); 7733 %} 7734 7735 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7736 %{ 7737 match(Set dst (MulI dst (LoadI src))); 7738 effect(KILL cr); 7739 7740 ins_cost(350); 7741 format %{ "imull $dst, $src\t# int" %} 7742 ins_encode %{ 7743 __ imull($dst$$Register, $src$$Address); 7744 %} 7745 ins_pipe(ialu_reg_mem_alu0); 7746 %} 7747 7748 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7749 %{ 7750 match(Set dst (MulI (LoadI src) imm)); 7751 effect(KILL cr); 7752 7753 ins_cost(300); 7754 format %{ "imull $dst, $src, $imm\t# int" %} 7755 ins_encode %{ 7756 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7757 %} 7758 ins_pipe(ialu_reg_mem_alu0); 7759 %} 7760 7761 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7762 %{ 7763 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7764 effect(KILL cr, KILL src2); 7765 7766 expand %{ mulI_rReg(dst, src1, cr); 7767 mulI_rReg(src2, src3, cr); 7768 addI_rReg(dst, src2, cr); %} 7769 %} 7770 7771 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7772 %{ 7773 match(Set dst (MulL dst src)); 7774 effect(KILL cr); 7775 7776 ins_cost(300); 7777 format %{ "imulq $dst, $src\t# long" %} 7778 ins_encode %{ 7779 __ imulq($dst$$Register, $src$$Register); 7780 %} 7781 ins_pipe(ialu_reg_reg_alu0); 7782 %} 7783 7784 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7785 %{ 7786 match(Set dst (MulL src imm)); 7787 effect(KILL cr); 7788 7789 ins_cost(300); 7790 format %{ "imulq $dst, $src, $imm\t# long" %} 7791 ins_encode %{ 7792 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7793 %} 7794 ins_pipe(ialu_reg_reg_alu0); 7795 %} 7796 7797 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7798 %{ 7799 match(Set dst (MulL dst (LoadL src))); 7800 effect(KILL cr); 7801 7802 ins_cost(350); 7803 format %{ "imulq $dst, $src\t# long" %} 7804 ins_encode %{ 7805 __ imulq($dst$$Register, $src$$Address); 7806 %} 7807 ins_pipe(ialu_reg_mem_alu0); 7808 %} 7809 7810 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7811 %{ 7812 match(Set dst (MulL (LoadL src) imm)); 7813 effect(KILL cr); 7814 7815 ins_cost(300); 7816 format %{ "imulq $dst, $src, $imm\t# long" %} 7817 ins_encode %{ 7818 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7819 %} 7820 ins_pipe(ialu_reg_mem_alu0); 7821 %} 7822 7823 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7824 %{ 7825 match(Set dst (MulHiL src rax)); 7826 effect(USE_KILL rax, KILL cr); 7827 7828 ins_cost(300); 7829 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7830 ins_encode %{ 7831 __ imulq($src$$Register); 7832 %} 7833 ins_pipe(ialu_reg_reg_alu0); 7834 %} 7835 7836 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7837 %{ 7838 match(Set dst (UMulHiL src rax)); 7839 effect(USE_KILL rax, KILL cr); 7840 7841 ins_cost(300); 7842 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7843 ins_encode %{ 7844 __ mulq($src$$Register); 7845 %} 7846 ins_pipe(ialu_reg_reg_alu0); 7847 %} 7848 7849 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7850 rFlagsReg cr) 7851 %{ 7852 match(Set rax (DivI rax div)); 7853 effect(KILL rdx, KILL cr); 7854 7855 ins_cost(30*100+10*100); // XXX 7856 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7857 "jne,s normal\n\t" 7858 "xorl rdx, rdx\n\t" 7859 "cmpl $div, -1\n\t" 7860 "je,s done\n" 7861 "normal: cdql\n\t" 7862 "idivl $div\n" 7863 "done:" %} 7864 ins_encode(cdql_enc(div)); 7865 ins_pipe(ialu_reg_reg_alu0); 7866 %} 7867 7868 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7869 rFlagsReg cr) 7870 %{ 7871 match(Set rax (DivL rax div)); 7872 effect(KILL rdx, KILL cr); 7873 7874 ins_cost(30*100+10*100); // XXX 7875 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7876 "cmpq rax, rdx\n\t" 7877 "jne,s normal\n\t" 7878 "xorl rdx, rdx\n\t" 7879 "cmpq $div, -1\n\t" 7880 "je,s done\n" 7881 "normal: cdqq\n\t" 7882 "idivq $div\n" 7883 "done:" %} 7884 ins_encode(cdqq_enc(div)); 7885 ins_pipe(ialu_reg_reg_alu0); 7886 %} 7887 7888 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7889 %{ 7890 match(Set rax (UDivI rax div)); 7891 effect(KILL rdx, KILL cr); 7892 7893 ins_cost(300); 7894 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7895 ins_encode %{ 7896 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7897 %} 7898 ins_pipe(ialu_reg_reg_alu0); 7899 %} 7900 7901 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7902 %{ 7903 match(Set rax (UDivL rax div)); 7904 effect(KILL rdx, KILL cr); 7905 7906 ins_cost(300); 7907 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7908 ins_encode %{ 7909 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7910 %} 7911 ins_pipe(ialu_reg_reg_alu0); 7912 %} 7913 7914 // Integer DIVMOD with Register, both quotient and mod results 7915 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7916 rFlagsReg cr) 7917 %{ 7918 match(DivModI rax div); 7919 effect(KILL cr); 7920 7921 ins_cost(30*100+10*100); // XXX 7922 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7923 "jne,s normal\n\t" 7924 "xorl rdx, rdx\n\t" 7925 "cmpl $div, -1\n\t" 7926 "je,s done\n" 7927 "normal: cdql\n\t" 7928 "idivl $div\n" 7929 "done:" %} 7930 ins_encode(cdql_enc(div)); 7931 ins_pipe(pipe_slow); 7932 %} 7933 7934 // Long DIVMOD with Register, both quotient and mod results 7935 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7936 rFlagsReg cr) 7937 %{ 7938 match(DivModL rax div); 7939 effect(KILL cr); 7940 7941 ins_cost(30*100+10*100); // XXX 7942 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7943 "cmpq rax, rdx\n\t" 7944 "jne,s normal\n\t" 7945 "xorl rdx, rdx\n\t" 7946 "cmpq $div, -1\n\t" 7947 "je,s done\n" 7948 "normal: cdqq\n\t" 7949 "idivq $div\n" 7950 "done:" %} 7951 ins_encode(cdqq_enc(div)); 7952 ins_pipe(pipe_slow); 7953 %} 7954 7955 // Unsigned integer DIVMOD with Register, both quotient and mod results 7956 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7957 no_rax_rdx_RegI div, rFlagsReg cr) 7958 %{ 7959 match(UDivModI rax div); 7960 effect(TEMP tmp, KILL cr); 7961 7962 ins_cost(300); 7963 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7964 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7965 %} 7966 ins_encode %{ 7967 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7968 %} 7969 ins_pipe(pipe_slow); 7970 %} 7971 7972 // Unsigned long DIVMOD with Register, both quotient and mod results 7973 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7974 no_rax_rdx_RegL div, rFlagsReg cr) 7975 %{ 7976 match(UDivModL rax div); 7977 effect(TEMP tmp, KILL cr); 7978 7979 ins_cost(300); 7980 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7981 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7982 %} 7983 ins_encode %{ 7984 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7985 %} 7986 ins_pipe(pipe_slow); 7987 %} 7988 7989 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7990 rFlagsReg cr) 7991 %{ 7992 match(Set rdx (ModI rax div)); 7993 effect(KILL rax, KILL cr); 7994 7995 ins_cost(300); // XXX 7996 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7997 "jne,s normal\n\t" 7998 "xorl rdx, rdx\n\t" 7999 "cmpl $div, -1\n\t" 8000 "je,s done\n" 8001 "normal: cdql\n\t" 8002 "idivl $div\n" 8003 "done:" %} 8004 ins_encode(cdql_enc(div)); 8005 ins_pipe(ialu_reg_reg_alu0); 8006 %} 8007 8008 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8009 rFlagsReg cr) 8010 %{ 8011 match(Set rdx (ModL rax div)); 8012 effect(KILL rax, KILL cr); 8013 8014 ins_cost(300); // XXX 8015 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8016 "cmpq rax, rdx\n\t" 8017 "jne,s normal\n\t" 8018 "xorl rdx, rdx\n\t" 8019 "cmpq $div, -1\n\t" 8020 "je,s done\n" 8021 "normal: cdqq\n\t" 8022 "idivq $div\n" 8023 "done:" %} 8024 ins_encode(cdqq_enc(div)); 8025 ins_pipe(ialu_reg_reg_alu0); 8026 %} 8027 8028 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8029 %{ 8030 match(Set rdx (UModI rax div)); 8031 effect(KILL rax, KILL cr); 8032 8033 ins_cost(300); 8034 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8035 ins_encode %{ 8036 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8037 %} 8038 ins_pipe(ialu_reg_reg_alu0); 8039 %} 8040 8041 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8042 %{ 8043 match(Set rdx (UModL rax div)); 8044 effect(KILL rax, KILL cr); 8045 8046 ins_cost(300); 8047 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8048 ins_encode %{ 8049 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8050 %} 8051 ins_pipe(ialu_reg_reg_alu0); 8052 %} 8053 8054 // Integer Shift Instructions 8055 // Shift Left by one, two, three 8056 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8057 %{ 8058 match(Set dst (LShiftI dst shift)); 8059 effect(KILL cr); 8060 8061 format %{ "sall $dst, $shift" %} 8062 ins_encode %{ 8063 __ sall($dst$$Register, $shift$$constant); 8064 %} 8065 ins_pipe(ialu_reg); 8066 %} 8067 8068 // Shift Left by 8-bit immediate 8069 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8070 %{ 8071 match(Set dst (LShiftI dst shift)); 8072 effect(KILL cr); 8073 8074 format %{ "sall $dst, $shift" %} 8075 ins_encode %{ 8076 __ sall($dst$$Register, $shift$$constant); 8077 %} 8078 ins_pipe(ialu_reg); 8079 %} 8080 8081 // Shift Left by 8-bit immediate 8082 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8083 %{ 8084 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8085 effect(KILL cr); 8086 8087 format %{ "sall $dst, $shift" %} 8088 ins_encode %{ 8089 __ sall($dst$$Address, $shift$$constant); 8090 %} 8091 ins_pipe(ialu_mem_imm); 8092 %} 8093 8094 // Shift Left by variable 8095 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8096 %{ 8097 predicate(!VM_Version::supports_bmi2()); 8098 match(Set dst (LShiftI dst shift)); 8099 effect(KILL cr); 8100 8101 format %{ "sall $dst, $shift" %} 8102 ins_encode %{ 8103 __ sall($dst$$Register); 8104 %} 8105 ins_pipe(ialu_reg_reg); 8106 %} 8107 8108 // Shift Left by variable 8109 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8110 %{ 8111 predicate(!VM_Version::supports_bmi2()); 8112 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8113 effect(KILL cr); 8114 8115 format %{ "sall $dst, $shift" %} 8116 ins_encode %{ 8117 __ sall($dst$$Address); 8118 %} 8119 ins_pipe(ialu_mem_reg); 8120 %} 8121 8122 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8123 %{ 8124 predicate(VM_Version::supports_bmi2()); 8125 match(Set dst (LShiftI src shift)); 8126 8127 format %{ "shlxl $dst, $src, $shift" %} 8128 ins_encode %{ 8129 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8130 %} 8131 ins_pipe(ialu_reg_reg); 8132 %} 8133 8134 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8135 %{ 8136 predicate(VM_Version::supports_bmi2()); 8137 match(Set dst (LShiftI (LoadI src) shift)); 8138 ins_cost(175); 8139 format %{ "shlxl $dst, $src, $shift" %} 8140 ins_encode %{ 8141 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8142 %} 8143 ins_pipe(ialu_reg_mem); 8144 %} 8145 8146 // Arithmetic Shift Right by 8-bit immediate 8147 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8148 %{ 8149 match(Set dst (RShiftI dst shift)); 8150 effect(KILL cr); 8151 8152 format %{ "sarl $dst, $shift" %} 8153 ins_encode %{ 8154 __ sarl($dst$$Register, $shift$$constant); 8155 %} 8156 ins_pipe(ialu_mem_imm); 8157 %} 8158 8159 // Arithmetic Shift Right by 8-bit immediate 8160 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8161 %{ 8162 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8163 effect(KILL cr); 8164 8165 format %{ "sarl $dst, $shift" %} 8166 ins_encode %{ 8167 __ sarl($dst$$Address, $shift$$constant); 8168 %} 8169 ins_pipe(ialu_mem_imm); 8170 %} 8171 8172 // Arithmetic Shift Right by variable 8173 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8174 %{ 8175 predicate(!VM_Version::supports_bmi2()); 8176 match(Set dst (RShiftI dst shift)); 8177 effect(KILL cr); 8178 8179 format %{ "sarl $dst, $shift" %} 8180 ins_encode %{ 8181 __ sarl($dst$$Register); 8182 %} 8183 ins_pipe(ialu_reg_reg); 8184 %} 8185 8186 // Arithmetic Shift Right by variable 8187 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8188 %{ 8189 predicate(!VM_Version::supports_bmi2()); 8190 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8191 effect(KILL cr); 8192 8193 format %{ "sarl $dst, $shift" %} 8194 ins_encode %{ 8195 __ sarl($dst$$Address); 8196 %} 8197 ins_pipe(ialu_mem_reg); 8198 %} 8199 8200 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8201 %{ 8202 predicate(VM_Version::supports_bmi2()); 8203 match(Set dst (RShiftI src shift)); 8204 8205 format %{ "sarxl $dst, $src, $shift" %} 8206 ins_encode %{ 8207 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8208 %} 8209 ins_pipe(ialu_reg_reg); 8210 %} 8211 8212 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8213 %{ 8214 predicate(VM_Version::supports_bmi2()); 8215 match(Set dst (RShiftI (LoadI src) shift)); 8216 ins_cost(175); 8217 format %{ "sarxl $dst, $src, $shift" %} 8218 ins_encode %{ 8219 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8220 %} 8221 ins_pipe(ialu_reg_mem); 8222 %} 8223 8224 // Logical Shift Right by 8-bit immediate 8225 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8226 %{ 8227 match(Set dst (URShiftI dst shift)); 8228 effect(KILL cr); 8229 8230 format %{ "shrl $dst, $shift" %} 8231 ins_encode %{ 8232 __ shrl($dst$$Register, $shift$$constant); 8233 %} 8234 ins_pipe(ialu_reg); 8235 %} 8236 8237 // Logical Shift Right by 8-bit immediate 8238 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8239 %{ 8240 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8241 effect(KILL cr); 8242 8243 format %{ "shrl $dst, $shift" %} 8244 ins_encode %{ 8245 __ shrl($dst$$Address, $shift$$constant); 8246 %} 8247 ins_pipe(ialu_mem_imm); 8248 %} 8249 8250 // Logical Shift Right by variable 8251 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8252 %{ 8253 predicate(!VM_Version::supports_bmi2()); 8254 match(Set dst (URShiftI dst shift)); 8255 effect(KILL cr); 8256 8257 format %{ "shrl $dst, $shift" %} 8258 ins_encode %{ 8259 __ shrl($dst$$Register); 8260 %} 8261 ins_pipe(ialu_reg_reg); 8262 %} 8263 8264 // Logical Shift Right by variable 8265 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8266 %{ 8267 predicate(!VM_Version::supports_bmi2()); 8268 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8269 effect(KILL cr); 8270 8271 format %{ "shrl $dst, $shift" %} 8272 ins_encode %{ 8273 __ shrl($dst$$Address); 8274 %} 8275 ins_pipe(ialu_mem_reg); 8276 %} 8277 8278 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8279 %{ 8280 predicate(VM_Version::supports_bmi2()); 8281 match(Set dst (URShiftI src shift)); 8282 8283 format %{ "shrxl $dst, $src, $shift" %} 8284 ins_encode %{ 8285 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8286 %} 8287 ins_pipe(ialu_reg_reg); 8288 %} 8289 8290 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8291 %{ 8292 predicate(VM_Version::supports_bmi2()); 8293 match(Set dst (URShiftI (LoadI src) shift)); 8294 ins_cost(175); 8295 format %{ "shrxl $dst, $src, $shift" %} 8296 ins_encode %{ 8297 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8298 %} 8299 ins_pipe(ialu_reg_mem); 8300 %} 8301 8302 // Long Shift Instructions 8303 // Shift Left by one, two, three 8304 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8305 %{ 8306 match(Set dst (LShiftL dst shift)); 8307 effect(KILL cr); 8308 8309 format %{ "salq $dst, $shift" %} 8310 ins_encode %{ 8311 __ salq($dst$$Register, $shift$$constant); 8312 %} 8313 ins_pipe(ialu_reg); 8314 %} 8315 8316 // Shift Left by 8-bit immediate 8317 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8318 %{ 8319 match(Set dst (LShiftL dst shift)); 8320 effect(KILL cr); 8321 8322 format %{ "salq $dst, $shift" %} 8323 ins_encode %{ 8324 __ salq($dst$$Register, $shift$$constant); 8325 %} 8326 ins_pipe(ialu_reg); 8327 %} 8328 8329 // Shift Left by 8-bit immediate 8330 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8331 %{ 8332 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8333 effect(KILL cr); 8334 8335 format %{ "salq $dst, $shift" %} 8336 ins_encode %{ 8337 __ salq($dst$$Address, $shift$$constant); 8338 %} 8339 ins_pipe(ialu_mem_imm); 8340 %} 8341 8342 // Shift Left by variable 8343 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8344 %{ 8345 predicate(!VM_Version::supports_bmi2()); 8346 match(Set dst (LShiftL dst shift)); 8347 effect(KILL cr); 8348 8349 format %{ "salq $dst, $shift" %} 8350 ins_encode %{ 8351 __ salq($dst$$Register); 8352 %} 8353 ins_pipe(ialu_reg_reg); 8354 %} 8355 8356 // Shift Left by variable 8357 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8358 %{ 8359 predicate(!VM_Version::supports_bmi2()); 8360 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8361 effect(KILL cr); 8362 8363 format %{ "salq $dst, $shift" %} 8364 ins_encode %{ 8365 __ salq($dst$$Address); 8366 %} 8367 ins_pipe(ialu_mem_reg); 8368 %} 8369 8370 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8371 %{ 8372 predicate(VM_Version::supports_bmi2()); 8373 match(Set dst (LShiftL src shift)); 8374 8375 format %{ "shlxq $dst, $src, $shift" %} 8376 ins_encode %{ 8377 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8378 %} 8379 ins_pipe(ialu_reg_reg); 8380 %} 8381 8382 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8383 %{ 8384 predicate(VM_Version::supports_bmi2()); 8385 match(Set dst (LShiftL (LoadL src) shift)); 8386 ins_cost(175); 8387 format %{ "shlxq $dst, $src, $shift" %} 8388 ins_encode %{ 8389 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8390 %} 8391 ins_pipe(ialu_reg_mem); 8392 %} 8393 8394 // Arithmetic Shift Right by 8-bit immediate 8395 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8396 %{ 8397 match(Set dst (RShiftL dst shift)); 8398 effect(KILL cr); 8399 8400 format %{ "sarq $dst, $shift" %} 8401 ins_encode %{ 8402 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8403 %} 8404 ins_pipe(ialu_mem_imm); 8405 %} 8406 8407 // Arithmetic Shift Right by 8-bit immediate 8408 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8409 %{ 8410 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8411 effect(KILL cr); 8412 8413 format %{ "sarq $dst, $shift" %} 8414 ins_encode %{ 8415 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8416 %} 8417 ins_pipe(ialu_mem_imm); 8418 %} 8419 8420 // Arithmetic Shift Right by variable 8421 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8422 %{ 8423 predicate(!VM_Version::supports_bmi2()); 8424 match(Set dst (RShiftL dst shift)); 8425 effect(KILL cr); 8426 8427 format %{ "sarq $dst, $shift" %} 8428 ins_encode %{ 8429 __ sarq($dst$$Register); 8430 %} 8431 ins_pipe(ialu_reg_reg); 8432 %} 8433 8434 // Arithmetic Shift Right by variable 8435 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8436 %{ 8437 predicate(!VM_Version::supports_bmi2()); 8438 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8439 effect(KILL cr); 8440 8441 format %{ "sarq $dst, $shift" %} 8442 ins_encode %{ 8443 __ sarq($dst$$Address); 8444 %} 8445 ins_pipe(ialu_mem_reg); 8446 %} 8447 8448 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8449 %{ 8450 predicate(VM_Version::supports_bmi2()); 8451 match(Set dst (RShiftL src shift)); 8452 8453 format %{ "sarxq $dst, $src, $shift" %} 8454 ins_encode %{ 8455 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8456 %} 8457 ins_pipe(ialu_reg_reg); 8458 %} 8459 8460 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8461 %{ 8462 predicate(VM_Version::supports_bmi2()); 8463 match(Set dst (RShiftL (LoadL src) shift)); 8464 ins_cost(175); 8465 format %{ "sarxq $dst, $src, $shift" %} 8466 ins_encode %{ 8467 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8468 %} 8469 ins_pipe(ialu_reg_mem); 8470 %} 8471 8472 // Logical Shift Right by 8-bit immediate 8473 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8474 %{ 8475 match(Set dst (URShiftL dst shift)); 8476 effect(KILL cr); 8477 8478 format %{ "shrq $dst, $shift" %} 8479 ins_encode %{ 8480 __ shrq($dst$$Register, $shift$$constant); 8481 %} 8482 ins_pipe(ialu_reg); 8483 %} 8484 8485 // Logical Shift Right by 8-bit immediate 8486 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8487 %{ 8488 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8489 effect(KILL cr); 8490 8491 format %{ "shrq $dst, $shift" %} 8492 ins_encode %{ 8493 __ shrq($dst$$Address, $shift$$constant); 8494 %} 8495 ins_pipe(ialu_mem_imm); 8496 %} 8497 8498 // Logical Shift Right by variable 8499 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8500 %{ 8501 predicate(!VM_Version::supports_bmi2()); 8502 match(Set dst (URShiftL dst shift)); 8503 effect(KILL cr); 8504 8505 format %{ "shrq $dst, $shift" %} 8506 ins_encode %{ 8507 __ shrq($dst$$Register); 8508 %} 8509 ins_pipe(ialu_reg_reg); 8510 %} 8511 8512 // Logical Shift Right by variable 8513 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8514 %{ 8515 predicate(!VM_Version::supports_bmi2()); 8516 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8517 effect(KILL cr); 8518 8519 format %{ "shrq $dst, $shift" %} 8520 ins_encode %{ 8521 __ shrq($dst$$Address); 8522 %} 8523 ins_pipe(ialu_mem_reg); 8524 %} 8525 8526 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8527 %{ 8528 predicate(VM_Version::supports_bmi2()); 8529 match(Set dst (URShiftL src shift)); 8530 8531 format %{ "shrxq $dst, $src, $shift" %} 8532 ins_encode %{ 8533 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8534 %} 8535 ins_pipe(ialu_reg_reg); 8536 %} 8537 8538 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8539 %{ 8540 predicate(VM_Version::supports_bmi2()); 8541 match(Set dst (URShiftL (LoadL src) shift)); 8542 ins_cost(175); 8543 format %{ "shrxq $dst, $src, $shift" %} 8544 ins_encode %{ 8545 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8546 %} 8547 ins_pipe(ialu_reg_mem); 8548 %} 8549 8550 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8551 // This idiom is used by the compiler for the i2b bytecode. 8552 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8553 %{ 8554 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8555 8556 format %{ "movsbl $dst, $src\t# i2b" %} 8557 ins_encode %{ 8558 __ movsbl($dst$$Register, $src$$Register); 8559 %} 8560 ins_pipe(ialu_reg_reg); 8561 %} 8562 8563 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8564 // This idiom is used by the compiler the i2s bytecode. 8565 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8566 %{ 8567 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8568 8569 format %{ "movswl $dst, $src\t# i2s" %} 8570 ins_encode %{ 8571 __ movswl($dst$$Register, $src$$Register); 8572 %} 8573 ins_pipe(ialu_reg_reg); 8574 %} 8575 8576 // ROL/ROR instructions 8577 8578 // Rotate left by constant. 8579 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8580 %{ 8581 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8582 match(Set dst (RotateLeft dst shift)); 8583 effect(KILL cr); 8584 format %{ "roll $dst, $shift" %} 8585 ins_encode %{ 8586 __ roll($dst$$Register, $shift$$constant); 8587 %} 8588 ins_pipe(ialu_reg); 8589 %} 8590 8591 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8592 %{ 8593 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8594 match(Set dst (RotateLeft src shift)); 8595 format %{ "rolxl $dst, $src, $shift" %} 8596 ins_encode %{ 8597 int shift = 32 - ($shift$$constant & 31); 8598 __ rorxl($dst$$Register, $src$$Register, shift); 8599 %} 8600 ins_pipe(ialu_reg_reg); 8601 %} 8602 8603 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8604 %{ 8605 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8606 match(Set dst (RotateLeft (LoadI src) shift)); 8607 ins_cost(175); 8608 format %{ "rolxl $dst, $src, $shift" %} 8609 ins_encode %{ 8610 int shift = 32 - ($shift$$constant & 31); 8611 __ rorxl($dst$$Register, $src$$Address, shift); 8612 %} 8613 ins_pipe(ialu_reg_mem); 8614 %} 8615 8616 // Rotate Left by variable 8617 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8618 %{ 8619 predicate(n->bottom_type()->basic_type() == T_INT); 8620 match(Set dst (RotateLeft dst shift)); 8621 effect(KILL cr); 8622 format %{ "roll $dst, $shift" %} 8623 ins_encode %{ 8624 __ roll($dst$$Register); 8625 %} 8626 ins_pipe(ialu_reg_reg); 8627 %} 8628 8629 // Rotate Right by constant. 8630 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8631 %{ 8632 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8633 match(Set dst (RotateRight dst shift)); 8634 effect(KILL cr); 8635 format %{ "rorl $dst, $shift" %} 8636 ins_encode %{ 8637 __ rorl($dst$$Register, $shift$$constant); 8638 %} 8639 ins_pipe(ialu_reg); 8640 %} 8641 8642 // Rotate Right by constant. 8643 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8644 %{ 8645 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8646 match(Set dst (RotateRight src shift)); 8647 format %{ "rorxl $dst, $src, $shift" %} 8648 ins_encode %{ 8649 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8650 %} 8651 ins_pipe(ialu_reg_reg); 8652 %} 8653 8654 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8655 %{ 8656 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8657 match(Set dst (RotateRight (LoadI src) shift)); 8658 ins_cost(175); 8659 format %{ "rorxl $dst, $src, $shift" %} 8660 ins_encode %{ 8661 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8662 %} 8663 ins_pipe(ialu_reg_mem); 8664 %} 8665 8666 // Rotate Right by variable 8667 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8668 %{ 8669 predicate(n->bottom_type()->basic_type() == T_INT); 8670 match(Set dst (RotateRight dst shift)); 8671 effect(KILL cr); 8672 format %{ "rorl $dst, $shift" %} 8673 ins_encode %{ 8674 __ rorl($dst$$Register); 8675 %} 8676 ins_pipe(ialu_reg_reg); 8677 %} 8678 8679 // Rotate Left by constant. 8680 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8681 %{ 8682 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8683 match(Set dst (RotateLeft dst shift)); 8684 effect(KILL cr); 8685 format %{ "rolq $dst, $shift" %} 8686 ins_encode %{ 8687 __ rolq($dst$$Register, $shift$$constant); 8688 %} 8689 ins_pipe(ialu_reg); 8690 %} 8691 8692 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8693 %{ 8694 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8695 match(Set dst (RotateLeft src shift)); 8696 format %{ "rolxq $dst, $src, $shift" %} 8697 ins_encode %{ 8698 int shift = 64 - ($shift$$constant & 63); 8699 __ rorxq($dst$$Register, $src$$Register, shift); 8700 %} 8701 ins_pipe(ialu_reg_reg); 8702 %} 8703 8704 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8705 %{ 8706 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8707 match(Set dst (RotateLeft (LoadL src) shift)); 8708 ins_cost(175); 8709 format %{ "rolxq $dst, $src, $shift" %} 8710 ins_encode %{ 8711 int shift = 64 - ($shift$$constant & 63); 8712 __ rorxq($dst$$Register, $src$$Address, shift); 8713 %} 8714 ins_pipe(ialu_reg_mem); 8715 %} 8716 8717 // Rotate Left by variable 8718 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8719 %{ 8720 predicate(n->bottom_type()->basic_type() == T_LONG); 8721 match(Set dst (RotateLeft dst shift)); 8722 effect(KILL cr); 8723 format %{ "rolq $dst, $shift" %} 8724 ins_encode %{ 8725 __ rolq($dst$$Register); 8726 %} 8727 ins_pipe(ialu_reg_reg); 8728 %} 8729 8730 // Rotate Right by constant. 8731 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8732 %{ 8733 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8734 match(Set dst (RotateRight dst shift)); 8735 effect(KILL cr); 8736 format %{ "rorq $dst, $shift" %} 8737 ins_encode %{ 8738 __ rorq($dst$$Register, $shift$$constant); 8739 %} 8740 ins_pipe(ialu_reg); 8741 %} 8742 8743 // Rotate Right by constant 8744 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8745 %{ 8746 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8747 match(Set dst (RotateRight src shift)); 8748 format %{ "rorxq $dst, $src, $shift" %} 8749 ins_encode %{ 8750 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8751 %} 8752 ins_pipe(ialu_reg_reg); 8753 %} 8754 8755 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8756 %{ 8757 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8758 match(Set dst (RotateRight (LoadL src) shift)); 8759 ins_cost(175); 8760 format %{ "rorxq $dst, $src, $shift" %} 8761 ins_encode %{ 8762 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8763 %} 8764 ins_pipe(ialu_reg_mem); 8765 %} 8766 8767 // Rotate Right by variable 8768 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8769 %{ 8770 predicate(n->bottom_type()->basic_type() == T_LONG); 8771 match(Set dst (RotateRight dst shift)); 8772 effect(KILL cr); 8773 format %{ "rorq $dst, $shift" %} 8774 ins_encode %{ 8775 __ rorq($dst$$Register); 8776 %} 8777 ins_pipe(ialu_reg_reg); 8778 %} 8779 8780 //----------------------------- CompressBits/ExpandBits ------------------------ 8781 8782 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8783 predicate(n->bottom_type()->isa_long()); 8784 match(Set dst (CompressBits src mask)); 8785 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8786 ins_encode %{ 8787 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8788 %} 8789 ins_pipe( pipe_slow ); 8790 %} 8791 8792 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8793 predicate(n->bottom_type()->isa_long()); 8794 match(Set dst (ExpandBits src mask)); 8795 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8796 ins_encode %{ 8797 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8798 %} 8799 ins_pipe( pipe_slow ); 8800 %} 8801 8802 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8803 predicate(n->bottom_type()->isa_long()); 8804 match(Set dst (CompressBits src (LoadL mask))); 8805 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8806 ins_encode %{ 8807 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8808 %} 8809 ins_pipe( pipe_slow ); 8810 %} 8811 8812 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8813 predicate(n->bottom_type()->isa_long()); 8814 match(Set dst (ExpandBits src (LoadL mask))); 8815 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8816 ins_encode %{ 8817 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8818 %} 8819 ins_pipe( pipe_slow ); 8820 %} 8821 8822 8823 // Logical Instructions 8824 8825 // Integer Logical Instructions 8826 8827 // And Instructions 8828 // And Register with Register 8829 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8830 %{ 8831 match(Set dst (AndI dst src)); 8832 effect(KILL cr); 8833 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); 8834 8835 format %{ "andl $dst, $src\t# int" %} 8836 ins_encode %{ 8837 __ andl($dst$$Register, $src$$Register); 8838 %} 8839 ins_pipe(ialu_reg_reg); 8840 %} 8841 8842 // And Register with Immediate 255 8843 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8844 %{ 8845 match(Set dst (AndI src mask)); 8846 8847 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8848 ins_encode %{ 8849 __ movzbl($dst$$Register, $src$$Register); 8850 %} 8851 ins_pipe(ialu_reg); 8852 %} 8853 8854 // And Register with Immediate 255 and promote to long 8855 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8856 %{ 8857 match(Set dst (ConvI2L (AndI src mask))); 8858 8859 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8860 ins_encode %{ 8861 __ movzbl($dst$$Register, $src$$Register); 8862 %} 8863 ins_pipe(ialu_reg); 8864 %} 8865 8866 // And Register with Immediate 65535 8867 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8868 %{ 8869 match(Set dst (AndI src mask)); 8870 8871 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8872 ins_encode %{ 8873 __ movzwl($dst$$Register, $src$$Register); 8874 %} 8875 ins_pipe(ialu_reg); 8876 %} 8877 8878 // And Register with Immediate 65535 and promote to long 8879 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8880 %{ 8881 match(Set dst (ConvI2L (AndI src mask))); 8882 8883 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8884 ins_encode %{ 8885 __ movzwl($dst$$Register, $src$$Register); 8886 %} 8887 ins_pipe(ialu_reg); 8888 %} 8889 8890 // Can skip int2long conversions after AND with small bitmask 8891 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8892 %{ 8893 predicate(VM_Version::supports_bmi2()); 8894 ins_cost(125); 8895 effect(TEMP tmp, KILL cr); 8896 match(Set dst (ConvI2L (AndI src mask))); 8897 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8898 ins_encode %{ 8899 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8900 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8901 %} 8902 ins_pipe(ialu_reg_reg); 8903 %} 8904 8905 // And Register with Immediate 8906 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8907 %{ 8908 match(Set dst (AndI dst src)); 8909 effect(KILL cr); 8910 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); 8911 8912 format %{ "andl $dst, $src\t# int" %} 8913 ins_encode %{ 8914 __ andl($dst$$Register, $src$$constant); 8915 %} 8916 ins_pipe(ialu_reg); 8917 %} 8918 8919 // And Register with Memory 8920 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8921 %{ 8922 match(Set dst (AndI dst (LoadI src))); 8923 effect(KILL cr); 8924 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); 8925 8926 ins_cost(150); 8927 format %{ "andl $dst, $src\t# int" %} 8928 ins_encode %{ 8929 __ andl($dst$$Register, $src$$Address); 8930 %} 8931 ins_pipe(ialu_reg_mem); 8932 %} 8933 8934 // And Memory with Register 8935 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8936 %{ 8937 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8938 effect(KILL cr); 8939 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); 8940 8941 ins_cost(150); 8942 format %{ "andb $dst, $src\t# byte" %} 8943 ins_encode %{ 8944 __ andb($dst$$Address, $src$$Register); 8945 %} 8946 ins_pipe(ialu_mem_reg); 8947 %} 8948 8949 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8950 %{ 8951 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8952 effect(KILL cr); 8953 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); 8954 8955 ins_cost(150); 8956 format %{ "andl $dst, $src\t# int" %} 8957 ins_encode %{ 8958 __ andl($dst$$Address, $src$$Register); 8959 %} 8960 ins_pipe(ialu_mem_reg); 8961 %} 8962 8963 // And Memory with Immediate 8964 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8965 %{ 8966 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8967 effect(KILL cr); 8968 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); 8969 8970 ins_cost(125); 8971 format %{ "andl $dst, $src\t# int" %} 8972 ins_encode %{ 8973 __ andl($dst$$Address, $src$$constant); 8974 %} 8975 ins_pipe(ialu_mem_imm); 8976 %} 8977 8978 // BMI1 instructions 8979 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8980 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8981 predicate(UseBMI1Instructions); 8982 effect(KILL cr); 8983 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8984 8985 ins_cost(125); 8986 format %{ "andnl $dst, $src1, $src2" %} 8987 8988 ins_encode %{ 8989 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8990 %} 8991 ins_pipe(ialu_reg_mem); 8992 %} 8993 8994 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8995 match(Set dst (AndI (XorI src1 minus_1) src2)); 8996 predicate(UseBMI1Instructions); 8997 effect(KILL cr); 8998 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8999 9000 format %{ "andnl $dst, $src1, $src2" %} 9001 9002 ins_encode %{ 9003 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9004 %} 9005 ins_pipe(ialu_reg); 9006 %} 9007 9008 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 9009 match(Set dst (AndI (SubI imm_zero src) src)); 9010 predicate(UseBMI1Instructions); 9011 effect(KILL cr); 9012 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9013 9014 format %{ "blsil $dst, $src" %} 9015 9016 ins_encode %{ 9017 __ blsil($dst$$Register, $src$$Register); 9018 %} 9019 ins_pipe(ialu_reg); 9020 %} 9021 9022 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 9023 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9024 predicate(UseBMI1Instructions); 9025 effect(KILL cr); 9026 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9027 9028 ins_cost(125); 9029 format %{ "blsil $dst, $src" %} 9030 9031 ins_encode %{ 9032 __ blsil($dst$$Register, $src$$Address); 9033 %} 9034 ins_pipe(ialu_reg_mem); 9035 %} 9036 9037 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9038 %{ 9039 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9040 predicate(UseBMI1Instructions); 9041 effect(KILL cr); 9042 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9043 9044 ins_cost(125); 9045 format %{ "blsmskl $dst, $src" %} 9046 9047 ins_encode %{ 9048 __ blsmskl($dst$$Register, $src$$Address); 9049 %} 9050 ins_pipe(ialu_reg_mem); 9051 %} 9052 9053 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9054 %{ 9055 match(Set dst (XorI (AddI src minus_1) src)); 9056 predicate(UseBMI1Instructions); 9057 effect(KILL cr); 9058 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9059 9060 format %{ "blsmskl $dst, $src" %} 9061 9062 ins_encode %{ 9063 __ blsmskl($dst$$Register, $src$$Register); 9064 %} 9065 9066 ins_pipe(ialu_reg); 9067 %} 9068 9069 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9070 %{ 9071 match(Set dst (AndI (AddI src minus_1) src) ); 9072 predicate(UseBMI1Instructions); 9073 effect(KILL cr); 9074 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9075 9076 format %{ "blsrl $dst, $src" %} 9077 9078 ins_encode %{ 9079 __ blsrl($dst$$Register, $src$$Register); 9080 %} 9081 9082 ins_pipe(ialu_reg_mem); 9083 %} 9084 9085 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9086 %{ 9087 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9088 predicate(UseBMI1Instructions); 9089 effect(KILL cr); 9090 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9091 9092 ins_cost(125); 9093 format %{ "blsrl $dst, $src" %} 9094 9095 ins_encode %{ 9096 __ blsrl($dst$$Register, $src$$Address); 9097 %} 9098 9099 ins_pipe(ialu_reg); 9100 %} 9101 9102 // Or Instructions 9103 // Or Register with Register 9104 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9105 %{ 9106 match(Set dst (OrI dst src)); 9107 effect(KILL cr); 9108 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); 9109 9110 format %{ "orl $dst, $src\t# int" %} 9111 ins_encode %{ 9112 __ orl($dst$$Register, $src$$Register); 9113 %} 9114 ins_pipe(ialu_reg_reg); 9115 %} 9116 9117 // Or Register with Immediate 9118 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9119 %{ 9120 match(Set dst (OrI dst src)); 9121 effect(KILL cr); 9122 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); 9123 9124 format %{ "orl $dst, $src\t# int" %} 9125 ins_encode %{ 9126 __ orl($dst$$Register, $src$$constant); 9127 %} 9128 ins_pipe(ialu_reg); 9129 %} 9130 9131 // Or Register with Memory 9132 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9133 %{ 9134 match(Set dst (OrI dst (LoadI src))); 9135 effect(KILL cr); 9136 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); 9137 9138 ins_cost(150); 9139 format %{ "orl $dst, $src\t# int" %} 9140 ins_encode %{ 9141 __ orl($dst$$Register, $src$$Address); 9142 %} 9143 ins_pipe(ialu_reg_mem); 9144 %} 9145 9146 // Or Memory with Register 9147 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9148 %{ 9149 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9150 effect(KILL cr); 9151 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); 9152 9153 ins_cost(150); 9154 format %{ "orb $dst, $src\t# byte" %} 9155 ins_encode %{ 9156 __ orb($dst$$Address, $src$$Register); 9157 %} 9158 ins_pipe(ialu_mem_reg); 9159 %} 9160 9161 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9162 %{ 9163 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9164 effect(KILL cr); 9165 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); 9166 9167 ins_cost(150); 9168 format %{ "orl $dst, $src\t# int" %} 9169 ins_encode %{ 9170 __ orl($dst$$Address, $src$$Register); 9171 %} 9172 ins_pipe(ialu_mem_reg); 9173 %} 9174 9175 // Or Memory with Immediate 9176 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9177 %{ 9178 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9179 effect(KILL cr); 9180 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); 9181 9182 ins_cost(125); 9183 format %{ "orl $dst, $src\t# int" %} 9184 ins_encode %{ 9185 __ orl($dst$$Address, $src$$constant); 9186 %} 9187 ins_pipe(ialu_mem_imm); 9188 %} 9189 9190 // Xor Instructions 9191 // Xor Register with Register 9192 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9193 %{ 9194 match(Set dst (XorI dst src)); 9195 effect(KILL cr); 9196 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); 9197 9198 format %{ "xorl $dst, $src\t# int" %} 9199 ins_encode %{ 9200 __ xorl($dst$$Register, $src$$Register); 9201 %} 9202 ins_pipe(ialu_reg_reg); 9203 %} 9204 9205 // Xor Register with Immediate -1 9206 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9207 match(Set dst (XorI dst imm)); 9208 9209 format %{ "not $dst" %} 9210 ins_encode %{ 9211 __ notl($dst$$Register); 9212 %} 9213 ins_pipe(ialu_reg); 9214 %} 9215 9216 // Xor Register with Immediate 9217 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9218 %{ 9219 match(Set dst (XorI dst src)); 9220 effect(KILL cr); 9221 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); 9222 9223 format %{ "xorl $dst, $src\t# int" %} 9224 ins_encode %{ 9225 __ xorl($dst$$Register, $src$$constant); 9226 %} 9227 ins_pipe(ialu_reg); 9228 %} 9229 9230 // Xor Register with Memory 9231 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9232 %{ 9233 match(Set dst (XorI dst (LoadI src))); 9234 effect(KILL cr); 9235 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); 9236 9237 ins_cost(150); 9238 format %{ "xorl $dst, $src\t# int" %} 9239 ins_encode %{ 9240 __ xorl($dst$$Register, $src$$Address); 9241 %} 9242 ins_pipe(ialu_reg_mem); 9243 %} 9244 9245 // Xor Memory with Register 9246 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9247 %{ 9248 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9249 effect(KILL cr); 9250 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); 9251 9252 ins_cost(150); 9253 format %{ "xorb $dst, $src\t# byte" %} 9254 ins_encode %{ 9255 __ xorb($dst$$Address, $src$$Register); 9256 %} 9257 ins_pipe(ialu_mem_reg); 9258 %} 9259 9260 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9261 %{ 9262 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9263 effect(KILL cr); 9264 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); 9265 9266 ins_cost(150); 9267 format %{ "xorl $dst, $src\t# int" %} 9268 ins_encode %{ 9269 __ xorl($dst$$Address, $src$$Register); 9270 %} 9271 ins_pipe(ialu_mem_reg); 9272 %} 9273 9274 // Xor Memory with Immediate 9275 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9276 %{ 9277 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9278 effect(KILL cr); 9279 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); 9280 9281 ins_cost(125); 9282 format %{ "xorl $dst, $src\t# int" %} 9283 ins_encode %{ 9284 __ xorl($dst$$Address, $src$$constant); 9285 %} 9286 ins_pipe(ialu_mem_imm); 9287 %} 9288 9289 9290 // Long Logical Instructions 9291 9292 // And Instructions 9293 // And Register with Register 9294 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9295 %{ 9296 match(Set dst (AndL dst src)); 9297 effect(KILL cr); 9298 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); 9299 9300 format %{ "andq $dst, $src\t# long" %} 9301 ins_encode %{ 9302 __ andq($dst$$Register, $src$$Register); 9303 %} 9304 ins_pipe(ialu_reg_reg); 9305 %} 9306 9307 // And Register with Immediate 255 9308 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9309 %{ 9310 match(Set dst (AndL src mask)); 9311 9312 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9313 ins_encode %{ 9314 // movzbl zeroes out the upper 32-bit and does not need REX.W 9315 __ movzbl($dst$$Register, $src$$Register); 9316 %} 9317 ins_pipe(ialu_reg); 9318 %} 9319 9320 // And Register with Immediate 65535 9321 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9322 %{ 9323 match(Set dst (AndL src mask)); 9324 9325 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9326 ins_encode %{ 9327 // movzwl zeroes out the upper 32-bit and does not need REX.W 9328 __ movzwl($dst$$Register, $src$$Register); 9329 %} 9330 ins_pipe(ialu_reg); 9331 %} 9332 9333 // And Register with Immediate 9334 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9335 %{ 9336 match(Set dst (AndL dst src)); 9337 effect(KILL cr); 9338 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); 9339 9340 format %{ "andq $dst, $src\t# long" %} 9341 ins_encode %{ 9342 __ andq($dst$$Register, $src$$constant); 9343 %} 9344 ins_pipe(ialu_reg); 9345 %} 9346 9347 // And Register with Memory 9348 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9349 %{ 9350 match(Set dst (AndL dst (LoadL src))); 9351 effect(KILL cr); 9352 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); 9353 9354 ins_cost(150); 9355 format %{ "andq $dst, $src\t# long" %} 9356 ins_encode %{ 9357 __ andq($dst$$Register, $src$$Address); 9358 %} 9359 ins_pipe(ialu_reg_mem); 9360 %} 9361 9362 // And Memory with Register 9363 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9364 %{ 9365 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9366 effect(KILL cr); 9367 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); 9368 9369 ins_cost(150); 9370 format %{ "andq $dst, $src\t# long" %} 9371 ins_encode %{ 9372 __ andq($dst$$Address, $src$$Register); 9373 %} 9374 ins_pipe(ialu_mem_reg); 9375 %} 9376 9377 // And Memory with Immediate 9378 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9379 %{ 9380 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9381 effect(KILL cr); 9382 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); 9383 9384 ins_cost(125); 9385 format %{ "andq $dst, $src\t# long" %} 9386 ins_encode %{ 9387 __ andq($dst$$Address, $src$$constant); 9388 %} 9389 ins_pipe(ialu_mem_imm); 9390 %} 9391 9392 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9393 %{ 9394 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9395 // because AND/OR works well enough for 8/32-bit values. 9396 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9397 9398 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9399 effect(KILL cr); 9400 9401 ins_cost(125); 9402 format %{ "btrq $dst, log2(not($con))\t# long" %} 9403 ins_encode %{ 9404 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9405 %} 9406 ins_pipe(ialu_mem_imm); 9407 %} 9408 9409 // BMI1 instructions 9410 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9411 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9412 predicate(UseBMI1Instructions); 9413 effect(KILL cr); 9414 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9415 9416 ins_cost(125); 9417 format %{ "andnq $dst, $src1, $src2" %} 9418 9419 ins_encode %{ 9420 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9421 %} 9422 ins_pipe(ialu_reg_mem); 9423 %} 9424 9425 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9426 match(Set dst (AndL (XorL src1 minus_1) src2)); 9427 predicate(UseBMI1Instructions); 9428 effect(KILL cr); 9429 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9430 9431 format %{ "andnq $dst, $src1, $src2" %} 9432 9433 ins_encode %{ 9434 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9435 %} 9436 ins_pipe(ialu_reg_mem); 9437 %} 9438 9439 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9440 match(Set dst (AndL (SubL imm_zero src) src)); 9441 predicate(UseBMI1Instructions); 9442 effect(KILL cr); 9443 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9444 9445 format %{ "blsiq $dst, $src" %} 9446 9447 ins_encode %{ 9448 __ blsiq($dst$$Register, $src$$Register); 9449 %} 9450 ins_pipe(ialu_reg); 9451 %} 9452 9453 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9454 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9455 predicate(UseBMI1Instructions); 9456 effect(KILL cr); 9457 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9458 9459 ins_cost(125); 9460 format %{ "blsiq $dst, $src" %} 9461 9462 ins_encode %{ 9463 __ blsiq($dst$$Register, $src$$Address); 9464 %} 9465 ins_pipe(ialu_reg_mem); 9466 %} 9467 9468 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9469 %{ 9470 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9471 predicate(UseBMI1Instructions); 9472 effect(KILL cr); 9473 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9474 9475 ins_cost(125); 9476 format %{ "blsmskq $dst, $src" %} 9477 9478 ins_encode %{ 9479 __ blsmskq($dst$$Register, $src$$Address); 9480 %} 9481 ins_pipe(ialu_reg_mem); 9482 %} 9483 9484 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9485 %{ 9486 match(Set dst (XorL (AddL src minus_1) src)); 9487 predicate(UseBMI1Instructions); 9488 effect(KILL cr); 9489 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9490 9491 format %{ "blsmskq $dst, $src" %} 9492 9493 ins_encode %{ 9494 __ blsmskq($dst$$Register, $src$$Register); 9495 %} 9496 9497 ins_pipe(ialu_reg); 9498 %} 9499 9500 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9501 %{ 9502 match(Set dst (AndL (AddL src minus_1) src) ); 9503 predicate(UseBMI1Instructions); 9504 effect(KILL cr); 9505 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9506 9507 format %{ "blsrq $dst, $src" %} 9508 9509 ins_encode %{ 9510 __ blsrq($dst$$Register, $src$$Register); 9511 %} 9512 9513 ins_pipe(ialu_reg); 9514 %} 9515 9516 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9517 %{ 9518 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9519 predicate(UseBMI1Instructions); 9520 effect(KILL cr); 9521 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9522 9523 ins_cost(125); 9524 format %{ "blsrq $dst, $src" %} 9525 9526 ins_encode %{ 9527 __ blsrq($dst$$Register, $src$$Address); 9528 %} 9529 9530 ins_pipe(ialu_reg); 9531 %} 9532 9533 // Or Instructions 9534 // Or Register with Register 9535 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9536 %{ 9537 match(Set dst (OrL dst src)); 9538 effect(KILL cr); 9539 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); 9540 9541 format %{ "orq $dst, $src\t# long" %} 9542 ins_encode %{ 9543 __ orq($dst$$Register, $src$$Register); 9544 %} 9545 ins_pipe(ialu_reg_reg); 9546 %} 9547 9548 // Use any_RegP to match R15 (TLS register) without spilling. 9549 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9550 match(Set dst (OrL dst (CastP2X src))); 9551 effect(KILL cr); 9552 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); 9553 9554 format %{ "orq $dst, $src\t# long" %} 9555 ins_encode %{ 9556 __ orq($dst$$Register, $src$$Register); 9557 %} 9558 ins_pipe(ialu_reg_reg); 9559 %} 9560 9561 9562 // Or Register with Immediate 9563 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9564 %{ 9565 match(Set dst (OrL dst src)); 9566 effect(KILL cr); 9567 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); 9568 9569 format %{ "orq $dst, $src\t# long" %} 9570 ins_encode %{ 9571 __ orq($dst$$Register, $src$$constant); 9572 %} 9573 ins_pipe(ialu_reg); 9574 %} 9575 9576 // Or Register with Memory 9577 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9578 %{ 9579 match(Set dst (OrL dst (LoadL src))); 9580 effect(KILL cr); 9581 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); 9582 9583 ins_cost(150); 9584 format %{ "orq $dst, $src\t# long" %} 9585 ins_encode %{ 9586 __ orq($dst$$Register, $src$$Address); 9587 %} 9588 ins_pipe(ialu_reg_mem); 9589 %} 9590 9591 // Or Memory with Register 9592 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9593 %{ 9594 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9595 effect(KILL cr); 9596 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); 9597 9598 ins_cost(150); 9599 format %{ "orq $dst, $src\t# long" %} 9600 ins_encode %{ 9601 __ orq($dst$$Address, $src$$Register); 9602 %} 9603 ins_pipe(ialu_mem_reg); 9604 %} 9605 9606 // Or Memory with Immediate 9607 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9608 %{ 9609 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9610 effect(KILL cr); 9611 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); 9612 9613 ins_cost(125); 9614 format %{ "orq $dst, $src\t# long" %} 9615 ins_encode %{ 9616 __ orq($dst$$Address, $src$$constant); 9617 %} 9618 ins_pipe(ialu_mem_imm); 9619 %} 9620 9621 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9622 %{ 9623 // con should be a pure 64-bit power of 2 immediate 9624 // because AND/OR works well enough for 8/32-bit values. 9625 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9626 9627 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9628 effect(KILL cr); 9629 9630 ins_cost(125); 9631 format %{ "btsq $dst, log2($con)\t# long" %} 9632 ins_encode %{ 9633 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9634 %} 9635 ins_pipe(ialu_mem_imm); 9636 %} 9637 9638 // Xor Instructions 9639 // Xor Register with Register 9640 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9641 %{ 9642 match(Set dst (XorL dst src)); 9643 effect(KILL cr); 9644 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); 9645 9646 format %{ "xorq $dst, $src\t# long" %} 9647 ins_encode %{ 9648 __ xorq($dst$$Register, $src$$Register); 9649 %} 9650 ins_pipe(ialu_reg_reg); 9651 %} 9652 9653 // Xor Register with Immediate -1 9654 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9655 match(Set dst (XorL dst imm)); 9656 9657 format %{ "notq $dst" %} 9658 ins_encode %{ 9659 __ notq($dst$$Register); 9660 %} 9661 ins_pipe(ialu_reg); 9662 %} 9663 9664 // Xor Register with Immediate 9665 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9666 %{ 9667 match(Set dst (XorL dst src)); 9668 effect(KILL cr); 9669 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); 9670 9671 format %{ "xorq $dst, $src\t# long" %} 9672 ins_encode %{ 9673 __ xorq($dst$$Register, $src$$constant); 9674 %} 9675 ins_pipe(ialu_reg); 9676 %} 9677 9678 // Xor Register with Memory 9679 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9680 %{ 9681 match(Set dst (XorL dst (LoadL src))); 9682 effect(KILL cr); 9683 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); 9684 9685 ins_cost(150); 9686 format %{ "xorq $dst, $src\t# long" %} 9687 ins_encode %{ 9688 __ xorq($dst$$Register, $src$$Address); 9689 %} 9690 ins_pipe(ialu_reg_mem); 9691 %} 9692 9693 // Xor Memory with Register 9694 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9695 %{ 9696 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9697 effect(KILL cr); 9698 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); 9699 9700 ins_cost(150); 9701 format %{ "xorq $dst, $src\t# long" %} 9702 ins_encode %{ 9703 __ xorq($dst$$Address, $src$$Register); 9704 %} 9705 ins_pipe(ialu_mem_reg); 9706 %} 9707 9708 // Xor Memory with Immediate 9709 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9710 %{ 9711 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9712 effect(KILL cr); 9713 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); 9714 9715 ins_cost(125); 9716 format %{ "xorq $dst, $src\t# long" %} 9717 ins_encode %{ 9718 __ xorq($dst$$Address, $src$$constant); 9719 %} 9720 ins_pipe(ialu_mem_imm); 9721 %} 9722 9723 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9724 %{ 9725 match(Set dst (CmpLTMask p q)); 9726 effect(KILL cr); 9727 9728 ins_cost(400); 9729 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9730 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 9731 "negl $dst" %} 9732 ins_encode %{ 9733 __ cmpl($p$$Register, $q$$Register); 9734 __ setcc(Assembler::less, $dst$$Register); 9735 __ negl($dst$$Register); 9736 %} 9737 ins_pipe(pipe_slow); 9738 %} 9739 9740 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9741 %{ 9742 match(Set dst (CmpLTMask dst zero)); 9743 effect(KILL cr); 9744 9745 ins_cost(100); 9746 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9747 ins_encode %{ 9748 __ sarl($dst$$Register, 31); 9749 %} 9750 ins_pipe(ialu_reg); 9751 %} 9752 9753 /* Better to save a register than avoid a branch */ 9754 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9755 %{ 9756 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9757 effect(KILL cr); 9758 ins_cost(300); 9759 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9760 "jge done\n\t" 9761 "addl $p,$y\n" 9762 "done: " %} 9763 ins_encode %{ 9764 Register Rp = $p$$Register; 9765 Register Rq = $q$$Register; 9766 Register Ry = $y$$Register; 9767 Label done; 9768 __ subl(Rp, Rq); 9769 __ jccb(Assembler::greaterEqual, done); 9770 __ addl(Rp, Ry); 9771 __ bind(done); 9772 %} 9773 ins_pipe(pipe_cmplt); 9774 %} 9775 9776 /* Better to save a register than avoid a branch */ 9777 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9778 %{ 9779 match(Set y (AndI (CmpLTMask p q) y)); 9780 effect(KILL cr); 9781 9782 ins_cost(300); 9783 9784 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9785 "jlt done\n\t" 9786 "xorl $y, $y\n" 9787 "done: " %} 9788 ins_encode %{ 9789 Register Rp = $p$$Register; 9790 Register Rq = $q$$Register; 9791 Register Ry = $y$$Register; 9792 Label done; 9793 __ cmpl(Rp, Rq); 9794 __ jccb(Assembler::less, done); 9795 __ xorl(Ry, Ry); 9796 __ bind(done); 9797 %} 9798 ins_pipe(pipe_cmplt); 9799 %} 9800 9801 9802 //---------- FP Instructions------------------------------------------------ 9803 9804 // Really expensive, avoid 9805 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9806 %{ 9807 match(Set cr (CmpF src1 src2)); 9808 9809 ins_cost(500); 9810 format %{ "ucomiss $src1, $src2\n\t" 9811 "jnp,s exit\n\t" 9812 "pushfq\t# saw NaN, set CF\n\t" 9813 "andq [rsp], #0xffffff2b\n\t" 9814 "popfq\n" 9815 "exit:" %} 9816 ins_encode %{ 9817 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9818 emit_cmpfp_fixup(masm); 9819 %} 9820 ins_pipe(pipe_slow); 9821 %} 9822 9823 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9824 match(Set cr (CmpF src1 src2)); 9825 9826 ins_cost(100); 9827 format %{ "ucomiss $src1, $src2" %} 9828 ins_encode %{ 9829 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9830 %} 9831 ins_pipe(pipe_slow); 9832 %} 9833 9834 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9835 match(Set cr (CmpF src1 (LoadF src2))); 9836 9837 ins_cost(100); 9838 format %{ "ucomiss $src1, $src2" %} 9839 ins_encode %{ 9840 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9841 %} 9842 ins_pipe(pipe_slow); 9843 %} 9844 9845 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9846 match(Set cr (CmpF src con)); 9847 ins_cost(100); 9848 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9849 ins_encode %{ 9850 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9851 %} 9852 ins_pipe(pipe_slow); 9853 %} 9854 9855 // Really expensive, avoid 9856 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9857 %{ 9858 match(Set cr (CmpD src1 src2)); 9859 9860 ins_cost(500); 9861 format %{ "ucomisd $src1, $src2\n\t" 9862 "jnp,s exit\n\t" 9863 "pushfq\t# saw NaN, set CF\n\t" 9864 "andq [rsp], #0xffffff2b\n\t" 9865 "popfq\n" 9866 "exit:" %} 9867 ins_encode %{ 9868 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9869 emit_cmpfp_fixup(masm); 9870 %} 9871 ins_pipe(pipe_slow); 9872 %} 9873 9874 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9875 match(Set cr (CmpD src1 src2)); 9876 9877 ins_cost(100); 9878 format %{ "ucomisd $src1, $src2 test" %} 9879 ins_encode %{ 9880 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9881 %} 9882 ins_pipe(pipe_slow); 9883 %} 9884 9885 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9886 match(Set cr (CmpD src1 (LoadD src2))); 9887 9888 ins_cost(100); 9889 format %{ "ucomisd $src1, $src2" %} 9890 ins_encode %{ 9891 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9892 %} 9893 ins_pipe(pipe_slow); 9894 %} 9895 9896 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9897 match(Set cr (CmpD src con)); 9898 ins_cost(100); 9899 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9900 ins_encode %{ 9901 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9902 %} 9903 ins_pipe(pipe_slow); 9904 %} 9905 9906 // Compare into -1,0,1 9907 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9908 %{ 9909 match(Set dst (CmpF3 src1 src2)); 9910 effect(KILL cr); 9911 9912 ins_cost(275); 9913 format %{ "ucomiss $src1, $src2\n\t" 9914 "movl $dst, #-1\n\t" 9915 "jp,s done\n\t" 9916 "jb,s done\n\t" 9917 "setne $dst\n\t" 9918 "movzbl $dst, $dst\n" 9919 "done:" %} 9920 ins_encode %{ 9921 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9922 emit_cmpfp3(masm, $dst$$Register); 9923 %} 9924 ins_pipe(pipe_slow); 9925 %} 9926 9927 // Compare into -1,0,1 9928 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9929 %{ 9930 match(Set dst (CmpF3 src1 (LoadF src2))); 9931 effect(KILL cr); 9932 9933 ins_cost(275); 9934 format %{ "ucomiss $src1, $src2\n\t" 9935 "movl $dst, #-1\n\t" 9936 "jp,s done\n\t" 9937 "jb,s done\n\t" 9938 "setne $dst\n\t" 9939 "movzbl $dst, $dst\n" 9940 "done:" %} 9941 ins_encode %{ 9942 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9943 emit_cmpfp3(masm, $dst$$Register); 9944 %} 9945 ins_pipe(pipe_slow); 9946 %} 9947 9948 // Compare into -1,0,1 9949 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9950 match(Set dst (CmpF3 src con)); 9951 effect(KILL cr); 9952 9953 ins_cost(275); 9954 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9955 "movl $dst, #-1\n\t" 9956 "jp,s done\n\t" 9957 "jb,s done\n\t" 9958 "setne $dst\n\t" 9959 "movzbl $dst, $dst\n" 9960 "done:" %} 9961 ins_encode %{ 9962 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9963 emit_cmpfp3(masm, $dst$$Register); 9964 %} 9965 ins_pipe(pipe_slow); 9966 %} 9967 9968 // Compare into -1,0,1 9969 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9970 %{ 9971 match(Set dst (CmpD3 src1 src2)); 9972 effect(KILL cr); 9973 9974 ins_cost(275); 9975 format %{ "ucomisd $src1, $src2\n\t" 9976 "movl $dst, #-1\n\t" 9977 "jp,s done\n\t" 9978 "jb,s done\n\t" 9979 "setne $dst\n\t" 9980 "movzbl $dst, $dst\n" 9981 "done:" %} 9982 ins_encode %{ 9983 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9984 emit_cmpfp3(masm, $dst$$Register); 9985 %} 9986 ins_pipe(pipe_slow); 9987 %} 9988 9989 // Compare into -1,0,1 9990 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9991 %{ 9992 match(Set dst (CmpD3 src1 (LoadD src2))); 9993 effect(KILL cr); 9994 9995 ins_cost(275); 9996 format %{ "ucomisd $src1, $src2\n\t" 9997 "movl $dst, #-1\n\t" 9998 "jp,s done\n\t" 9999 "jb,s done\n\t" 10000 "setne $dst\n\t" 10001 "movzbl $dst, $dst\n" 10002 "done:" %} 10003 ins_encode %{ 10004 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10005 emit_cmpfp3(masm, $dst$$Register); 10006 %} 10007 ins_pipe(pipe_slow); 10008 %} 10009 10010 // Compare into -1,0,1 10011 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10012 match(Set dst (CmpD3 src con)); 10013 effect(KILL cr); 10014 10015 ins_cost(275); 10016 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10017 "movl $dst, #-1\n\t" 10018 "jp,s done\n\t" 10019 "jb,s done\n\t" 10020 "setne $dst\n\t" 10021 "movzbl $dst, $dst\n" 10022 "done:" %} 10023 ins_encode %{ 10024 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10025 emit_cmpfp3(masm, $dst$$Register); 10026 %} 10027 ins_pipe(pipe_slow); 10028 %} 10029 10030 //----------Arithmetic Conversion Instructions--------------------------------- 10031 10032 instruct convF2D_reg_reg(regD dst, regF src) 10033 %{ 10034 match(Set dst (ConvF2D src)); 10035 10036 format %{ "cvtss2sd $dst, $src" %} 10037 ins_encode %{ 10038 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10039 %} 10040 ins_pipe(pipe_slow); // XXX 10041 %} 10042 10043 instruct convF2D_reg_mem(regD dst, memory src) 10044 %{ 10045 predicate(UseAVX == 0); 10046 match(Set dst (ConvF2D (LoadF src))); 10047 10048 format %{ "cvtss2sd $dst, $src" %} 10049 ins_encode %{ 10050 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10051 %} 10052 ins_pipe(pipe_slow); // XXX 10053 %} 10054 10055 instruct convD2F_reg_reg(regF dst, regD src) 10056 %{ 10057 match(Set dst (ConvD2F src)); 10058 10059 format %{ "cvtsd2ss $dst, $src" %} 10060 ins_encode %{ 10061 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10062 %} 10063 ins_pipe(pipe_slow); // XXX 10064 %} 10065 10066 instruct convD2F_reg_mem(regF dst, memory src) 10067 %{ 10068 predicate(UseAVX == 0); 10069 match(Set dst (ConvD2F (LoadD src))); 10070 10071 format %{ "cvtsd2ss $dst, $src" %} 10072 ins_encode %{ 10073 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10074 %} 10075 ins_pipe(pipe_slow); // XXX 10076 %} 10077 10078 // XXX do mem variants 10079 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10080 %{ 10081 match(Set dst (ConvF2I src)); 10082 effect(KILL cr); 10083 format %{ "convert_f2i $dst, $src" %} 10084 ins_encode %{ 10085 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10086 %} 10087 ins_pipe(pipe_slow); 10088 %} 10089 10090 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10091 %{ 10092 match(Set dst (ConvF2L src)); 10093 effect(KILL cr); 10094 format %{ "convert_f2l $dst, $src"%} 10095 ins_encode %{ 10096 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10097 %} 10098 ins_pipe(pipe_slow); 10099 %} 10100 10101 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10102 %{ 10103 match(Set dst (ConvD2I src)); 10104 effect(KILL cr); 10105 format %{ "convert_d2i $dst, $src"%} 10106 ins_encode %{ 10107 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10108 %} 10109 ins_pipe(pipe_slow); 10110 %} 10111 10112 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10113 %{ 10114 match(Set dst (ConvD2L src)); 10115 effect(KILL cr); 10116 format %{ "convert_d2l $dst, $src"%} 10117 ins_encode %{ 10118 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10119 %} 10120 ins_pipe(pipe_slow); 10121 %} 10122 10123 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10124 %{ 10125 match(Set dst (RoundD src)); 10126 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10127 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10128 ins_encode %{ 10129 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10130 %} 10131 ins_pipe(pipe_slow); 10132 %} 10133 10134 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10135 %{ 10136 match(Set dst (RoundF src)); 10137 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10138 format %{ "round_float $dst,$src" %} 10139 ins_encode %{ 10140 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10141 %} 10142 ins_pipe(pipe_slow); 10143 %} 10144 10145 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10146 %{ 10147 predicate(!UseXmmI2F); 10148 match(Set dst (ConvI2F src)); 10149 10150 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10151 ins_encode %{ 10152 if (UseAVX > 0) { 10153 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10154 } 10155 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10156 %} 10157 ins_pipe(pipe_slow); // XXX 10158 %} 10159 10160 instruct convI2F_reg_mem(regF dst, memory src) 10161 %{ 10162 predicate(UseAVX == 0); 10163 match(Set dst (ConvI2F (LoadI src))); 10164 10165 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10166 ins_encode %{ 10167 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10168 %} 10169 ins_pipe(pipe_slow); // XXX 10170 %} 10171 10172 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10173 %{ 10174 predicate(!UseXmmI2D); 10175 match(Set dst (ConvI2D src)); 10176 10177 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10178 ins_encode %{ 10179 if (UseAVX > 0) { 10180 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10181 } 10182 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10183 %} 10184 ins_pipe(pipe_slow); // XXX 10185 %} 10186 10187 instruct convI2D_reg_mem(regD dst, memory src) 10188 %{ 10189 predicate(UseAVX == 0); 10190 match(Set dst (ConvI2D (LoadI src))); 10191 10192 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10193 ins_encode %{ 10194 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10195 %} 10196 ins_pipe(pipe_slow); // XXX 10197 %} 10198 10199 instruct convXI2F_reg(regF dst, rRegI src) 10200 %{ 10201 predicate(UseXmmI2F); 10202 match(Set dst (ConvI2F src)); 10203 10204 format %{ "movdl $dst, $src\n\t" 10205 "cvtdq2psl $dst, $dst\t# i2f" %} 10206 ins_encode %{ 10207 __ movdl($dst$$XMMRegister, $src$$Register); 10208 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10209 %} 10210 ins_pipe(pipe_slow); // XXX 10211 %} 10212 10213 instruct convXI2D_reg(regD dst, rRegI src) 10214 %{ 10215 predicate(UseXmmI2D); 10216 match(Set dst (ConvI2D src)); 10217 10218 format %{ "movdl $dst, $src\n\t" 10219 "cvtdq2pdl $dst, $dst\t# i2d" %} 10220 ins_encode %{ 10221 __ movdl($dst$$XMMRegister, $src$$Register); 10222 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10223 %} 10224 ins_pipe(pipe_slow); // XXX 10225 %} 10226 10227 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10228 %{ 10229 match(Set dst (ConvL2F src)); 10230 10231 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10232 ins_encode %{ 10233 if (UseAVX > 0) { 10234 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10235 } 10236 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10237 %} 10238 ins_pipe(pipe_slow); // XXX 10239 %} 10240 10241 instruct convL2F_reg_mem(regF dst, memory src) 10242 %{ 10243 predicate(UseAVX == 0); 10244 match(Set dst (ConvL2F (LoadL src))); 10245 10246 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10247 ins_encode %{ 10248 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10249 %} 10250 ins_pipe(pipe_slow); // XXX 10251 %} 10252 10253 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10254 %{ 10255 match(Set dst (ConvL2D src)); 10256 10257 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10258 ins_encode %{ 10259 if (UseAVX > 0) { 10260 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10261 } 10262 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10263 %} 10264 ins_pipe(pipe_slow); // XXX 10265 %} 10266 10267 instruct convL2D_reg_mem(regD dst, memory src) 10268 %{ 10269 predicate(UseAVX == 0); 10270 match(Set dst (ConvL2D (LoadL src))); 10271 10272 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10273 ins_encode %{ 10274 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10275 %} 10276 ins_pipe(pipe_slow); // XXX 10277 %} 10278 10279 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10280 %{ 10281 match(Set dst (ConvI2L src)); 10282 10283 ins_cost(125); 10284 format %{ "movslq $dst, $src\t# i2l" %} 10285 ins_encode %{ 10286 __ movslq($dst$$Register, $src$$Register); 10287 %} 10288 ins_pipe(ialu_reg_reg); 10289 %} 10290 10291 // Zero-extend convert int to long 10292 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10293 %{ 10294 match(Set dst (AndL (ConvI2L src) mask)); 10295 10296 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10297 ins_encode %{ 10298 if ($dst$$reg != $src$$reg) { 10299 __ movl($dst$$Register, $src$$Register); 10300 } 10301 %} 10302 ins_pipe(ialu_reg_reg); 10303 %} 10304 10305 // Zero-extend convert int to long 10306 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10307 %{ 10308 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10309 10310 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10311 ins_encode %{ 10312 __ movl($dst$$Register, $src$$Address); 10313 %} 10314 ins_pipe(ialu_reg_mem); 10315 %} 10316 10317 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10318 %{ 10319 match(Set dst (AndL src mask)); 10320 10321 format %{ "movl $dst, $src\t# zero-extend long" %} 10322 ins_encode %{ 10323 __ movl($dst$$Register, $src$$Register); 10324 %} 10325 ins_pipe(ialu_reg_reg); 10326 %} 10327 10328 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10329 %{ 10330 match(Set dst (ConvL2I src)); 10331 10332 format %{ "movl $dst, $src\t# l2i" %} 10333 ins_encode %{ 10334 __ movl($dst$$Register, $src$$Register); 10335 %} 10336 ins_pipe(ialu_reg_reg); 10337 %} 10338 10339 10340 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10341 match(Set dst (MoveF2I src)); 10342 effect(DEF dst, USE src); 10343 10344 ins_cost(125); 10345 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10346 ins_encode %{ 10347 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10348 %} 10349 ins_pipe(ialu_reg_mem); 10350 %} 10351 10352 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10353 match(Set dst (MoveI2F src)); 10354 effect(DEF dst, USE src); 10355 10356 ins_cost(125); 10357 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10358 ins_encode %{ 10359 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10360 %} 10361 ins_pipe(pipe_slow); 10362 %} 10363 10364 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10365 match(Set dst (MoveD2L src)); 10366 effect(DEF dst, USE src); 10367 10368 ins_cost(125); 10369 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10370 ins_encode %{ 10371 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10372 %} 10373 ins_pipe(ialu_reg_mem); 10374 %} 10375 10376 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10377 predicate(!UseXmmLoadAndClearUpper); 10378 match(Set dst (MoveL2D src)); 10379 effect(DEF dst, USE src); 10380 10381 ins_cost(125); 10382 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10383 ins_encode %{ 10384 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10385 %} 10386 ins_pipe(pipe_slow); 10387 %} 10388 10389 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10390 predicate(UseXmmLoadAndClearUpper); 10391 match(Set dst (MoveL2D src)); 10392 effect(DEF dst, USE src); 10393 10394 ins_cost(125); 10395 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10396 ins_encode %{ 10397 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10398 %} 10399 ins_pipe(pipe_slow); 10400 %} 10401 10402 10403 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10404 match(Set dst (MoveF2I src)); 10405 effect(DEF dst, USE src); 10406 10407 ins_cost(95); // XXX 10408 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10409 ins_encode %{ 10410 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10411 %} 10412 ins_pipe(pipe_slow); 10413 %} 10414 10415 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10416 match(Set dst (MoveI2F src)); 10417 effect(DEF dst, USE src); 10418 10419 ins_cost(100); 10420 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10421 ins_encode %{ 10422 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10423 %} 10424 ins_pipe( ialu_mem_reg ); 10425 %} 10426 10427 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10428 match(Set dst (MoveD2L src)); 10429 effect(DEF dst, USE src); 10430 10431 ins_cost(95); // XXX 10432 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10433 ins_encode %{ 10434 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10435 %} 10436 ins_pipe(pipe_slow); 10437 %} 10438 10439 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10440 match(Set dst (MoveL2D src)); 10441 effect(DEF dst, USE src); 10442 10443 ins_cost(100); 10444 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10445 ins_encode %{ 10446 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10447 %} 10448 ins_pipe(ialu_mem_reg); 10449 %} 10450 10451 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10452 match(Set dst (MoveF2I src)); 10453 effect(DEF dst, USE src); 10454 ins_cost(85); 10455 format %{ "movd $dst,$src\t# MoveF2I" %} 10456 ins_encode %{ 10457 __ movdl($dst$$Register, $src$$XMMRegister); 10458 %} 10459 ins_pipe( pipe_slow ); 10460 %} 10461 10462 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10463 match(Set dst (MoveD2L src)); 10464 effect(DEF dst, USE src); 10465 ins_cost(85); 10466 format %{ "movd $dst,$src\t# MoveD2L" %} 10467 ins_encode %{ 10468 __ movdq($dst$$Register, $src$$XMMRegister); 10469 %} 10470 ins_pipe( pipe_slow ); 10471 %} 10472 10473 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10474 match(Set dst (MoveI2F src)); 10475 effect(DEF dst, USE src); 10476 ins_cost(100); 10477 format %{ "movd $dst,$src\t# MoveI2F" %} 10478 ins_encode %{ 10479 __ movdl($dst$$XMMRegister, $src$$Register); 10480 %} 10481 ins_pipe( pipe_slow ); 10482 %} 10483 10484 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10485 match(Set dst (MoveL2D src)); 10486 effect(DEF dst, USE src); 10487 ins_cost(100); 10488 format %{ "movd $dst,$src\t# MoveL2D" %} 10489 ins_encode %{ 10490 __ movdq($dst$$XMMRegister, $src$$Register); 10491 %} 10492 ins_pipe( pipe_slow ); 10493 %} 10494 10495 // Fast clearing of an array 10496 // Small non-constant lenght ClearArray for non-AVX512 targets. 10497 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10498 Universe dummy, rFlagsReg cr) 10499 %{ 10500 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 10501 match(Set dummy (ClearArray cnt base)); 10502 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10503 10504 format %{ $$template 10505 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10506 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10507 $$emit$$"jg LARGE\n\t" 10508 $$emit$$"dec rcx\n\t" 10509 $$emit$$"js DONE\t# Zero length\n\t" 10510 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10511 $$emit$$"dec rcx\n\t" 10512 $$emit$$"jge LOOP\n\t" 10513 $$emit$$"jmp DONE\n\t" 10514 $$emit$$"# LARGE:\n\t" 10515 if (UseFastStosb) { 10516 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10517 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10518 } else if (UseXMMForObjInit) { 10519 $$emit$$"mov rdi,rax\n\t" 10520 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10521 $$emit$$"jmpq L_zero_64_bytes\n\t" 10522 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10523 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10524 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10525 $$emit$$"add 0x40,rax\n\t" 10526 $$emit$$"# L_zero_64_bytes:\n\t" 10527 $$emit$$"sub 0x8,rcx\n\t" 10528 $$emit$$"jge L_loop\n\t" 10529 $$emit$$"add 0x4,rcx\n\t" 10530 $$emit$$"jl L_tail\n\t" 10531 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10532 $$emit$$"add 0x20,rax\n\t" 10533 $$emit$$"sub 0x4,rcx\n\t" 10534 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10535 $$emit$$"add 0x4,rcx\n\t" 10536 $$emit$$"jle L_end\n\t" 10537 $$emit$$"dec rcx\n\t" 10538 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10539 $$emit$$"vmovq xmm0,(rax)\n\t" 10540 $$emit$$"add 0x8,rax\n\t" 10541 $$emit$$"dec rcx\n\t" 10542 $$emit$$"jge L_sloop\n\t" 10543 $$emit$$"# L_end:\n\t" 10544 } else { 10545 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10546 } 10547 $$emit$$"# DONE" 10548 %} 10549 ins_encode %{ 10550 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10551 $tmp$$XMMRegister, false, knoreg); 10552 %} 10553 ins_pipe(pipe_slow); 10554 %} 10555 10556 // Small non-constant length ClearArray for AVX512 targets. 10557 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10558 Universe dummy, rFlagsReg cr) 10559 %{ 10560 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 10561 match(Set dummy (ClearArray cnt base)); 10562 ins_cost(125); 10563 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10564 10565 format %{ $$template 10566 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10567 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10568 $$emit$$"jg LARGE\n\t" 10569 $$emit$$"dec rcx\n\t" 10570 $$emit$$"js DONE\t# Zero length\n\t" 10571 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10572 $$emit$$"dec rcx\n\t" 10573 $$emit$$"jge LOOP\n\t" 10574 $$emit$$"jmp DONE\n\t" 10575 $$emit$$"# LARGE:\n\t" 10576 if (UseFastStosb) { 10577 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10578 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10579 } else if (UseXMMForObjInit) { 10580 $$emit$$"mov rdi,rax\n\t" 10581 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10582 $$emit$$"jmpq L_zero_64_bytes\n\t" 10583 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10584 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10585 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10586 $$emit$$"add 0x40,rax\n\t" 10587 $$emit$$"# L_zero_64_bytes:\n\t" 10588 $$emit$$"sub 0x8,rcx\n\t" 10589 $$emit$$"jge L_loop\n\t" 10590 $$emit$$"add 0x4,rcx\n\t" 10591 $$emit$$"jl L_tail\n\t" 10592 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10593 $$emit$$"add 0x20,rax\n\t" 10594 $$emit$$"sub 0x4,rcx\n\t" 10595 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10596 $$emit$$"add 0x4,rcx\n\t" 10597 $$emit$$"jle L_end\n\t" 10598 $$emit$$"dec rcx\n\t" 10599 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10600 $$emit$$"vmovq xmm0,(rax)\n\t" 10601 $$emit$$"add 0x8,rax\n\t" 10602 $$emit$$"dec rcx\n\t" 10603 $$emit$$"jge L_sloop\n\t" 10604 $$emit$$"# L_end:\n\t" 10605 } else { 10606 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10607 } 10608 $$emit$$"# DONE" 10609 %} 10610 ins_encode %{ 10611 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10612 $tmp$$XMMRegister, false, $ktmp$$KRegister); 10613 %} 10614 ins_pipe(pipe_slow); 10615 %} 10616 10617 // Large non-constant length ClearArray for non-AVX512 targets. 10618 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10619 Universe dummy, rFlagsReg cr) 10620 %{ 10621 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 10622 match(Set dummy (ClearArray cnt base)); 10623 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10624 10625 format %{ $$template 10626 if (UseFastStosb) { 10627 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10628 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10629 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10630 } else if (UseXMMForObjInit) { 10631 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10632 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10633 $$emit$$"jmpq L_zero_64_bytes\n\t" 10634 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10635 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10636 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10637 $$emit$$"add 0x40,rax\n\t" 10638 $$emit$$"# L_zero_64_bytes:\n\t" 10639 $$emit$$"sub 0x8,rcx\n\t" 10640 $$emit$$"jge L_loop\n\t" 10641 $$emit$$"add 0x4,rcx\n\t" 10642 $$emit$$"jl L_tail\n\t" 10643 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10644 $$emit$$"add 0x20,rax\n\t" 10645 $$emit$$"sub 0x4,rcx\n\t" 10646 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10647 $$emit$$"add 0x4,rcx\n\t" 10648 $$emit$$"jle L_end\n\t" 10649 $$emit$$"dec rcx\n\t" 10650 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10651 $$emit$$"vmovq xmm0,(rax)\n\t" 10652 $$emit$$"add 0x8,rax\n\t" 10653 $$emit$$"dec rcx\n\t" 10654 $$emit$$"jge L_sloop\n\t" 10655 $$emit$$"# L_end:\n\t" 10656 } else { 10657 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10658 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10659 } 10660 %} 10661 ins_encode %{ 10662 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10663 $tmp$$XMMRegister, true, knoreg); 10664 %} 10665 ins_pipe(pipe_slow); 10666 %} 10667 10668 // Large non-constant length ClearArray for AVX512 targets. 10669 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 10670 Universe dummy, rFlagsReg cr) 10671 %{ 10672 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 10673 match(Set dummy (ClearArray cnt base)); 10674 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 10675 10676 format %{ $$template 10677 if (UseFastStosb) { 10678 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10679 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10680 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10681 } else if (UseXMMForObjInit) { 10682 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10683 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10684 $$emit$$"jmpq L_zero_64_bytes\n\t" 10685 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10686 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10687 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10688 $$emit$$"add 0x40,rax\n\t" 10689 $$emit$$"# L_zero_64_bytes:\n\t" 10690 $$emit$$"sub 0x8,rcx\n\t" 10691 $$emit$$"jge L_loop\n\t" 10692 $$emit$$"add 0x4,rcx\n\t" 10693 $$emit$$"jl L_tail\n\t" 10694 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10695 $$emit$$"add 0x20,rax\n\t" 10696 $$emit$$"sub 0x4,rcx\n\t" 10697 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10698 $$emit$$"add 0x4,rcx\n\t" 10699 $$emit$$"jle L_end\n\t" 10700 $$emit$$"dec rcx\n\t" 10701 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10702 $$emit$$"vmovq xmm0,(rax)\n\t" 10703 $$emit$$"add 0x8,rax\n\t" 10704 $$emit$$"dec rcx\n\t" 10705 $$emit$$"jge L_sloop\n\t" 10706 $$emit$$"# L_end:\n\t" 10707 } else { 10708 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10709 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10710 } 10711 %} 10712 ins_encode %{ 10713 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10714 $tmp$$XMMRegister, true, $ktmp$$KRegister); 10715 %} 10716 ins_pipe(pipe_slow); 10717 %} 10718 10719 // Small constant length ClearArray for AVX512 targets. 10720 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 10721 %{ 10722 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 10723 match(Set dummy (ClearArray cnt base)); 10724 ins_cost(100); 10725 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 10726 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10727 ins_encode %{ 10728 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10729 %} 10730 ins_pipe(pipe_slow); 10731 %} 10732 10733 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10734 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10735 %{ 10736 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10737 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10738 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10739 10740 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10741 ins_encode %{ 10742 __ string_compare($str1$$Register, $str2$$Register, 10743 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10744 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10745 %} 10746 ins_pipe( pipe_slow ); 10747 %} 10748 10749 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10750 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10751 %{ 10752 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10753 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10754 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10755 10756 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10757 ins_encode %{ 10758 __ string_compare($str1$$Register, $str2$$Register, 10759 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10760 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10761 %} 10762 ins_pipe( pipe_slow ); 10763 %} 10764 10765 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10766 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10767 %{ 10768 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10769 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10770 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10771 10772 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10773 ins_encode %{ 10774 __ string_compare($str1$$Register, $str2$$Register, 10775 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10776 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10777 %} 10778 ins_pipe( pipe_slow ); 10779 %} 10780 10781 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10782 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10783 %{ 10784 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10785 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10786 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10787 10788 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10789 ins_encode %{ 10790 __ string_compare($str1$$Register, $str2$$Register, 10791 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10792 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10793 %} 10794 ins_pipe( pipe_slow ); 10795 %} 10796 10797 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10798 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10799 %{ 10800 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10801 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10802 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10803 10804 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10805 ins_encode %{ 10806 __ string_compare($str1$$Register, $str2$$Register, 10807 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10808 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 10809 %} 10810 ins_pipe( pipe_slow ); 10811 %} 10812 10813 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10814 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10815 %{ 10816 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10817 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10818 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10819 10820 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10821 ins_encode %{ 10822 __ string_compare($str1$$Register, $str2$$Register, 10823 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10824 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 10825 %} 10826 ins_pipe( pipe_slow ); 10827 %} 10828 10829 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10830 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10831 %{ 10832 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10833 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10834 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10835 10836 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10837 ins_encode %{ 10838 __ string_compare($str2$$Register, $str1$$Register, 10839 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10840 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 10841 %} 10842 ins_pipe( pipe_slow ); 10843 %} 10844 10845 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10846 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10847 %{ 10848 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10849 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10850 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10851 10852 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10853 ins_encode %{ 10854 __ string_compare($str2$$Register, $str1$$Register, 10855 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10856 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 10857 %} 10858 ins_pipe( pipe_slow ); 10859 %} 10860 10861 // fast search of substring with known size. 10862 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10863 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10864 %{ 10865 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10866 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10867 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10868 10869 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10870 ins_encode %{ 10871 int icnt2 = (int)$int_cnt2$$constant; 10872 if (icnt2 >= 16) { 10873 // IndexOf for constant substrings with size >= 16 elements 10874 // which don't need to be loaded through stack. 10875 __ string_indexofC8($str1$$Register, $str2$$Register, 10876 $cnt1$$Register, $cnt2$$Register, 10877 icnt2, $result$$Register, 10878 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10879 } else { 10880 // Small strings are loaded through stack if they cross page boundary. 10881 __ string_indexof($str1$$Register, $str2$$Register, 10882 $cnt1$$Register, $cnt2$$Register, 10883 icnt2, $result$$Register, 10884 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10885 } 10886 %} 10887 ins_pipe( pipe_slow ); 10888 %} 10889 10890 // fast search of substring with known size. 10891 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10892 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10893 %{ 10894 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10895 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10896 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10897 10898 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10899 ins_encode %{ 10900 int icnt2 = (int)$int_cnt2$$constant; 10901 if (icnt2 >= 8) { 10902 // IndexOf for constant substrings with size >= 8 elements 10903 // which don't need to be loaded through stack. 10904 __ string_indexofC8($str1$$Register, $str2$$Register, 10905 $cnt1$$Register, $cnt2$$Register, 10906 icnt2, $result$$Register, 10907 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10908 } else { 10909 // Small strings are loaded through stack if they cross page boundary. 10910 __ string_indexof($str1$$Register, $str2$$Register, 10911 $cnt1$$Register, $cnt2$$Register, 10912 icnt2, $result$$Register, 10913 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10914 } 10915 %} 10916 ins_pipe( pipe_slow ); 10917 %} 10918 10919 // fast search of substring with known size. 10920 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10921 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10922 %{ 10923 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10924 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10925 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10926 10927 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 10928 ins_encode %{ 10929 int icnt2 = (int)$int_cnt2$$constant; 10930 if (icnt2 >= 8) { 10931 // IndexOf for constant substrings with size >= 8 elements 10932 // which don't need to be loaded through stack. 10933 __ string_indexofC8($str1$$Register, $str2$$Register, 10934 $cnt1$$Register, $cnt2$$Register, 10935 icnt2, $result$$Register, 10936 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10937 } else { 10938 // Small strings are loaded through stack if they cross page boundary. 10939 __ string_indexof($str1$$Register, $str2$$Register, 10940 $cnt1$$Register, $cnt2$$Register, 10941 icnt2, $result$$Register, 10942 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10943 } 10944 %} 10945 ins_pipe( pipe_slow ); 10946 %} 10947 10948 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10949 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10950 %{ 10951 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10952 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10953 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10954 10955 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10956 ins_encode %{ 10957 __ string_indexof($str1$$Register, $str2$$Register, 10958 $cnt1$$Register, $cnt2$$Register, 10959 (-1), $result$$Register, 10960 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10961 %} 10962 ins_pipe( pipe_slow ); 10963 %} 10964 10965 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10966 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10967 %{ 10968 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10969 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10970 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10971 10972 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10973 ins_encode %{ 10974 __ string_indexof($str1$$Register, $str2$$Register, 10975 $cnt1$$Register, $cnt2$$Register, 10976 (-1), $result$$Register, 10977 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10978 %} 10979 ins_pipe( pipe_slow ); 10980 %} 10981 10982 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10983 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 10984 %{ 10985 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10986 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10987 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10988 10989 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10990 ins_encode %{ 10991 __ string_indexof($str1$$Register, $str2$$Register, 10992 $cnt1$$Register, $cnt2$$Register, 10993 (-1), $result$$Register, 10994 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10995 %} 10996 ins_pipe( pipe_slow ); 10997 %} 10998 10999 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11000 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11001 %{ 11002 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 11003 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11004 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11005 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11006 ins_encode %{ 11007 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11008 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11009 %} 11010 ins_pipe( pipe_slow ); 11011 %} 11012 11013 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11014 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11015 %{ 11016 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 11017 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11018 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11019 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11020 ins_encode %{ 11021 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11022 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11023 %} 11024 ins_pipe( pipe_slow ); 11025 %} 11026 11027 // fast string equals 11028 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11029 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11030 %{ 11031 predicate(!VM_Version::supports_avx512vlbw()); 11032 match(Set result (StrEquals (Binary str1 str2) cnt)); 11033 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11034 11035 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11036 ins_encode %{ 11037 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11038 $cnt$$Register, $result$$Register, $tmp3$$Register, 11039 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11040 %} 11041 ins_pipe( pipe_slow ); 11042 %} 11043 11044 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11045 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11046 %{ 11047 predicate(VM_Version::supports_avx512vlbw()); 11048 match(Set result (StrEquals (Binary str1 str2) cnt)); 11049 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11050 11051 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11052 ins_encode %{ 11053 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11054 $cnt$$Register, $result$$Register, $tmp3$$Register, 11055 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11056 %} 11057 ins_pipe( pipe_slow ); 11058 %} 11059 11060 // fast array equals 11061 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11062 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11063 %{ 11064 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11065 match(Set result (AryEq ary1 ary2)); 11066 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11067 11068 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11069 ins_encode %{ 11070 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11071 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11072 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11073 %} 11074 ins_pipe( pipe_slow ); 11075 %} 11076 11077 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11078 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11079 %{ 11080 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11081 match(Set result (AryEq ary1 ary2)); 11082 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11083 11084 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11085 ins_encode %{ 11086 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11087 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11088 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11089 %} 11090 ins_pipe( pipe_slow ); 11091 %} 11092 11093 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11094 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11095 %{ 11096 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11097 match(Set result (AryEq ary1 ary2)); 11098 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11099 11100 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11101 ins_encode %{ 11102 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11103 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11104 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11105 %} 11106 ins_pipe( pipe_slow ); 11107 %} 11108 11109 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11110 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11111 %{ 11112 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11113 match(Set result (AryEq ary1 ary2)); 11114 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11115 11116 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11117 ins_encode %{ 11118 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11119 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11120 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11121 %} 11122 ins_pipe( pipe_slow ); 11123 %} 11124 11125 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11126 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11127 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11128 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11129 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11130 %{ 11131 predicate(UseAVX >= 2); 11132 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11133 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11134 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11135 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11136 USE basic_type, KILL cr); 11137 11138 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11139 ins_encode %{ 11140 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11141 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11142 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11143 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11144 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11145 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11146 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11147 %} 11148 ins_pipe( pipe_slow ); 11149 %} 11150 11151 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11152 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11153 %{ 11154 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11155 match(Set result (CountPositives ary1 len)); 11156 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11157 11158 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11159 ins_encode %{ 11160 __ count_positives($ary1$$Register, $len$$Register, 11161 $result$$Register, $tmp3$$Register, 11162 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11163 %} 11164 ins_pipe( pipe_slow ); 11165 %} 11166 11167 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11168 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11169 %{ 11170 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11171 match(Set result (CountPositives ary1 len)); 11172 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11173 11174 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11175 ins_encode %{ 11176 __ count_positives($ary1$$Register, $len$$Register, 11177 $result$$Register, $tmp3$$Register, 11178 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11179 %} 11180 ins_pipe( pipe_slow ); 11181 %} 11182 11183 // fast char[] to byte[] compression 11184 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11185 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11186 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11187 match(Set result (StrCompressedCopy src (Binary dst len))); 11188 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11189 USE_KILL len, KILL tmp5, KILL cr); 11190 11191 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11192 ins_encode %{ 11193 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11194 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11195 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11196 knoreg, knoreg); 11197 %} 11198 ins_pipe( pipe_slow ); 11199 %} 11200 11201 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11202 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11203 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11204 match(Set result (StrCompressedCopy src (Binary dst len))); 11205 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11206 USE_KILL len, KILL tmp5, KILL cr); 11207 11208 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11209 ins_encode %{ 11210 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11211 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11212 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11213 $ktmp1$$KRegister, $ktmp2$$KRegister); 11214 %} 11215 ins_pipe( pipe_slow ); 11216 %} 11217 // fast byte[] to char[] inflation 11218 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11219 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11220 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11221 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11222 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11223 11224 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11225 ins_encode %{ 11226 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11227 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11228 %} 11229 ins_pipe( pipe_slow ); 11230 %} 11231 11232 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11233 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11234 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11235 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11236 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11237 11238 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11239 ins_encode %{ 11240 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11241 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11242 %} 11243 ins_pipe( pipe_slow ); 11244 %} 11245 11246 // encode char[] to byte[] in ISO_8859_1 11247 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11248 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11249 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11250 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11251 match(Set result (EncodeISOArray src (Binary dst len))); 11252 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11253 11254 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11255 ins_encode %{ 11256 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11257 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11258 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11259 %} 11260 ins_pipe( pipe_slow ); 11261 %} 11262 11263 // encode char[] to byte[] in ASCII 11264 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11265 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11266 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11267 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11268 match(Set result (EncodeISOArray src (Binary dst len))); 11269 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11270 11271 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11272 ins_encode %{ 11273 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11274 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11275 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11276 %} 11277 ins_pipe( pipe_slow ); 11278 %} 11279 11280 //----------Overflow Math Instructions----------------------------------------- 11281 11282 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11283 %{ 11284 match(Set cr (OverflowAddI op1 op2)); 11285 effect(DEF cr, USE_KILL op1, USE op2); 11286 11287 format %{ "addl $op1, $op2\t# overflow check int" %} 11288 11289 ins_encode %{ 11290 __ addl($op1$$Register, $op2$$Register); 11291 %} 11292 ins_pipe(ialu_reg_reg); 11293 %} 11294 11295 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11296 %{ 11297 match(Set cr (OverflowAddI op1 op2)); 11298 effect(DEF cr, USE_KILL op1, USE op2); 11299 11300 format %{ "addl $op1, $op2\t# overflow check int" %} 11301 11302 ins_encode %{ 11303 __ addl($op1$$Register, $op2$$constant); 11304 %} 11305 ins_pipe(ialu_reg_reg); 11306 %} 11307 11308 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11309 %{ 11310 match(Set cr (OverflowAddL op1 op2)); 11311 effect(DEF cr, USE_KILL op1, USE op2); 11312 11313 format %{ "addq $op1, $op2\t# overflow check long" %} 11314 ins_encode %{ 11315 __ addq($op1$$Register, $op2$$Register); 11316 %} 11317 ins_pipe(ialu_reg_reg); 11318 %} 11319 11320 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11321 %{ 11322 match(Set cr (OverflowAddL op1 op2)); 11323 effect(DEF cr, USE_KILL op1, USE op2); 11324 11325 format %{ "addq $op1, $op2\t# overflow check long" %} 11326 ins_encode %{ 11327 __ addq($op1$$Register, $op2$$constant); 11328 %} 11329 ins_pipe(ialu_reg_reg); 11330 %} 11331 11332 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11333 %{ 11334 match(Set cr (OverflowSubI op1 op2)); 11335 11336 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11337 ins_encode %{ 11338 __ cmpl($op1$$Register, $op2$$Register); 11339 %} 11340 ins_pipe(ialu_reg_reg); 11341 %} 11342 11343 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11344 %{ 11345 match(Set cr (OverflowSubI op1 op2)); 11346 11347 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11348 ins_encode %{ 11349 __ cmpl($op1$$Register, $op2$$constant); 11350 %} 11351 ins_pipe(ialu_reg_reg); 11352 %} 11353 11354 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11355 %{ 11356 match(Set cr (OverflowSubL op1 op2)); 11357 11358 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11359 ins_encode %{ 11360 __ cmpq($op1$$Register, $op2$$Register); 11361 %} 11362 ins_pipe(ialu_reg_reg); 11363 %} 11364 11365 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11366 %{ 11367 match(Set cr (OverflowSubL op1 op2)); 11368 11369 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11370 ins_encode %{ 11371 __ cmpq($op1$$Register, $op2$$constant); 11372 %} 11373 ins_pipe(ialu_reg_reg); 11374 %} 11375 11376 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11377 %{ 11378 match(Set cr (OverflowSubI zero op2)); 11379 effect(DEF cr, USE_KILL op2); 11380 11381 format %{ "negl $op2\t# overflow check int" %} 11382 ins_encode %{ 11383 __ negl($op2$$Register); 11384 %} 11385 ins_pipe(ialu_reg_reg); 11386 %} 11387 11388 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11389 %{ 11390 match(Set cr (OverflowSubL zero op2)); 11391 effect(DEF cr, USE_KILL op2); 11392 11393 format %{ "negq $op2\t# overflow check long" %} 11394 ins_encode %{ 11395 __ negq($op2$$Register); 11396 %} 11397 ins_pipe(ialu_reg_reg); 11398 %} 11399 11400 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11401 %{ 11402 match(Set cr (OverflowMulI op1 op2)); 11403 effect(DEF cr, USE_KILL op1, USE op2); 11404 11405 format %{ "imull $op1, $op2\t# overflow check int" %} 11406 ins_encode %{ 11407 __ imull($op1$$Register, $op2$$Register); 11408 %} 11409 ins_pipe(ialu_reg_reg_alu0); 11410 %} 11411 11412 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11413 %{ 11414 match(Set cr (OverflowMulI op1 op2)); 11415 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11416 11417 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11418 ins_encode %{ 11419 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11420 %} 11421 ins_pipe(ialu_reg_reg_alu0); 11422 %} 11423 11424 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11425 %{ 11426 match(Set cr (OverflowMulL op1 op2)); 11427 effect(DEF cr, USE_KILL op1, USE op2); 11428 11429 format %{ "imulq $op1, $op2\t# overflow check long" %} 11430 ins_encode %{ 11431 __ imulq($op1$$Register, $op2$$Register); 11432 %} 11433 ins_pipe(ialu_reg_reg_alu0); 11434 %} 11435 11436 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11437 %{ 11438 match(Set cr (OverflowMulL op1 op2)); 11439 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11440 11441 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11442 ins_encode %{ 11443 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11444 %} 11445 ins_pipe(ialu_reg_reg_alu0); 11446 %} 11447 11448 11449 //----------Control Flow Instructions------------------------------------------ 11450 // Signed compare Instructions 11451 11452 // XXX more variants!! 11453 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11454 %{ 11455 match(Set cr (CmpI op1 op2)); 11456 effect(DEF cr, USE op1, USE op2); 11457 11458 format %{ "cmpl $op1, $op2" %} 11459 ins_encode %{ 11460 __ cmpl($op1$$Register, $op2$$Register); 11461 %} 11462 ins_pipe(ialu_cr_reg_reg); 11463 %} 11464 11465 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11466 %{ 11467 match(Set cr (CmpI op1 op2)); 11468 11469 format %{ "cmpl $op1, $op2" %} 11470 ins_encode %{ 11471 __ cmpl($op1$$Register, $op2$$constant); 11472 %} 11473 ins_pipe(ialu_cr_reg_imm); 11474 %} 11475 11476 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11477 %{ 11478 match(Set cr (CmpI op1 (LoadI op2))); 11479 11480 ins_cost(500); // XXX 11481 format %{ "cmpl $op1, $op2" %} 11482 ins_encode %{ 11483 __ cmpl($op1$$Register, $op2$$Address); 11484 %} 11485 ins_pipe(ialu_cr_reg_mem); 11486 %} 11487 11488 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11489 %{ 11490 match(Set cr (CmpI src zero)); 11491 11492 format %{ "testl $src, $src" %} 11493 ins_encode %{ 11494 __ testl($src$$Register, $src$$Register); 11495 %} 11496 ins_pipe(ialu_cr_reg_imm); 11497 %} 11498 11499 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11500 %{ 11501 match(Set cr (CmpI (AndI src con) zero)); 11502 11503 format %{ "testl $src, $con" %} 11504 ins_encode %{ 11505 __ testl($src$$Register, $con$$constant); 11506 %} 11507 ins_pipe(ialu_cr_reg_imm); 11508 %} 11509 11510 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11511 %{ 11512 match(Set cr (CmpI (AndI src1 src2) zero)); 11513 11514 format %{ "testl $src1, $src2" %} 11515 ins_encode %{ 11516 __ testl($src1$$Register, $src2$$Register); 11517 %} 11518 ins_pipe(ialu_cr_reg_imm); 11519 %} 11520 11521 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11522 %{ 11523 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11524 11525 format %{ "testl $src, $mem" %} 11526 ins_encode %{ 11527 __ testl($src$$Register, $mem$$Address); 11528 %} 11529 ins_pipe(ialu_cr_reg_mem); 11530 %} 11531 11532 // Unsigned compare Instructions; really, same as signed except they 11533 // produce an rFlagsRegU instead of rFlagsReg. 11534 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11535 %{ 11536 match(Set cr (CmpU op1 op2)); 11537 11538 format %{ "cmpl $op1, $op2\t# unsigned" %} 11539 ins_encode %{ 11540 __ cmpl($op1$$Register, $op2$$Register); 11541 %} 11542 ins_pipe(ialu_cr_reg_reg); 11543 %} 11544 11545 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11546 %{ 11547 match(Set cr (CmpU op1 op2)); 11548 11549 format %{ "cmpl $op1, $op2\t# unsigned" %} 11550 ins_encode %{ 11551 __ cmpl($op1$$Register, $op2$$constant); 11552 %} 11553 ins_pipe(ialu_cr_reg_imm); 11554 %} 11555 11556 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11557 %{ 11558 match(Set cr (CmpU op1 (LoadI op2))); 11559 11560 ins_cost(500); // XXX 11561 format %{ "cmpl $op1, $op2\t# unsigned" %} 11562 ins_encode %{ 11563 __ cmpl($op1$$Register, $op2$$Address); 11564 %} 11565 ins_pipe(ialu_cr_reg_mem); 11566 %} 11567 11568 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11569 %{ 11570 match(Set cr (CmpU src zero)); 11571 11572 format %{ "testl $src, $src\t# unsigned" %} 11573 ins_encode %{ 11574 __ testl($src$$Register, $src$$Register); 11575 %} 11576 ins_pipe(ialu_cr_reg_imm); 11577 %} 11578 11579 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11580 %{ 11581 match(Set cr (CmpP op1 op2)); 11582 11583 format %{ "cmpq $op1, $op2\t# ptr" %} 11584 ins_encode %{ 11585 __ cmpq($op1$$Register, $op2$$Register); 11586 %} 11587 ins_pipe(ialu_cr_reg_reg); 11588 %} 11589 11590 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11591 %{ 11592 match(Set cr (CmpP op1 (LoadP op2))); 11593 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11594 11595 ins_cost(500); // XXX 11596 format %{ "cmpq $op1, $op2\t# ptr" %} 11597 ins_encode %{ 11598 __ cmpq($op1$$Register, $op2$$Address); 11599 %} 11600 ins_pipe(ialu_cr_reg_mem); 11601 %} 11602 11603 // XXX this is generalized by compP_rReg_mem??? 11604 // Compare raw pointer (used in out-of-heap check). 11605 // Only works because non-oop pointers must be raw pointers 11606 // and raw pointers have no anti-dependencies. 11607 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11608 %{ 11609 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11610 n->in(2)->as_Load()->barrier_data() == 0); 11611 match(Set cr (CmpP op1 (LoadP op2))); 11612 11613 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11614 ins_encode %{ 11615 __ cmpq($op1$$Register, $op2$$Address); 11616 %} 11617 ins_pipe(ialu_cr_reg_mem); 11618 %} 11619 11620 // This will generate a signed flags result. This should be OK since 11621 // any compare to a zero should be eq/neq. 11622 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11623 %{ 11624 match(Set cr (CmpP src zero)); 11625 11626 format %{ "testq $src, $src\t# ptr" %} 11627 ins_encode %{ 11628 __ testq($src$$Register, $src$$Register); 11629 %} 11630 ins_pipe(ialu_cr_reg_imm); 11631 %} 11632 11633 // This will generate a signed flags result. This should be OK since 11634 // any compare to a zero should be eq/neq. 11635 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11636 %{ 11637 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11638 n->in(1)->as_Load()->barrier_data() == 0); 11639 match(Set cr (CmpP (LoadP op) zero)); 11640 11641 ins_cost(500); // XXX 11642 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11643 ins_encode %{ 11644 __ testq($op$$Address, 0xFFFFFFFF); 11645 %} 11646 ins_pipe(ialu_cr_reg_imm); 11647 %} 11648 11649 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11650 %{ 11651 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11652 n->in(1)->as_Load()->barrier_data() == 0); 11653 match(Set cr (CmpP (LoadP mem) zero)); 11654 11655 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11656 ins_encode %{ 11657 __ cmpq(r12, $mem$$Address); 11658 %} 11659 ins_pipe(ialu_cr_reg_mem); 11660 %} 11661 11662 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11663 %{ 11664 match(Set cr (CmpN op1 op2)); 11665 11666 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11667 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11668 ins_pipe(ialu_cr_reg_reg); 11669 %} 11670 11671 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11672 %{ 11673 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11674 match(Set cr (CmpN src (LoadN mem))); 11675 11676 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11677 ins_encode %{ 11678 __ cmpl($src$$Register, $mem$$Address); 11679 %} 11680 ins_pipe(ialu_cr_reg_mem); 11681 %} 11682 11683 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11684 match(Set cr (CmpN op1 op2)); 11685 11686 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11687 ins_encode %{ 11688 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11689 %} 11690 ins_pipe(ialu_cr_reg_imm); 11691 %} 11692 11693 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11694 %{ 11695 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11696 match(Set cr (CmpN src (LoadN mem))); 11697 11698 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11699 ins_encode %{ 11700 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11701 %} 11702 ins_pipe(ialu_cr_reg_mem); 11703 %} 11704 11705 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11706 match(Set cr (CmpN op1 op2)); 11707 11708 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11709 ins_encode %{ 11710 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11711 %} 11712 ins_pipe(ialu_cr_reg_imm); 11713 %} 11714 11715 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11716 %{ 11717 predicate(!UseCompactObjectHeaders); 11718 match(Set cr (CmpN src (LoadNKlass mem))); 11719 11720 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11721 ins_encode %{ 11722 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11723 %} 11724 ins_pipe(ialu_cr_reg_mem); 11725 %} 11726 11727 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11728 match(Set cr (CmpN src zero)); 11729 11730 format %{ "testl $src, $src\t# compressed ptr" %} 11731 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11732 ins_pipe(ialu_cr_reg_imm); 11733 %} 11734 11735 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11736 %{ 11737 predicate(CompressedOops::base() != nullptr && 11738 n->in(1)->as_Load()->barrier_data() == 0); 11739 match(Set cr (CmpN (LoadN mem) zero)); 11740 11741 ins_cost(500); // XXX 11742 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11743 ins_encode %{ 11744 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11745 %} 11746 ins_pipe(ialu_cr_reg_mem); 11747 %} 11748 11749 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11750 %{ 11751 predicate(CompressedOops::base() == nullptr && 11752 n->in(1)->as_Load()->barrier_data() == 0); 11753 match(Set cr (CmpN (LoadN mem) zero)); 11754 11755 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11756 ins_encode %{ 11757 __ cmpl(r12, $mem$$Address); 11758 %} 11759 ins_pipe(ialu_cr_reg_mem); 11760 %} 11761 11762 // Yanked all unsigned pointer compare operations. 11763 // Pointer compares are done with CmpP which is already unsigned. 11764 11765 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11766 %{ 11767 match(Set cr (CmpL op1 op2)); 11768 11769 format %{ "cmpq $op1, $op2" %} 11770 ins_encode %{ 11771 __ cmpq($op1$$Register, $op2$$Register); 11772 %} 11773 ins_pipe(ialu_cr_reg_reg); 11774 %} 11775 11776 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11777 %{ 11778 match(Set cr (CmpL op1 op2)); 11779 11780 format %{ "cmpq $op1, $op2" %} 11781 ins_encode %{ 11782 __ cmpq($op1$$Register, $op2$$constant); 11783 %} 11784 ins_pipe(ialu_cr_reg_imm); 11785 %} 11786 11787 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11788 %{ 11789 match(Set cr (CmpL op1 (LoadL op2))); 11790 11791 format %{ "cmpq $op1, $op2" %} 11792 ins_encode %{ 11793 __ cmpq($op1$$Register, $op2$$Address); 11794 %} 11795 ins_pipe(ialu_cr_reg_mem); 11796 %} 11797 11798 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11799 %{ 11800 match(Set cr (CmpL src zero)); 11801 11802 format %{ "testq $src, $src" %} 11803 ins_encode %{ 11804 __ testq($src$$Register, $src$$Register); 11805 %} 11806 ins_pipe(ialu_cr_reg_imm); 11807 %} 11808 11809 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11810 %{ 11811 match(Set cr (CmpL (AndL src con) zero)); 11812 11813 format %{ "testq $src, $con\t# long" %} 11814 ins_encode %{ 11815 __ testq($src$$Register, $con$$constant); 11816 %} 11817 ins_pipe(ialu_cr_reg_imm); 11818 %} 11819 11820 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 11821 %{ 11822 match(Set cr (CmpL (AndL src1 src2) zero)); 11823 11824 format %{ "testq $src1, $src2\t# long" %} 11825 ins_encode %{ 11826 __ testq($src1$$Register, $src2$$Register); 11827 %} 11828 ins_pipe(ialu_cr_reg_imm); 11829 %} 11830 11831 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11832 %{ 11833 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11834 11835 format %{ "testq $src, $mem" %} 11836 ins_encode %{ 11837 __ testq($src$$Register, $mem$$Address); 11838 %} 11839 ins_pipe(ialu_cr_reg_mem); 11840 %} 11841 11842 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11843 %{ 11844 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11845 11846 format %{ "testq $src, $mem" %} 11847 ins_encode %{ 11848 __ testq($src$$Register, $mem$$Address); 11849 %} 11850 ins_pipe(ialu_cr_reg_mem); 11851 %} 11852 11853 // Manifest a CmpU result in an integer register. Very painful. 11854 // This is the test to avoid. 11855 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 11856 %{ 11857 match(Set dst (CmpU3 src1 src2)); 11858 effect(KILL flags); 11859 11860 ins_cost(275); // XXX 11861 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 11862 "movl $dst, -1\n\t" 11863 "jb,u done\n\t" 11864 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11865 "done:" %} 11866 ins_encode %{ 11867 Label done; 11868 __ cmpl($src1$$Register, $src2$$Register); 11869 __ movl($dst$$Register, -1); 11870 __ jccb(Assembler::below, done); 11871 __ setcc(Assembler::notZero, $dst$$Register); 11872 __ bind(done); 11873 %} 11874 ins_pipe(pipe_slow); 11875 %} 11876 11877 // Manifest a CmpL result in an integer register. Very painful. 11878 // This is the test to avoid. 11879 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11880 %{ 11881 match(Set dst (CmpL3 src1 src2)); 11882 effect(KILL flags); 11883 11884 ins_cost(275); // XXX 11885 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11886 "movl $dst, -1\n\t" 11887 "jl,s done\n\t" 11888 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11889 "done:" %} 11890 ins_encode %{ 11891 Label done; 11892 __ cmpq($src1$$Register, $src2$$Register); 11893 __ movl($dst$$Register, -1); 11894 __ jccb(Assembler::less, done); 11895 __ setcc(Assembler::notZero, $dst$$Register); 11896 __ bind(done); 11897 %} 11898 ins_pipe(pipe_slow); 11899 %} 11900 11901 // Manifest a CmpUL result in an integer register. Very painful. 11902 // This is the test to avoid. 11903 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11904 %{ 11905 match(Set dst (CmpUL3 src1 src2)); 11906 effect(KILL flags); 11907 11908 ins_cost(275); // XXX 11909 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11910 "movl $dst, -1\n\t" 11911 "jb,u done\n\t" 11912 "setcc $dst \t# emits setne + movzbl or setzune for APX" 11913 "done:" %} 11914 ins_encode %{ 11915 Label done; 11916 __ cmpq($src1$$Register, $src2$$Register); 11917 __ movl($dst$$Register, -1); 11918 __ jccb(Assembler::below, done); 11919 __ setcc(Assembler::notZero, $dst$$Register); 11920 __ bind(done); 11921 %} 11922 ins_pipe(pipe_slow); 11923 %} 11924 11925 // Unsigned long compare Instructions; really, same as signed long except they 11926 // produce an rFlagsRegU instead of rFlagsReg. 11927 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11928 %{ 11929 match(Set cr (CmpUL op1 op2)); 11930 11931 format %{ "cmpq $op1, $op2\t# unsigned" %} 11932 ins_encode %{ 11933 __ cmpq($op1$$Register, $op2$$Register); 11934 %} 11935 ins_pipe(ialu_cr_reg_reg); 11936 %} 11937 11938 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11939 %{ 11940 match(Set cr (CmpUL op1 op2)); 11941 11942 format %{ "cmpq $op1, $op2\t# unsigned" %} 11943 ins_encode %{ 11944 __ cmpq($op1$$Register, $op2$$constant); 11945 %} 11946 ins_pipe(ialu_cr_reg_imm); 11947 %} 11948 11949 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11950 %{ 11951 match(Set cr (CmpUL op1 (LoadL op2))); 11952 11953 format %{ "cmpq $op1, $op2\t# unsigned" %} 11954 ins_encode %{ 11955 __ cmpq($op1$$Register, $op2$$Address); 11956 %} 11957 ins_pipe(ialu_cr_reg_mem); 11958 %} 11959 11960 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11961 %{ 11962 match(Set cr (CmpUL src zero)); 11963 11964 format %{ "testq $src, $src\t# unsigned" %} 11965 ins_encode %{ 11966 __ testq($src$$Register, $src$$Register); 11967 %} 11968 ins_pipe(ialu_cr_reg_imm); 11969 %} 11970 11971 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11972 %{ 11973 match(Set cr (CmpI (LoadB mem) imm)); 11974 11975 ins_cost(125); 11976 format %{ "cmpb $mem, $imm" %} 11977 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11978 ins_pipe(ialu_cr_reg_mem); 11979 %} 11980 11981 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 11982 %{ 11983 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 11984 11985 ins_cost(125); 11986 format %{ "testb $mem, $imm\t# ubyte" %} 11987 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11988 ins_pipe(ialu_cr_reg_mem); 11989 %} 11990 11991 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 11992 %{ 11993 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11994 11995 ins_cost(125); 11996 format %{ "testb $mem, $imm\t# byte" %} 11997 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11998 ins_pipe(ialu_cr_reg_mem); 11999 %} 12000 12001 //----------Max and Min-------------------------------------------------------- 12002 // Min Instructions 12003 12004 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12005 %{ 12006 effect(USE_DEF dst, USE src, USE cr); 12007 12008 format %{ "cmovlgt $dst, $src\t# min" %} 12009 ins_encode %{ 12010 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 12011 %} 12012 ins_pipe(pipe_cmov_reg); 12013 %} 12014 12015 12016 instruct minI_rReg(rRegI dst, rRegI src) 12017 %{ 12018 match(Set dst (MinI dst src)); 12019 12020 ins_cost(200); 12021 expand %{ 12022 rFlagsReg cr; 12023 compI_rReg(cr, dst, src); 12024 cmovI_reg_g(dst, src, cr); 12025 %} 12026 %} 12027 12028 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12029 %{ 12030 effect(USE_DEF dst, USE src, USE cr); 12031 12032 format %{ "cmovllt $dst, $src\t# max" %} 12033 ins_encode %{ 12034 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12035 %} 12036 ins_pipe(pipe_cmov_reg); 12037 %} 12038 12039 12040 instruct maxI_rReg(rRegI dst, rRegI src) 12041 %{ 12042 match(Set dst (MaxI dst src)); 12043 12044 ins_cost(200); 12045 expand %{ 12046 rFlagsReg cr; 12047 compI_rReg(cr, dst, src); 12048 cmovI_reg_l(dst, src, cr); 12049 %} 12050 %} 12051 12052 // ============================================================================ 12053 // Branch Instructions 12054 12055 // Jump Direct - Label defines a relative address from JMP+1 12056 instruct jmpDir(label labl) 12057 %{ 12058 match(Goto); 12059 effect(USE labl); 12060 12061 ins_cost(300); 12062 format %{ "jmp $labl" %} 12063 size(5); 12064 ins_encode %{ 12065 Label* L = $labl$$label; 12066 __ jmp(*L, false); // Always long jump 12067 %} 12068 ins_pipe(pipe_jmp); 12069 %} 12070 12071 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12072 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12073 %{ 12074 match(If cop cr); 12075 effect(USE labl); 12076 12077 ins_cost(300); 12078 format %{ "j$cop $labl" %} 12079 size(6); 12080 ins_encode %{ 12081 Label* L = $labl$$label; 12082 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12083 %} 12084 ins_pipe(pipe_jcc); 12085 %} 12086 12087 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12088 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12089 %{ 12090 match(CountedLoopEnd cop cr); 12091 effect(USE labl); 12092 12093 ins_cost(300); 12094 format %{ "j$cop $labl\t# loop end" %} 12095 size(6); 12096 ins_encode %{ 12097 Label* L = $labl$$label; 12098 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12099 %} 12100 ins_pipe(pipe_jcc); 12101 %} 12102 12103 // Jump Direct Conditional - using unsigned comparison 12104 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12105 match(If cop cmp); 12106 effect(USE labl); 12107 12108 ins_cost(300); 12109 format %{ "j$cop,u $labl" %} 12110 size(6); 12111 ins_encode %{ 12112 Label* L = $labl$$label; 12113 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12114 %} 12115 ins_pipe(pipe_jcc); 12116 %} 12117 12118 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12119 match(If cop cmp); 12120 effect(USE labl); 12121 12122 ins_cost(200); 12123 format %{ "j$cop,u $labl" %} 12124 size(6); 12125 ins_encode %{ 12126 Label* L = $labl$$label; 12127 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12128 %} 12129 ins_pipe(pipe_jcc); 12130 %} 12131 12132 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12133 match(If cop cmp); 12134 effect(USE labl); 12135 12136 ins_cost(200); 12137 format %{ $$template 12138 if ($cop$$cmpcode == Assembler::notEqual) { 12139 $$emit$$"jp,u $labl\n\t" 12140 $$emit$$"j$cop,u $labl" 12141 } else { 12142 $$emit$$"jp,u done\n\t" 12143 $$emit$$"j$cop,u $labl\n\t" 12144 $$emit$$"done:" 12145 } 12146 %} 12147 ins_encode %{ 12148 Label* l = $labl$$label; 12149 if ($cop$$cmpcode == Assembler::notEqual) { 12150 __ jcc(Assembler::parity, *l, false); 12151 __ jcc(Assembler::notEqual, *l, false); 12152 } else if ($cop$$cmpcode == Assembler::equal) { 12153 Label done; 12154 __ jccb(Assembler::parity, done); 12155 __ jcc(Assembler::equal, *l, false); 12156 __ bind(done); 12157 } else { 12158 ShouldNotReachHere(); 12159 } 12160 %} 12161 ins_pipe(pipe_jcc); 12162 %} 12163 12164 // ============================================================================ 12165 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12166 // superklass array for an instance of the superklass. Set a hidden 12167 // internal cache on a hit (cache is checked with exposed code in 12168 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12169 // encoding ALSO sets flags. 12170 12171 instruct partialSubtypeCheck(rdi_RegP result, 12172 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12173 rFlagsReg cr) 12174 %{ 12175 match(Set result (PartialSubtypeCheck sub super)); 12176 predicate(!UseSecondarySupersTable); 12177 effect(KILL rcx, KILL cr); 12178 12179 ins_cost(1100); // slightly larger than the next version 12180 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12181 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12182 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12183 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12184 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12185 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12186 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12187 "miss:\t" %} 12188 12189 ins_encode %{ 12190 Label miss; 12191 // NB: Callers may assume that, when $result is a valid register, 12192 // check_klass_subtype_slow_path_linear sets it to a nonzero 12193 // value. 12194 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 12195 $rcx$$Register, $result$$Register, 12196 nullptr, &miss, 12197 /*set_cond_codes:*/ true); 12198 __ xorptr($result$$Register, $result$$Register); 12199 __ bind(miss); 12200 %} 12201 12202 ins_pipe(pipe_slow); 12203 %} 12204 12205 // ============================================================================ 12206 // Two versions of hashtable-based partialSubtypeCheck, both used when 12207 // we need to search for a super class in the secondary supers array. 12208 // The first is used when we don't know _a priori_ the class being 12209 // searched for. The second, far more common, is used when we do know: 12210 // this is used for instanceof, checkcast, and any case where C2 can 12211 // determine it by constant propagation. 12212 12213 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 12214 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12215 rFlagsReg cr) 12216 %{ 12217 match(Set result (PartialSubtypeCheck sub super)); 12218 predicate(UseSecondarySupersTable); 12219 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12220 12221 ins_cost(1000); 12222 format %{ "partialSubtypeCheck $result, $sub, $super" %} 12223 12224 ins_encode %{ 12225 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 12226 $temp3$$Register, $temp4$$Register, $result$$Register); 12227 %} 12228 12229 ins_pipe(pipe_slow); 12230 %} 12231 12232 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12233 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12234 rFlagsReg cr) 12235 %{ 12236 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12237 predicate(UseSecondarySupersTable); 12238 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12239 12240 ins_cost(700); // smaller than the next version 12241 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12242 12243 ins_encode %{ 12244 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12245 if (InlineSecondarySupersTest) { 12246 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12247 $temp3$$Register, $temp4$$Register, $result$$Register, 12248 super_klass_slot); 12249 } else { 12250 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12251 } 12252 %} 12253 12254 ins_pipe(pipe_slow); 12255 %} 12256 12257 // ============================================================================ 12258 // Branch Instructions -- short offset versions 12259 // 12260 // These instructions are used to replace jumps of a long offset (the default 12261 // match) with jumps of a shorter offset. These instructions are all tagged 12262 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12263 // match rules in general matching. Instead, the ADLC generates a conversion 12264 // method in the MachNode which can be used to do in-place replacement of the 12265 // long variant with the shorter variant. The compiler will determine if a 12266 // branch can be taken by the is_short_branch_offset() predicate in the machine 12267 // specific code section of the file. 12268 12269 // Jump Direct - Label defines a relative address from JMP+1 12270 instruct jmpDir_short(label labl) %{ 12271 match(Goto); 12272 effect(USE labl); 12273 12274 ins_cost(300); 12275 format %{ "jmp,s $labl" %} 12276 size(2); 12277 ins_encode %{ 12278 Label* L = $labl$$label; 12279 __ jmpb(*L); 12280 %} 12281 ins_pipe(pipe_jmp); 12282 ins_short_branch(1); 12283 %} 12284 12285 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12286 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12287 match(If cop cr); 12288 effect(USE labl); 12289 12290 ins_cost(300); 12291 format %{ "j$cop,s $labl" %} 12292 size(2); 12293 ins_encode %{ 12294 Label* L = $labl$$label; 12295 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12296 %} 12297 ins_pipe(pipe_jcc); 12298 ins_short_branch(1); 12299 %} 12300 12301 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12302 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12303 match(CountedLoopEnd cop cr); 12304 effect(USE labl); 12305 12306 ins_cost(300); 12307 format %{ "j$cop,s $labl\t# loop end" %} 12308 size(2); 12309 ins_encode %{ 12310 Label* L = $labl$$label; 12311 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12312 %} 12313 ins_pipe(pipe_jcc); 12314 ins_short_branch(1); 12315 %} 12316 12317 // Jump Direct Conditional - using unsigned comparison 12318 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12319 match(If cop cmp); 12320 effect(USE labl); 12321 12322 ins_cost(300); 12323 format %{ "j$cop,us $labl" %} 12324 size(2); 12325 ins_encode %{ 12326 Label* L = $labl$$label; 12327 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12328 %} 12329 ins_pipe(pipe_jcc); 12330 ins_short_branch(1); 12331 %} 12332 12333 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12334 match(If cop cmp); 12335 effect(USE labl); 12336 12337 ins_cost(300); 12338 format %{ "j$cop,us $labl" %} 12339 size(2); 12340 ins_encode %{ 12341 Label* L = $labl$$label; 12342 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12343 %} 12344 ins_pipe(pipe_jcc); 12345 ins_short_branch(1); 12346 %} 12347 12348 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12349 match(If cop cmp); 12350 effect(USE labl); 12351 12352 ins_cost(300); 12353 format %{ $$template 12354 if ($cop$$cmpcode == Assembler::notEqual) { 12355 $$emit$$"jp,u,s $labl\n\t" 12356 $$emit$$"j$cop,u,s $labl" 12357 } else { 12358 $$emit$$"jp,u,s done\n\t" 12359 $$emit$$"j$cop,u,s $labl\n\t" 12360 $$emit$$"done:" 12361 } 12362 %} 12363 size(4); 12364 ins_encode %{ 12365 Label* l = $labl$$label; 12366 if ($cop$$cmpcode == Assembler::notEqual) { 12367 __ jccb(Assembler::parity, *l); 12368 __ jccb(Assembler::notEqual, *l); 12369 } else if ($cop$$cmpcode == Assembler::equal) { 12370 Label done; 12371 __ jccb(Assembler::parity, done); 12372 __ jccb(Assembler::equal, *l); 12373 __ bind(done); 12374 } else { 12375 ShouldNotReachHere(); 12376 } 12377 %} 12378 ins_pipe(pipe_jcc); 12379 ins_short_branch(1); 12380 %} 12381 12382 // ============================================================================ 12383 // inlined locking and unlocking 12384 12385 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12386 predicate(LockingMode != LM_LIGHTWEIGHT); 12387 match(Set cr (FastLock object box)); 12388 effect(TEMP tmp, TEMP scr, USE_KILL box); 12389 ins_cost(300); 12390 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12391 ins_encode %{ 12392 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12393 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12394 %} 12395 ins_pipe(pipe_slow); 12396 %} 12397 12398 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12399 predicate(LockingMode != LM_LIGHTWEIGHT); 12400 match(Set cr (FastUnlock object box)); 12401 effect(TEMP tmp, USE_KILL box); 12402 ins_cost(300); 12403 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12404 ins_encode %{ 12405 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12406 %} 12407 ins_pipe(pipe_slow); 12408 %} 12409 12410 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12411 predicate(LockingMode == LM_LIGHTWEIGHT); 12412 match(Set cr (FastLock object box)); 12413 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12414 ins_cost(300); 12415 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12416 ins_encode %{ 12417 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12418 %} 12419 ins_pipe(pipe_slow); 12420 %} 12421 12422 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12423 predicate(LockingMode == LM_LIGHTWEIGHT); 12424 match(Set cr (FastUnlock object rax_reg)); 12425 effect(TEMP tmp, USE_KILL rax_reg); 12426 ins_cost(300); 12427 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12428 ins_encode %{ 12429 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12430 %} 12431 ins_pipe(pipe_slow); 12432 %} 12433 12434 12435 // ============================================================================ 12436 // Safepoint Instructions 12437 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12438 %{ 12439 match(SafePoint poll); 12440 effect(KILL cr, USE poll); 12441 12442 format %{ "testl rax, [$poll]\t" 12443 "# Safepoint: poll for GC" %} 12444 ins_cost(125); 12445 ins_encode %{ 12446 __ relocate(relocInfo::poll_type); 12447 address pre_pc = __ pc(); 12448 __ testl(rax, Address($poll$$Register, 0)); 12449 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12450 %} 12451 ins_pipe(ialu_reg_mem); 12452 %} 12453 12454 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12455 match(Set dst (MaskAll src)); 12456 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12457 ins_encode %{ 12458 int mask_len = Matcher::vector_length(this); 12459 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12460 %} 12461 ins_pipe( pipe_slow ); 12462 %} 12463 12464 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12465 predicate(Matcher::vector_length(n) > 32); 12466 match(Set dst (MaskAll src)); 12467 effect(TEMP tmp); 12468 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12469 ins_encode %{ 12470 int mask_len = Matcher::vector_length(this); 12471 __ movslq($tmp$$Register, $src$$Register); 12472 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12473 %} 12474 ins_pipe( pipe_slow ); 12475 %} 12476 12477 // ============================================================================ 12478 // Procedure Call/Return Instructions 12479 // Call Java Static Instruction 12480 // Note: If this code changes, the corresponding ret_addr_offset() and 12481 // compute_padding() functions will have to be adjusted. 12482 instruct CallStaticJavaDirect(method meth) %{ 12483 match(CallStaticJava); 12484 effect(USE meth); 12485 12486 ins_cost(300); 12487 format %{ "call,static " %} 12488 opcode(0xE8); /* E8 cd */ 12489 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12490 ins_pipe(pipe_slow); 12491 ins_alignment(4); 12492 %} 12493 12494 // Call Java Dynamic Instruction 12495 // Note: If this code changes, the corresponding ret_addr_offset() and 12496 // compute_padding() functions will have to be adjusted. 12497 instruct CallDynamicJavaDirect(method meth) 12498 %{ 12499 match(CallDynamicJava); 12500 effect(USE meth); 12501 12502 ins_cost(300); 12503 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12504 "call,dynamic " %} 12505 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12506 ins_pipe(pipe_slow); 12507 ins_alignment(4); 12508 %} 12509 12510 // Call Runtime Instruction 12511 instruct CallRuntimeDirect(method meth) 12512 %{ 12513 match(CallRuntime); 12514 effect(USE meth); 12515 12516 ins_cost(300); 12517 format %{ "call,runtime " %} 12518 ins_encode(clear_avx, Java_To_Runtime(meth)); 12519 ins_pipe(pipe_slow); 12520 %} 12521 12522 // Call runtime without safepoint 12523 instruct CallLeafDirect(method meth) 12524 %{ 12525 match(CallLeaf); 12526 effect(USE meth); 12527 12528 ins_cost(300); 12529 format %{ "call_leaf,runtime " %} 12530 ins_encode(clear_avx, Java_To_Runtime(meth)); 12531 ins_pipe(pipe_slow); 12532 %} 12533 12534 // Call runtime without safepoint and with vector arguments 12535 instruct CallLeafDirectVector(method meth) 12536 %{ 12537 match(CallLeafVector); 12538 effect(USE meth); 12539 12540 ins_cost(300); 12541 format %{ "call_leaf,vector " %} 12542 ins_encode(Java_To_Runtime(meth)); 12543 ins_pipe(pipe_slow); 12544 %} 12545 12546 // Call runtime without safepoint 12547 instruct CallLeafNoFPDirect(method meth) 12548 %{ 12549 match(CallLeafNoFP); 12550 effect(USE meth); 12551 12552 ins_cost(300); 12553 format %{ "call_leaf_nofp,runtime " %} 12554 ins_encode(clear_avx, Java_To_Runtime(meth)); 12555 ins_pipe(pipe_slow); 12556 %} 12557 12558 // Return Instruction 12559 // Remove the return address & jump to it. 12560 // Notice: We always emit a nop after a ret to make sure there is room 12561 // for safepoint patching 12562 instruct Ret() 12563 %{ 12564 match(Return); 12565 12566 format %{ "ret" %} 12567 ins_encode %{ 12568 __ ret(0); 12569 %} 12570 ins_pipe(pipe_jmp); 12571 %} 12572 12573 // Tail Call; Jump from runtime stub to Java code. 12574 // Also known as an 'interprocedural jump'. 12575 // Target of jump will eventually return to caller. 12576 // TailJump below removes the return address. 12577 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12578 // emitted just above the TailCall which has reset rbp to the caller state. 12579 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12580 %{ 12581 match(TailCall jump_target method_ptr); 12582 12583 ins_cost(300); 12584 format %{ "jmp $jump_target\t# rbx holds method" %} 12585 ins_encode %{ 12586 __ jmp($jump_target$$Register); 12587 %} 12588 ins_pipe(pipe_jmp); 12589 %} 12590 12591 // Tail Jump; remove the return address; jump to target. 12592 // TailCall above leaves the return address around. 12593 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12594 %{ 12595 match(TailJump jump_target ex_oop); 12596 12597 ins_cost(300); 12598 format %{ "popq rdx\t# pop return address\n\t" 12599 "jmp $jump_target" %} 12600 ins_encode %{ 12601 __ popq(as_Register(RDX_enc)); 12602 __ jmp($jump_target$$Register); 12603 %} 12604 ins_pipe(pipe_jmp); 12605 %} 12606 12607 // Forward exception. 12608 instruct ForwardExceptionjmp() 12609 %{ 12610 match(ForwardException); 12611 12612 format %{ "jmp forward_exception_stub" %} 12613 ins_encode %{ 12614 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 12615 %} 12616 ins_pipe(pipe_jmp); 12617 %} 12618 12619 // Create exception oop: created by stack-crawling runtime code. 12620 // Created exception is now available to this handler, and is setup 12621 // just prior to jumping to this handler. No code emitted. 12622 instruct CreateException(rax_RegP ex_oop) 12623 %{ 12624 match(Set ex_oop (CreateEx)); 12625 12626 size(0); 12627 // use the following format syntax 12628 format %{ "# exception oop is in rax; no code emitted" %} 12629 ins_encode(); 12630 ins_pipe(empty); 12631 %} 12632 12633 // Rethrow exception: 12634 // The exception oop will come in the first argument position. 12635 // Then JUMP (not call) to the rethrow stub code. 12636 instruct RethrowException() 12637 %{ 12638 match(Rethrow); 12639 12640 // use the following format syntax 12641 format %{ "jmp rethrow_stub" %} 12642 ins_encode %{ 12643 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12644 %} 12645 ins_pipe(pipe_jmp); 12646 %} 12647 12648 // ============================================================================ 12649 // This name is KNOWN by the ADLC and cannot be changed. 12650 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12651 // for this guy. 12652 instruct tlsLoadP(r15_RegP dst) %{ 12653 match(Set dst (ThreadLocal)); 12654 effect(DEF dst); 12655 12656 size(0); 12657 format %{ "# TLS is in R15" %} 12658 ins_encode( /*empty encoding*/ ); 12659 ins_pipe(ialu_reg_reg); 12660 %} 12661 12662 12663 //----------PEEPHOLE RULES----------------------------------------------------- 12664 // These must follow all instruction definitions as they use the names 12665 // defined in the instructions definitions. 12666 // 12667 // peeppredicate ( rule_predicate ); 12668 // // the predicate unless which the peephole rule will be ignored 12669 // 12670 // peepmatch ( root_instr_name [preceding_instruction]* ); 12671 // 12672 // peepprocedure ( procedure_name ); 12673 // // provide a procedure name to perform the optimization, the procedure should 12674 // // reside in the architecture dependent peephole file, the method has the 12675 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12676 // // with the arguments being the basic block, the current node index inside the 12677 // // block, the register allocator, the functions upon invoked return a new node 12678 // // defined in peepreplace, and the rules of the nodes appearing in the 12679 // // corresponding peepmatch, the function return true if successful, else 12680 // // return false 12681 // 12682 // peepconstraint %{ 12683 // (instruction_number.operand_name relational_op instruction_number.operand_name 12684 // [, ...] ); 12685 // // instruction numbers are zero-based using left to right order in peepmatch 12686 // 12687 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12688 // // provide an instruction_number.operand_name for each operand that appears 12689 // // in the replacement instruction's match rule 12690 // 12691 // ---------VM FLAGS--------------------------------------------------------- 12692 // 12693 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12694 // 12695 // Each peephole rule is given an identifying number starting with zero and 12696 // increasing by one in the order seen by the parser. An individual peephole 12697 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12698 // on the command-line. 12699 // 12700 // ---------CURRENT LIMITATIONS---------------------------------------------- 12701 // 12702 // Only transformations inside a basic block (do we need more for peephole) 12703 // 12704 // ---------EXAMPLE---------------------------------------------------------- 12705 // 12706 // // pertinent parts of existing instructions in architecture description 12707 // instruct movI(rRegI dst, rRegI src) 12708 // %{ 12709 // match(Set dst (CopyI src)); 12710 // %} 12711 // 12712 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12713 // %{ 12714 // match(Set dst (AddI dst src)); 12715 // effect(KILL cr); 12716 // %} 12717 // 12718 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12719 // %{ 12720 // match(Set dst (AddI dst src)); 12721 // %} 12722 // 12723 // 1. Simple replacement 12724 // - Only match adjacent instructions in same basic block 12725 // - Only equality constraints 12726 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12727 // - Only one replacement instruction 12728 // 12729 // // Change (inc mov) to lea 12730 // peephole %{ 12731 // // lea should only be emitted when beneficial 12732 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12733 // // increment preceded by register-register move 12734 // peepmatch ( incI_rReg movI ); 12735 // // require that the destination register of the increment 12736 // // match the destination register of the move 12737 // peepconstraint ( 0.dst == 1.dst ); 12738 // // construct a replacement instruction that sets 12739 // // the destination to ( move's source register + one ) 12740 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12741 // %} 12742 // 12743 // 2. Procedural replacement 12744 // - More flexible finding relevent nodes 12745 // - More flexible constraints 12746 // - More flexible transformations 12747 // - May utilise architecture-dependent API more effectively 12748 // - Currently only one replacement instruction due to adlc parsing capabilities 12749 // 12750 // // Change (inc mov) to lea 12751 // peephole %{ 12752 // // lea should only be emitted when beneficial 12753 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12754 // // the rule numbers of these nodes inside are passed into the function below 12755 // peepmatch ( incI_rReg movI ); 12756 // // the method that takes the responsibility of transformation 12757 // peepprocedure ( inc_mov_to_lea ); 12758 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12759 // // node is passed into the function above 12760 // peepreplace ( leaI_rReg_immI() ); 12761 // %} 12762 12763 // These instructions is not matched by the matcher but used by the peephole 12764 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12765 %{ 12766 predicate(false); 12767 match(Set dst (AddI src1 src2)); 12768 format %{ "leal $dst, [$src1 + $src2]" %} 12769 ins_encode %{ 12770 Register dst = $dst$$Register; 12771 Register src1 = $src1$$Register; 12772 Register src2 = $src2$$Register; 12773 if (src1 != rbp && src1 != r13) { 12774 __ leal(dst, Address(src1, src2, Address::times_1)); 12775 } else { 12776 assert(src2 != rbp && src2 != r13, ""); 12777 __ leal(dst, Address(src2, src1, Address::times_1)); 12778 } 12779 %} 12780 ins_pipe(ialu_reg_reg); 12781 %} 12782 12783 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 12784 %{ 12785 predicate(false); 12786 match(Set dst (AddI src1 src2)); 12787 format %{ "leal $dst, [$src1 + $src2]" %} 12788 ins_encode %{ 12789 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 12790 %} 12791 ins_pipe(ialu_reg_reg); 12792 %} 12793 12794 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 12795 %{ 12796 predicate(false); 12797 match(Set dst (LShiftI src shift)); 12798 format %{ "leal $dst, [$src << $shift]" %} 12799 ins_encode %{ 12800 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12801 Register src = $src$$Register; 12802 if (scale == Address::times_2 && src != rbp && src != r13) { 12803 __ leal($dst$$Register, Address(src, src, Address::times_1)); 12804 } else { 12805 __ leal($dst$$Register, Address(noreg, src, scale)); 12806 } 12807 %} 12808 ins_pipe(ialu_reg_reg); 12809 %} 12810 12811 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 12812 %{ 12813 predicate(false); 12814 match(Set dst (AddL src1 src2)); 12815 format %{ "leaq $dst, [$src1 + $src2]" %} 12816 ins_encode %{ 12817 Register dst = $dst$$Register; 12818 Register src1 = $src1$$Register; 12819 Register src2 = $src2$$Register; 12820 if (src1 != rbp && src1 != r13) { 12821 __ leaq(dst, Address(src1, src2, Address::times_1)); 12822 } else { 12823 assert(src2 != rbp && src2 != r13, ""); 12824 __ leaq(dst, Address(src2, src1, Address::times_1)); 12825 } 12826 %} 12827 ins_pipe(ialu_reg_reg); 12828 %} 12829 12830 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 12831 %{ 12832 predicate(false); 12833 match(Set dst (AddL src1 src2)); 12834 format %{ "leaq $dst, [$src1 + $src2]" %} 12835 ins_encode %{ 12836 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 12837 %} 12838 ins_pipe(ialu_reg_reg); 12839 %} 12840 12841 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 12842 %{ 12843 predicate(false); 12844 match(Set dst (LShiftL src shift)); 12845 format %{ "leaq $dst, [$src << $shift]" %} 12846 ins_encode %{ 12847 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 12848 Register src = $src$$Register; 12849 if (scale == Address::times_2 && src != rbp && src != r13) { 12850 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 12851 } else { 12852 __ leaq($dst$$Register, Address(noreg, src, scale)); 12853 } 12854 %} 12855 ins_pipe(ialu_reg_reg); 12856 %} 12857 12858 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 12859 // sal}) with lea instructions. The {add, sal} rules are beneficial in 12860 // processors with at least partial ALU support for lea 12861 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 12862 // beneficial for processors with full ALU support 12863 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 12864 12865 peephole 12866 %{ 12867 peeppredicate(VM_Version::supports_fast_2op_lea()); 12868 peepmatch (addI_rReg); 12869 peepprocedure (lea_coalesce_reg); 12870 peepreplace (leaI_rReg_rReg_peep()); 12871 %} 12872 12873 peephole 12874 %{ 12875 peeppredicate(VM_Version::supports_fast_2op_lea()); 12876 peepmatch (addI_rReg_imm); 12877 peepprocedure (lea_coalesce_imm); 12878 peepreplace (leaI_rReg_immI_peep()); 12879 %} 12880 12881 peephole 12882 %{ 12883 peeppredicate(VM_Version::supports_fast_3op_lea() || 12884 VM_Version::is_intel_cascade_lake()); 12885 peepmatch (incI_rReg); 12886 peepprocedure (lea_coalesce_imm); 12887 peepreplace (leaI_rReg_immI_peep()); 12888 %} 12889 12890 peephole 12891 %{ 12892 peeppredicate(VM_Version::supports_fast_3op_lea() || 12893 VM_Version::is_intel_cascade_lake()); 12894 peepmatch (decI_rReg); 12895 peepprocedure (lea_coalesce_imm); 12896 peepreplace (leaI_rReg_immI_peep()); 12897 %} 12898 12899 peephole 12900 %{ 12901 peeppredicate(VM_Version::supports_fast_2op_lea()); 12902 peepmatch (salI_rReg_immI2); 12903 peepprocedure (lea_coalesce_imm); 12904 peepreplace (leaI_rReg_immI2_peep()); 12905 %} 12906 12907 peephole 12908 %{ 12909 peeppredicate(VM_Version::supports_fast_2op_lea()); 12910 peepmatch (addL_rReg); 12911 peepprocedure (lea_coalesce_reg); 12912 peepreplace (leaL_rReg_rReg_peep()); 12913 %} 12914 12915 peephole 12916 %{ 12917 peeppredicate(VM_Version::supports_fast_2op_lea()); 12918 peepmatch (addL_rReg_imm); 12919 peepprocedure (lea_coalesce_imm); 12920 peepreplace (leaL_rReg_immL32_peep()); 12921 %} 12922 12923 peephole 12924 %{ 12925 peeppredicate(VM_Version::supports_fast_3op_lea() || 12926 VM_Version::is_intel_cascade_lake()); 12927 peepmatch (incL_rReg); 12928 peepprocedure (lea_coalesce_imm); 12929 peepreplace (leaL_rReg_immL32_peep()); 12930 %} 12931 12932 peephole 12933 %{ 12934 peeppredicate(VM_Version::supports_fast_3op_lea() || 12935 VM_Version::is_intel_cascade_lake()); 12936 peepmatch (decL_rReg); 12937 peepprocedure (lea_coalesce_imm); 12938 peepreplace (leaL_rReg_immL32_peep()); 12939 %} 12940 12941 peephole 12942 %{ 12943 peeppredicate(VM_Version::supports_fast_2op_lea()); 12944 peepmatch (salL_rReg_immI2); 12945 peepprocedure (lea_coalesce_imm); 12946 peepreplace (leaL_rReg_immI2_peep()); 12947 %} 12948 12949 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 12950 // 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 12951 12952 //int variant 12953 peephole 12954 %{ 12955 peepmatch (testI_reg); 12956 peepprocedure (test_may_remove); 12957 %} 12958 12959 //long variant 12960 peephole 12961 %{ 12962 peepmatch (testL_reg); 12963 peepprocedure (test_may_remove); 12964 %} 12965 12966 12967 //----------SMARTSPILL RULES--------------------------------------------------- 12968 // These must follow all instruction definitions as they use the names 12969 // defined in the instructions definitions.