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 extern RegMask _ANY_REG_mask; 430 extern RegMask _PTR_REG_mask; 431 extern RegMask _PTR_REG_NO_RBP_mask; 432 extern RegMask _PTR_NO_RAX_REG_mask; 433 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 434 extern RegMask _LONG_REG_mask; 435 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 436 extern RegMask _LONG_NO_RCX_REG_mask; 437 extern RegMask _LONG_NO_RBP_R13_REG_mask; 438 extern RegMask _INT_REG_mask; 439 extern RegMask _INT_NO_RAX_RDX_REG_mask; 440 extern RegMask _INT_NO_RCX_REG_mask; 441 extern RegMask _INT_NO_RBP_R13_REG_mask; 442 extern RegMask _FLOAT_REG_mask; 443 444 extern RegMask _STACK_OR_PTR_REG_mask; 445 extern RegMask _STACK_OR_LONG_REG_mask; 446 extern RegMask _STACK_OR_INT_REG_mask; 447 448 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 449 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 450 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 451 452 %} 453 454 source %{ 455 #define RELOC_IMM64 Assembler::imm_operand 456 #define RELOC_DISP32 Assembler::disp32_operand 457 458 #define __ masm-> 459 460 RegMask _ANY_REG_mask; 461 RegMask _PTR_REG_mask; 462 RegMask _PTR_REG_NO_RBP_mask; 463 RegMask _PTR_NO_RAX_REG_mask; 464 RegMask _PTR_NO_RAX_RBX_REG_mask; 465 RegMask _LONG_REG_mask; 466 RegMask _LONG_NO_RAX_RDX_REG_mask; 467 RegMask _LONG_NO_RCX_REG_mask; 468 RegMask _LONG_NO_RBP_R13_REG_mask; 469 RegMask _INT_REG_mask; 470 RegMask _INT_NO_RAX_RDX_REG_mask; 471 RegMask _INT_NO_RCX_REG_mask; 472 RegMask _INT_NO_RBP_R13_REG_mask; 473 RegMask _FLOAT_REG_mask; 474 RegMask _STACK_OR_PTR_REG_mask; 475 RegMask _STACK_OR_LONG_REG_mask; 476 RegMask _STACK_OR_INT_REG_mask; 477 478 static bool need_r12_heapbase() { 479 return UseCompressedOops; 480 } 481 482 void reg_mask_init() { 483 constexpr Register egprs[] = {r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31}; 484 485 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 486 // We derive a number of subsets from it. 487 _ANY_REG_mask = _ALL_REG_mask; 488 489 if (PreserveFramePointer) { 490 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 491 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 492 } 493 if (need_r12_heapbase()) { 494 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 495 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 496 } 497 498 _PTR_REG_mask = _ANY_REG_mask; 499 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 500 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 501 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 502 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 503 if (!UseAPX) { 504 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 505 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 506 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg()->next())); 507 } 508 } 509 510 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 511 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 512 513 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 514 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 515 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 516 517 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 518 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 519 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 520 521 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 522 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 523 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 524 525 526 _LONG_REG_mask = _PTR_REG_mask; 527 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 528 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 529 530 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 531 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 532 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 533 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 534 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 535 536 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 537 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 538 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 539 540 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 541 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 542 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 543 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 544 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 545 546 _INT_REG_mask = _ALL_INT_REG_mask; 547 if (!UseAPX) { 548 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 549 _INT_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 550 } 551 } 552 553 if (PreserveFramePointer) { 554 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 555 } 556 if (need_r12_heapbase()) { 557 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 558 } 559 560 _STACK_OR_INT_REG_mask = _INT_REG_mask; 561 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 562 563 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 564 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 565 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 566 567 _INT_NO_RCX_REG_mask = _INT_REG_mask; 568 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 569 570 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 571 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 572 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 573 574 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 575 // from the float_reg_legacy/float_reg_evex register class. 576 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 577 } 578 579 static bool generate_vzeroupper(Compile* C) { 580 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 581 } 582 583 static int clear_avx_size() { 584 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 585 } 586 587 // !!!!! Special hack to get all types of calls to specify the byte offset 588 // from the start of the call to the point where the return address 589 // will point. 590 int MachCallStaticJavaNode::ret_addr_offset() 591 { 592 int offset = 5; // 5 bytes from start of call to where return address points 593 offset += clear_avx_size(); 594 return offset; 595 } 596 597 int MachCallDynamicJavaNode::ret_addr_offset() 598 { 599 int offset = 15; // 15 bytes from start of call to where return address points 600 offset += clear_avx_size(); 601 return offset; 602 } 603 604 int MachCallRuntimeNode::ret_addr_offset() { 605 int offset = 13; // movq r10,#addr; callq (r10) 606 if (this->ideal_Opcode() != Op_CallLeafVector) { 607 offset += clear_avx_size(); 608 } 609 return offset; 610 } 611 // 612 // Compute padding required for nodes which need alignment 613 // 614 615 // The address of the call instruction needs to be 4-byte aligned to 616 // ensure that it does not span a cache line so that it can be patched. 617 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 618 { 619 current_offset += clear_avx_size(); // skip vzeroupper 620 current_offset += 1; // skip call opcode byte 621 return align_up(current_offset, alignment_required()) - current_offset; 622 } 623 624 // The address of the call instruction needs to be 4-byte aligned to 625 // ensure that it does not span a cache line so that it can be patched. 626 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 627 { 628 current_offset += clear_avx_size(); // skip vzeroupper 629 current_offset += 11; // skip movq instruction + call opcode byte 630 return align_up(current_offset, alignment_required()) - current_offset; 631 } 632 633 // This could be in MacroAssembler but it's fairly C2 specific 634 static void emit_cmpfp_fixup(MacroAssembler* masm) { 635 Label exit; 636 __ jccb(Assembler::noParity, exit); 637 __ pushf(); 638 // 639 // comiss/ucomiss instructions set ZF,PF,CF flags and 640 // zero OF,AF,SF for NaN values. 641 // Fixup flags by zeroing ZF,PF so that compare of NaN 642 // values returns 'less than' result (CF is set). 643 // Leave the rest of flags unchanged. 644 // 645 // 7 6 5 4 3 2 1 0 646 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 647 // 0 0 1 0 1 0 1 1 (0x2B) 648 // 649 __ andq(Address(rsp, 0), 0xffffff2b); 650 __ popf(); 651 __ bind(exit); 652 } 653 654 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 655 Label done; 656 __ movl(dst, -1); 657 __ jcc(Assembler::parity, done); 658 __ jcc(Assembler::below, done); 659 __ setcc(Assembler::notEqual, dst); 660 __ bind(done); 661 } 662 663 // Math.min() # Math.max() 664 // -------------------------- 665 // ucomis[s/d] # 666 // ja -> b # a 667 // jp -> NaN # NaN 668 // jb -> a # b 669 // je # 670 // |-jz -> a | b # a & b 671 // | -> a # 672 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 673 XMMRegister a, XMMRegister b, 674 XMMRegister xmmt, Register rt, 675 bool min, bool single) { 676 677 Label nan, zero, below, above, done; 678 679 if (single) 680 __ ucomiss(a, b); 681 else 682 __ ucomisd(a, b); 683 684 if (dst->encoding() != (min ? b : a)->encoding()) 685 __ jccb(Assembler::above, above); // CF=0 & ZF=0 686 else 687 __ jccb(Assembler::above, done); 688 689 __ jccb(Assembler::parity, nan); // PF=1 690 __ jccb(Assembler::below, below); // CF=1 691 692 // equal 693 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 694 if (single) { 695 __ ucomiss(a, xmmt); 696 __ jccb(Assembler::equal, zero); 697 698 __ movflt(dst, a); 699 __ jmp(done); 700 } 701 else { 702 __ ucomisd(a, xmmt); 703 __ jccb(Assembler::equal, zero); 704 705 __ movdbl(dst, a); 706 __ jmp(done); 707 } 708 709 __ bind(zero); 710 if (min) 711 __ vpor(dst, a, b, Assembler::AVX_128bit); 712 else 713 __ vpand(dst, a, b, Assembler::AVX_128bit); 714 715 __ jmp(done); 716 717 __ bind(above); 718 if (single) 719 __ movflt(dst, min ? b : a); 720 else 721 __ movdbl(dst, min ? b : a); 722 723 __ jmp(done); 724 725 __ bind(nan); 726 if (single) { 727 __ movl(rt, 0x7fc00000); // Float.NaN 728 __ movdl(dst, rt); 729 } 730 else { 731 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 732 __ movdq(dst, rt); 733 } 734 __ jmp(done); 735 736 __ bind(below); 737 if (single) 738 __ movflt(dst, min ? a : b); 739 else 740 __ movdbl(dst, min ? a : b); 741 742 __ bind(done); 743 } 744 745 //============================================================================= 746 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 747 748 int ConstantTable::calculate_table_base_offset() const { 749 return 0; // absolute addressing, no offset 750 } 751 752 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 753 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 754 ShouldNotReachHere(); 755 } 756 757 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 758 // Empty encoding 759 } 760 761 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 762 return 0; 763 } 764 765 #ifndef PRODUCT 766 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 767 st->print("# MachConstantBaseNode (empty encoding)"); 768 } 769 #endif 770 771 772 //============================================================================= 773 #ifndef PRODUCT 774 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 775 Compile* C = ra_->C; 776 777 int framesize = C->output()->frame_size_in_bytes(); 778 int bangsize = C->output()->bang_size_in_bytes(); 779 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 780 // Remove wordSize for return addr which is already pushed. 781 framesize -= wordSize; 782 783 if (C->output()->need_stack_bang(bangsize)) { 784 framesize -= wordSize; 785 st->print("# stack bang (%d bytes)", bangsize); 786 st->print("\n\t"); 787 st->print("pushq rbp\t# Save rbp"); 788 if (PreserveFramePointer) { 789 st->print("\n\t"); 790 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 791 } 792 if (framesize) { 793 st->print("\n\t"); 794 st->print("subq rsp, #%d\t# Create frame",framesize); 795 } 796 } else { 797 st->print("subq rsp, #%d\t# Create frame",framesize); 798 st->print("\n\t"); 799 framesize -= wordSize; 800 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 801 if (PreserveFramePointer) { 802 st->print("\n\t"); 803 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 804 if (framesize > 0) { 805 st->print("\n\t"); 806 st->print("addq rbp, #%d", framesize); 807 } 808 } 809 } 810 811 if (VerifyStackAtCalls) { 812 st->print("\n\t"); 813 framesize -= wordSize; 814 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 815 #ifdef ASSERT 816 st->print("\n\t"); 817 st->print("# stack alignment check"); 818 #endif 819 } 820 if (C->stub_function() != nullptr) { 821 st->print("\n\t"); 822 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 823 st->print("\n\t"); 824 st->print("je fast_entry\t"); 825 st->print("\n\t"); 826 st->print("call #nmethod_entry_barrier_stub\t"); 827 st->print("\n\tfast_entry:"); 828 } 829 st->cr(); 830 } 831 #endif 832 833 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 834 Compile* C = ra_->C; 835 836 int framesize = C->output()->frame_size_in_bytes(); 837 int bangsize = C->output()->bang_size_in_bytes(); 838 839 if (C->clinit_barrier_on_entry()) { 840 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 841 assert(!C->method()->holder()->is_not_initialized() || C->do_clinit_barriers(), "initialization should have been started"); 842 843 Label L_skip_barrier; 844 Register klass = rscratch1; 845 846 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 847 __ clinit_barrier(klass, r15_thread, &L_skip_barrier /*L_fast_path*/); 848 849 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 850 851 __ bind(L_skip_barrier); 852 } 853 854 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 855 856 C->output()->set_frame_complete(__ offset()); 857 858 if (C->has_mach_constant_base_node()) { 859 // NOTE: We set the table base offset here because users might be 860 // emitted before MachConstantBaseNode. 861 ConstantTable& constant_table = C->output()->constant_table(); 862 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 863 } 864 } 865 866 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 867 { 868 return MachNode::size(ra_); // too many variables; just compute it 869 // the hard way 870 } 871 872 int MachPrologNode::reloc() const 873 { 874 return 0; // a large enough number 875 } 876 877 //============================================================================= 878 #ifndef PRODUCT 879 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 880 { 881 Compile* C = ra_->C; 882 if (generate_vzeroupper(C)) { 883 st->print("vzeroupper"); 884 st->cr(); st->print("\t"); 885 } 886 887 int framesize = C->output()->frame_size_in_bytes(); 888 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 889 // Remove word for return adr already pushed 890 // and RBP 891 framesize -= 2*wordSize; 892 893 if (framesize) { 894 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 895 st->print("\t"); 896 } 897 898 st->print_cr("popq rbp"); 899 if (do_polling() && C->is_method_compilation()) { 900 st->print("\t"); 901 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 902 "ja #safepoint_stub\t" 903 "# Safepoint: poll for GC"); 904 } 905 } 906 #endif 907 908 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 909 { 910 Compile* C = ra_->C; 911 912 if (generate_vzeroupper(C)) { 913 // Clear upper bits of YMM registers when current compiled code uses 914 // wide vectors to avoid AVX <-> SSE transition penalty during call. 915 __ vzeroupper(); 916 } 917 918 int framesize = C->output()->frame_size_in_bytes(); 919 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 920 // Remove word for return adr already pushed 921 // and RBP 922 framesize -= 2*wordSize; 923 924 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 925 926 if (framesize) { 927 __ addq(rsp, framesize); 928 } 929 930 __ popq(rbp); 931 932 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 933 __ reserved_stack_check(); 934 } 935 936 if (do_polling() && C->is_method_compilation()) { 937 Label dummy_label; 938 Label* code_stub = &dummy_label; 939 if (!C->output()->in_scratch_emit_size()) { 940 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 941 C->output()->add_stub(stub); 942 code_stub = &stub->entry(); 943 } 944 __ relocate(relocInfo::poll_return_type); 945 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 946 } 947 } 948 949 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 950 { 951 return MachNode::size(ra_); // too many variables; just compute it 952 // the hard way 953 } 954 955 int MachEpilogNode::reloc() const 956 { 957 return 2; // a large enough number 958 } 959 960 const Pipeline* MachEpilogNode::pipeline() const 961 { 962 return MachNode::pipeline_class(); 963 } 964 965 //============================================================================= 966 967 enum RC { 968 rc_bad, 969 rc_int, 970 rc_kreg, 971 rc_float, 972 rc_stack 973 }; 974 975 static enum RC rc_class(OptoReg::Name reg) 976 { 977 if( !OptoReg::is_valid(reg) ) return rc_bad; 978 979 if (OptoReg::is_stack(reg)) return rc_stack; 980 981 VMReg r = OptoReg::as_VMReg(reg); 982 983 if (r->is_Register()) return rc_int; 984 985 if (r->is_KRegister()) return rc_kreg; 986 987 assert(r->is_XMMRegister(), "must be"); 988 return rc_float; 989 } 990 991 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 992 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 993 int src_hi, int dst_hi, uint ireg, outputStream* st); 994 995 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 996 int stack_offset, int reg, uint ireg, outputStream* st); 997 998 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 999 int dst_offset, uint ireg, outputStream* st) { 1000 if (masm) { 1001 switch (ireg) { 1002 case Op_VecS: 1003 __ movq(Address(rsp, -8), rax); 1004 __ movl(rax, Address(rsp, src_offset)); 1005 __ movl(Address(rsp, dst_offset), rax); 1006 __ movq(rax, Address(rsp, -8)); 1007 break; 1008 case Op_VecD: 1009 __ pushq(Address(rsp, src_offset)); 1010 __ popq (Address(rsp, dst_offset)); 1011 break; 1012 case Op_VecX: 1013 __ pushq(Address(rsp, src_offset)); 1014 __ popq (Address(rsp, dst_offset)); 1015 __ pushq(Address(rsp, src_offset+8)); 1016 __ popq (Address(rsp, dst_offset+8)); 1017 break; 1018 case Op_VecY: 1019 __ vmovdqu(Address(rsp, -32), xmm0); 1020 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1021 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1022 __ vmovdqu(xmm0, Address(rsp, -32)); 1023 break; 1024 case Op_VecZ: 1025 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1026 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1027 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1028 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1029 break; 1030 default: 1031 ShouldNotReachHere(); 1032 } 1033 #ifndef PRODUCT 1034 } else { 1035 switch (ireg) { 1036 case Op_VecS: 1037 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1038 "movl rax, [rsp + #%d]\n\t" 1039 "movl [rsp + #%d], rax\n\t" 1040 "movq rax, [rsp - #8]", 1041 src_offset, dst_offset); 1042 break; 1043 case Op_VecD: 1044 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1045 "popq [rsp + #%d]", 1046 src_offset, dst_offset); 1047 break; 1048 case Op_VecX: 1049 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1050 "popq [rsp + #%d]\n\t" 1051 "pushq [rsp + #%d]\n\t" 1052 "popq [rsp + #%d]", 1053 src_offset, dst_offset, src_offset+8, dst_offset+8); 1054 break; 1055 case Op_VecY: 1056 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1057 "vmovdqu xmm0, [rsp + #%d]\n\t" 1058 "vmovdqu [rsp + #%d], xmm0\n\t" 1059 "vmovdqu xmm0, [rsp - #32]", 1060 src_offset, dst_offset); 1061 break; 1062 case Op_VecZ: 1063 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1064 "vmovdqu xmm0, [rsp + #%d]\n\t" 1065 "vmovdqu [rsp + #%d], xmm0\n\t" 1066 "vmovdqu xmm0, [rsp - #64]", 1067 src_offset, dst_offset); 1068 break; 1069 default: 1070 ShouldNotReachHere(); 1071 } 1072 #endif 1073 } 1074 } 1075 1076 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1077 PhaseRegAlloc* ra_, 1078 bool do_size, 1079 outputStream* st) const { 1080 assert(masm != nullptr || st != nullptr, "sanity"); 1081 // Get registers to move 1082 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1083 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1084 OptoReg::Name dst_second = ra_->get_reg_second(this); 1085 OptoReg::Name dst_first = ra_->get_reg_first(this); 1086 1087 enum RC src_second_rc = rc_class(src_second); 1088 enum RC src_first_rc = rc_class(src_first); 1089 enum RC dst_second_rc = rc_class(dst_second); 1090 enum RC dst_first_rc = rc_class(dst_first); 1091 1092 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1093 "must move at least 1 register" ); 1094 1095 if (src_first == dst_first && src_second == dst_second) { 1096 // Self copy, no move 1097 return 0; 1098 } 1099 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1100 uint ireg = ideal_reg(); 1101 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1102 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1103 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1104 // mem -> mem 1105 int src_offset = ra_->reg2offset(src_first); 1106 int dst_offset = ra_->reg2offset(dst_first); 1107 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1108 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1109 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1110 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1111 int stack_offset = ra_->reg2offset(dst_first); 1112 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1113 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1114 int stack_offset = ra_->reg2offset(src_first); 1115 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1116 } else { 1117 ShouldNotReachHere(); 1118 } 1119 return 0; 1120 } 1121 if (src_first_rc == rc_stack) { 1122 // mem -> 1123 if (dst_first_rc == rc_stack) { 1124 // mem -> mem 1125 assert(src_second != dst_first, "overlap"); 1126 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1127 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1128 // 64-bit 1129 int src_offset = ra_->reg2offset(src_first); 1130 int dst_offset = ra_->reg2offset(dst_first); 1131 if (masm) { 1132 __ pushq(Address(rsp, src_offset)); 1133 __ popq (Address(rsp, dst_offset)); 1134 #ifndef PRODUCT 1135 } else { 1136 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1137 "popq [rsp + #%d]", 1138 src_offset, dst_offset); 1139 #endif 1140 } 1141 } else { 1142 // 32-bit 1143 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1144 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1145 // No pushl/popl, so: 1146 int src_offset = ra_->reg2offset(src_first); 1147 int dst_offset = ra_->reg2offset(dst_first); 1148 if (masm) { 1149 __ movq(Address(rsp, -8), rax); 1150 __ movl(rax, Address(rsp, src_offset)); 1151 __ movl(Address(rsp, dst_offset), rax); 1152 __ movq(rax, Address(rsp, -8)); 1153 #ifndef PRODUCT 1154 } else { 1155 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1156 "movl rax, [rsp + #%d]\n\t" 1157 "movl [rsp + #%d], rax\n\t" 1158 "movq rax, [rsp - #8]", 1159 src_offset, dst_offset); 1160 #endif 1161 } 1162 } 1163 return 0; 1164 } else if (dst_first_rc == rc_int) { 1165 // mem -> gpr 1166 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1167 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1168 // 64-bit 1169 int offset = ra_->reg2offset(src_first); 1170 if (masm) { 1171 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1172 #ifndef PRODUCT 1173 } else { 1174 st->print("movq %s, [rsp + #%d]\t# spill", 1175 Matcher::regName[dst_first], 1176 offset); 1177 #endif 1178 } 1179 } else { 1180 // 32-bit 1181 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1182 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1183 int offset = ra_->reg2offset(src_first); 1184 if (masm) { 1185 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1186 #ifndef PRODUCT 1187 } else { 1188 st->print("movl %s, [rsp + #%d]\t# spill", 1189 Matcher::regName[dst_first], 1190 offset); 1191 #endif 1192 } 1193 } 1194 return 0; 1195 } else if (dst_first_rc == rc_float) { 1196 // mem-> xmm 1197 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1198 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1199 // 64-bit 1200 int offset = ra_->reg2offset(src_first); 1201 if (masm) { 1202 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1203 #ifndef PRODUCT 1204 } else { 1205 st->print("%s %s, [rsp + #%d]\t# spill", 1206 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1207 Matcher::regName[dst_first], 1208 offset); 1209 #endif 1210 } 1211 } else { 1212 // 32-bit 1213 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1214 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1215 int offset = ra_->reg2offset(src_first); 1216 if (masm) { 1217 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1218 #ifndef PRODUCT 1219 } else { 1220 st->print("movss %s, [rsp + #%d]\t# spill", 1221 Matcher::regName[dst_first], 1222 offset); 1223 #endif 1224 } 1225 } 1226 return 0; 1227 } else if (dst_first_rc == rc_kreg) { 1228 // mem -> kreg 1229 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1230 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1231 // 64-bit 1232 int offset = ra_->reg2offset(src_first); 1233 if (masm) { 1234 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1235 #ifndef PRODUCT 1236 } else { 1237 st->print("kmovq %s, [rsp + #%d]\t# spill", 1238 Matcher::regName[dst_first], 1239 offset); 1240 #endif 1241 } 1242 } 1243 return 0; 1244 } 1245 } else if (src_first_rc == rc_int) { 1246 // gpr -> 1247 if (dst_first_rc == rc_stack) { 1248 // gpr -> mem 1249 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1250 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1251 // 64-bit 1252 int offset = ra_->reg2offset(dst_first); 1253 if (masm) { 1254 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1255 #ifndef PRODUCT 1256 } else { 1257 st->print("movq [rsp + #%d], %s\t# spill", 1258 offset, 1259 Matcher::regName[src_first]); 1260 #endif 1261 } 1262 } else { 1263 // 32-bit 1264 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1265 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1266 int offset = ra_->reg2offset(dst_first); 1267 if (masm) { 1268 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1269 #ifndef PRODUCT 1270 } else { 1271 st->print("movl [rsp + #%d], %s\t# spill", 1272 offset, 1273 Matcher::regName[src_first]); 1274 #endif 1275 } 1276 } 1277 return 0; 1278 } else if (dst_first_rc == rc_int) { 1279 // gpr -> gpr 1280 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1281 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1282 // 64-bit 1283 if (masm) { 1284 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1285 as_Register(Matcher::_regEncode[src_first])); 1286 #ifndef PRODUCT 1287 } else { 1288 st->print("movq %s, %s\t# spill", 1289 Matcher::regName[dst_first], 1290 Matcher::regName[src_first]); 1291 #endif 1292 } 1293 return 0; 1294 } else { 1295 // 32-bit 1296 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1297 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1298 if (masm) { 1299 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1300 as_Register(Matcher::_regEncode[src_first])); 1301 #ifndef PRODUCT 1302 } else { 1303 st->print("movl %s, %s\t# spill", 1304 Matcher::regName[dst_first], 1305 Matcher::regName[src_first]); 1306 #endif 1307 } 1308 return 0; 1309 } 1310 } else if (dst_first_rc == rc_float) { 1311 // gpr -> xmm 1312 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1313 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1314 // 64-bit 1315 if (masm) { 1316 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1317 #ifndef PRODUCT 1318 } else { 1319 st->print("movdq %s, %s\t# spill", 1320 Matcher::regName[dst_first], 1321 Matcher::regName[src_first]); 1322 #endif 1323 } 1324 } else { 1325 // 32-bit 1326 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1327 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1328 if (masm) { 1329 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1330 #ifndef PRODUCT 1331 } else { 1332 st->print("movdl %s, %s\t# spill", 1333 Matcher::regName[dst_first], 1334 Matcher::regName[src_first]); 1335 #endif 1336 } 1337 } 1338 return 0; 1339 } else if (dst_first_rc == rc_kreg) { 1340 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1341 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1342 // 64-bit 1343 if (masm) { 1344 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1345 #ifndef PRODUCT 1346 } else { 1347 st->print("kmovq %s, %s\t# spill", 1348 Matcher::regName[dst_first], 1349 Matcher::regName[src_first]); 1350 #endif 1351 } 1352 } 1353 Unimplemented(); 1354 return 0; 1355 } 1356 } else if (src_first_rc == rc_float) { 1357 // xmm -> 1358 if (dst_first_rc == rc_stack) { 1359 // xmm -> mem 1360 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1361 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1362 // 64-bit 1363 int offset = ra_->reg2offset(dst_first); 1364 if (masm) { 1365 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1366 #ifndef PRODUCT 1367 } else { 1368 st->print("movsd [rsp + #%d], %s\t# spill", 1369 offset, 1370 Matcher::regName[src_first]); 1371 #endif 1372 } 1373 } else { 1374 // 32-bit 1375 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1376 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1377 int offset = ra_->reg2offset(dst_first); 1378 if (masm) { 1379 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1380 #ifndef PRODUCT 1381 } else { 1382 st->print("movss [rsp + #%d], %s\t# spill", 1383 offset, 1384 Matcher::regName[src_first]); 1385 #endif 1386 } 1387 } 1388 return 0; 1389 } else if (dst_first_rc == rc_int) { 1390 // xmm -> gpr 1391 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1392 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1393 // 64-bit 1394 if (masm) { 1395 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1396 #ifndef PRODUCT 1397 } else { 1398 st->print("movdq %s, %s\t# spill", 1399 Matcher::regName[dst_first], 1400 Matcher::regName[src_first]); 1401 #endif 1402 } 1403 } else { 1404 // 32-bit 1405 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1406 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1407 if (masm) { 1408 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1409 #ifndef PRODUCT 1410 } else { 1411 st->print("movdl %s, %s\t# spill", 1412 Matcher::regName[dst_first], 1413 Matcher::regName[src_first]); 1414 #endif 1415 } 1416 } 1417 return 0; 1418 } else if (dst_first_rc == rc_float) { 1419 // xmm -> xmm 1420 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1421 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1422 // 64-bit 1423 if (masm) { 1424 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1425 #ifndef PRODUCT 1426 } else { 1427 st->print("%s %s, %s\t# spill", 1428 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1429 Matcher::regName[dst_first], 1430 Matcher::regName[src_first]); 1431 #endif 1432 } 1433 } else { 1434 // 32-bit 1435 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1436 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1437 if (masm) { 1438 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1439 #ifndef PRODUCT 1440 } else { 1441 st->print("%s %s, %s\t# spill", 1442 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1443 Matcher::regName[dst_first], 1444 Matcher::regName[src_first]); 1445 #endif 1446 } 1447 } 1448 return 0; 1449 } else if (dst_first_rc == rc_kreg) { 1450 assert(false, "Illegal spilling"); 1451 return 0; 1452 } 1453 } else if (src_first_rc == rc_kreg) { 1454 if (dst_first_rc == rc_stack) { 1455 // mem -> kreg 1456 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1457 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1458 // 64-bit 1459 int offset = ra_->reg2offset(dst_first); 1460 if (masm) { 1461 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1462 #ifndef PRODUCT 1463 } else { 1464 st->print("kmovq [rsp + #%d] , %s\t# spill", 1465 offset, 1466 Matcher::regName[src_first]); 1467 #endif 1468 } 1469 } 1470 return 0; 1471 } else if (dst_first_rc == rc_int) { 1472 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1473 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1474 // 64-bit 1475 if (masm) { 1476 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1477 #ifndef PRODUCT 1478 } else { 1479 st->print("kmovq %s, %s\t# spill", 1480 Matcher::regName[dst_first], 1481 Matcher::regName[src_first]); 1482 #endif 1483 } 1484 } 1485 Unimplemented(); 1486 return 0; 1487 } else if (dst_first_rc == rc_kreg) { 1488 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1489 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1490 // 64-bit 1491 if (masm) { 1492 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1493 #ifndef PRODUCT 1494 } else { 1495 st->print("kmovq %s, %s\t# spill", 1496 Matcher::regName[dst_first], 1497 Matcher::regName[src_first]); 1498 #endif 1499 } 1500 } 1501 return 0; 1502 } else if (dst_first_rc == rc_float) { 1503 assert(false, "Illegal spill"); 1504 return 0; 1505 } 1506 } 1507 1508 assert(0," foo "); 1509 Unimplemented(); 1510 return 0; 1511 } 1512 1513 #ifndef PRODUCT 1514 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1515 implementation(nullptr, ra_, false, st); 1516 } 1517 #endif 1518 1519 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1520 implementation(masm, ra_, false, nullptr); 1521 } 1522 1523 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1524 return MachNode::size(ra_); 1525 } 1526 1527 //============================================================================= 1528 #ifndef PRODUCT 1529 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1530 { 1531 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1532 int reg = ra_->get_reg_first(this); 1533 st->print("leaq %s, [rsp + #%d]\t# box lock", 1534 Matcher::regName[reg], offset); 1535 } 1536 #endif 1537 1538 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1539 { 1540 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1541 int reg = ra_->get_encode(this); 1542 1543 __ lea(as_Register(reg), Address(rsp, offset)); 1544 } 1545 1546 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1547 { 1548 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1549 if (ra_->get_encode(this) > 15) { 1550 return (offset < 0x80) ? 6 : 9; // REX2 1551 } else { 1552 return (offset < 0x80) ? 5 : 8; // REX 1553 } 1554 } 1555 1556 //============================================================================= 1557 #ifndef PRODUCT 1558 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1559 { 1560 if (UseCompressedClassPointers) { 1561 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1562 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1563 } else { 1564 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1565 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1566 } 1567 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1568 } 1569 #endif 1570 1571 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1572 { 1573 __ ic_check(InteriorEntryAlignment); 1574 } 1575 1576 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1577 { 1578 return MachNode::size(ra_); // too many variables; just compute it 1579 // the hard way 1580 } 1581 1582 1583 //============================================================================= 1584 1585 bool Matcher::supports_vector_calling_convention(void) { 1586 if (EnableVectorSupport && UseVectorStubs) { 1587 return true; 1588 } 1589 return false; 1590 } 1591 1592 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1593 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1594 int lo = XMM0_num; 1595 int hi = XMM0b_num; 1596 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1597 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1598 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1599 return OptoRegPair(hi, lo); 1600 } 1601 1602 // Is this branch offset short enough that a short branch can be used? 1603 // 1604 // NOTE: If the platform does not provide any short branch variants, then 1605 // this method should return false for offset 0. 1606 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1607 // The passed offset is relative to address of the branch. 1608 // On 86 a branch displacement is calculated relative to address 1609 // of a next instruction. 1610 offset -= br_size; 1611 1612 // the short version of jmpConUCF2 contains multiple branches, 1613 // making the reach slightly less 1614 if (rule == jmpConUCF2_rule) 1615 return (-126 <= offset && offset <= 125); 1616 return (-128 <= offset && offset <= 127); 1617 } 1618 1619 // Return whether or not this register is ever used as an argument. 1620 // This function is used on startup to build the trampoline stubs in 1621 // generateOptoStub. Registers not mentioned will be killed by the VM 1622 // call in the trampoline, and arguments in those registers not be 1623 // available to the callee. 1624 bool Matcher::can_be_java_arg(int reg) 1625 { 1626 return 1627 reg == RDI_num || reg == RDI_H_num || 1628 reg == RSI_num || reg == RSI_H_num || 1629 reg == RDX_num || reg == RDX_H_num || 1630 reg == RCX_num || reg == RCX_H_num || 1631 reg == R8_num || reg == R8_H_num || 1632 reg == R9_num || reg == R9_H_num || 1633 reg == R12_num || reg == R12_H_num || 1634 reg == XMM0_num || reg == XMM0b_num || 1635 reg == XMM1_num || reg == XMM1b_num || 1636 reg == XMM2_num || reg == XMM2b_num || 1637 reg == XMM3_num || reg == XMM3b_num || 1638 reg == XMM4_num || reg == XMM4b_num || 1639 reg == XMM5_num || reg == XMM5b_num || 1640 reg == XMM6_num || reg == XMM6b_num || 1641 reg == XMM7_num || reg == XMM7b_num; 1642 } 1643 1644 bool Matcher::is_spillable_arg(int reg) 1645 { 1646 return can_be_java_arg(reg); 1647 } 1648 1649 uint Matcher::int_pressure_limit() 1650 { 1651 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1652 } 1653 1654 uint Matcher::float_pressure_limit() 1655 { 1656 // After experiment around with different values, the following default threshold 1657 // works best for LCM's register pressure scheduling on x64. 1658 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1659 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1660 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1661 } 1662 1663 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1664 // In 64 bit mode a code which use multiply when 1665 // devisor is constant is faster than hardware 1666 // DIV instruction (it uses MulHiL). 1667 return false; 1668 } 1669 1670 // Register for DIVI projection of divmodI 1671 RegMask Matcher::divI_proj_mask() { 1672 return INT_RAX_REG_mask(); 1673 } 1674 1675 // Register for MODI projection of divmodI 1676 RegMask Matcher::modI_proj_mask() { 1677 return INT_RDX_REG_mask(); 1678 } 1679 1680 // Register for DIVL projection of divmodL 1681 RegMask Matcher::divL_proj_mask() { 1682 return LONG_RAX_REG_mask(); 1683 } 1684 1685 // Register for MODL projection of divmodL 1686 RegMask Matcher::modL_proj_mask() { 1687 return LONG_RDX_REG_mask(); 1688 } 1689 1690 // Register for saving SP into on method handle invokes. Not used on x86_64. 1691 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1692 return NO_REG_mask(); 1693 } 1694 1695 %} 1696 1697 //----------ENCODING BLOCK----------------------------------------------------- 1698 // This block specifies the encoding classes used by the compiler to 1699 // output byte streams. Encoding classes are parameterized macros 1700 // used by Machine Instruction Nodes in order to generate the bit 1701 // encoding of the instruction. Operands specify their base encoding 1702 // interface with the interface keyword. There are currently 1703 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1704 // COND_INTER. REG_INTER causes an operand to generate a function 1705 // which returns its register number when queried. CONST_INTER causes 1706 // an operand to generate a function which returns the value of the 1707 // constant when queried. MEMORY_INTER causes an operand to generate 1708 // four functions which return the Base Register, the Index Register, 1709 // the Scale Value, and the Offset Value of the operand when queried. 1710 // COND_INTER causes an operand to generate six functions which return 1711 // the encoding code (ie - encoding bits for the instruction) 1712 // associated with each basic boolean condition for a conditional 1713 // instruction. 1714 // 1715 // Instructions specify two basic values for encoding. Again, a 1716 // function is available to check if the constant displacement is an 1717 // oop. They use the ins_encode keyword to specify their encoding 1718 // classes (which must be a sequence of enc_class names, and their 1719 // parameters, specified in the encoding block), and they use the 1720 // opcode keyword to specify, in order, their primary, secondary, and 1721 // tertiary opcode. Only the opcode sections which a particular 1722 // instruction needs for encoding need to be specified. 1723 encode %{ 1724 enc_class cdql_enc(no_rax_rdx_RegI div) 1725 %{ 1726 // Full implementation of Java idiv and irem; checks for 1727 // special case as described in JVM spec., p.243 & p.271. 1728 // 1729 // normal case special case 1730 // 1731 // input : rax: dividend min_int 1732 // reg: divisor -1 1733 // 1734 // output: rax: quotient (= rax idiv reg) min_int 1735 // rdx: remainder (= rax irem reg) 0 1736 // 1737 // Code sequnce: 1738 // 1739 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1740 // 5: 75 07/08 jne e <normal> 1741 // 7: 33 d2 xor %edx,%edx 1742 // [div >= 8 -> offset + 1] 1743 // [REX_B] 1744 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1745 // c: 74 03/04 je 11 <done> 1746 // 000000000000000e <normal>: 1747 // e: 99 cltd 1748 // [div >= 8 -> offset + 1] 1749 // [REX_B] 1750 // f: f7 f9 idiv $div 1751 // 0000000000000011 <done>: 1752 Label normal; 1753 Label done; 1754 1755 // cmp $0x80000000,%eax 1756 __ cmpl(as_Register(RAX_enc), 0x80000000); 1757 1758 // jne e <normal> 1759 __ jccb(Assembler::notEqual, normal); 1760 1761 // xor %edx,%edx 1762 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1763 1764 // cmp $0xffffffffffffffff,%ecx 1765 __ cmpl($div$$Register, -1); 1766 1767 // je 11 <done> 1768 __ jccb(Assembler::equal, done); 1769 1770 // <normal> 1771 // cltd 1772 __ bind(normal); 1773 __ cdql(); 1774 1775 // idivl 1776 // <done> 1777 __ idivl($div$$Register); 1778 __ bind(done); 1779 %} 1780 1781 enc_class cdqq_enc(no_rax_rdx_RegL div) 1782 %{ 1783 // Full implementation of Java ldiv and lrem; checks for 1784 // special case as described in JVM spec., p.243 & p.271. 1785 // 1786 // normal case special case 1787 // 1788 // input : rax: dividend min_long 1789 // reg: divisor -1 1790 // 1791 // output: rax: quotient (= rax idiv reg) min_long 1792 // rdx: remainder (= rax irem reg) 0 1793 // 1794 // Code sequnce: 1795 // 1796 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1797 // 7: 00 00 80 1798 // a: 48 39 d0 cmp %rdx,%rax 1799 // d: 75 08 jne 17 <normal> 1800 // f: 33 d2 xor %edx,%edx 1801 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1802 // 15: 74 05 je 1c <done> 1803 // 0000000000000017 <normal>: 1804 // 17: 48 99 cqto 1805 // 19: 48 f7 f9 idiv $div 1806 // 000000000000001c <done>: 1807 Label normal; 1808 Label done; 1809 1810 // mov $0x8000000000000000,%rdx 1811 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1812 1813 // cmp %rdx,%rax 1814 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1815 1816 // jne 17 <normal> 1817 __ jccb(Assembler::notEqual, normal); 1818 1819 // xor %edx,%edx 1820 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1821 1822 // cmp $0xffffffffffffffff,$div 1823 __ cmpq($div$$Register, -1); 1824 1825 // je 1e <done> 1826 __ jccb(Assembler::equal, done); 1827 1828 // <normal> 1829 // cqto 1830 __ bind(normal); 1831 __ cdqq(); 1832 1833 // idivq (note: must be emitted by the user of this rule) 1834 // <done> 1835 __ idivq($div$$Register); 1836 __ bind(done); 1837 %} 1838 1839 enc_class clear_avx %{ 1840 debug_only(int off0 = __ offset()); 1841 if (generate_vzeroupper(Compile::current())) { 1842 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1843 // Clear upper bits of YMM registers when current compiled code uses 1844 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1845 __ vzeroupper(); 1846 } 1847 debug_only(int off1 = __ offset()); 1848 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1849 %} 1850 1851 enc_class Java_To_Runtime(method meth) %{ 1852 // No relocation needed 1853 if (SCCache::is_on_for_write()) { 1854 // Created runtime_call_type relocation when caching code 1855 __ lea(r10, RuntimeAddress((address)$meth$$method)); 1856 } else { 1857 __ mov64(r10, (int64_t) $meth$$method); 1858 } 1859 __ call(r10); 1860 __ post_call_nop(); 1861 %} 1862 1863 enc_class Java_Static_Call(method meth) 1864 %{ 1865 // JAVA STATIC CALL 1866 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1867 // determine who we intended to call. 1868 if (!_method) { 1869 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1870 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1871 // The NOP here is purely to ensure that eliding a call to 1872 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1873 __ addr_nop_5(); 1874 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1875 } else { 1876 int method_index = resolved_method_index(masm); 1877 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1878 : static_call_Relocation::spec(method_index); 1879 address mark = __ pc(); 1880 int call_offset = __ offset(); 1881 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1882 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1883 // Calls of the same statically bound method can share 1884 // a stub to the interpreter. 1885 __ code()->shared_stub_to_interp_for(_method, call_offset); 1886 } else { 1887 // Emit stubs for static call. 1888 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1889 __ clear_inst_mark(); 1890 if (stub == nullptr) { 1891 ciEnv::current()->record_failure("CodeCache is full"); 1892 return; 1893 } 1894 } 1895 } 1896 __ post_call_nop(); 1897 %} 1898 1899 enc_class Java_Dynamic_Call(method meth) %{ 1900 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1901 __ post_call_nop(); 1902 %} 1903 1904 %} 1905 1906 1907 1908 //----------FRAME-------------------------------------------------------------- 1909 // Definition of frame structure and management information. 1910 // 1911 // S T A C K L A Y O U T Allocators stack-slot number 1912 // | (to get allocators register number 1913 // G Owned by | | v add OptoReg::stack0()) 1914 // r CALLER | | 1915 // o | +--------+ pad to even-align allocators stack-slot 1916 // w V | pad0 | numbers; owned by CALLER 1917 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1918 // h ^ | in | 5 1919 // | | args | 4 Holes in incoming args owned by SELF 1920 // | | | | 3 1921 // | | +--------+ 1922 // V | | old out| Empty on Intel, window on Sparc 1923 // | old |preserve| Must be even aligned. 1924 // | SP-+--------+----> Matcher::_old_SP, even aligned 1925 // | | in | 3 area for Intel ret address 1926 // Owned by |preserve| Empty on Sparc. 1927 // SELF +--------+ 1928 // | | pad2 | 2 pad to align old SP 1929 // | +--------+ 1 1930 // | | locks | 0 1931 // | +--------+----> OptoReg::stack0(), even aligned 1932 // | | pad1 | 11 pad to align new SP 1933 // | +--------+ 1934 // | | | 10 1935 // | | spills | 9 spills 1936 // V | | 8 (pad0 slot for callee) 1937 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1938 // ^ | out | 7 1939 // | | args | 6 Holes in outgoing args owned by CALLEE 1940 // Owned by +--------+ 1941 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1942 // | new |preserve| Must be even-aligned. 1943 // | SP-+--------+----> Matcher::_new_SP, even aligned 1944 // | | | 1945 // 1946 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1947 // known from SELF's arguments and the Java calling convention. 1948 // Region 6-7 is determined per call site. 1949 // Note 2: If the calling convention leaves holes in the incoming argument 1950 // area, those holes are owned by SELF. Holes in the outgoing area 1951 // are owned by the CALLEE. Holes should not be necessary in the 1952 // incoming area, as the Java calling convention is completely under 1953 // the control of the AD file. Doubles can be sorted and packed to 1954 // avoid holes. Holes in the outgoing arguments may be necessary for 1955 // varargs C calling conventions. 1956 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1957 // even aligned with pad0 as needed. 1958 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1959 // region 6-11 is even aligned; it may be padded out more so that 1960 // the region from SP to FP meets the minimum stack alignment. 1961 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1962 // alignment. Region 11, pad1, may be dynamically extended so that 1963 // SP meets the minimum alignment. 1964 1965 frame 1966 %{ 1967 // These three registers define part of the calling convention 1968 // between compiled code and the interpreter. 1969 inline_cache_reg(RAX); // Inline Cache Register 1970 1971 // Optional: name the operand used by cisc-spilling to access 1972 // [stack_pointer + offset] 1973 cisc_spilling_operand_name(indOffset32); 1974 1975 // Number of stack slots consumed by locking an object 1976 sync_stack_slots(2); 1977 1978 // Compiled code's Frame Pointer 1979 frame_pointer(RSP); 1980 1981 // Interpreter stores its frame pointer in a register which is 1982 // stored to the stack by I2CAdaptors. 1983 // I2CAdaptors convert from interpreted java to compiled java. 1984 interpreter_frame_pointer(RBP); 1985 1986 // Stack alignment requirement 1987 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1988 1989 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1990 // for calls to C. Supports the var-args backing area for register parms. 1991 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1992 1993 // The after-PROLOG location of the return address. Location of 1994 // return address specifies a type (REG or STACK) and a number 1995 // representing the register number (i.e. - use a register name) or 1996 // stack slot. 1997 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 1998 // Otherwise, it is above the locks and verification slot and alignment word 1999 return_addr(STACK - 2 + 2000 align_up((Compile::current()->in_preserve_stack_slots() + 2001 Compile::current()->fixed_slots()), 2002 stack_alignment_in_slots())); 2003 2004 // Location of compiled Java return values. Same as C for now. 2005 return_value 2006 %{ 2007 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2008 "only return normal values"); 2009 2010 static const int lo[Op_RegL + 1] = { 2011 0, 2012 0, 2013 RAX_num, // Op_RegN 2014 RAX_num, // Op_RegI 2015 RAX_num, // Op_RegP 2016 XMM0_num, // Op_RegF 2017 XMM0_num, // Op_RegD 2018 RAX_num // Op_RegL 2019 }; 2020 static const int hi[Op_RegL + 1] = { 2021 0, 2022 0, 2023 OptoReg::Bad, // Op_RegN 2024 OptoReg::Bad, // Op_RegI 2025 RAX_H_num, // Op_RegP 2026 OptoReg::Bad, // Op_RegF 2027 XMM0b_num, // Op_RegD 2028 RAX_H_num // Op_RegL 2029 }; 2030 // Excluded flags and vector registers. 2031 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2032 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2033 %} 2034 %} 2035 2036 //----------ATTRIBUTES--------------------------------------------------------- 2037 //----------Operand Attributes------------------------------------------------- 2038 op_attrib op_cost(0); // Required cost attribute 2039 2040 //----------Instruction Attributes--------------------------------------------- 2041 ins_attrib ins_cost(100); // Required cost attribute 2042 ins_attrib ins_size(8); // Required size attribute (in bits) 2043 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2044 // a non-matching short branch variant 2045 // of some long branch? 2046 ins_attrib ins_alignment(1); // Required alignment attribute (must 2047 // be a power of 2) specifies the 2048 // alignment that some part of the 2049 // instruction (not necessarily the 2050 // start) requires. If > 1, a 2051 // compute_padding() function must be 2052 // provided for the instruction 2053 2054 //----------OPERANDS----------------------------------------------------------- 2055 // Operand definitions must precede instruction definitions for correct parsing 2056 // in the ADLC because operands constitute user defined types which are used in 2057 // instruction definitions. 2058 2059 //----------Simple Operands---------------------------------------------------- 2060 // Immediate Operands 2061 // Integer Immediate 2062 operand immI() 2063 %{ 2064 match(ConI); 2065 2066 op_cost(10); 2067 format %{ %} 2068 interface(CONST_INTER); 2069 %} 2070 2071 // Constant for test vs zero 2072 operand immI_0() 2073 %{ 2074 predicate(n->get_int() == 0); 2075 match(ConI); 2076 2077 op_cost(0); 2078 format %{ %} 2079 interface(CONST_INTER); 2080 %} 2081 2082 // Constant for increment 2083 operand immI_1() 2084 %{ 2085 predicate(n->get_int() == 1); 2086 match(ConI); 2087 2088 op_cost(0); 2089 format %{ %} 2090 interface(CONST_INTER); 2091 %} 2092 2093 // Constant for decrement 2094 operand immI_M1() 2095 %{ 2096 predicate(n->get_int() == -1); 2097 match(ConI); 2098 2099 op_cost(0); 2100 format %{ %} 2101 interface(CONST_INTER); 2102 %} 2103 2104 operand immI_2() 2105 %{ 2106 predicate(n->get_int() == 2); 2107 match(ConI); 2108 2109 op_cost(0); 2110 format %{ %} 2111 interface(CONST_INTER); 2112 %} 2113 2114 operand immI_4() 2115 %{ 2116 predicate(n->get_int() == 4); 2117 match(ConI); 2118 2119 op_cost(0); 2120 format %{ %} 2121 interface(CONST_INTER); 2122 %} 2123 2124 operand immI_8() 2125 %{ 2126 predicate(n->get_int() == 8); 2127 match(ConI); 2128 2129 op_cost(0); 2130 format %{ %} 2131 interface(CONST_INTER); 2132 %} 2133 2134 // Valid scale values for addressing modes 2135 operand immI2() 2136 %{ 2137 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2138 match(ConI); 2139 2140 format %{ %} 2141 interface(CONST_INTER); 2142 %} 2143 2144 operand immU7() 2145 %{ 2146 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2147 match(ConI); 2148 2149 op_cost(5); 2150 format %{ %} 2151 interface(CONST_INTER); 2152 %} 2153 2154 operand immI8() 2155 %{ 2156 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2157 match(ConI); 2158 2159 op_cost(5); 2160 format %{ %} 2161 interface(CONST_INTER); 2162 %} 2163 2164 operand immU8() 2165 %{ 2166 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2167 match(ConI); 2168 2169 op_cost(5); 2170 format %{ %} 2171 interface(CONST_INTER); 2172 %} 2173 2174 operand immI16() 2175 %{ 2176 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2177 match(ConI); 2178 2179 op_cost(10); 2180 format %{ %} 2181 interface(CONST_INTER); 2182 %} 2183 2184 // Int Immediate non-negative 2185 operand immU31() 2186 %{ 2187 predicate(n->get_int() >= 0); 2188 match(ConI); 2189 2190 op_cost(0); 2191 format %{ %} 2192 interface(CONST_INTER); 2193 %} 2194 2195 // Pointer Immediate 2196 operand immP() 2197 %{ 2198 match(ConP); 2199 2200 op_cost(10); 2201 format %{ %} 2202 interface(CONST_INTER); 2203 %} 2204 2205 // Null Pointer Immediate 2206 operand immP0() 2207 %{ 2208 predicate(n->get_ptr() == 0); 2209 match(ConP); 2210 2211 op_cost(5); 2212 format %{ %} 2213 interface(CONST_INTER); 2214 %} 2215 2216 // Pointer Immediate 2217 operand immN() %{ 2218 match(ConN); 2219 2220 op_cost(10); 2221 format %{ %} 2222 interface(CONST_INTER); 2223 %} 2224 2225 operand immNKlass() %{ 2226 match(ConNKlass); 2227 2228 op_cost(10); 2229 format %{ %} 2230 interface(CONST_INTER); 2231 %} 2232 2233 // Null Pointer Immediate 2234 operand immN0() %{ 2235 predicate(n->get_narrowcon() == 0); 2236 match(ConN); 2237 2238 op_cost(5); 2239 format %{ %} 2240 interface(CONST_INTER); 2241 %} 2242 2243 operand immP31() 2244 %{ 2245 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2246 && (n->get_ptr() >> 31) == 0); 2247 match(ConP); 2248 2249 op_cost(5); 2250 format %{ %} 2251 interface(CONST_INTER); 2252 %} 2253 2254 2255 // Long Immediate 2256 operand immL() 2257 %{ 2258 match(ConL); 2259 2260 op_cost(20); 2261 format %{ %} 2262 interface(CONST_INTER); 2263 %} 2264 2265 // Long Immediate 8-bit 2266 operand immL8() 2267 %{ 2268 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2269 match(ConL); 2270 2271 op_cost(5); 2272 format %{ %} 2273 interface(CONST_INTER); 2274 %} 2275 2276 // Long Immediate 32-bit unsigned 2277 operand immUL32() 2278 %{ 2279 predicate(n->get_long() == (unsigned int) (n->get_long())); 2280 match(ConL); 2281 2282 op_cost(10); 2283 format %{ %} 2284 interface(CONST_INTER); 2285 %} 2286 2287 // Long Immediate 32-bit signed 2288 operand immL32() 2289 %{ 2290 predicate(n->get_long() == (int) (n->get_long())); 2291 match(ConL); 2292 2293 op_cost(15); 2294 format %{ %} 2295 interface(CONST_INTER); 2296 %} 2297 2298 operand immL_Pow2() 2299 %{ 2300 predicate(is_power_of_2((julong)n->get_long())); 2301 match(ConL); 2302 2303 op_cost(15); 2304 format %{ %} 2305 interface(CONST_INTER); 2306 %} 2307 2308 operand immL_NotPow2() 2309 %{ 2310 predicate(is_power_of_2((julong)~n->get_long())); 2311 match(ConL); 2312 2313 op_cost(15); 2314 format %{ %} 2315 interface(CONST_INTER); 2316 %} 2317 2318 // Long Immediate zero 2319 operand immL0() 2320 %{ 2321 predicate(n->get_long() == 0L); 2322 match(ConL); 2323 2324 op_cost(10); 2325 format %{ %} 2326 interface(CONST_INTER); 2327 %} 2328 2329 // Constant for increment 2330 operand immL1() 2331 %{ 2332 predicate(n->get_long() == 1); 2333 match(ConL); 2334 2335 format %{ %} 2336 interface(CONST_INTER); 2337 %} 2338 2339 // Constant for decrement 2340 operand immL_M1() 2341 %{ 2342 predicate(n->get_long() == -1); 2343 match(ConL); 2344 2345 format %{ %} 2346 interface(CONST_INTER); 2347 %} 2348 2349 // Long Immediate: low 32-bit mask 2350 operand immL_32bits() 2351 %{ 2352 predicate(n->get_long() == 0xFFFFFFFFL); 2353 match(ConL); 2354 op_cost(20); 2355 2356 format %{ %} 2357 interface(CONST_INTER); 2358 %} 2359 2360 // Int Immediate: 2^n-1, positive 2361 operand immI_Pow2M1() 2362 %{ 2363 predicate((n->get_int() > 0) 2364 && is_power_of_2((juint)n->get_int() + 1)); 2365 match(ConI); 2366 2367 op_cost(20); 2368 format %{ %} 2369 interface(CONST_INTER); 2370 %} 2371 2372 // Float Immediate zero 2373 operand immF0() 2374 %{ 2375 predicate(jint_cast(n->getf()) == 0); 2376 match(ConF); 2377 2378 op_cost(5); 2379 format %{ %} 2380 interface(CONST_INTER); 2381 %} 2382 2383 // Float Immediate 2384 operand immF() 2385 %{ 2386 match(ConF); 2387 2388 op_cost(15); 2389 format %{ %} 2390 interface(CONST_INTER); 2391 %} 2392 2393 // Half Float Immediate 2394 operand immH() 2395 %{ 2396 match(ConH); 2397 2398 op_cost(15); 2399 format %{ %} 2400 interface(CONST_INTER); 2401 %} 2402 2403 // Double Immediate zero 2404 operand immD0() 2405 %{ 2406 predicate(jlong_cast(n->getd()) == 0); 2407 match(ConD); 2408 2409 op_cost(5); 2410 format %{ %} 2411 interface(CONST_INTER); 2412 %} 2413 2414 // Double Immediate 2415 operand immD() 2416 %{ 2417 match(ConD); 2418 2419 op_cost(15); 2420 format %{ %} 2421 interface(CONST_INTER); 2422 %} 2423 2424 // Immediates for special shifts (sign extend) 2425 2426 // Constants for increment 2427 operand immI_16() 2428 %{ 2429 predicate(n->get_int() == 16); 2430 match(ConI); 2431 2432 format %{ %} 2433 interface(CONST_INTER); 2434 %} 2435 2436 operand immI_24() 2437 %{ 2438 predicate(n->get_int() == 24); 2439 match(ConI); 2440 2441 format %{ %} 2442 interface(CONST_INTER); 2443 %} 2444 2445 // Constant for byte-wide masking 2446 operand immI_255() 2447 %{ 2448 predicate(n->get_int() == 255); 2449 match(ConI); 2450 2451 format %{ %} 2452 interface(CONST_INTER); 2453 %} 2454 2455 // Constant for short-wide masking 2456 operand immI_65535() 2457 %{ 2458 predicate(n->get_int() == 65535); 2459 match(ConI); 2460 2461 format %{ %} 2462 interface(CONST_INTER); 2463 %} 2464 2465 // Constant for byte-wide masking 2466 operand immL_255() 2467 %{ 2468 predicate(n->get_long() == 255); 2469 match(ConL); 2470 2471 format %{ %} 2472 interface(CONST_INTER); 2473 %} 2474 2475 // Constant for short-wide masking 2476 operand immL_65535() 2477 %{ 2478 predicate(n->get_long() == 65535); 2479 match(ConL); 2480 2481 format %{ %} 2482 interface(CONST_INTER); 2483 %} 2484 2485 // AOT Runtime Constants Address 2486 operand immAOTRuntimeConstantsAddress() 2487 %{ 2488 // Check if the address is in the range of AOT Runtime Constants 2489 predicate(AOTRuntimeConstants::contains((address)(n->get_ptr()))); 2490 match(ConP); 2491 2492 op_cost(0); 2493 format %{ %} 2494 interface(CONST_INTER); 2495 %} 2496 2497 operand kReg() 2498 %{ 2499 constraint(ALLOC_IN_RC(vectmask_reg)); 2500 match(RegVectMask); 2501 format %{%} 2502 interface(REG_INTER); 2503 %} 2504 2505 // Register Operands 2506 // Integer Register 2507 operand rRegI() 2508 %{ 2509 constraint(ALLOC_IN_RC(int_reg)); 2510 match(RegI); 2511 2512 match(rax_RegI); 2513 match(rbx_RegI); 2514 match(rcx_RegI); 2515 match(rdx_RegI); 2516 match(rdi_RegI); 2517 2518 format %{ %} 2519 interface(REG_INTER); 2520 %} 2521 2522 // Special Registers 2523 operand rax_RegI() 2524 %{ 2525 constraint(ALLOC_IN_RC(int_rax_reg)); 2526 match(RegI); 2527 match(rRegI); 2528 2529 format %{ "RAX" %} 2530 interface(REG_INTER); 2531 %} 2532 2533 // Special Registers 2534 operand rbx_RegI() 2535 %{ 2536 constraint(ALLOC_IN_RC(int_rbx_reg)); 2537 match(RegI); 2538 match(rRegI); 2539 2540 format %{ "RBX" %} 2541 interface(REG_INTER); 2542 %} 2543 2544 operand rcx_RegI() 2545 %{ 2546 constraint(ALLOC_IN_RC(int_rcx_reg)); 2547 match(RegI); 2548 match(rRegI); 2549 2550 format %{ "RCX" %} 2551 interface(REG_INTER); 2552 %} 2553 2554 operand rdx_RegI() 2555 %{ 2556 constraint(ALLOC_IN_RC(int_rdx_reg)); 2557 match(RegI); 2558 match(rRegI); 2559 2560 format %{ "RDX" %} 2561 interface(REG_INTER); 2562 %} 2563 2564 operand rdi_RegI() 2565 %{ 2566 constraint(ALLOC_IN_RC(int_rdi_reg)); 2567 match(RegI); 2568 match(rRegI); 2569 2570 format %{ "RDI" %} 2571 interface(REG_INTER); 2572 %} 2573 2574 operand no_rax_rdx_RegI() 2575 %{ 2576 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2577 match(RegI); 2578 match(rbx_RegI); 2579 match(rcx_RegI); 2580 match(rdi_RegI); 2581 2582 format %{ %} 2583 interface(REG_INTER); 2584 %} 2585 2586 operand no_rbp_r13_RegI() 2587 %{ 2588 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2589 match(RegI); 2590 match(rRegI); 2591 match(rax_RegI); 2592 match(rbx_RegI); 2593 match(rcx_RegI); 2594 match(rdx_RegI); 2595 match(rdi_RegI); 2596 2597 format %{ %} 2598 interface(REG_INTER); 2599 %} 2600 2601 // Pointer Register 2602 operand any_RegP() 2603 %{ 2604 constraint(ALLOC_IN_RC(any_reg)); 2605 match(RegP); 2606 match(rax_RegP); 2607 match(rbx_RegP); 2608 match(rdi_RegP); 2609 match(rsi_RegP); 2610 match(rbp_RegP); 2611 match(r15_RegP); 2612 match(rRegP); 2613 2614 format %{ %} 2615 interface(REG_INTER); 2616 %} 2617 2618 operand rRegP() 2619 %{ 2620 constraint(ALLOC_IN_RC(ptr_reg)); 2621 match(RegP); 2622 match(rax_RegP); 2623 match(rbx_RegP); 2624 match(rdi_RegP); 2625 match(rsi_RegP); 2626 match(rbp_RegP); // See Q&A below about 2627 match(r15_RegP); // r15_RegP and rbp_RegP. 2628 2629 format %{ %} 2630 interface(REG_INTER); 2631 %} 2632 2633 operand rRegN() %{ 2634 constraint(ALLOC_IN_RC(int_reg)); 2635 match(RegN); 2636 2637 format %{ %} 2638 interface(REG_INTER); 2639 %} 2640 2641 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2642 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2643 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2644 // The output of an instruction is controlled by the allocator, which respects 2645 // register class masks, not match rules. Unless an instruction mentions 2646 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2647 // by the allocator as an input. 2648 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2649 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2650 // result, RBP is not included in the output of the instruction either. 2651 2652 // This operand is not allowed to use RBP even if 2653 // RBP is not used to hold the frame pointer. 2654 operand no_rbp_RegP() 2655 %{ 2656 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2657 match(RegP); 2658 match(rbx_RegP); 2659 match(rsi_RegP); 2660 match(rdi_RegP); 2661 2662 format %{ %} 2663 interface(REG_INTER); 2664 %} 2665 2666 // Special Registers 2667 // Return a pointer value 2668 operand rax_RegP() 2669 %{ 2670 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2671 match(RegP); 2672 match(rRegP); 2673 2674 format %{ %} 2675 interface(REG_INTER); 2676 %} 2677 2678 // Special Registers 2679 // Return a compressed pointer value 2680 operand rax_RegN() 2681 %{ 2682 constraint(ALLOC_IN_RC(int_rax_reg)); 2683 match(RegN); 2684 match(rRegN); 2685 2686 format %{ %} 2687 interface(REG_INTER); 2688 %} 2689 2690 // Used in AtomicAdd 2691 operand rbx_RegP() 2692 %{ 2693 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2694 match(RegP); 2695 match(rRegP); 2696 2697 format %{ %} 2698 interface(REG_INTER); 2699 %} 2700 2701 operand rsi_RegP() 2702 %{ 2703 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2704 match(RegP); 2705 match(rRegP); 2706 2707 format %{ %} 2708 interface(REG_INTER); 2709 %} 2710 2711 operand rbp_RegP() 2712 %{ 2713 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2714 match(RegP); 2715 match(rRegP); 2716 2717 format %{ %} 2718 interface(REG_INTER); 2719 %} 2720 2721 // Used in rep stosq 2722 operand rdi_RegP() 2723 %{ 2724 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2725 match(RegP); 2726 match(rRegP); 2727 2728 format %{ %} 2729 interface(REG_INTER); 2730 %} 2731 2732 operand r15_RegP() 2733 %{ 2734 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2735 match(RegP); 2736 match(rRegP); 2737 2738 format %{ %} 2739 interface(REG_INTER); 2740 %} 2741 2742 operand rRegL() 2743 %{ 2744 constraint(ALLOC_IN_RC(long_reg)); 2745 match(RegL); 2746 match(rax_RegL); 2747 match(rdx_RegL); 2748 2749 format %{ %} 2750 interface(REG_INTER); 2751 %} 2752 2753 // Special Registers 2754 operand no_rax_rdx_RegL() 2755 %{ 2756 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2757 match(RegL); 2758 match(rRegL); 2759 2760 format %{ %} 2761 interface(REG_INTER); 2762 %} 2763 2764 operand rax_RegL() 2765 %{ 2766 constraint(ALLOC_IN_RC(long_rax_reg)); 2767 match(RegL); 2768 match(rRegL); 2769 2770 format %{ "RAX" %} 2771 interface(REG_INTER); 2772 %} 2773 2774 operand rcx_RegL() 2775 %{ 2776 constraint(ALLOC_IN_RC(long_rcx_reg)); 2777 match(RegL); 2778 match(rRegL); 2779 2780 format %{ %} 2781 interface(REG_INTER); 2782 %} 2783 2784 operand rdx_RegL() 2785 %{ 2786 constraint(ALLOC_IN_RC(long_rdx_reg)); 2787 match(RegL); 2788 match(rRegL); 2789 2790 format %{ %} 2791 interface(REG_INTER); 2792 %} 2793 2794 operand r11_RegL() 2795 %{ 2796 constraint(ALLOC_IN_RC(long_r11_reg)); 2797 match(RegL); 2798 match(rRegL); 2799 2800 format %{ %} 2801 interface(REG_INTER); 2802 %} 2803 2804 operand no_rbp_r13_RegL() 2805 %{ 2806 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2807 match(RegL); 2808 match(rRegL); 2809 match(rax_RegL); 2810 match(rcx_RegL); 2811 match(rdx_RegL); 2812 2813 format %{ %} 2814 interface(REG_INTER); 2815 %} 2816 2817 // Flags register, used as output of compare instructions 2818 operand rFlagsReg() 2819 %{ 2820 constraint(ALLOC_IN_RC(int_flags)); 2821 match(RegFlags); 2822 2823 format %{ "RFLAGS" %} 2824 interface(REG_INTER); 2825 %} 2826 2827 // Flags register, used as output of FLOATING POINT compare instructions 2828 operand rFlagsRegU() 2829 %{ 2830 constraint(ALLOC_IN_RC(int_flags)); 2831 match(RegFlags); 2832 2833 format %{ "RFLAGS_U" %} 2834 interface(REG_INTER); 2835 %} 2836 2837 operand rFlagsRegUCF() %{ 2838 constraint(ALLOC_IN_RC(int_flags)); 2839 match(RegFlags); 2840 predicate(false); 2841 2842 format %{ "RFLAGS_U_CF" %} 2843 interface(REG_INTER); 2844 %} 2845 2846 // Float register operands 2847 operand regF() %{ 2848 constraint(ALLOC_IN_RC(float_reg)); 2849 match(RegF); 2850 2851 format %{ %} 2852 interface(REG_INTER); 2853 %} 2854 2855 // Float register operands 2856 operand legRegF() %{ 2857 constraint(ALLOC_IN_RC(float_reg_legacy)); 2858 match(RegF); 2859 2860 format %{ %} 2861 interface(REG_INTER); 2862 %} 2863 2864 // Float register operands 2865 operand vlRegF() %{ 2866 constraint(ALLOC_IN_RC(float_reg_vl)); 2867 match(RegF); 2868 2869 format %{ %} 2870 interface(REG_INTER); 2871 %} 2872 2873 // Double register operands 2874 operand regD() %{ 2875 constraint(ALLOC_IN_RC(double_reg)); 2876 match(RegD); 2877 2878 format %{ %} 2879 interface(REG_INTER); 2880 %} 2881 2882 // Double register operands 2883 operand legRegD() %{ 2884 constraint(ALLOC_IN_RC(double_reg_legacy)); 2885 match(RegD); 2886 2887 format %{ %} 2888 interface(REG_INTER); 2889 %} 2890 2891 // Double register operands 2892 operand vlRegD() %{ 2893 constraint(ALLOC_IN_RC(double_reg_vl)); 2894 match(RegD); 2895 2896 format %{ %} 2897 interface(REG_INTER); 2898 %} 2899 2900 //----------Memory Operands---------------------------------------------------- 2901 // Direct Memory Operand 2902 // operand direct(immP addr) 2903 // %{ 2904 // match(addr); 2905 2906 // format %{ "[$addr]" %} 2907 // interface(MEMORY_INTER) %{ 2908 // base(0xFFFFFFFF); 2909 // index(0x4); 2910 // scale(0x0); 2911 // disp($addr); 2912 // %} 2913 // %} 2914 2915 // Indirect Memory Operand 2916 operand indirect(any_RegP reg) 2917 %{ 2918 constraint(ALLOC_IN_RC(ptr_reg)); 2919 match(reg); 2920 2921 format %{ "[$reg]" %} 2922 interface(MEMORY_INTER) %{ 2923 base($reg); 2924 index(0x4); 2925 scale(0x0); 2926 disp(0x0); 2927 %} 2928 %} 2929 2930 // Indirect Memory Plus Short Offset Operand 2931 operand indOffset8(any_RegP reg, immL8 off) 2932 %{ 2933 constraint(ALLOC_IN_RC(ptr_reg)); 2934 match(AddP reg off); 2935 2936 format %{ "[$reg + $off (8-bit)]" %} 2937 interface(MEMORY_INTER) %{ 2938 base($reg); 2939 index(0x4); 2940 scale(0x0); 2941 disp($off); 2942 %} 2943 %} 2944 2945 // Indirect Memory Plus Long Offset Operand 2946 operand indOffset32(any_RegP reg, immL32 off) 2947 %{ 2948 constraint(ALLOC_IN_RC(ptr_reg)); 2949 match(AddP reg off); 2950 2951 format %{ "[$reg + $off (32-bit)]" %} 2952 interface(MEMORY_INTER) %{ 2953 base($reg); 2954 index(0x4); 2955 scale(0x0); 2956 disp($off); 2957 %} 2958 %} 2959 2960 // Indirect Memory Plus Index Register Plus Offset Operand 2961 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2962 %{ 2963 constraint(ALLOC_IN_RC(ptr_reg)); 2964 match(AddP (AddP reg lreg) off); 2965 2966 op_cost(10); 2967 format %{"[$reg + $off + $lreg]" %} 2968 interface(MEMORY_INTER) %{ 2969 base($reg); 2970 index($lreg); 2971 scale(0x0); 2972 disp($off); 2973 %} 2974 %} 2975 2976 // Indirect Memory Plus Index Register Plus Offset Operand 2977 operand indIndex(any_RegP reg, rRegL lreg) 2978 %{ 2979 constraint(ALLOC_IN_RC(ptr_reg)); 2980 match(AddP reg lreg); 2981 2982 op_cost(10); 2983 format %{"[$reg + $lreg]" %} 2984 interface(MEMORY_INTER) %{ 2985 base($reg); 2986 index($lreg); 2987 scale(0x0); 2988 disp(0x0); 2989 %} 2990 %} 2991 2992 // Indirect Memory Times Scale Plus Index Register 2993 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2994 %{ 2995 constraint(ALLOC_IN_RC(ptr_reg)); 2996 match(AddP reg (LShiftL lreg scale)); 2997 2998 op_cost(10); 2999 format %{"[$reg + $lreg << $scale]" %} 3000 interface(MEMORY_INTER) %{ 3001 base($reg); 3002 index($lreg); 3003 scale($scale); 3004 disp(0x0); 3005 %} 3006 %} 3007 3008 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3009 %{ 3010 constraint(ALLOC_IN_RC(ptr_reg)); 3011 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3012 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3013 3014 op_cost(10); 3015 format %{"[$reg + pos $idx << $scale]" %} 3016 interface(MEMORY_INTER) %{ 3017 base($reg); 3018 index($idx); 3019 scale($scale); 3020 disp(0x0); 3021 %} 3022 %} 3023 3024 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3025 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3026 %{ 3027 constraint(ALLOC_IN_RC(ptr_reg)); 3028 match(AddP (AddP reg (LShiftL lreg scale)) off); 3029 3030 op_cost(10); 3031 format %{"[$reg + $off + $lreg << $scale]" %} 3032 interface(MEMORY_INTER) %{ 3033 base($reg); 3034 index($lreg); 3035 scale($scale); 3036 disp($off); 3037 %} 3038 %} 3039 3040 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3041 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3042 %{ 3043 constraint(ALLOC_IN_RC(ptr_reg)); 3044 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3045 match(AddP (AddP reg (ConvI2L idx)) off); 3046 3047 op_cost(10); 3048 format %{"[$reg + $off + $idx]" %} 3049 interface(MEMORY_INTER) %{ 3050 base($reg); 3051 index($idx); 3052 scale(0x0); 3053 disp($off); 3054 %} 3055 %} 3056 3057 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3058 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3059 %{ 3060 constraint(ALLOC_IN_RC(ptr_reg)); 3061 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3062 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3063 3064 op_cost(10); 3065 format %{"[$reg + $off + $idx << $scale]" %} 3066 interface(MEMORY_INTER) %{ 3067 base($reg); 3068 index($idx); 3069 scale($scale); 3070 disp($off); 3071 %} 3072 %} 3073 3074 // Indirect Narrow Oop Plus Offset Operand 3075 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3076 // we can't free r12 even with CompressedOops::base() == nullptr. 3077 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3078 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3079 constraint(ALLOC_IN_RC(ptr_reg)); 3080 match(AddP (DecodeN reg) off); 3081 3082 op_cost(10); 3083 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3084 interface(MEMORY_INTER) %{ 3085 base(0xc); // R12 3086 index($reg); 3087 scale(0x3); 3088 disp($off); 3089 %} 3090 %} 3091 3092 // Indirect Memory Operand 3093 operand indirectNarrow(rRegN reg) 3094 %{ 3095 predicate(CompressedOops::shift() == 0); 3096 constraint(ALLOC_IN_RC(ptr_reg)); 3097 match(DecodeN reg); 3098 3099 format %{ "[$reg]" %} 3100 interface(MEMORY_INTER) %{ 3101 base($reg); 3102 index(0x4); 3103 scale(0x0); 3104 disp(0x0); 3105 %} 3106 %} 3107 3108 // Indirect Memory Plus Short Offset Operand 3109 operand indOffset8Narrow(rRegN reg, immL8 off) 3110 %{ 3111 predicate(CompressedOops::shift() == 0); 3112 constraint(ALLOC_IN_RC(ptr_reg)); 3113 match(AddP (DecodeN reg) off); 3114 3115 format %{ "[$reg + $off (8-bit)]" %} 3116 interface(MEMORY_INTER) %{ 3117 base($reg); 3118 index(0x4); 3119 scale(0x0); 3120 disp($off); 3121 %} 3122 %} 3123 3124 // Indirect Memory Plus Long Offset Operand 3125 operand indOffset32Narrow(rRegN reg, immL32 off) 3126 %{ 3127 predicate(CompressedOops::shift() == 0); 3128 constraint(ALLOC_IN_RC(ptr_reg)); 3129 match(AddP (DecodeN reg) off); 3130 3131 format %{ "[$reg + $off (32-bit)]" %} 3132 interface(MEMORY_INTER) %{ 3133 base($reg); 3134 index(0x4); 3135 scale(0x0); 3136 disp($off); 3137 %} 3138 %} 3139 3140 // Indirect Memory Plus Index Register Plus Offset Operand 3141 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3142 %{ 3143 predicate(CompressedOops::shift() == 0); 3144 constraint(ALLOC_IN_RC(ptr_reg)); 3145 match(AddP (AddP (DecodeN reg) lreg) off); 3146 3147 op_cost(10); 3148 format %{"[$reg + $off + $lreg]" %} 3149 interface(MEMORY_INTER) %{ 3150 base($reg); 3151 index($lreg); 3152 scale(0x0); 3153 disp($off); 3154 %} 3155 %} 3156 3157 // Indirect Memory Plus Index Register Plus Offset Operand 3158 operand indIndexNarrow(rRegN reg, rRegL lreg) 3159 %{ 3160 predicate(CompressedOops::shift() == 0); 3161 constraint(ALLOC_IN_RC(ptr_reg)); 3162 match(AddP (DecodeN reg) lreg); 3163 3164 op_cost(10); 3165 format %{"[$reg + $lreg]" %} 3166 interface(MEMORY_INTER) %{ 3167 base($reg); 3168 index($lreg); 3169 scale(0x0); 3170 disp(0x0); 3171 %} 3172 %} 3173 3174 // Indirect Memory Times Scale Plus Index Register 3175 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3176 %{ 3177 predicate(CompressedOops::shift() == 0); 3178 constraint(ALLOC_IN_RC(ptr_reg)); 3179 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3180 3181 op_cost(10); 3182 format %{"[$reg + $lreg << $scale]" %} 3183 interface(MEMORY_INTER) %{ 3184 base($reg); 3185 index($lreg); 3186 scale($scale); 3187 disp(0x0); 3188 %} 3189 %} 3190 3191 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3192 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3193 %{ 3194 predicate(CompressedOops::shift() == 0); 3195 constraint(ALLOC_IN_RC(ptr_reg)); 3196 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3197 3198 op_cost(10); 3199 format %{"[$reg + $off + $lreg << $scale]" %} 3200 interface(MEMORY_INTER) %{ 3201 base($reg); 3202 index($lreg); 3203 scale($scale); 3204 disp($off); 3205 %} 3206 %} 3207 3208 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3209 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3210 %{ 3211 constraint(ALLOC_IN_RC(ptr_reg)); 3212 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3213 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3214 3215 op_cost(10); 3216 format %{"[$reg + $off + $idx]" %} 3217 interface(MEMORY_INTER) %{ 3218 base($reg); 3219 index($idx); 3220 scale(0x0); 3221 disp($off); 3222 %} 3223 %} 3224 3225 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3226 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3227 %{ 3228 constraint(ALLOC_IN_RC(ptr_reg)); 3229 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3230 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3231 3232 op_cost(10); 3233 format %{"[$reg + $off + $idx << $scale]" %} 3234 interface(MEMORY_INTER) %{ 3235 base($reg); 3236 index($idx); 3237 scale($scale); 3238 disp($off); 3239 %} 3240 %} 3241 3242 //----------Special Memory Operands-------------------------------------------- 3243 // Stack Slot Operand - This operand is used for loading and storing temporary 3244 // values on the stack where a match requires a value to 3245 // flow through memory. 3246 operand stackSlotP(sRegP reg) 3247 %{ 3248 constraint(ALLOC_IN_RC(stack_slots)); 3249 // No match rule because this operand is only generated in matching 3250 3251 format %{ "[$reg]" %} 3252 interface(MEMORY_INTER) %{ 3253 base(0x4); // RSP 3254 index(0x4); // No Index 3255 scale(0x0); // No Scale 3256 disp($reg); // Stack Offset 3257 %} 3258 %} 3259 3260 operand stackSlotI(sRegI reg) 3261 %{ 3262 constraint(ALLOC_IN_RC(stack_slots)); 3263 // No match rule because this operand is only generated in matching 3264 3265 format %{ "[$reg]" %} 3266 interface(MEMORY_INTER) %{ 3267 base(0x4); // RSP 3268 index(0x4); // No Index 3269 scale(0x0); // No Scale 3270 disp($reg); // Stack Offset 3271 %} 3272 %} 3273 3274 operand stackSlotF(sRegF reg) 3275 %{ 3276 constraint(ALLOC_IN_RC(stack_slots)); 3277 // No match rule because this operand is only generated in matching 3278 3279 format %{ "[$reg]" %} 3280 interface(MEMORY_INTER) %{ 3281 base(0x4); // RSP 3282 index(0x4); // No Index 3283 scale(0x0); // No Scale 3284 disp($reg); // Stack Offset 3285 %} 3286 %} 3287 3288 operand stackSlotD(sRegD reg) 3289 %{ 3290 constraint(ALLOC_IN_RC(stack_slots)); 3291 // No match rule because this operand is only generated in matching 3292 3293 format %{ "[$reg]" %} 3294 interface(MEMORY_INTER) %{ 3295 base(0x4); // RSP 3296 index(0x4); // No Index 3297 scale(0x0); // No Scale 3298 disp($reg); // Stack Offset 3299 %} 3300 %} 3301 operand stackSlotL(sRegL reg) 3302 %{ 3303 constraint(ALLOC_IN_RC(stack_slots)); 3304 // No match rule because this operand is only generated in matching 3305 3306 format %{ "[$reg]" %} 3307 interface(MEMORY_INTER) %{ 3308 base(0x4); // RSP 3309 index(0x4); // No Index 3310 scale(0x0); // No Scale 3311 disp($reg); // Stack Offset 3312 %} 3313 %} 3314 3315 //----------Conditional Branch Operands---------------------------------------- 3316 // Comparison Op - This is the operation of the comparison, and is limited to 3317 // the following set of codes: 3318 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3319 // 3320 // Other attributes of the comparison, such as unsignedness, are specified 3321 // by the comparison instruction that sets a condition code flags register. 3322 // That result is represented by a flags operand whose subtype is appropriate 3323 // to the unsignedness (etc.) of the comparison. 3324 // 3325 // Later, the instruction which matches both the Comparison Op (a Bool) and 3326 // the flags (produced by the Cmp) specifies the coding of the comparison op 3327 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3328 3329 // Comparison Code 3330 operand cmpOp() 3331 %{ 3332 match(Bool); 3333 3334 format %{ "" %} 3335 interface(COND_INTER) %{ 3336 equal(0x4, "e"); 3337 not_equal(0x5, "ne"); 3338 less(0xC, "l"); 3339 greater_equal(0xD, "ge"); 3340 less_equal(0xE, "le"); 3341 greater(0xF, "g"); 3342 overflow(0x0, "o"); 3343 no_overflow(0x1, "no"); 3344 %} 3345 %} 3346 3347 // Comparison Code, unsigned compare. Used by FP also, with 3348 // C2 (unordered) turned into GT or LT already. The other bits 3349 // C0 and C3 are turned into Carry & Zero flags. 3350 operand cmpOpU() 3351 %{ 3352 match(Bool); 3353 3354 format %{ "" %} 3355 interface(COND_INTER) %{ 3356 equal(0x4, "e"); 3357 not_equal(0x5, "ne"); 3358 less(0x2, "b"); 3359 greater_equal(0x3, "ae"); 3360 less_equal(0x6, "be"); 3361 greater(0x7, "a"); 3362 overflow(0x0, "o"); 3363 no_overflow(0x1, "no"); 3364 %} 3365 %} 3366 3367 3368 // Floating comparisons that don't require any fixup for the unordered case, 3369 // If both inputs of the comparison are the same, ZF is always set so we 3370 // don't need to use cmpOpUCF2 for eq/ne 3371 operand cmpOpUCF() %{ 3372 match(Bool); 3373 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3374 n->as_Bool()->_test._test == BoolTest::ge || 3375 n->as_Bool()->_test._test == BoolTest::le || 3376 n->as_Bool()->_test._test == BoolTest::gt || 3377 n->in(1)->in(1) == n->in(1)->in(2)); 3378 format %{ "" %} 3379 interface(COND_INTER) %{ 3380 equal(0xb, "np"); 3381 not_equal(0xa, "p"); 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 3392 // Floating comparisons that can be fixed up with extra conditional jumps 3393 operand cmpOpUCF2() %{ 3394 match(Bool); 3395 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3396 n->as_Bool()->_test._test == BoolTest::eq) && 3397 n->in(1)->in(1) != n->in(1)->in(2)); 3398 format %{ "" %} 3399 interface(COND_INTER) %{ 3400 equal(0x4, "e"); 3401 not_equal(0x5, "ne"); 3402 less(0x2, "b"); 3403 greater_equal(0x3, "ae"); 3404 less_equal(0x6, "be"); 3405 greater(0x7, "a"); 3406 overflow(0x0, "o"); 3407 no_overflow(0x1, "no"); 3408 %} 3409 %} 3410 3411 //----------OPERAND CLASSES---------------------------------------------------- 3412 // Operand Classes are groups of operands that are used as to simplify 3413 // instruction definitions by not requiring the AD writer to specify separate 3414 // instructions for every form of operand when the instruction accepts 3415 // multiple operand types with the same basic encoding and format. The classic 3416 // case of this is memory operands. 3417 3418 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3419 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3420 indCompressedOopOffset, 3421 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3422 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3423 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3424 3425 //----------PIPELINE----------------------------------------------------------- 3426 // Rules which define the behavior of the target architectures pipeline. 3427 pipeline %{ 3428 3429 //----------ATTRIBUTES--------------------------------------------------------- 3430 attributes %{ 3431 variable_size_instructions; // Fixed size instructions 3432 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3433 instruction_unit_size = 1; // An instruction is 1 bytes long 3434 instruction_fetch_unit_size = 16; // The processor fetches one line 3435 instruction_fetch_units = 1; // of 16 bytes 3436 3437 // List of nop instructions 3438 nops( MachNop ); 3439 %} 3440 3441 //----------RESOURCES---------------------------------------------------------- 3442 // Resources are the functional units available to the machine 3443 3444 // Generic P2/P3 pipeline 3445 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3446 // 3 instructions decoded per cycle. 3447 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3448 // 3 ALU op, only ALU0 handles mul instructions. 3449 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3450 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3451 BR, FPU, 3452 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3453 3454 //----------PIPELINE DESCRIPTION----------------------------------------------- 3455 // Pipeline Description specifies the stages in the machine's pipeline 3456 3457 // Generic P2/P3 pipeline 3458 pipe_desc(S0, S1, S2, S3, S4, S5); 3459 3460 //----------PIPELINE CLASSES--------------------------------------------------- 3461 // Pipeline Classes describe the stages in which input and output are 3462 // referenced by the hardware pipeline. 3463 3464 // Naming convention: ialu or fpu 3465 // Then: _reg 3466 // Then: _reg if there is a 2nd register 3467 // Then: _long if it's a pair of instructions implementing a long 3468 // Then: _fat if it requires the big decoder 3469 // Or: _mem if it requires the big decoder and a memory unit. 3470 3471 // Integer ALU reg operation 3472 pipe_class ialu_reg(rRegI dst) 3473 %{ 3474 single_instruction; 3475 dst : S4(write); 3476 dst : S3(read); 3477 DECODE : S0; // any decoder 3478 ALU : S3; // any alu 3479 %} 3480 3481 // Long ALU reg operation 3482 pipe_class ialu_reg_long(rRegL dst) 3483 %{ 3484 instruction_count(2); 3485 dst : S4(write); 3486 dst : S3(read); 3487 DECODE : S0(2); // any 2 decoders 3488 ALU : S3(2); // both alus 3489 %} 3490 3491 // Integer ALU reg operation using big decoder 3492 pipe_class ialu_reg_fat(rRegI dst) 3493 %{ 3494 single_instruction; 3495 dst : S4(write); 3496 dst : S3(read); 3497 D0 : S0; // big decoder only 3498 ALU : S3; // any alu 3499 %} 3500 3501 // Integer ALU reg-reg operation 3502 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3503 %{ 3504 single_instruction; 3505 dst : S4(write); 3506 src : S3(read); 3507 DECODE : S0; // any decoder 3508 ALU : S3; // any alu 3509 %} 3510 3511 // Integer ALU reg-reg operation 3512 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3513 %{ 3514 single_instruction; 3515 dst : S4(write); 3516 src : S3(read); 3517 D0 : S0; // big decoder only 3518 ALU : S3; // any alu 3519 %} 3520 3521 // Integer ALU reg-mem operation 3522 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3523 %{ 3524 single_instruction; 3525 dst : S5(write); 3526 mem : S3(read); 3527 D0 : S0; // big decoder only 3528 ALU : S4; // any alu 3529 MEM : S3; // any mem 3530 %} 3531 3532 // Integer mem operation (prefetch) 3533 pipe_class ialu_mem(memory mem) 3534 %{ 3535 single_instruction; 3536 mem : S3(read); 3537 D0 : S0; // big decoder only 3538 MEM : S3; // any mem 3539 %} 3540 3541 // Integer Store to Memory 3542 pipe_class ialu_mem_reg(memory mem, rRegI src) 3543 %{ 3544 single_instruction; 3545 mem : S3(read); 3546 src : S5(read); 3547 D0 : S0; // big decoder only 3548 ALU : S4; // any alu 3549 MEM : S3; 3550 %} 3551 3552 // // Long Store to Memory 3553 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3554 // %{ 3555 // instruction_count(2); 3556 // mem : S3(read); 3557 // src : S5(read); 3558 // D0 : S0(2); // big decoder only; twice 3559 // ALU : S4(2); // any 2 alus 3560 // MEM : S3(2); // Both mems 3561 // %} 3562 3563 // Integer Store to Memory 3564 pipe_class ialu_mem_imm(memory mem) 3565 %{ 3566 single_instruction; 3567 mem : S3(read); 3568 D0 : S0; // big decoder only 3569 ALU : S4; // any alu 3570 MEM : S3; 3571 %} 3572 3573 // Integer ALU0 reg-reg operation 3574 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3575 %{ 3576 single_instruction; 3577 dst : S4(write); 3578 src : S3(read); 3579 D0 : S0; // Big decoder only 3580 ALU0 : S3; // only alu0 3581 %} 3582 3583 // Integer ALU0 reg-mem operation 3584 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3585 %{ 3586 single_instruction; 3587 dst : S5(write); 3588 mem : S3(read); 3589 D0 : S0; // big decoder only 3590 ALU0 : S4; // ALU0 only 3591 MEM : S3; // any mem 3592 %} 3593 3594 // Integer ALU reg-reg operation 3595 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3596 %{ 3597 single_instruction; 3598 cr : S4(write); 3599 src1 : S3(read); 3600 src2 : S3(read); 3601 DECODE : S0; // any decoder 3602 ALU : S3; // any alu 3603 %} 3604 3605 // Integer ALU reg-imm operation 3606 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3607 %{ 3608 single_instruction; 3609 cr : S4(write); 3610 src1 : S3(read); 3611 DECODE : S0; // any decoder 3612 ALU : S3; // any alu 3613 %} 3614 3615 // Integer ALU reg-mem operation 3616 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3617 %{ 3618 single_instruction; 3619 cr : S4(write); 3620 src1 : S3(read); 3621 src2 : S3(read); 3622 D0 : S0; // big decoder only 3623 ALU : S4; // any alu 3624 MEM : S3; 3625 %} 3626 3627 // Conditional move reg-reg 3628 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3629 %{ 3630 instruction_count(4); 3631 y : S4(read); 3632 q : S3(read); 3633 p : S3(read); 3634 DECODE : S0(4); // any decoder 3635 %} 3636 3637 // Conditional move reg-reg 3638 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3639 %{ 3640 single_instruction; 3641 dst : S4(write); 3642 src : S3(read); 3643 cr : S3(read); 3644 DECODE : S0; // any decoder 3645 %} 3646 3647 // Conditional move reg-mem 3648 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3649 %{ 3650 single_instruction; 3651 dst : S4(write); 3652 src : S3(read); 3653 cr : S3(read); 3654 DECODE : S0; // any decoder 3655 MEM : S3; 3656 %} 3657 3658 // Conditional move reg-reg long 3659 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3660 %{ 3661 single_instruction; 3662 dst : S4(write); 3663 src : S3(read); 3664 cr : S3(read); 3665 DECODE : S0(2); // any 2 decoders 3666 %} 3667 3668 // Float reg-reg operation 3669 pipe_class fpu_reg(regD dst) 3670 %{ 3671 instruction_count(2); 3672 dst : S3(read); 3673 DECODE : S0(2); // any 2 decoders 3674 FPU : S3; 3675 %} 3676 3677 // Float reg-reg operation 3678 pipe_class fpu_reg_reg(regD dst, regD src) 3679 %{ 3680 instruction_count(2); 3681 dst : S4(write); 3682 src : S3(read); 3683 DECODE : S0(2); // any 2 decoders 3684 FPU : S3; 3685 %} 3686 3687 // Float reg-reg operation 3688 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3689 %{ 3690 instruction_count(3); 3691 dst : S4(write); 3692 src1 : S3(read); 3693 src2 : S3(read); 3694 DECODE : S0(3); // any 3 decoders 3695 FPU : S3(2); 3696 %} 3697 3698 // Float reg-reg operation 3699 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3700 %{ 3701 instruction_count(4); 3702 dst : S4(write); 3703 src1 : S3(read); 3704 src2 : S3(read); 3705 src3 : S3(read); 3706 DECODE : S0(4); // any 3 decoders 3707 FPU : S3(2); 3708 %} 3709 3710 // Float reg-reg operation 3711 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3712 %{ 3713 instruction_count(4); 3714 dst : S4(write); 3715 src1 : S3(read); 3716 src2 : S3(read); 3717 src3 : S3(read); 3718 DECODE : S1(3); // any 3 decoders 3719 D0 : S0; // Big decoder only 3720 FPU : S3(2); 3721 MEM : S3; 3722 %} 3723 3724 // Float reg-mem operation 3725 pipe_class fpu_reg_mem(regD dst, memory mem) 3726 %{ 3727 instruction_count(2); 3728 dst : S5(write); 3729 mem : S3(read); 3730 D0 : S0; // big decoder only 3731 DECODE : S1; // any decoder for FPU POP 3732 FPU : S4; 3733 MEM : S3; // any mem 3734 %} 3735 3736 // Float reg-mem operation 3737 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3738 %{ 3739 instruction_count(3); 3740 dst : S5(write); 3741 src1 : S3(read); 3742 mem : S3(read); 3743 D0 : S0; // big decoder only 3744 DECODE : S1(2); // any decoder for FPU POP 3745 FPU : S4; 3746 MEM : S3; // any mem 3747 %} 3748 3749 // Float mem-reg operation 3750 pipe_class fpu_mem_reg(memory mem, regD src) 3751 %{ 3752 instruction_count(2); 3753 src : S5(read); 3754 mem : S3(read); 3755 DECODE : S0; // any decoder for FPU PUSH 3756 D0 : S1; // big decoder only 3757 FPU : S4; 3758 MEM : S3; // any mem 3759 %} 3760 3761 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3762 %{ 3763 instruction_count(3); 3764 src1 : S3(read); 3765 src2 : S3(read); 3766 mem : S3(read); 3767 DECODE : S0(2); // any decoder for FPU PUSH 3768 D0 : S1; // big decoder only 3769 FPU : S4; 3770 MEM : S3; // any mem 3771 %} 3772 3773 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3774 %{ 3775 instruction_count(3); 3776 src1 : S3(read); 3777 src2 : S3(read); 3778 mem : S4(read); 3779 DECODE : S0; // any decoder for FPU PUSH 3780 D0 : S0(2); // big decoder only 3781 FPU : S4; 3782 MEM : S3(2); // any mem 3783 %} 3784 3785 pipe_class fpu_mem_mem(memory dst, memory src1) 3786 %{ 3787 instruction_count(2); 3788 src1 : S3(read); 3789 dst : S4(read); 3790 D0 : S0(2); // big decoder only 3791 MEM : S3(2); // any mem 3792 %} 3793 3794 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3795 %{ 3796 instruction_count(3); 3797 src1 : S3(read); 3798 src2 : S3(read); 3799 dst : S4(read); 3800 D0 : S0(3); // big decoder only 3801 FPU : S4; 3802 MEM : S3(3); // any mem 3803 %} 3804 3805 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3806 %{ 3807 instruction_count(3); 3808 src1 : S4(read); 3809 mem : S4(read); 3810 DECODE : S0; // any decoder for FPU PUSH 3811 D0 : S0(2); // big decoder only 3812 FPU : S4; 3813 MEM : S3(2); // any mem 3814 %} 3815 3816 // Float load constant 3817 pipe_class fpu_reg_con(regD dst) 3818 %{ 3819 instruction_count(2); 3820 dst : S5(write); 3821 D0 : S0; // big decoder only for the load 3822 DECODE : S1; // any decoder for FPU POP 3823 FPU : S4; 3824 MEM : S3; // any mem 3825 %} 3826 3827 // Float load constant 3828 pipe_class fpu_reg_reg_con(regD dst, regD src) 3829 %{ 3830 instruction_count(3); 3831 dst : S5(write); 3832 src : S3(read); 3833 D0 : S0; // big decoder only for the load 3834 DECODE : S1(2); // any decoder for FPU POP 3835 FPU : S4; 3836 MEM : S3; // any mem 3837 %} 3838 3839 // UnConditional branch 3840 pipe_class pipe_jmp(label labl) 3841 %{ 3842 single_instruction; 3843 BR : S3; 3844 %} 3845 3846 // Conditional branch 3847 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3848 %{ 3849 single_instruction; 3850 cr : S1(read); 3851 BR : S3; 3852 %} 3853 3854 // Allocation idiom 3855 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3856 %{ 3857 instruction_count(1); force_serialization; 3858 fixed_latency(6); 3859 heap_ptr : S3(read); 3860 DECODE : S0(3); 3861 D0 : S2; 3862 MEM : S3; 3863 ALU : S3(2); 3864 dst : S5(write); 3865 BR : S5; 3866 %} 3867 3868 // Generic big/slow expanded idiom 3869 pipe_class pipe_slow() 3870 %{ 3871 instruction_count(10); multiple_bundles; force_serialization; 3872 fixed_latency(100); 3873 D0 : S0(2); 3874 MEM : S3(2); 3875 %} 3876 3877 // The real do-nothing guy 3878 pipe_class empty() 3879 %{ 3880 instruction_count(0); 3881 %} 3882 3883 // Define the class for the Nop node 3884 define 3885 %{ 3886 MachNop = empty; 3887 %} 3888 3889 %} 3890 3891 //----------INSTRUCTIONS------------------------------------------------------- 3892 // 3893 // match -- States which machine-independent subtree may be replaced 3894 // by this instruction. 3895 // ins_cost -- The estimated cost of this instruction is used by instruction 3896 // selection to identify a minimum cost tree of machine 3897 // instructions that matches a tree of machine-independent 3898 // instructions. 3899 // format -- A string providing the disassembly for this instruction. 3900 // The value of an instruction's operand may be inserted 3901 // by referring to it with a '$' prefix. 3902 // opcode -- Three instruction opcodes may be provided. These are referred 3903 // to within an encode class as $primary, $secondary, and $tertiary 3904 // rrspectively. The primary opcode is commonly used to 3905 // indicate the type of machine instruction, while secondary 3906 // and tertiary are often used for prefix options or addressing 3907 // modes. 3908 // ins_encode -- A list of encode classes with parameters. The encode class 3909 // name must have been defined in an 'enc_class' specification 3910 // in the encode section of the architecture description. 3911 3912 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3913 // Load Float 3914 instruct MoveF2VL(vlRegF dst, regF 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 MoveF2LEG(legRegF dst, regF 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 Float 3934 instruct MoveVL2F(regF dst, vlRegF src) %{ 3935 match(Set dst src); 3936 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3937 ins_encode %{ 3938 ShouldNotReachHere(); 3939 %} 3940 ins_pipe( fpu_reg_reg ); 3941 %} 3942 3943 // Load Float 3944 instruct MoveLEG2F(regF dst, legRegF src) %{ 3945 match(Set dst src); 3946 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3947 ins_encode %{ 3948 ShouldNotReachHere(); 3949 %} 3950 ins_pipe( fpu_reg_reg ); 3951 %} 3952 3953 // Load Double 3954 instruct MoveD2VL(vlRegD dst, regD 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 MoveD2LEG(legRegD dst, regD 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 Double 3974 instruct MoveVL2D(regD dst, vlRegD src) %{ 3975 match(Set dst src); 3976 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3977 ins_encode %{ 3978 ShouldNotReachHere(); 3979 %} 3980 ins_pipe( fpu_reg_reg ); 3981 %} 3982 3983 // Load Double 3984 instruct MoveLEG2D(regD dst, legRegD src) %{ 3985 match(Set dst src); 3986 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3987 ins_encode %{ 3988 ShouldNotReachHere(); 3989 %} 3990 ins_pipe( fpu_reg_reg ); 3991 %} 3992 3993 //----------Load/Store/Move Instructions--------------------------------------- 3994 //----------Load Instructions-------------------------------------------------- 3995 3996 // Load Byte (8 bit signed) 3997 instruct loadB(rRegI dst, memory mem) 3998 %{ 3999 match(Set dst (LoadB mem)); 4000 4001 ins_cost(125); 4002 format %{ "movsbl $dst, $mem\t# byte" %} 4003 4004 ins_encode %{ 4005 __ movsbl($dst$$Register, $mem$$Address); 4006 %} 4007 4008 ins_pipe(ialu_reg_mem); 4009 %} 4010 4011 // Load Byte (8 bit signed) into Long Register 4012 instruct loadB2L(rRegL dst, memory mem) 4013 %{ 4014 match(Set dst (ConvI2L (LoadB mem))); 4015 4016 ins_cost(125); 4017 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4018 4019 ins_encode %{ 4020 __ movsbq($dst$$Register, $mem$$Address); 4021 %} 4022 4023 ins_pipe(ialu_reg_mem); 4024 %} 4025 4026 // Load Unsigned Byte (8 bit UNsigned) 4027 instruct loadUB(rRegI dst, memory mem) 4028 %{ 4029 match(Set dst (LoadUB mem)); 4030 4031 ins_cost(125); 4032 format %{ "movzbl $dst, $mem\t# ubyte" %} 4033 4034 ins_encode %{ 4035 __ movzbl($dst$$Register, $mem$$Address); 4036 %} 4037 4038 ins_pipe(ialu_reg_mem); 4039 %} 4040 4041 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4042 instruct loadUB2L(rRegL dst, memory mem) 4043 %{ 4044 match(Set dst (ConvI2L (LoadUB mem))); 4045 4046 ins_cost(125); 4047 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4048 4049 ins_encode %{ 4050 __ movzbq($dst$$Register, $mem$$Address); 4051 %} 4052 4053 ins_pipe(ialu_reg_mem); 4054 %} 4055 4056 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4057 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4058 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4059 effect(KILL cr); 4060 4061 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4062 "andl $dst, right_n_bits($mask, 8)" %} 4063 ins_encode %{ 4064 Register Rdst = $dst$$Register; 4065 __ movzbq(Rdst, $mem$$Address); 4066 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4067 %} 4068 ins_pipe(ialu_reg_mem); 4069 %} 4070 4071 // Load Short (16 bit signed) 4072 instruct loadS(rRegI dst, memory mem) 4073 %{ 4074 match(Set dst (LoadS mem)); 4075 4076 ins_cost(125); 4077 format %{ "movswl $dst, $mem\t# short" %} 4078 4079 ins_encode %{ 4080 __ movswl($dst$$Register, $mem$$Address); 4081 %} 4082 4083 ins_pipe(ialu_reg_mem); 4084 %} 4085 4086 // Load Short (16 bit signed) to Byte (8 bit signed) 4087 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4088 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4089 4090 ins_cost(125); 4091 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4092 ins_encode %{ 4093 __ movsbl($dst$$Register, $mem$$Address); 4094 %} 4095 ins_pipe(ialu_reg_mem); 4096 %} 4097 4098 // Load Short (16 bit signed) into Long Register 4099 instruct loadS2L(rRegL dst, memory mem) 4100 %{ 4101 match(Set dst (ConvI2L (LoadS mem))); 4102 4103 ins_cost(125); 4104 format %{ "movswq $dst, $mem\t# short -> long" %} 4105 4106 ins_encode %{ 4107 __ movswq($dst$$Register, $mem$$Address); 4108 %} 4109 4110 ins_pipe(ialu_reg_mem); 4111 %} 4112 4113 // Load Unsigned Short/Char (16 bit UNsigned) 4114 instruct loadUS(rRegI dst, memory mem) 4115 %{ 4116 match(Set dst (LoadUS mem)); 4117 4118 ins_cost(125); 4119 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4120 4121 ins_encode %{ 4122 __ movzwl($dst$$Register, $mem$$Address); 4123 %} 4124 4125 ins_pipe(ialu_reg_mem); 4126 %} 4127 4128 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4129 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4130 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4131 4132 ins_cost(125); 4133 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4134 ins_encode %{ 4135 __ movsbl($dst$$Register, $mem$$Address); 4136 %} 4137 ins_pipe(ialu_reg_mem); 4138 %} 4139 4140 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4141 instruct loadUS2L(rRegL dst, memory mem) 4142 %{ 4143 match(Set dst (ConvI2L (LoadUS mem))); 4144 4145 ins_cost(125); 4146 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4147 4148 ins_encode %{ 4149 __ movzwq($dst$$Register, $mem$$Address); 4150 %} 4151 4152 ins_pipe(ialu_reg_mem); 4153 %} 4154 4155 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4156 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4157 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4158 4159 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4160 ins_encode %{ 4161 __ movzbq($dst$$Register, $mem$$Address); 4162 %} 4163 ins_pipe(ialu_reg_mem); 4164 %} 4165 4166 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4167 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4168 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4169 effect(KILL cr); 4170 4171 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4172 "andl $dst, right_n_bits($mask, 16)" %} 4173 ins_encode %{ 4174 Register Rdst = $dst$$Register; 4175 __ movzwq(Rdst, $mem$$Address); 4176 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4177 %} 4178 ins_pipe(ialu_reg_mem); 4179 %} 4180 4181 // Load Integer 4182 instruct loadI(rRegI dst, memory mem) 4183 %{ 4184 match(Set dst (LoadI mem)); 4185 4186 ins_cost(125); 4187 format %{ "movl $dst, $mem\t# int" %} 4188 4189 ins_encode %{ 4190 __ movl($dst$$Register, $mem$$Address); 4191 %} 4192 4193 ins_pipe(ialu_reg_mem); 4194 %} 4195 4196 // Load Integer (32 bit signed) to Byte (8 bit signed) 4197 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4198 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4199 4200 ins_cost(125); 4201 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4202 ins_encode %{ 4203 __ movsbl($dst$$Register, $mem$$Address); 4204 %} 4205 ins_pipe(ialu_reg_mem); 4206 %} 4207 4208 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4209 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4210 match(Set dst (AndI (LoadI mem) mask)); 4211 4212 ins_cost(125); 4213 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4214 ins_encode %{ 4215 __ movzbl($dst$$Register, $mem$$Address); 4216 %} 4217 ins_pipe(ialu_reg_mem); 4218 %} 4219 4220 // Load Integer (32 bit signed) to Short (16 bit signed) 4221 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4222 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4223 4224 ins_cost(125); 4225 format %{ "movswl $dst, $mem\t# int -> short" %} 4226 ins_encode %{ 4227 __ movswl($dst$$Register, $mem$$Address); 4228 %} 4229 ins_pipe(ialu_reg_mem); 4230 %} 4231 4232 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4233 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4234 match(Set dst (AndI (LoadI mem) mask)); 4235 4236 ins_cost(125); 4237 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4238 ins_encode %{ 4239 __ movzwl($dst$$Register, $mem$$Address); 4240 %} 4241 ins_pipe(ialu_reg_mem); 4242 %} 4243 4244 // Load Integer into Long Register 4245 instruct loadI2L(rRegL dst, memory mem) 4246 %{ 4247 match(Set dst (ConvI2L (LoadI mem))); 4248 4249 ins_cost(125); 4250 format %{ "movslq $dst, $mem\t# int -> long" %} 4251 4252 ins_encode %{ 4253 __ movslq($dst$$Register, $mem$$Address); 4254 %} 4255 4256 ins_pipe(ialu_reg_mem); 4257 %} 4258 4259 // Load Integer with mask 0xFF into Long Register 4260 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4261 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4262 4263 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4264 ins_encode %{ 4265 __ movzbq($dst$$Register, $mem$$Address); 4266 %} 4267 ins_pipe(ialu_reg_mem); 4268 %} 4269 4270 // Load Integer with mask 0xFFFF into Long Register 4271 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4272 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4273 4274 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4275 ins_encode %{ 4276 __ movzwq($dst$$Register, $mem$$Address); 4277 %} 4278 ins_pipe(ialu_reg_mem); 4279 %} 4280 4281 // Load Integer with a 31-bit mask into Long Register 4282 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4283 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4284 effect(KILL cr); 4285 4286 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4287 "andl $dst, $mask" %} 4288 ins_encode %{ 4289 Register Rdst = $dst$$Register; 4290 __ movl(Rdst, $mem$$Address); 4291 __ andl(Rdst, $mask$$constant); 4292 %} 4293 ins_pipe(ialu_reg_mem); 4294 %} 4295 4296 // Load Unsigned Integer into Long Register 4297 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4298 %{ 4299 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4300 4301 ins_cost(125); 4302 format %{ "movl $dst, $mem\t# uint -> long" %} 4303 4304 ins_encode %{ 4305 __ movl($dst$$Register, $mem$$Address); 4306 %} 4307 4308 ins_pipe(ialu_reg_mem); 4309 %} 4310 4311 // Load Long 4312 instruct loadL(rRegL dst, memory mem) 4313 %{ 4314 match(Set dst (LoadL mem)); 4315 4316 ins_cost(125); 4317 format %{ "movq $dst, $mem\t# long" %} 4318 4319 ins_encode %{ 4320 __ movq($dst$$Register, $mem$$Address); 4321 %} 4322 4323 ins_pipe(ialu_reg_mem); // XXX 4324 %} 4325 4326 // Load Range 4327 instruct loadRange(rRegI dst, memory mem) 4328 %{ 4329 match(Set dst (LoadRange mem)); 4330 4331 ins_cost(125); // XXX 4332 format %{ "movl $dst, $mem\t# range" %} 4333 ins_encode %{ 4334 __ movl($dst$$Register, $mem$$Address); 4335 %} 4336 ins_pipe(ialu_reg_mem); 4337 %} 4338 4339 // Load Pointer 4340 instruct loadP(rRegP dst, memory mem) 4341 %{ 4342 match(Set dst (LoadP mem)); 4343 predicate(n->as_Load()->barrier_data() == 0); 4344 4345 ins_cost(125); // XXX 4346 format %{ "movq $dst, $mem\t# ptr" %} 4347 ins_encode %{ 4348 __ movq($dst$$Register, $mem$$Address); 4349 %} 4350 ins_pipe(ialu_reg_mem); // XXX 4351 %} 4352 4353 // Load Compressed Pointer 4354 instruct loadN(rRegN dst, memory mem) 4355 %{ 4356 predicate(n->as_Load()->barrier_data() == 0); 4357 match(Set dst (LoadN mem)); 4358 4359 ins_cost(125); // XXX 4360 format %{ "movl $dst, $mem\t# compressed ptr" %} 4361 ins_encode %{ 4362 __ movl($dst$$Register, $mem$$Address); 4363 %} 4364 ins_pipe(ialu_reg_mem); // XXX 4365 %} 4366 4367 4368 // Load Klass Pointer 4369 instruct loadKlass(rRegP dst, memory mem) 4370 %{ 4371 match(Set dst (LoadKlass mem)); 4372 4373 ins_cost(125); // XXX 4374 format %{ "movq $dst, $mem\t# class" %} 4375 ins_encode %{ 4376 __ movq($dst$$Register, $mem$$Address); 4377 %} 4378 ins_pipe(ialu_reg_mem); // XXX 4379 %} 4380 4381 // Load narrow Klass Pointer 4382 instruct loadNKlass(rRegN dst, memory mem) 4383 %{ 4384 predicate(!UseCompactObjectHeaders); 4385 match(Set dst (LoadNKlass mem)); 4386 4387 ins_cost(125); // XXX 4388 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4389 ins_encode %{ 4390 __ movl($dst$$Register, $mem$$Address); 4391 %} 4392 ins_pipe(ialu_reg_mem); // XXX 4393 %} 4394 4395 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4396 %{ 4397 predicate(UseCompactObjectHeaders); 4398 match(Set dst (LoadNKlass mem)); 4399 effect(KILL cr); 4400 ins_cost(125); 4401 format %{ 4402 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4403 "shrl $dst, markWord::klass_shift_at_offset" 4404 %} 4405 ins_encode %{ 4406 if (UseAPX) { 4407 __ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false); 4408 } 4409 else { 4410 __ movl($dst$$Register, $mem$$Address); 4411 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4412 } 4413 %} 4414 ins_pipe(ialu_reg_mem); 4415 %} 4416 4417 // Load Float 4418 instruct loadF(regF dst, memory mem) 4419 %{ 4420 match(Set dst (LoadF mem)); 4421 4422 ins_cost(145); // XXX 4423 format %{ "movss $dst, $mem\t# float" %} 4424 ins_encode %{ 4425 __ movflt($dst$$XMMRegister, $mem$$Address); 4426 %} 4427 ins_pipe(pipe_slow); // XXX 4428 %} 4429 4430 // Load Double 4431 instruct loadD_partial(regD dst, memory mem) 4432 %{ 4433 predicate(!UseXmmLoadAndClearUpper); 4434 match(Set dst (LoadD mem)); 4435 4436 ins_cost(145); // XXX 4437 format %{ "movlpd $dst, $mem\t# double" %} 4438 ins_encode %{ 4439 __ movdbl($dst$$XMMRegister, $mem$$Address); 4440 %} 4441 ins_pipe(pipe_slow); // XXX 4442 %} 4443 4444 instruct loadD(regD dst, memory mem) 4445 %{ 4446 predicate(UseXmmLoadAndClearUpper); 4447 match(Set dst (LoadD mem)); 4448 4449 ins_cost(145); // XXX 4450 format %{ "movsd $dst, $mem\t# double" %} 4451 ins_encode %{ 4452 __ movdbl($dst$$XMMRegister, $mem$$Address); 4453 %} 4454 ins_pipe(pipe_slow); // XXX 4455 %} 4456 4457 instruct loadAOTRCAddress(rRegP dst, immAOTRuntimeConstantsAddress con) 4458 %{ 4459 match(Set dst con); 4460 4461 format %{ "leaq $dst, $con\t# AOT Runtime Constants Address" %} 4462 4463 ins_encode %{ 4464 __ load_aotrc_address($dst$$Register, (address)$con$$constant); 4465 %} 4466 4467 ins_pipe(ialu_reg_fat); 4468 %} 4469 4470 // max = java.lang.Math.max(float a, float b) 4471 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4472 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4473 match(Set dst (MaxF a b)); 4474 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4475 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4476 ins_encode %{ 4477 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4478 %} 4479 ins_pipe( pipe_slow ); 4480 %} 4481 4482 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4483 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4484 match(Set dst (MaxF a b)); 4485 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4486 4487 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4488 ins_encode %{ 4489 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4490 false /*min*/, true /*single*/); 4491 %} 4492 ins_pipe( pipe_slow ); 4493 %} 4494 4495 // max = java.lang.Math.max(double a, double b) 4496 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4497 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4498 match(Set dst (MaxD a b)); 4499 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4500 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4501 ins_encode %{ 4502 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4503 %} 4504 ins_pipe( pipe_slow ); 4505 %} 4506 4507 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4508 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4509 match(Set dst (MaxD a b)); 4510 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4511 4512 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4513 ins_encode %{ 4514 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4515 false /*min*/, false /*single*/); 4516 %} 4517 ins_pipe( pipe_slow ); 4518 %} 4519 4520 // min = java.lang.Math.min(float a, float b) 4521 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4522 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4523 match(Set dst (MinF a b)); 4524 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4525 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4526 ins_encode %{ 4527 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4528 %} 4529 ins_pipe( pipe_slow ); 4530 %} 4531 4532 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4533 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4534 match(Set dst (MinF a b)); 4535 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4536 4537 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4538 ins_encode %{ 4539 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4540 true /*min*/, true /*single*/); 4541 %} 4542 ins_pipe( pipe_slow ); 4543 %} 4544 4545 // min = java.lang.Math.min(double a, double b) 4546 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4547 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4548 match(Set dst (MinD a b)); 4549 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4550 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4551 ins_encode %{ 4552 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4553 %} 4554 ins_pipe( pipe_slow ); 4555 %} 4556 4557 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4558 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4559 match(Set dst (MinD a b)); 4560 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4561 4562 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4563 ins_encode %{ 4564 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4565 true /*min*/, false /*single*/); 4566 %} 4567 ins_pipe( pipe_slow ); 4568 %} 4569 4570 // Load Effective Address 4571 instruct leaP8(rRegP dst, indOffset8 mem) 4572 %{ 4573 match(Set dst mem); 4574 4575 ins_cost(110); // XXX 4576 format %{ "leaq $dst, $mem\t# ptr 8" %} 4577 ins_encode %{ 4578 __ leaq($dst$$Register, $mem$$Address); 4579 %} 4580 ins_pipe(ialu_reg_reg_fat); 4581 %} 4582 4583 instruct leaP32(rRegP dst, indOffset32 mem) 4584 %{ 4585 match(Set dst mem); 4586 4587 ins_cost(110); 4588 format %{ "leaq $dst, $mem\t# ptr 32" %} 4589 ins_encode %{ 4590 __ leaq($dst$$Register, $mem$$Address); 4591 %} 4592 ins_pipe(ialu_reg_reg_fat); 4593 %} 4594 4595 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4596 %{ 4597 match(Set dst mem); 4598 4599 ins_cost(110); 4600 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4601 ins_encode %{ 4602 __ leaq($dst$$Register, $mem$$Address); 4603 %} 4604 ins_pipe(ialu_reg_reg_fat); 4605 %} 4606 4607 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4608 %{ 4609 match(Set dst mem); 4610 4611 ins_cost(110); 4612 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4613 ins_encode %{ 4614 __ leaq($dst$$Register, $mem$$Address); 4615 %} 4616 ins_pipe(ialu_reg_reg_fat); 4617 %} 4618 4619 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4620 %{ 4621 match(Set dst mem); 4622 4623 ins_cost(110); 4624 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4625 ins_encode %{ 4626 __ leaq($dst$$Register, $mem$$Address); 4627 %} 4628 ins_pipe(ialu_reg_reg_fat); 4629 %} 4630 4631 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4632 %{ 4633 match(Set dst mem); 4634 4635 ins_cost(110); 4636 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4637 ins_encode %{ 4638 __ leaq($dst$$Register, $mem$$Address); 4639 %} 4640 ins_pipe(ialu_reg_reg_fat); 4641 %} 4642 4643 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4644 %{ 4645 match(Set dst mem); 4646 4647 ins_cost(110); 4648 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4649 ins_encode %{ 4650 __ leaq($dst$$Register, $mem$$Address); 4651 %} 4652 ins_pipe(ialu_reg_reg_fat); 4653 %} 4654 4655 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4656 %{ 4657 match(Set dst mem); 4658 4659 ins_cost(110); 4660 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4661 ins_encode %{ 4662 __ leaq($dst$$Register, $mem$$Address); 4663 %} 4664 ins_pipe(ialu_reg_reg_fat); 4665 %} 4666 4667 // Load Effective Address which uses Narrow (32-bits) oop 4668 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4669 %{ 4670 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4671 match(Set dst mem); 4672 4673 ins_cost(110); 4674 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4675 ins_encode %{ 4676 __ leaq($dst$$Register, $mem$$Address); 4677 %} 4678 ins_pipe(ialu_reg_reg_fat); 4679 %} 4680 4681 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4682 %{ 4683 predicate(CompressedOops::shift() == 0); 4684 match(Set dst mem); 4685 4686 ins_cost(110); // XXX 4687 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4688 ins_encode %{ 4689 __ leaq($dst$$Register, $mem$$Address); 4690 %} 4691 ins_pipe(ialu_reg_reg_fat); 4692 %} 4693 4694 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4695 %{ 4696 predicate(CompressedOops::shift() == 0); 4697 match(Set dst mem); 4698 4699 ins_cost(110); 4700 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4701 ins_encode %{ 4702 __ leaq($dst$$Register, $mem$$Address); 4703 %} 4704 ins_pipe(ialu_reg_reg_fat); 4705 %} 4706 4707 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4708 %{ 4709 predicate(CompressedOops::shift() == 0); 4710 match(Set dst mem); 4711 4712 ins_cost(110); 4713 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4714 ins_encode %{ 4715 __ leaq($dst$$Register, $mem$$Address); 4716 %} 4717 ins_pipe(ialu_reg_reg_fat); 4718 %} 4719 4720 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4721 %{ 4722 predicate(CompressedOops::shift() == 0); 4723 match(Set dst mem); 4724 4725 ins_cost(110); 4726 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4727 ins_encode %{ 4728 __ leaq($dst$$Register, $mem$$Address); 4729 %} 4730 ins_pipe(ialu_reg_reg_fat); 4731 %} 4732 4733 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4734 %{ 4735 predicate(CompressedOops::shift() == 0); 4736 match(Set dst mem); 4737 4738 ins_cost(110); 4739 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4740 ins_encode %{ 4741 __ leaq($dst$$Register, $mem$$Address); 4742 %} 4743 ins_pipe(ialu_reg_reg_fat); 4744 %} 4745 4746 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4747 %{ 4748 predicate(CompressedOops::shift() == 0); 4749 match(Set dst mem); 4750 4751 ins_cost(110); 4752 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4753 ins_encode %{ 4754 __ leaq($dst$$Register, $mem$$Address); 4755 %} 4756 ins_pipe(ialu_reg_reg_fat); 4757 %} 4758 4759 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4760 %{ 4761 predicate(CompressedOops::shift() == 0); 4762 match(Set dst mem); 4763 4764 ins_cost(110); 4765 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4766 ins_encode %{ 4767 __ leaq($dst$$Register, $mem$$Address); 4768 %} 4769 ins_pipe(ialu_reg_reg_fat); 4770 %} 4771 4772 instruct loadConI(rRegI dst, immI src) 4773 %{ 4774 match(Set dst src); 4775 4776 format %{ "movl $dst, $src\t# int" %} 4777 ins_encode %{ 4778 __ movl($dst$$Register, $src$$constant); 4779 %} 4780 ins_pipe(ialu_reg_fat); // XXX 4781 %} 4782 4783 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4784 %{ 4785 match(Set dst src); 4786 effect(KILL cr); 4787 4788 ins_cost(50); 4789 format %{ "xorl $dst, $dst\t# int" %} 4790 ins_encode %{ 4791 __ xorl($dst$$Register, $dst$$Register); 4792 %} 4793 ins_pipe(ialu_reg); 4794 %} 4795 4796 instruct loadConL(rRegL dst, immL src) 4797 %{ 4798 match(Set dst src); 4799 4800 ins_cost(150); 4801 format %{ "movq $dst, $src\t# long" %} 4802 ins_encode %{ 4803 __ mov64($dst$$Register, $src$$constant); 4804 %} 4805 ins_pipe(ialu_reg); 4806 %} 4807 4808 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4809 %{ 4810 match(Set dst src); 4811 effect(KILL cr); 4812 4813 ins_cost(50); 4814 format %{ "xorl $dst, $dst\t# long" %} 4815 ins_encode %{ 4816 __ xorl($dst$$Register, $dst$$Register); 4817 %} 4818 ins_pipe(ialu_reg); // XXX 4819 %} 4820 4821 instruct loadConUL32(rRegL dst, immUL32 src) 4822 %{ 4823 match(Set dst src); 4824 4825 ins_cost(60); 4826 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4827 ins_encode %{ 4828 __ movl($dst$$Register, $src$$constant); 4829 %} 4830 ins_pipe(ialu_reg); 4831 %} 4832 4833 instruct loadConL32(rRegL dst, immL32 src) 4834 %{ 4835 match(Set dst src); 4836 4837 ins_cost(70); 4838 format %{ "movq $dst, $src\t# long (32-bit)" %} 4839 ins_encode %{ 4840 __ movq($dst$$Register, $src$$constant); 4841 %} 4842 ins_pipe(ialu_reg); 4843 %} 4844 4845 instruct loadConP(rRegP dst, immP con) %{ 4846 match(Set dst con); 4847 4848 format %{ "movq $dst, $con\t# ptr" %} 4849 ins_encode %{ 4850 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4851 %} 4852 ins_pipe(ialu_reg_fat); // XXX 4853 %} 4854 4855 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4856 %{ 4857 match(Set dst src); 4858 effect(KILL cr); 4859 4860 ins_cost(50); 4861 format %{ "xorl $dst, $dst\t# ptr" %} 4862 ins_encode %{ 4863 __ xorl($dst$$Register, $dst$$Register); 4864 %} 4865 ins_pipe(ialu_reg); 4866 %} 4867 4868 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4869 %{ 4870 match(Set dst src); 4871 effect(KILL cr); 4872 4873 ins_cost(60); 4874 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4875 ins_encode %{ 4876 __ movl($dst$$Register, $src$$constant); 4877 %} 4878 ins_pipe(ialu_reg); 4879 %} 4880 4881 instruct loadConF(regF dst, immF con) %{ 4882 match(Set dst con); 4883 ins_cost(125); 4884 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4885 ins_encode %{ 4886 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4887 %} 4888 ins_pipe(pipe_slow); 4889 %} 4890 4891 instruct loadConH(regF dst, immH con) %{ 4892 match(Set dst con); 4893 ins_cost(125); 4894 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4895 ins_encode %{ 4896 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4897 %} 4898 ins_pipe(pipe_slow); 4899 %} 4900 4901 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4902 match(Set dst src); 4903 effect(KILL cr); 4904 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4905 ins_encode %{ 4906 __ xorq($dst$$Register, $dst$$Register); 4907 %} 4908 ins_pipe(ialu_reg); 4909 %} 4910 4911 instruct loadConN(rRegN dst, immN src) %{ 4912 match(Set dst src); 4913 4914 ins_cost(125); 4915 format %{ "movl $dst, $src\t# compressed ptr" %} 4916 ins_encode %{ 4917 address con = (address)$src$$constant; 4918 if (con == nullptr) { 4919 ShouldNotReachHere(); 4920 } else { 4921 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4922 } 4923 %} 4924 ins_pipe(ialu_reg_fat); // XXX 4925 %} 4926 4927 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4928 match(Set dst src); 4929 4930 ins_cost(125); 4931 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4932 ins_encode %{ 4933 address con = (address)$src$$constant; 4934 if (con == nullptr) { 4935 ShouldNotReachHere(); 4936 } else { 4937 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4938 } 4939 %} 4940 ins_pipe(ialu_reg_fat); // XXX 4941 %} 4942 4943 instruct loadConF0(regF dst, immF0 src) 4944 %{ 4945 match(Set dst src); 4946 ins_cost(100); 4947 4948 format %{ "xorps $dst, $dst\t# float 0.0" %} 4949 ins_encode %{ 4950 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4951 %} 4952 ins_pipe(pipe_slow); 4953 %} 4954 4955 // Use the same format since predicate() can not be used here. 4956 instruct loadConD(regD dst, immD con) %{ 4957 match(Set dst con); 4958 ins_cost(125); 4959 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4960 ins_encode %{ 4961 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4962 %} 4963 ins_pipe(pipe_slow); 4964 %} 4965 4966 instruct loadConD0(regD dst, immD0 src) 4967 %{ 4968 match(Set dst src); 4969 ins_cost(100); 4970 4971 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4972 ins_encode %{ 4973 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4974 %} 4975 ins_pipe(pipe_slow); 4976 %} 4977 4978 instruct loadSSI(rRegI dst, stackSlotI src) 4979 %{ 4980 match(Set dst src); 4981 4982 ins_cost(125); 4983 format %{ "movl $dst, $src\t# int stk" %} 4984 ins_encode %{ 4985 __ movl($dst$$Register, $src$$Address); 4986 %} 4987 ins_pipe(ialu_reg_mem); 4988 %} 4989 4990 instruct loadSSL(rRegL dst, stackSlotL src) 4991 %{ 4992 match(Set dst src); 4993 4994 ins_cost(125); 4995 format %{ "movq $dst, $src\t# long stk" %} 4996 ins_encode %{ 4997 __ movq($dst$$Register, $src$$Address); 4998 %} 4999 ins_pipe(ialu_reg_mem); 5000 %} 5001 5002 instruct loadSSP(rRegP dst, stackSlotP src) 5003 %{ 5004 match(Set dst src); 5005 5006 ins_cost(125); 5007 format %{ "movq $dst, $src\t# ptr stk" %} 5008 ins_encode %{ 5009 __ movq($dst$$Register, $src$$Address); 5010 %} 5011 ins_pipe(ialu_reg_mem); 5012 %} 5013 5014 instruct loadSSF(regF dst, stackSlotF src) 5015 %{ 5016 match(Set dst src); 5017 5018 ins_cost(125); 5019 format %{ "movss $dst, $src\t# float stk" %} 5020 ins_encode %{ 5021 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5022 %} 5023 ins_pipe(pipe_slow); // XXX 5024 %} 5025 5026 // Use the same format since predicate() can not be used here. 5027 instruct loadSSD(regD dst, stackSlotD src) 5028 %{ 5029 match(Set dst src); 5030 5031 ins_cost(125); 5032 format %{ "movsd $dst, $src\t# double stk" %} 5033 ins_encode %{ 5034 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5035 %} 5036 ins_pipe(pipe_slow); // XXX 5037 %} 5038 5039 // Prefetch instructions for allocation. 5040 // Must be safe to execute with invalid address (cannot fault). 5041 5042 instruct prefetchAlloc( memory mem ) %{ 5043 predicate(AllocatePrefetchInstr==3); 5044 match(PrefetchAllocation mem); 5045 ins_cost(125); 5046 5047 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5048 ins_encode %{ 5049 __ prefetchw($mem$$Address); 5050 %} 5051 ins_pipe(ialu_mem); 5052 %} 5053 5054 instruct prefetchAllocNTA( memory mem ) %{ 5055 predicate(AllocatePrefetchInstr==0); 5056 match(PrefetchAllocation mem); 5057 ins_cost(125); 5058 5059 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5060 ins_encode %{ 5061 __ prefetchnta($mem$$Address); 5062 %} 5063 ins_pipe(ialu_mem); 5064 %} 5065 5066 instruct prefetchAllocT0( memory mem ) %{ 5067 predicate(AllocatePrefetchInstr==1); 5068 match(PrefetchAllocation mem); 5069 ins_cost(125); 5070 5071 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5072 ins_encode %{ 5073 __ prefetcht0($mem$$Address); 5074 %} 5075 ins_pipe(ialu_mem); 5076 %} 5077 5078 instruct prefetchAllocT2( memory mem ) %{ 5079 predicate(AllocatePrefetchInstr==2); 5080 match(PrefetchAllocation mem); 5081 ins_cost(125); 5082 5083 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5084 ins_encode %{ 5085 __ prefetcht2($mem$$Address); 5086 %} 5087 ins_pipe(ialu_mem); 5088 %} 5089 5090 //----------Store Instructions------------------------------------------------- 5091 5092 // Store Byte 5093 instruct storeB(memory mem, rRegI src) 5094 %{ 5095 match(Set mem (StoreB mem src)); 5096 5097 ins_cost(125); // XXX 5098 format %{ "movb $mem, $src\t# byte" %} 5099 ins_encode %{ 5100 __ movb($mem$$Address, $src$$Register); 5101 %} 5102 ins_pipe(ialu_mem_reg); 5103 %} 5104 5105 // Store Char/Short 5106 instruct storeC(memory mem, rRegI src) 5107 %{ 5108 match(Set mem (StoreC mem src)); 5109 5110 ins_cost(125); // XXX 5111 format %{ "movw $mem, $src\t# char/short" %} 5112 ins_encode %{ 5113 __ movw($mem$$Address, $src$$Register); 5114 %} 5115 ins_pipe(ialu_mem_reg); 5116 %} 5117 5118 // Store Integer 5119 instruct storeI(memory mem, rRegI src) 5120 %{ 5121 match(Set mem (StoreI mem src)); 5122 5123 ins_cost(125); // XXX 5124 format %{ "movl $mem, $src\t# int" %} 5125 ins_encode %{ 5126 __ movl($mem$$Address, $src$$Register); 5127 %} 5128 ins_pipe(ialu_mem_reg); 5129 %} 5130 5131 // Store Long 5132 instruct storeL(memory mem, rRegL src) 5133 %{ 5134 match(Set mem (StoreL mem src)); 5135 5136 ins_cost(125); // XXX 5137 format %{ "movq $mem, $src\t# long" %} 5138 ins_encode %{ 5139 __ movq($mem$$Address, $src$$Register); 5140 %} 5141 ins_pipe(ialu_mem_reg); // XXX 5142 %} 5143 5144 // Store Pointer 5145 instruct storeP(memory mem, any_RegP src) 5146 %{ 5147 predicate(n->as_Store()->barrier_data() == 0); 5148 match(Set mem (StoreP mem src)); 5149 5150 ins_cost(125); // XXX 5151 format %{ "movq $mem, $src\t# ptr" %} 5152 ins_encode %{ 5153 __ movq($mem$$Address, $src$$Register); 5154 %} 5155 ins_pipe(ialu_mem_reg); 5156 %} 5157 5158 instruct storeImmP0(memory mem, immP0 zero) 5159 %{ 5160 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5161 match(Set mem (StoreP mem zero)); 5162 5163 ins_cost(125); // XXX 5164 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5165 ins_encode %{ 5166 __ movq($mem$$Address, r12); 5167 %} 5168 ins_pipe(ialu_mem_reg); 5169 %} 5170 5171 // Store Null Pointer, mark word, or other simple pointer constant. 5172 instruct storeImmP(memory mem, immP31 src) 5173 %{ 5174 predicate(n->as_Store()->barrier_data() == 0); 5175 match(Set mem (StoreP mem src)); 5176 5177 ins_cost(150); // XXX 5178 format %{ "movq $mem, $src\t# ptr" %} 5179 ins_encode %{ 5180 __ movq($mem$$Address, $src$$constant); 5181 %} 5182 ins_pipe(ialu_mem_imm); 5183 %} 5184 5185 // Store Compressed Pointer 5186 instruct storeN(memory mem, rRegN src) 5187 %{ 5188 predicate(n->as_Store()->barrier_data() == 0); 5189 match(Set mem (StoreN mem src)); 5190 5191 ins_cost(125); // XXX 5192 format %{ "movl $mem, $src\t# compressed ptr" %} 5193 ins_encode %{ 5194 __ movl($mem$$Address, $src$$Register); 5195 %} 5196 ins_pipe(ialu_mem_reg); 5197 %} 5198 5199 instruct storeNKlass(memory mem, rRegN src) 5200 %{ 5201 match(Set mem (StoreNKlass mem src)); 5202 5203 ins_cost(125); // XXX 5204 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5205 ins_encode %{ 5206 __ movl($mem$$Address, $src$$Register); 5207 %} 5208 ins_pipe(ialu_mem_reg); 5209 %} 5210 5211 instruct storeImmN0(memory mem, immN0 zero) 5212 %{ 5213 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5214 match(Set mem (StoreN mem zero)); 5215 5216 ins_cost(125); // XXX 5217 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5218 ins_encode %{ 5219 __ movl($mem$$Address, r12); 5220 %} 5221 ins_pipe(ialu_mem_reg); 5222 %} 5223 5224 instruct storeImmN(memory mem, immN src) 5225 %{ 5226 predicate(n->as_Store()->barrier_data() == 0); 5227 match(Set mem (StoreN mem src)); 5228 5229 ins_cost(150); // XXX 5230 format %{ "movl $mem, $src\t# compressed ptr" %} 5231 ins_encode %{ 5232 address con = (address)$src$$constant; 5233 if (con == nullptr) { 5234 __ movl($mem$$Address, 0); 5235 } else { 5236 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5237 } 5238 %} 5239 ins_pipe(ialu_mem_imm); 5240 %} 5241 5242 instruct storeImmNKlass(memory mem, immNKlass src) 5243 %{ 5244 match(Set mem (StoreNKlass mem src)); 5245 5246 ins_cost(150); // XXX 5247 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5248 ins_encode %{ 5249 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5250 %} 5251 ins_pipe(ialu_mem_imm); 5252 %} 5253 5254 // Store Integer Immediate 5255 instruct storeImmI0(memory mem, immI_0 zero) 5256 %{ 5257 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5258 match(Set mem (StoreI mem zero)); 5259 5260 ins_cost(125); // XXX 5261 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5262 ins_encode %{ 5263 __ movl($mem$$Address, r12); 5264 %} 5265 ins_pipe(ialu_mem_reg); 5266 %} 5267 5268 instruct storeImmI(memory mem, immI src) 5269 %{ 5270 match(Set mem (StoreI mem src)); 5271 5272 ins_cost(150); 5273 format %{ "movl $mem, $src\t# int" %} 5274 ins_encode %{ 5275 __ movl($mem$$Address, $src$$constant); 5276 %} 5277 ins_pipe(ialu_mem_imm); 5278 %} 5279 5280 // Store Long Immediate 5281 instruct storeImmL0(memory mem, immL0 zero) 5282 %{ 5283 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5284 match(Set mem (StoreL mem zero)); 5285 5286 ins_cost(125); // XXX 5287 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5288 ins_encode %{ 5289 __ movq($mem$$Address, r12); 5290 %} 5291 ins_pipe(ialu_mem_reg); 5292 %} 5293 5294 instruct storeImmL(memory mem, immL32 src) 5295 %{ 5296 match(Set mem (StoreL mem src)); 5297 5298 ins_cost(150); 5299 format %{ "movq $mem, $src\t# long" %} 5300 ins_encode %{ 5301 __ movq($mem$$Address, $src$$constant); 5302 %} 5303 ins_pipe(ialu_mem_imm); 5304 %} 5305 5306 // Store Short/Char Immediate 5307 instruct storeImmC0(memory mem, immI_0 zero) 5308 %{ 5309 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5310 match(Set mem (StoreC mem zero)); 5311 5312 ins_cost(125); // XXX 5313 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5314 ins_encode %{ 5315 __ movw($mem$$Address, r12); 5316 %} 5317 ins_pipe(ialu_mem_reg); 5318 %} 5319 5320 instruct storeImmI16(memory mem, immI16 src) 5321 %{ 5322 predicate(UseStoreImmI16); 5323 match(Set mem (StoreC mem src)); 5324 5325 ins_cost(150); 5326 format %{ "movw $mem, $src\t# short/char" %} 5327 ins_encode %{ 5328 __ movw($mem$$Address, $src$$constant); 5329 %} 5330 ins_pipe(ialu_mem_imm); 5331 %} 5332 5333 // Store Byte Immediate 5334 instruct storeImmB0(memory mem, immI_0 zero) 5335 %{ 5336 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5337 match(Set mem (StoreB mem zero)); 5338 5339 ins_cost(125); // XXX 5340 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5341 ins_encode %{ 5342 __ movb($mem$$Address, r12); 5343 %} 5344 ins_pipe(ialu_mem_reg); 5345 %} 5346 5347 instruct storeImmB(memory mem, immI8 src) 5348 %{ 5349 match(Set mem (StoreB mem src)); 5350 5351 ins_cost(150); // XXX 5352 format %{ "movb $mem, $src\t# byte" %} 5353 ins_encode %{ 5354 __ movb($mem$$Address, $src$$constant); 5355 %} 5356 ins_pipe(ialu_mem_imm); 5357 %} 5358 5359 // Store Float 5360 instruct storeF(memory mem, regF src) 5361 %{ 5362 match(Set mem (StoreF mem src)); 5363 5364 ins_cost(95); // XXX 5365 format %{ "movss $mem, $src\t# float" %} 5366 ins_encode %{ 5367 __ movflt($mem$$Address, $src$$XMMRegister); 5368 %} 5369 ins_pipe(pipe_slow); // XXX 5370 %} 5371 5372 // Store immediate Float value (it is faster than store from XMM register) 5373 instruct storeF0(memory mem, immF0 zero) 5374 %{ 5375 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5376 match(Set mem (StoreF mem zero)); 5377 5378 ins_cost(25); // XXX 5379 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5380 ins_encode %{ 5381 __ movl($mem$$Address, r12); 5382 %} 5383 ins_pipe(ialu_mem_reg); 5384 %} 5385 5386 instruct storeF_imm(memory mem, immF src) 5387 %{ 5388 match(Set mem (StoreF mem src)); 5389 5390 ins_cost(50); 5391 format %{ "movl $mem, $src\t# float" %} 5392 ins_encode %{ 5393 __ movl($mem$$Address, jint_cast($src$$constant)); 5394 %} 5395 ins_pipe(ialu_mem_imm); 5396 %} 5397 5398 // Store Double 5399 instruct storeD(memory mem, regD src) 5400 %{ 5401 match(Set mem (StoreD mem src)); 5402 5403 ins_cost(95); // XXX 5404 format %{ "movsd $mem, $src\t# double" %} 5405 ins_encode %{ 5406 __ movdbl($mem$$Address, $src$$XMMRegister); 5407 %} 5408 ins_pipe(pipe_slow); // XXX 5409 %} 5410 5411 // Store immediate double 0.0 (it is faster than store from XMM register) 5412 instruct storeD0_imm(memory mem, immD0 src) 5413 %{ 5414 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5415 match(Set mem (StoreD mem src)); 5416 5417 ins_cost(50); 5418 format %{ "movq $mem, $src\t# double 0." %} 5419 ins_encode %{ 5420 __ movq($mem$$Address, $src$$constant); 5421 %} 5422 ins_pipe(ialu_mem_imm); 5423 %} 5424 5425 instruct storeD0(memory mem, immD0 zero) 5426 %{ 5427 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5428 match(Set mem (StoreD mem zero)); 5429 5430 ins_cost(25); // XXX 5431 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5432 ins_encode %{ 5433 __ movq($mem$$Address, r12); 5434 %} 5435 ins_pipe(ialu_mem_reg); 5436 %} 5437 5438 instruct storeSSI(stackSlotI dst, rRegI src) 5439 %{ 5440 match(Set dst src); 5441 5442 ins_cost(100); 5443 format %{ "movl $dst, $src\t# int stk" %} 5444 ins_encode %{ 5445 __ movl($dst$$Address, $src$$Register); 5446 %} 5447 ins_pipe( ialu_mem_reg ); 5448 %} 5449 5450 instruct storeSSL(stackSlotL dst, rRegL src) 5451 %{ 5452 match(Set dst src); 5453 5454 ins_cost(100); 5455 format %{ "movq $dst, $src\t# long stk" %} 5456 ins_encode %{ 5457 __ movq($dst$$Address, $src$$Register); 5458 %} 5459 ins_pipe(ialu_mem_reg); 5460 %} 5461 5462 instruct storeSSP(stackSlotP dst, rRegP src) 5463 %{ 5464 match(Set dst src); 5465 5466 ins_cost(100); 5467 format %{ "movq $dst, $src\t# ptr stk" %} 5468 ins_encode %{ 5469 __ movq($dst$$Address, $src$$Register); 5470 %} 5471 ins_pipe(ialu_mem_reg); 5472 %} 5473 5474 instruct storeSSF(stackSlotF dst, regF src) 5475 %{ 5476 match(Set dst src); 5477 5478 ins_cost(95); // XXX 5479 format %{ "movss $dst, $src\t# float stk" %} 5480 ins_encode %{ 5481 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5482 %} 5483 ins_pipe(pipe_slow); // XXX 5484 %} 5485 5486 instruct storeSSD(stackSlotD dst, regD src) 5487 %{ 5488 match(Set dst src); 5489 5490 ins_cost(95); // XXX 5491 format %{ "movsd $dst, $src\t# double stk" %} 5492 ins_encode %{ 5493 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5494 %} 5495 ins_pipe(pipe_slow); // XXX 5496 %} 5497 5498 instruct cacheWB(indirect addr) 5499 %{ 5500 predicate(VM_Version::supports_data_cache_line_flush()); 5501 match(CacheWB addr); 5502 5503 ins_cost(100); 5504 format %{"cache wb $addr" %} 5505 ins_encode %{ 5506 assert($addr->index_position() < 0, "should be"); 5507 assert($addr$$disp == 0, "should be"); 5508 __ cache_wb(Address($addr$$base$$Register, 0)); 5509 %} 5510 ins_pipe(pipe_slow); // XXX 5511 %} 5512 5513 instruct cacheWBPreSync() 5514 %{ 5515 predicate(VM_Version::supports_data_cache_line_flush()); 5516 match(CacheWBPreSync); 5517 5518 ins_cost(100); 5519 format %{"cache wb presync" %} 5520 ins_encode %{ 5521 __ cache_wbsync(true); 5522 %} 5523 ins_pipe(pipe_slow); // XXX 5524 %} 5525 5526 instruct cacheWBPostSync() 5527 %{ 5528 predicate(VM_Version::supports_data_cache_line_flush()); 5529 match(CacheWBPostSync); 5530 5531 ins_cost(100); 5532 format %{"cache wb postsync" %} 5533 ins_encode %{ 5534 __ cache_wbsync(false); 5535 %} 5536 ins_pipe(pipe_slow); // XXX 5537 %} 5538 5539 //----------BSWAP Instructions------------------------------------------------- 5540 instruct bytes_reverse_int(rRegI dst) %{ 5541 match(Set dst (ReverseBytesI dst)); 5542 5543 format %{ "bswapl $dst" %} 5544 ins_encode %{ 5545 __ bswapl($dst$$Register); 5546 %} 5547 ins_pipe( ialu_reg ); 5548 %} 5549 5550 instruct bytes_reverse_long(rRegL dst) %{ 5551 match(Set dst (ReverseBytesL dst)); 5552 5553 format %{ "bswapq $dst" %} 5554 ins_encode %{ 5555 __ bswapq($dst$$Register); 5556 %} 5557 ins_pipe( ialu_reg); 5558 %} 5559 5560 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5561 match(Set dst (ReverseBytesUS dst)); 5562 effect(KILL cr); 5563 5564 format %{ "bswapl $dst\n\t" 5565 "shrl $dst,16\n\t" %} 5566 ins_encode %{ 5567 __ bswapl($dst$$Register); 5568 __ shrl($dst$$Register, 16); 5569 %} 5570 ins_pipe( ialu_reg ); 5571 %} 5572 5573 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5574 match(Set dst (ReverseBytesS dst)); 5575 effect(KILL cr); 5576 5577 format %{ "bswapl $dst\n\t" 5578 "sar $dst,16\n\t" %} 5579 ins_encode %{ 5580 __ bswapl($dst$$Register); 5581 __ sarl($dst$$Register, 16); 5582 %} 5583 ins_pipe( ialu_reg ); 5584 %} 5585 5586 //---------- Zeros Count Instructions ------------------------------------------ 5587 5588 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5589 predicate(UseCountLeadingZerosInstruction); 5590 match(Set dst (CountLeadingZerosI src)); 5591 effect(KILL cr); 5592 5593 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5594 ins_encode %{ 5595 __ lzcntl($dst$$Register, $src$$Register); 5596 %} 5597 ins_pipe(ialu_reg); 5598 %} 5599 5600 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5601 predicate(UseCountLeadingZerosInstruction); 5602 match(Set dst (CountLeadingZerosI (LoadI src))); 5603 effect(KILL cr); 5604 ins_cost(175); 5605 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5606 ins_encode %{ 5607 __ lzcntl($dst$$Register, $src$$Address); 5608 %} 5609 ins_pipe(ialu_reg_mem); 5610 %} 5611 5612 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5613 predicate(!UseCountLeadingZerosInstruction); 5614 match(Set dst (CountLeadingZerosI src)); 5615 effect(KILL cr); 5616 5617 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5618 "jnz skip\n\t" 5619 "movl $dst, -1\n" 5620 "skip:\n\t" 5621 "negl $dst\n\t" 5622 "addl $dst, 31" %} 5623 ins_encode %{ 5624 Register Rdst = $dst$$Register; 5625 Register Rsrc = $src$$Register; 5626 Label skip; 5627 __ bsrl(Rdst, Rsrc); 5628 __ jccb(Assembler::notZero, skip); 5629 __ movl(Rdst, -1); 5630 __ bind(skip); 5631 __ negl(Rdst); 5632 __ addl(Rdst, BitsPerInt - 1); 5633 %} 5634 ins_pipe(ialu_reg); 5635 %} 5636 5637 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5638 predicate(UseCountLeadingZerosInstruction); 5639 match(Set dst (CountLeadingZerosL src)); 5640 effect(KILL cr); 5641 5642 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5643 ins_encode %{ 5644 __ lzcntq($dst$$Register, $src$$Register); 5645 %} 5646 ins_pipe(ialu_reg); 5647 %} 5648 5649 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5650 predicate(UseCountLeadingZerosInstruction); 5651 match(Set dst (CountLeadingZerosL (LoadL src))); 5652 effect(KILL cr); 5653 ins_cost(175); 5654 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5655 ins_encode %{ 5656 __ lzcntq($dst$$Register, $src$$Address); 5657 %} 5658 ins_pipe(ialu_reg_mem); 5659 %} 5660 5661 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5662 predicate(!UseCountLeadingZerosInstruction); 5663 match(Set dst (CountLeadingZerosL src)); 5664 effect(KILL cr); 5665 5666 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5667 "jnz skip\n\t" 5668 "movl $dst, -1\n" 5669 "skip:\n\t" 5670 "negl $dst\n\t" 5671 "addl $dst, 63" %} 5672 ins_encode %{ 5673 Register Rdst = $dst$$Register; 5674 Register Rsrc = $src$$Register; 5675 Label skip; 5676 __ bsrq(Rdst, Rsrc); 5677 __ jccb(Assembler::notZero, skip); 5678 __ movl(Rdst, -1); 5679 __ bind(skip); 5680 __ negl(Rdst); 5681 __ addl(Rdst, BitsPerLong - 1); 5682 %} 5683 ins_pipe(ialu_reg); 5684 %} 5685 5686 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5687 predicate(UseCountTrailingZerosInstruction); 5688 match(Set dst (CountTrailingZerosI src)); 5689 effect(KILL cr); 5690 5691 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5692 ins_encode %{ 5693 __ tzcntl($dst$$Register, $src$$Register); 5694 %} 5695 ins_pipe(ialu_reg); 5696 %} 5697 5698 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5699 predicate(UseCountTrailingZerosInstruction); 5700 match(Set dst (CountTrailingZerosI (LoadI src))); 5701 effect(KILL cr); 5702 ins_cost(175); 5703 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5704 ins_encode %{ 5705 __ tzcntl($dst$$Register, $src$$Address); 5706 %} 5707 ins_pipe(ialu_reg_mem); 5708 %} 5709 5710 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5711 predicate(!UseCountTrailingZerosInstruction); 5712 match(Set dst (CountTrailingZerosI src)); 5713 effect(KILL cr); 5714 5715 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5716 "jnz done\n\t" 5717 "movl $dst, 32\n" 5718 "done:" %} 5719 ins_encode %{ 5720 Register Rdst = $dst$$Register; 5721 Label done; 5722 __ bsfl(Rdst, $src$$Register); 5723 __ jccb(Assembler::notZero, done); 5724 __ movl(Rdst, BitsPerInt); 5725 __ bind(done); 5726 %} 5727 ins_pipe(ialu_reg); 5728 %} 5729 5730 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5731 predicate(UseCountTrailingZerosInstruction); 5732 match(Set dst (CountTrailingZerosL src)); 5733 effect(KILL cr); 5734 5735 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5736 ins_encode %{ 5737 __ tzcntq($dst$$Register, $src$$Register); 5738 %} 5739 ins_pipe(ialu_reg); 5740 %} 5741 5742 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5743 predicate(UseCountTrailingZerosInstruction); 5744 match(Set dst (CountTrailingZerosL (LoadL src))); 5745 effect(KILL cr); 5746 ins_cost(175); 5747 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5748 ins_encode %{ 5749 __ tzcntq($dst$$Register, $src$$Address); 5750 %} 5751 ins_pipe(ialu_reg_mem); 5752 %} 5753 5754 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5755 predicate(!UseCountTrailingZerosInstruction); 5756 match(Set dst (CountTrailingZerosL src)); 5757 effect(KILL cr); 5758 5759 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5760 "jnz done\n\t" 5761 "movl $dst, 64\n" 5762 "done:" %} 5763 ins_encode %{ 5764 Register Rdst = $dst$$Register; 5765 Label done; 5766 __ bsfq(Rdst, $src$$Register); 5767 __ jccb(Assembler::notZero, done); 5768 __ movl(Rdst, BitsPerLong); 5769 __ bind(done); 5770 %} 5771 ins_pipe(ialu_reg); 5772 %} 5773 5774 //--------------- Reverse Operation Instructions ---------------- 5775 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5776 predicate(!VM_Version::supports_gfni()); 5777 match(Set dst (ReverseI src)); 5778 effect(TEMP dst, TEMP rtmp, KILL cr); 5779 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5780 ins_encode %{ 5781 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5782 %} 5783 ins_pipe( ialu_reg ); 5784 %} 5785 5786 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5787 predicate(VM_Version::supports_gfni()); 5788 match(Set dst (ReverseI src)); 5789 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5790 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5791 ins_encode %{ 5792 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5793 %} 5794 ins_pipe( ialu_reg ); 5795 %} 5796 5797 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5798 predicate(!VM_Version::supports_gfni()); 5799 match(Set dst (ReverseL src)); 5800 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5801 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5802 ins_encode %{ 5803 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5804 %} 5805 ins_pipe( ialu_reg ); 5806 %} 5807 5808 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5809 predicate(VM_Version::supports_gfni()); 5810 match(Set dst (ReverseL src)); 5811 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5812 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5813 ins_encode %{ 5814 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5815 %} 5816 ins_pipe( ialu_reg ); 5817 %} 5818 5819 //---------- Population Count Instructions ------------------------------------- 5820 5821 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5822 predicate(UsePopCountInstruction); 5823 match(Set dst (PopCountI src)); 5824 effect(KILL cr); 5825 5826 format %{ "popcnt $dst, $src" %} 5827 ins_encode %{ 5828 __ popcntl($dst$$Register, $src$$Register); 5829 %} 5830 ins_pipe(ialu_reg); 5831 %} 5832 5833 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5834 predicate(UsePopCountInstruction); 5835 match(Set dst (PopCountI (LoadI mem))); 5836 effect(KILL cr); 5837 5838 format %{ "popcnt $dst, $mem" %} 5839 ins_encode %{ 5840 __ popcntl($dst$$Register, $mem$$Address); 5841 %} 5842 ins_pipe(ialu_reg); 5843 %} 5844 5845 // Note: Long.bitCount(long) returns an int. 5846 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5847 predicate(UsePopCountInstruction); 5848 match(Set dst (PopCountL src)); 5849 effect(KILL cr); 5850 5851 format %{ "popcnt $dst, $src" %} 5852 ins_encode %{ 5853 __ popcntq($dst$$Register, $src$$Register); 5854 %} 5855 ins_pipe(ialu_reg); 5856 %} 5857 5858 // Note: Long.bitCount(long) returns an int. 5859 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5860 predicate(UsePopCountInstruction); 5861 match(Set dst (PopCountL (LoadL mem))); 5862 effect(KILL cr); 5863 5864 format %{ "popcnt $dst, $mem" %} 5865 ins_encode %{ 5866 __ popcntq($dst$$Register, $mem$$Address); 5867 %} 5868 ins_pipe(ialu_reg); 5869 %} 5870 5871 5872 //----------MemBar Instructions----------------------------------------------- 5873 // Memory barrier flavors 5874 5875 instruct membar_acquire() 5876 %{ 5877 match(MemBarAcquire); 5878 match(LoadFence); 5879 ins_cost(0); 5880 5881 size(0); 5882 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5883 ins_encode(); 5884 ins_pipe(empty); 5885 %} 5886 5887 instruct membar_acquire_lock() 5888 %{ 5889 match(MemBarAcquireLock); 5890 ins_cost(0); 5891 5892 size(0); 5893 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5894 ins_encode(); 5895 ins_pipe(empty); 5896 %} 5897 5898 instruct membar_release() 5899 %{ 5900 match(MemBarRelease); 5901 match(StoreFence); 5902 ins_cost(0); 5903 5904 size(0); 5905 format %{ "MEMBAR-release ! (empty encoding)" %} 5906 ins_encode(); 5907 ins_pipe(empty); 5908 %} 5909 5910 instruct membar_release_lock() 5911 %{ 5912 match(MemBarReleaseLock); 5913 ins_cost(0); 5914 5915 size(0); 5916 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5917 ins_encode(); 5918 ins_pipe(empty); 5919 %} 5920 5921 instruct membar_volatile(rFlagsReg cr) %{ 5922 match(MemBarVolatile); 5923 effect(KILL cr); 5924 ins_cost(400); 5925 5926 format %{ 5927 $$template 5928 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5929 %} 5930 ins_encode %{ 5931 __ membar(Assembler::StoreLoad); 5932 %} 5933 ins_pipe(pipe_slow); 5934 %} 5935 5936 instruct unnecessary_membar_volatile() 5937 %{ 5938 match(MemBarVolatile); 5939 predicate(Matcher::post_store_load_barrier(n)); 5940 ins_cost(0); 5941 5942 size(0); 5943 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5944 ins_encode(); 5945 ins_pipe(empty); 5946 %} 5947 5948 instruct membar_storestore() %{ 5949 match(MemBarStoreStore); 5950 match(StoreStoreFence); 5951 ins_cost(0); 5952 5953 size(0); 5954 format %{ "MEMBAR-storestore (empty encoding)" %} 5955 ins_encode( ); 5956 ins_pipe(empty); 5957 %} 5958 5959 //----------Move Instructions-------------------------------------------------- 5960 5961 instruct castX2P(rRegP dst, rRegL src) 5962 %{ 5963 match(Set dst (CastX2P src)); 5964 5965 format %{ "movq $dst, $src\t# long->ptr" %} 5966 ins_encode %{ 5967 if ($dst$$reg != $src$$reg) { 5968 __ movptr($dst$$Register, $src$$Register); 5969 } 5970 %} 5971 ins_pipe(ialu_reg_reg); // XXX 5972 %} 5973 5974 instruct castP2X(rRegL dst, rRegP src) 5975 %{ 5976 match(Set dst (CastP2X src)); 5977 5978 format %{ "movq $dst, $src\t# ptr -> long" %} 5979 ins_encode %{ 5980 if ($dst$$reg != $src$$reg) { 5981 __ movptr($dst$$Register, $src$$Register); 5982 } 5983 %} 5984 ins_pipe(ialu_reg_reg); // XXX 5985 %} 5986 5987 // Convert oop into int for vectors alignment masking 5988 instruct convP2I(rRegI dst, rRegP src) 5989 %{ 5990 match(Set dst (ConvL2I (CastP2X src))); 5991 5992 format %{ "movl $dst, $src\t# ptr -> int" %} 5993 ins_encode %{ 5994 __ movl($dst$$Register, $src$$Register); 5995 %} 5996 ins_pipe(ialu_reg_reg); // XXX 5997 %} 5998 5999 // Convert compressed oop into int for vectors alignment masking 6000 // in case of 32bit oops (heap < 4Gb). 6001 instruct convN2I(rRegI dst, rRegN src) 6002 %{ 6003 predicate(CompressedOops::shift() == 0); 6004 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6005 6006 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6007 ins_encode %{ 6008 __ movl($dst$$Register, $src$$Register); 6009 %} 6010 ins_pipe(ialu_reg_reg); // XXX 6011 %} 6012 6013 // Convert oop pointer into compressed form 6014 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6015 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6016 match(Set dst (EncodeP src)); 6017 effect(KILL cr); 6018 format %{ "encode_heap_oop $dst,$src" %} 6019 ins_encode %{ 6020 Register s = $src$$Register; 6021 Register d = $dst$$Register; 6022 if (s != d) { 6023 __ movq(d, s); 6024 } 6025 __ encode_heap_oop(d); 6026 %} 6027 ins_pipe(ialu_reg_long); 6028 %} 6029 6030 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6031 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6032 match(Set dst (EncodeP src)); 6033 effect(KILL cr); 6034 format %{ "encode_heap_oop_not_null $dst,$src" %} 6035 ins_encode %{ 6036 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6037 %} 6038 ins_pipe(ialu_reg_long); 6039 %} 6040 6041 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6042 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6043 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6044 match(Set dst (DecodeN src)); 6045 effect(KILL cr); 6046 format %{ "decode_heap_oop $dst,$src" %} 6047 ins_encode %{ 6048 Register s = $src$$Register; 6049 Register d = $dst$$Register; 6050 if (s != d) { 6051 __ movq(d, s); 6052 } 6053 __ decode_heap_oop(d); 6054 %} 6055 ins_pipe(ialu_reg_long); 6056 %} 6057 6058 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6059 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6060 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6061 match(Set dst (DecodeN src)); 6062 effect(KILL cr); 6063 format %{ "decode_heap_oop_not_null $dst,$src" %} 6064 ins_encode %{ 6065 Register s = $src$$Register; 6066 Register d = $dst$$Register; 6067 if (s != d) { 6068 __ decode_heap_oop_not_null(d, s); 6069 } else { 6070 __ decode_heap_oop_not_null(d); 6071 } 6072 %} 6073 ins_pipe(ialu_reg_long); 6074 %} 6075 6076 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6077 match(Set dst (EncodePKlass src)); 6078 effect(TEMP dst, KILL cr); 6079 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6080 ins_encode %{ 6081 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6082 %} 6083 ins_pipe(ialu_reg_long); 6084 %} 6085 6086 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6087 match(Set dst (DecodeNKlass src)); 6088 effect(TEMP dst, KILL cr); 6089 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6090 ins_encode %{ 6091 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6092 %} 6093 ins_pipe(ialu_reg_long); 6094 %} 6095 6096 //----------Conditional Move--------------------------------------------------- 6097 // Jump 6098 // dummy instruction for generating temp registers 6099 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6100 match(Jump (LShiftL switch_val shift)); 6101 ins_cost(350); 6102 predicate(false); 6103 effect(TEMP dest); 6104 6105 format %{ "leaq $dest, [$constantaddress]\n\t" 6106 "jmp [$dest + $switch_val << $shift]\n\t" %} 6107 ins_encode %{ 6108 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6109 // to do that and the compiler is using that register as one it can allocate. 6110 // So we build it all by hand. 6111 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6112 // ArrayAddress dispatch(table, index); 6113 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6114 __ lea($dest$$Register, $constantaddress); 6115 __ jmp(dispatch); 6116 %} 6117 ins_pipe(pipe_jmp); 6118 %} 6119 6120 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6121 match(Jump (AddL (LShiftL switch_val shift) offset)); 6122 ins_cost(350); 6123 effect(TEMP dest); 6124 6125 format %{ "leaq $dest, [$constantaddress]\n\t" 6126 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6127 ins_encode %{ 6128 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6129 // to do that and the compiler is using that register as one it can allocate. 6130 // So we build it all by hand. 6131 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6132 // ArrayAddress dispatch(table, index); 6133 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6134 __ lea($dest$$Register, $constantaddress); 6135 __ jmp(dispatch); 6136 %} 6137 ins_pipe(pipe_jmp); 6138 %} 6139 6140 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6141 match(Jump switch_val); 6142 ins_cost(350); 6143 effect(TEMP dest); 6144 6145 format %{ "leaq $dest, [$constantaddress]\n\t" 6146 "jmp [$dest + $switch_val]\n\t" %} 6147 ins_encode %{ 6148 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6149 // to do that and the compiler is using that register as one it can allocate. 6150 // So we build it all by hand. 6151 // Address index(noreg, switch_reg, Address::times_1); 6152 // ArrayAddress dispatch(table, index); 6153 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6154 __ lea($dest$$Register, $constantaddress); 6155 __ jmp(dispatch); 6156 %} 6157 ins_pipe(pipe_jmp); 6158 %} 6159 6160 // Conditional move 6161 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6162 %{ 6163 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6164 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6165 6166 ins_cost(100); // XXX 6167 format %{ "setbn$cop $dst\t# signed, int" %} 6168 ins_encode %{ 6169 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6170 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6171 %} 6172 ins_pipe(ialu_reg); 6173 %} 6174 6175 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6176 %{ 6177 predicate(!UseAPX); 6178 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6179 6180 ins_cost(200); // XXX 6181 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6182 ins_encode %{ 6183 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6184 %} 6185 ins_pipe(pipe_cmov_reg); 6186 %} 6187 6188 instruct cmovI_reg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr, cmpOp cop) 6189 %{ 6190 predicate(UseAPX); 6191 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6192 6193 ins_cost(200); 6194 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6195 ins_encode %{ 6196 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6197 %} 6198 ins_pipe(pipe_cmov_reg); 6199 %} 6200 6201 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6202 %{ 6203 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6204 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6205 6206 ins_cost(100); // XXX 6207 format %{ "setbn$cop $dst\t# unsigned, int" %} 6208 ins_encode %{ 6209 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6210 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6211 %} 6212 ins_pipe(ialu_reg); 6213 %} 6214 6215 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6216 predicate(!UseAPX); 6217 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6218 6219 ins_cost(200); // XXX 6220 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6221 ins_encode %{ 6222 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6223 %} 6224 ins_pipe(pipe_cmov_reg); 6225 %} 6226 6227 instruct cmovI_regU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, rRegI src2) %{ 6228 predicate(UseAPX); 6229 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6230 6231 ins_cost(200); 6232 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6233 ins_encode %{ 6234 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6235 %} 6236 ins_pipe(pipe_cmov_reg); 6237 %} 6238 6239 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6240 %{ 6241 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6242 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6243 6244 ins_cost(100); // XXX 6245 format %{ "setbn$cop $dst\t# unsigned, int" %} 6246 ins_encode %{ 6247 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6248 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6249 %} 6250 ins_pipe(ialu_reg); 6251 %} 6252 6253 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6254 predicate(!UseAPX); 6255 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6256 ins_cost(200); 6257 expand %{ 6258 cmovI_regU(cop, cr, dst, src); 6259 %} 6260 %} 6261 6262 instruct cmovI_regUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, rRegI src2) %{ 6263 predicate(UseAPX); 6264 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6265 ins_cost(200); 6266 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6267 ins_encode %{ 6268 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6269 %} 6270 ins_pipe(pipe_cmov_reg); 6271 %} 6272 6273 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6274 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6275 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6276 6277 ins_cost(200); // XXX 6278 format %{ "cmovpl $dst, $src\n\t" 6279 "cmovnel $dst, $src" %} 6280 ins_encode %{ 6281 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6282 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6283 %} 6284 ins_pipe(pipe_cmov_reg); 6285 %} 6286 6287 instruct cmovI_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6288 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6289 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6290 6291 ins_cost(200); 6292 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6293 "ecmovnel $dst, $src1, $src2" %} 6294 ins_encode %{ 6295 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6296 __ ecmovl(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6297 %} 6298 ins_pipe(pipe_cmov_reg); 6299 %} 6300 6301 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6302 // inputs of the CMove 6303 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6304 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6305 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6306 6307 ins_cost(200); // XXX 6308 format %{ "cmovpl $dst, $src\n\t" 6309 "cmovnel $dst, $src" %} 6310 ins_encode %{ 6311 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6312 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6313 %} 6314 ins_pipe(pipe_cmov_reg); 6315 %} 6316 6317 // We need this special handling for only eq / neq comparison since NaN == NaN is false, 6318 // and parity flag bit is set if any of the operand is a NaN. 6319 instruct cmovI_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6320 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6321 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6322 6323 ins_cost(200); 6324 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6325 "ecmovnel $dst, $src1, $src2" %} 6326 ins_encode %{ 6327 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6328 __ ecmovl(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6329 %} 6330 ins_pipe(pipe_cmov_reg); 6331 %} 6332 6333 // Conditional move 6334 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6335 predicate(!UseAPX); 6336 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6337 6338 ins_cost(250); // XXX 6339 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6340 ins_encode %{ 6341 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6342 %} 6343 ins_pipe(pipe_cmov_mem); 6344 %} 6345 6346 // Conditional move 6347 instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2) 6348 %{ 6349 predicate(UseAPX); 6350 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6351 6352 ins_cost(250); 6353 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6354 ins_encode %{ 6355 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6356 %} 6357 ins_pipe(pipe_cmov_mem); 6358 %} 6359 6360 // Conditional move 6361 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6362 %{ 6363 predicate(!UseAPX); 6364 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6365 6366 ins_cost(250); // XXX 6367 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6368 ins_encode %{ 6369 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6370 %} 6371 ins_pipe(pipe_cmov_mem); 6372 %} 6373 6374 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6375 predicate(!UseAPX); 6376 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6377 ins_cost(250); 6378 expand %{ 6379 cmovI_memU(cop, cr, dst, src); 6380 %} 6381 %} 6382 6383 instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2) 6384 %{ 6385 predicate(UseAPX); 6386 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6387 6388 ins_cost(250); 6389 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6390 ins_encode %{ 6391 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6392 %} 6393 ins_pipe(pipe_cmov_mem); 6394 %} 6395 6396 instruct cmovI_rReg_rReg_memUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, memory src2) 6397 %{ 6398 predicate(UseAPX); 6399 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6400 ins_cost(250); 6401 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6402 ins_encode %{ 6403 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6404 %} 6405 ins_pipe(pipe_cmov_mem); 6406 %} 6407 6408 // Conditional move 6409 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6410 %{ 6411 predicate(!UseAPX); 6412 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6413 6414 ins_cost(200); // XXX 6415 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6416 ins_encode %{ 6417 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6418 %} 6419 ins_pipe(pipe_cmov_reg); 6420 %} 6421 6422 // Conditional move ndd 6423 instruct cmovN_reg_ndd(rRegN dst, rRegN src1, rRegN src2, rFlagsReg cr, cmpOp cop) 6424 %{ 6425 predicate(UseAPX); 6426 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6427 6428 ins_cost(200); 6429 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, compressed ptr ndd" %} 6430 ins_encode %{ 6431 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6432 %} 6433 ins_pipe(pipe_cmov_reg); 6434 %} 6435 6436 // Conditional move 6437 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6438 %{ 6439 predicate(!UseAPX); 6440 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6441 6442 ins_cost(200); // XXX 6443 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6444 ins_encode %{ 6445 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6446 %} 6447 ins_pipe(pipe_cmov_reg); 6448 %} 6449 6450 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6451 predicate(!UseAPX); 6452 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6453 ins_cost(200); 6454 expand %{ 6455 cmovN_regU(cop, cr, dst, src); 6456 %} 6457 %} 6458 6459 // Conditional move ndd 6460 instruct cmovN_regU_ndd(rRegN dst, cmpOpU cop, rFlagsRegU cr, rRegN src1, rRegN src2) 6461 %{ 6462 predicate(UseAPX); 6463 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6464 6465 ins_cost(200); 6466 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6467 ins_encode %{ 6468 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6469 %} 6470 ins_pipe(pipe_cmov_reg); 6471 %} 6472 6473 instruct cmovN_regUCF_ndd(rRegN dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegN src1, rRegN src2) %{ 6474 predicate(UseAPX); 6475 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6476 ins_cost(200); 6477 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6478 ins_encode %{ 6479 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6480 %} 6481 ins_pipe(pipe_cmov_reg); 6482 %} 6483 6484 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6485 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6486 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6487 6488 ins_cost(200); // XXX 6489 format %{ "cmovpl $dst, $src\n\t" 6490 "cmovnel $dst, $src" %} 6491 ins_encode %{ 6492 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6493 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6494 %} 6495 ins_pipe(pipe_cmov_reg); 6496 %} 6497 6498 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6499 // inputs of the CMove 6500 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6501 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6502 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6503 6504 ins_cost(200); // XXX 6505 format %{ "cmovpl $dst, $src\n\t" 6506 "cmovnel $dst, $src" %} 6507 ins_encode %{ 6508 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6509 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6510 %} 6511 ins_pipe(pipe_cmov_reg); 6512 %} 6513 6514 // Conditional move 6515 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6516 %{ 6517 predicate(!UseAPX); 6518 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6519 6520 ins_cost(200); // XXX 6521 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6522 ins_encode %{ 6523 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6524 %} 6525 ins_pipe(pipe_cmov_reg); // XXX 6526 %} 6527 6528 // Conditional move ndd 6529 instruct cmovP_reg_ndd(rRegP dst, rRegP src1, rRegP src2, rFlagsReg cr, cmpOp cop) 6530 %{ 6531 predicate(UseAPX); 6532 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6533 6534 ins_cost(200); 6535 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, ptr ndd" %} 6536 ins_encode %{ 6537 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6538 %} 6539 ins_pipe(pipe_cmov_reg); 6540 %} 6541 6542 // Conditional move 6543 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6544 %{ 6545 predicate(!UseAPX); 6546 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6547 6548 ins_cost(200); // XXX 6549 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6550 ins_encode %{ 6551 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6552 %} 6553 ins_pipe(pipe_cmov_reg); // XXX 6554 %} 6555 6556 // Conditional move ndd 6557 instruct cmovP_regU_ndd(rRegP dst, cmpOpU cop, rFlagsRegU cr, rRegP src1, rRegP src2) 6558 %{ 6559 predicate(UseAPX); 6560 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6561 6562 ins_cost(200); 6563 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6564 ins_encode %{ 6565 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6566 %} 6567 ins_pipe(pipe_cmov_reg); 6568 %} 6569 6570 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6571 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6572 ins_cost(200); 6573 expand %{ 6574 cmovP_regU(cop, cr, dst, src); 6575 %} 6576 %} 6577 6578 instruct cmovP_regUCF_ndd(rRegP dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegP src1, rRegP src2) %{ 6579 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6580 ins_cost(200); 6581 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6582 ins_encode %{ 6583 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6584 %} 6585 ins_pipe(pipe_cmov_reg); 6586 %} 6587 6588 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6589 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6590 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6591 6592 ins_cost(200); // XXX 6593 format %{ "cmovpq $dst, $src\n\t" 6594 "cmovneq $dst, $src" %} 6595 ins_encode %{ 6596 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6597 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6598 %} 6599 ins_pipe(pipe_cmov_reg); 6600 %} 6601 6602 instruct cmovP_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6603 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6604 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6605 6606 ins_cost(200); 6607 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6608 "ecmovneq $dst, $src1, $src2" %} 6609 ins_encode %{ 6610 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6611 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6612 %} 6613 ins_pipe(pipe_cmov_reg); 6614 %} 6615 6616 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6617 // inputs of the CMove 6618 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6619 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6620 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6621 6622 ins_cost(200); // XXX 6623 format %{ "cmovpq $dst, $src\n\t" 6624 "cmovneq $dst, $src" %} 6625 ins_encode %{ 6626 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6627 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6628 %} 6629 ins_pipe(pipe_cmov_reg); 6630 %} 6631 6632 instruct cmovP_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6633 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6634 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6635 6636 ins_cost(200); 6637 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6638 "ecmovneq $dst, $src1, $src2" %} 6639 ins_encode %{ 6640 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6641 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6642 %} 6643 ins_pipe(pipe_cmov_reg); 6644 %} 6645 6646 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6647 %{ 6648 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6649 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6650 6651 ins_cost(100); // XXX 6652 format %{ "setbn$cop $dst\t# signed, long" %} 6653 ins_encode %{ 6654 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6655 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6656 %} 6657 ins_pipe(ialu_reg); 6658 %} 6659 6660 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6661 %{ 6662 predicate(!UseAPX); 6663 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6664 6665 ins_cost(200); // XXX 6666 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6667 ins_encode %{ 6668 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6669 %} 6670 ins_pipe(pipe_cmov_reg); // XXX 6671 %} 6672 6673 instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src2) 6674 %{ 6675 predicate(UseAPX); 6676 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6677 6678 ins_cost(200); 6679 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6680 ins_encode %{ 6681 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6682 %} 6683 ins_pipe(pipe_cmov_reg); 6684 %} 6685 6686 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6687 %{ 6688 predicate(!UseAPX); 6689 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6690 6691 ins_cost(200); // XXX 6692 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6693 ins_encode %{ 6694 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6695 %} 6696 ins_pipe(pipe_cmov_mem); // XXX 6697 %} 6698 6699 instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2) 6700 %{ 6701 predicate(UseAPX); 6702 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6703 6704 ins_cost(200); 6705 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6706 ins_encode %{ 6707 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6708 %} 6709 ins_pipe(pipe_cmov_mem); 6710 %} 6711 6712 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6713 %{ 6714 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6715 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6716 6717 ins_cost(100); // XXX 6718 format %{ "setbn$cop $dst\t# unsigned, long" %} 6719 ins_encode %{ 6720 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6721 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6722 %} 6723 ins_pipe(ialu_reg); 6724 %} 6725 6726 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6727 %{ 6728 predicate(!UseAPX); 6729 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6730 6731 ins_cost(200); // XXX 6732 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6733 ins_encode %{ 6734 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6735 %} 6736 ins_pipe(pipe_cmov_reg); // XXX 6737 %} 6738 6739 instruct cmovL_regU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, rRegL src2) 6740 %{ 6741 predicate(UseAPX); 6742 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6743 6744 ins_cost(200); 6745 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6746 ins_encode %{ 6747 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6748 %} 6749 ins_pipe(pipe_cmov_reg); 6750 %} 6751 6752 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6753 %{ 6754 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6755 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6756 6757 ins_cost(100); // XXX 6758 format %{ "setbn$cop $dst\t# unsigned, long" %} 6759 ins_encode %{ 6760 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6761 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6762 %} 6763 ins_pipe(ialu_reg); 6764 %} 6765 6766 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6767 predicate(!UseAPX); 6768 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6769 ins_cost(200); 6770 expand %{ 6771 cmovL_regU(cop, cr, dst, src); 6772 %} 6773 %} 6774 6775 instruct cmovL_regUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, rRegL src2) 6776 %{ 6777 predicate(UseAPX); 6778 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6779 ins_cost(200); 6780 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6781 ins_encode %{ 6782 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6783 %} 6784 ins_pipe(pipe_cmov_reg); 6785 %} 6786 6787 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6788 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6789 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6790 6791 ins_cost(200); // XXX 6792 format %{ "cmovpq $dst, $src\n\t" 6793 "cmovneq $dst, $src" %} 6794 ins_encode %{ 6795 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6796 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6797 %} 6798 ins_pipe(pipe_cmov_reg); 6799 %} 6800 6801 instruct cmovL_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6802 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6803 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6804 6805 ins_cost(200); 6806 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6807 "ecmovneq $dst, $src1, $src2" %} 6808 ins_encode %{ 6809 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6810 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6811 %} 6812 ins_pipe(pipe_cmov_reg); 6813 %} 6814 6815 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6816 // inputs of the CMove 6817 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6818 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6819 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6820 6821 ins_cost(200); // XXX 6822 format %{ "cmovpq $dst, $src\n\t" 6823 "cmovneq $dst, $src" %} 6824 ins_encode %{ 6825 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6826 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6827 %} 6828 ins_pipe(pipe_cmov_reg); 6829 %} 6830 6831 instruct cmovL_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6832 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6833 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6834 6835 ins_cost(200); 6836 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6837 "ecmovneq $dst, $src1, $src2" %} 6838 ins_encode %{ 6839 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6840 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6841 %} 6842 ins_pipe(pipe_cmov_reg); 6843 %} 6844 6845 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6846 %{ 6847 predicate(!UseAPX); 6848 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6849 6850 ins_cost(200); // XXX 6851 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6852 ins_encode %{ 6853 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6854 %} 6855 ins_pipe(pipe_cmov_mem); // XXX 6856 %} 6857 6858 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6859 predicate(!UseAPX); 6860 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6861 ins_cost(200); 6862 expand %{ 6863 cmovL_memU(cop, cr, dst, src); 6864 %} 6865 %} 6866 6867 instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2) 6868 %{ 6869 predicate(UseAPX); 6870 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6871 6872 ins_cost(200); 6873 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6874 ins_encode %{ 6875 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6876 %} 6877 ins_pipe(pipe_cmov_mem); 6878 %} 6879 6880 instruct cmovL_rReg_rReg_memUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, memory src2) 6881 %{ 6882 predicate(UseAPX); 6883 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6884 ins_cost(200); 6885 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6886 ins_encode %{ 6887 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6888 %} 6889 ins_pipe(pipe_cmov_mem); 6890 %} 6891 6892 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6893 %{ 6894 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6895 6896 ins_cost(200); // XXX 6897 format %{ "jn$cop skip\t# signed cmove float\n\t" 6898 "movss $dst, $src\n" 6899 "skip:" %} 6900 ins_encode %{ 6901 Label Lskip; 6902 // Invert sense of branch from sense of CMOV 6903 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6904 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6905 __ bind(Lskip); 6906 %} 6907 ins_pipe(pipe_slow); 6908 %} 6909 6910 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6911 %{ 6912 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6913 6914 ins_cost(200); // XXX 6915 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6916 "movss $dst, $src\n" 6917 "skip:" %} 6918 ins_encode %{ 6919 Label Lskip; 6920 // Invert sense of branch from sense of CMOV 6921 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6922 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6923 __ bind(Lskip); 6924 %} 6925 ins_pipe(pipe_slow); 6926 %} 6927 6928 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6929 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6930 ins_cost(200); 6931 expand %{ 6932 cmovF_regU(cop, cr, dst, src); 6933 %} 6934 %} 6935 6936 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6937 %{ 6938 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6939 6940 ins_cost(200); // XXX 6941 format %{ "jn$cop skip\t# signed cmove double\n\t" 6942 "movsd $dst, $src\n" 6943 "skip:" %} 6944 ins_encode %{ 6945 Label Lskip; 6946 // Invert sense of branch from sense of CMOV 6947 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6948 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6949 __ bind(Lskip); 6950 %} 6951 ins_pipe(pipe_slow); 6952 %} 6953 6954 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6955 %{ 6956 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6957 6958 ins_cost(200); // XXX 6959 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6960 "movsd $dst, $src\n" 6961 "skip:" %} 6962 ins_encode %{ 6963 Label Lskip; 6964 // Invert sense of branch from sense of CMOV 6965 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6966 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6967 __ bind(Lskip); 6968 %} 6969 ins_pipe(pipe_slow); 6970 %} 6971 6972 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6973 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6974 ins_cost(200); 6975 expand %{ 6976 cmovD_regU(cop, cr, dst, src); 6977 %} 6978 %} 6979 6980 //----------Arithmetic Instructions-------------------------------------------- 6981 //----------Addition Instructions---------------------------------------------- 6982 6983 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6984 %{ 6985 predicate(!UseAPX); 6986 match(Set dst (AddI dst src)); 6987 effect(KILL cr); 6988 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); 6989 format %{ "addl $dst, $src\t# int" %} 6990 ins_encode %{ 6991 __ addl($dst$$Register, $src$$Register); 6992 %} 6993 ins_pipe(ialu_reg_reg); 6994 %} 6995 6996 instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 6997 %{ 6998 predicate(UseAPX); 6999 match(Set dst (AddI src1 src2)); 7000 effect(KILL cr); 7001 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); 7002 7003 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7004 ins_encode %{ 7005 __ eaddl($dst$$Register, $src1$$Register, $src2$$Register, false); 7006 %} 7007 ins_pipe(ialu_reg_reg); 7008 %} 7009 7010 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7011 %{ 7012 predicate(!UseAPX); 7013 match(Set dst (AddI dst src)); 7014 effect(KILL cr); 7015 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); 7016 7017 format %{ "addl $dst, $src\t# int" %} 7018 ins_encode %{ 7019 __ addl($dst$$Register, $src$$constant); 7020 %} 7021 ins_pipe( ialu_reg ); 7022 %} 7023 7024 instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 7025 %{ 7026 predicate(UseAPX); 7027 match(Set dst (AddI src1 src2)); 7028 effect(KILL cr); 7029 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); 7030 7031 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7032 ins_encode %{ 7033 __ eaddl($dst$$Register, $src1$$Register, $src2$$constant, false); 7034 %} 7035 ins_pipe( ialu_reg ); 7036 %} 7037 7038 instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 7039 %{ 7040 predicate(UseAPX); 7041 match(Set dst (AddI (LoadI src1) src2)); 7042 effect(KILL cr); 7043 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); 7044 7045 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7046 ins_encode %{ 7047 __ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false); 7048 %} 7049 ins_pipe( ialu_reg ); 7050 %} 7051 7052 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7053 %{ 7054 predicate(!UseAPX); 7055 match(Set dst (AddI dst (LoadI src))); 7056 effect(KILL cr); 7057 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); 7058 7059 ins_cost(150); // XXX 7060 format %{ "addl $dst, $src\t# int" %} 7061 ins_encode %{ 7062 __ addl($dst$$Register, $src$$Address); 7063 %} 7064 ins_pipe(ialu_reg_mem); 7065 %} 7066 7067 instruct addI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 7068 %{ 7069 predicate(UseAPX); 7070 match(Set dst (AddI (LoadI src1) src2)); 7071 effect(KILL cr); 7072 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); 7073 7074 ins_cost(150); 7075 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7076 ins_encode %{ 7077 __ eaddl($dst$$Register, $src1$$Address, $src2$$Register, false); 7078 %} 7079 ins_pipe(ialu_reg_mem); 7080 %} 7081 7082 instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 7083 %{ 7084 predicate(UseAPX); 7085 match(Set dst (AddI src1 (LoadI src2))); 7086 effect(KILL cr); 7087 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); 7088 7089 ins_cost(150); 7090 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7091 ins_encode %{ 7092 __ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false); 7093 %} 7094 ins_pipe(ialu_reg_mem); 7095 %} 7096 7097 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7098 %{ 7099 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7100 effect(KILL cr); 7101 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); 7102 7103 ins_cost(150); // XXX 7104 format %{ "addl $dst, $src\t# int" %} 7105 ins_encode %{ 7106 __ addl($dst$$Address, $src$$Register); 7107 %} 7108 ins_pipe(ialu_mem_reg); 7109 %} 7110 7111 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7112 %{ 7113 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7114 effect(KILL cr); 7115 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); 7116 7117 7118 ins_cost(125); // XXX 7119 format %{ "addl $dst, $src\t# int" %} 7120 ins_encode %{ 7121 __ addl($dst$$Address, $src$$constant); 7122 %} 7123 ins_pipe(ialu_mem_imm); 7124 %} 7125 7126 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 7127 %{ 7128 predicate(!UseAPX && UseIncDec); 7129 match(Set dst (AddI dst src)); 7130 effect(KILL cr); 7131 7132 format %{ "incl $dst\t# int" %} 7133 ins_encode %{ 7134 __ incrementl($dst$$Register); 7135 %} 7136 ins_pipe(ialu_reg); 7137 %} 7138 7139 instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr) 7140 %{ 7141 predicate(UseAPX && UseIncDec); 7142 match(Set dst (AddI src val)); 7143 effect(KILL cr); 7144 7145 format %{ "eincl $dst, $src\t# int ndd" %} 7146 ins_encode %{ 7147 __ eincl($dst$$Register, $src$$Register, false); 7148 %} 7149 ins_pipe(ialu_reg); 7150 %} 7151 7152 instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr) 7153 %{ 7154 predicate(UseAPX && UseIncDec); 7155 match(Set dst (AddI (LoadI src) val)); 7156 effect(KILL cr); 7157 7158 format %{ "eincl $dst, $src\t# int ndd" %} 7159 ins_encode %{ 7160 __ eincl($dst$$Register, $src$$Address, false); 7161 %} 7162 ins_pipe(ialu_reg); 7163 %} 7164 7165 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 7166 %{ 7167 predicate(UseIncDec); 7168 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7169 effect(KILL cr); 7170 7171 ins_cost(125); // XXX 7172 format %{ "incl $dst\t# int" %} 7173 ins_encode %{ 7174 __ incrementl($dst$$Address); 7175 %} 7176 ins_pipe(ialu_mem_imm); 7177 %} 7178 7179 // XXX why does that use AddI 7180 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7181 %{ 7182 predicate(!UseAPX && UseIncDec); 7183 match(Set dst (AddI dst src)); 7184 effect(KILL cr); 7185 7186 format %{ "decl $dst\t# int" %} 7187 ins_encode %{ 7188 __ decrementl($dst$$Register); 7189 %} 7190 ins_pipe(ialu_reg); 7191 %} 7192 7193 instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr) 7194 %{ 7195 predicate(UseAPX && UseIncDec); 7196 match(Set dst (AddI src val)); 7197 effect(KILL cr); 7198 7199 format %{ "edecl $dst, $src\t# int ndd" %} 7200 ins_encode %{ 7201 __ edecl($dst$$Register, $src$$Register, false); 7202 %} 7203 ins_pipe(ialu_reg); 7204 %} 7205 7206 instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr) 7207 %{ 7208 predicate(UseAPX && UseIncDec); 7209 match(Set dst (AddI (LoadI src) val)); 7210 effect(KILL cr); 7211 7212 format %{ "edecl $dst, $src\t# int ndd" %} 7213 ins_encode %{ 7214 __ edecl($dst$$Register, $src$$Address, false); 7215 %} 7216 ins_pipe(ialu_reg); 7217 %} 7218 7219 // XXX why does that use AddI 7220 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7221 %{ 7222 predicate(UseIncDec); 7223 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7224 effect(KILL cr); 7225 7226 ins_cost(125); // XXX 7227 format %{ "decl $dst\t# int" %} 7228 ins_encode %{ 7229 __ decrementl($dst$$Address); 7230 %} 7231 ins_pipe(ialu_mem_imm); 7232 %} 7233 7234 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 7235 %{ 7236 predicate(VM_Version::supports_fast_2op_lea()); 7237 match(Set dst (AddI (LShiftI index scale) disp)); 7238 7239 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 7240 ins_encode %{ 7241 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7242 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7243 %} 7244 ins_pipe(ialu_reg_reg); 7245 %} 7246 7247 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 7248 %{ 7249 predicate(VM_Version::supports_fast_3op_lea()); 7250 match(Set dst (AddI (AddI base index) disp)); 7251 7252 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 7253 ins_encode %{ 7254 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7255 %} 7256 ins_pipe(ialu_reg_reg); 7257 %} 7258 7259 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 7260 %{ 7261 predicate(VM_Version::supports_fast_2op_lea()); 7262 match(Set dst (AddI base (LShiftI index scale))); 7263 7264 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 7265 ins_encode %{ 7266 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7267 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7268 %} 7269 ins_pipe(ialu_reg_reg); 7270 %} 7271 7272 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 7273 %{ 7274 predicate(VM_Version::supports_fast_3op_lea()); 7275 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 7276 7277 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 7278 ins_encode %{ 7279 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7280 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7281 %} 7282 ins_pipe(ialu_reg_reg); 7283 %} 7284 7285 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7286 %{ 7287 predicate(!UseAPX); 7288 match(Set dst (AddL dst src)); 7289 effect(KILL cr); 7290 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); 7291 7292 format %{ "addq $dst, $src\t# long" %} 7293 ins_encode %{ 7294 __ addq($dst$$Register, $src$$Register); 7295 %} 7296 ins_pipe(ialu_reg_reg); 7297 %} 7298 7299 instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 7300 %{ 7301 predicate(UseAPX); 7302 match(Set dst (AddL src1 src2)); 7303 effect(KILL cr); 7304 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); 7305 7306 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7307 ins_encode %{ 7308 __ eaddq($dst$$Register, $src1$$Register, $src2$$Register, false); 7309 %} 7310 ins_pipe(ialu_reg_reg); 7311 %} 7312 7313 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7314 %{ 7315 predicate(!UseAPX); 7316 match(Set dst (AddL dst src)); 7317 effect(KILL cr); 7318 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); 7319 7320 format %{ "addq $dst, $src\t# long" %} 7321 ins_encode %{ 7322 __ addq($dst$$Register, $src$$constant); 7323 %} 7324 ins_pipe( ialu_reg ); 7325 %} 7326 7327 instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 7328 %{ 7329 predicate(UseAPX); 7330 match(Set dst (AddL src1 src2)); 7331 effect(KILL cr); 7332 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); 7333 7334 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7335 ins_encode %{ 7336 __ eaddq($dst$$Register, $src1$$Register, $src2$$constant, false); 7337 %} 7338 ins_pipe( ialu_reg ); 7339 %} 7340 7341 instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 7342 %{ 7343 predicate(UseAPX); 7344 match(Set dst (AddL (LoadL src1) src2)); 7345 effect(KILL cr); 7346 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); 7347 7348 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7349 ins_encode %{ 7350 __ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false); 7351 %} 7352 ins_pipe( ialu_reg ); 7353 %} 7354 7355 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7356 %{ 7357 predicate(!UseAPX); 7358 match(Set dst (AddL dst (LoadL src))); 7359 effect(KILL cr); 7360 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); 7361 7362 ins_cost(150); // XXX 7363 format %{ "addq $dst, $src\t# long" %} 7364 ins_encode %{ 7365 __ addq($dst$$Register, $src$$Address); 7366 %} 7367 ins_pipe(ialu_reg_mem); 7368 %} 7369 7370 instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 7371 %{ 7372 predicate(UseAPX); 7373 match(Set dst (AddL src1 (LoadL src2))); 7374 effect(KILL cr); 7375 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); 7376 7377 ins_cost(150); 7378 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7379 ins_encode %{ 7380 __ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false); 7381 %} 7382 ins_pipe(ialu_reg_mem); 7383 %} 7384 7385 instruct addL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 7386 %{ 7387 predicate(UseAPX); 7388 match(Set dst (AddL (LoadL src1) src2)); 7389 effect(KILL cr); 7390 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); 7391 7392 ins_cost(150); 7393 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7394 ins_encode %{ 7395 __ eaddq($dst$$Register, $src1$$Address, $src2$$Register, false); 7396 %} 7397 ins_pipe(ialu_reg_mem); 7398 %} 7399 7400 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7401 %{ 7402 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7403 effect(KILL cr); 7404 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); 7405 7406 ins_cost(150); // XXX 7407 format %{ "addq $dst, $src\t# long" %} 7408 ins_encode %{ 7409 __ addq($dst$$Address, $src$$Register); 7410 %} 7411 ins_pipe(ialu_mem_reg); 7412 %} 7413 7414 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7415 %{ 7416 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7417 effect(KILL cr); 7418 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); 7419 7420 ins_cost(125); // XXX 7421 format %{ "addq $dst, $src\t# long" %} 7422 ins_encode %{ 7423 __ addq($dst$$Address, $src$$constant); 7424 %} 7425 ins_pipe(ialu_mem_imm); 7426 %} 7427 7428 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7429 %{ 7430 predicate(!UseAPX && UseIncDec); 7431 match(Set dst (AddL dst src)); 7432 effect(KILL cr); 7433 7434 format %{ "incq $dst\t# long" %} 7435 ins_encode %{ 7436 __ incrementq($dst$$Register); 7437 %} 7438 ins_pipe(ialu_reg); 7439 %} 7440 7441 instruct incL_rReg_ndd(rRegI dst, rRegI src, immL1 val, rFlagsReg cr) 7442 %{ 7443 predicate(UseAPX && UseIncDec); 7444 match(Set dst (AddL src val)); 7445 effect(KILL cr); 7446 7447 format %{ "eincq $dst, $src\t# long ndd" %} 7448 ins_encode %{ 7449 __ eincq($dst$$Register, $src$$Register, false); 7450 %} 7451 ins_pipe(ialu_reg); 7452 %} 7453 7454 instruct incL_rReg_mem_ndd(rRegI dst, memory src, immL1 val, rFlagsReg cr) 7455 %{ 7456 predicate(UseAPX && UseIncDec); 7457 match(Set dst (AddL (LoadL src) val)); 7458 effect(KILL cr); 7459 7460 format %{ "eincq $dst, $src\t# long ndd" %} 7461 ins_encode %{ 7462 __ eincq($dst$$Register, $src$$Address, false); 7463 %} 7464 ins_pipe(ialu_reg); 7465 %} 7466 7467 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7468 %{ 7469 predicate(UseIncDec); 7470 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7471 effect(KILL cr); 7472 7473 ins_cost(125); // XXX 7474 format %{ "incq $dst\t# long" %} 7475 ins_encode %{ 7476 __ incrementq($dst$$Address); 7477 %} 7478 ins_pipe(ialu_mem_imm); 7479 %} 7480 7481 // XXX why does that use AddL 7482 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7483 %{ 7484 predicate(!UseAPX && UseIncDec); 7485 match(Set dst (AddL dst src)); 7486 effect(KILL cr); 7487 7488 format %{ "decq $dst\t# long" %} 7489 ins_encode %{ 7490 __ decrementq($dst$$Register); 7491 %} 7492 ins_pipe(ialu_reg); 7493 %} 7494 7495 instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr) 7496 %{ 7497 predicate(UseAPX && UseIncDec); 7498 match(Set dst (AddL src val)); 7499 effect(KILL cr); 7500 7501 format %{ "edecq $dst, $src\t# long ndd" %} 7502 ins_encode %{ 7503 __ edecq($dst$$Register, $src$$Register, false); 7504 %} 7505 ins_pipe(ialu_reg); 7506 %} 7507 7508 instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr) 7509 %{ 7510 predicate(UseAPX && UseIncDec); 7511 match(Set dst (AddL (LoadL src) val)); 7512 effect(KILL cr); 7513 7514 format %{ "edecq $dst, $src\t# long ndd" %} 7515 ins_encode %{ 7516 __ edecq($dst$$Register, $src$$Address, false); 7517 %} 7518 ins_pipe(ialu_reg); 7519 %} 7520 7521 // XXX why does that use AddL 7522 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7523 %{ 7524 predicate(UseIncDec); 7525 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7526 effect(KILL cr); 7527 7528 ins_cost(125); // XXX 7529 format %{ "decq $dst\t# long" %} 7530 ins_encode %{ 7531 __ decrementq($dst$$Address); 7532 %} 7533 ins_pipe(ialu_mem_imm); 7534 %} 7535 7536 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7537 %{ 7538 predicate(VM_Version::supports_fast_2op_lea()); 7539 match(Set dst (AddL (LShiftL index scale) disp)); 7540 7541 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7542 ins_encode %{ 7543 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7544 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7545 %} 7546 ins_pipe(ialu_reg_reg); 7547 %} 7548 7549 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7550 %{ 7551 predicate(VM_Version::supports_fast_3op_lea()); 7552 match(Set dst (AddL (AddL base index) disp)); 7553 7554 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7555 ins_encode %{ 7556 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7557 %} 7558 ins_pipe(ialu_reg_reg); 7559 %} 7560 7561 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7562 %{ 7563 predicate(VM_Version::supports_fast_2op_lea()); 7564 match(Set dst (AddL base (LShiftL index scale))); 7565 7566 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7567 ins_encode %{ 7568 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7569 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7570 %} 7571 ins_pipe(ialu_reg_reg); 7572 %} 7573 7574 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7575 %{ 7576 predicate(VM_Version::supports_fast_3op_lea()); 7577 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7578 7579 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7580 ins_encode %{ 7581 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7582 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7583 %} 7584 ins_pipe(ialu_reg_reg); 7585 %} 7586 7587 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7588 %{ 7589 match(Set dst (AddP dst src)); 7590 effect(KILL cr); 7591 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); 7592 7593 format %{ "addq $dst, $src\t# ptr" %} 7594 ins_encode %{ 7595 __ addq($dst$$Register, $src$$Register); 7596 %} 7597 ins_pipe(ialu_reg_reg); 7598 %} 7599 7600 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7601 %{ 7602 match(Set dst (AddP dst src)); 7603 effect(KILL cr); 7604 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); 7605 7606 format %{ "addq $dst, $src\t# ptr" %} 7607 ins_encode %{ 7608 __ addq($dst$$Register, $src$$constant); 7609 %} 7610 ins_pipe( ialu_reg ); 7611 %} 7612 7613 // XXX addP mem ops ???? 7614 7615 instruct checkCastPP(rRegP dst) 7616 %{ 7617 match(Set dst (CheckCastPP dst)); 7618 7619 size(0); 7620 format %{ "# checkcastPP of $dst" %} 7621 ins_encode(/* empty encoding */); 7622 ins_pipe(empty); 7623 %} 7624 7625 instruct castPP(rRegP dst) 7626 %{ 7627 match(Set dst (CastPP dst)); 7628 7629 size(0); 7630 format %{ "# castPP of $dst" %} 7631 ins_encode(/* empty encoding */); 7632 ins_pipe(empty); 7633 %} 7634 7635 instruct castII(rRegI dst) 7636 %{ 7637 match(Set dst (CastII dst)); 7638 7639 size(0); 7640 format %{ "# castII of $dst" %} 7641 ins_encode(/* empty encoding */); 7642 ins_cost(0); 7643 ins_pipe(empty); 7644 %} 7645 7646 instruct castLL(rRegL dst) 7647 %{ 7648 match(Set dst (CastLL dst)); 7649 7650 size(0); 7651 format %{ "# castLL of $dst" %} 7652 ins_encode(/* empty encoding */); 7653 ins_cost(0); 7654 ins_pipe(empty); 7655 %} 7656 7657 instruct castFF(regF dst) 7658 %{ 7659 match(Set dst (CastFF dst)); 7660 7661 size(0); 7662 format %{ "# castFF of $dst" %} 7663 ins_encode(/* empty encoding */); 7664 ins_cost(0); 7665 ins_pipe(empty); 7666 %} 7667 7668 instruct castHH(regF dst) 7669 %{ 7670 match(Set dst (CastHH dst)); 7671 7672 size(0); 7673 format %{ "# castHH of $dst" %} 7674 ins_encode(/* empty encoding */); 7675 ins_cost(0); 7676 ins_pipe(empty); 7677 %} 7678 7679 instruct castDD(regD dst) 7680 %{ 7681 match(Set dst (CastDD dst)); 7682 7683 size(0); 7684 format %{ "# castDD of $dst" %} 7685 ins_encode(/* empty encoding */); 7686 ins_cost(0); 7687 ins_pipe(empty); 7688 %} 7689 7690 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7691 instruct compareAndSwapP(rRegI res, 7692 memory mem_ptr, 7693 rax_RegP oldval, rRegP newval, 7694 rFlagsReg cr) 7695 %{ 7696 predicate(n->as_LoadStore()->barrier_data() == 0); 7697 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7698 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7699 effect(KILL cr, KILL oldval); 7700 7701 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7702 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7703 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7704 ins_encode %{ 7705 __ lock(); 7706 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7707 __ setcc(Assembler::equal, $res$$Register); 7708 %} 7709 ins_pipe( pipe_cmpxchg ); 7710 %} 7711 7712 instruct compareAndSwapL(rRegI res, 7713 memory mem_ptr, 7714 rax_RegL oldval, rRegL newval, 7715 rFlagsReg cr) 7716 %{ 7717 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7718 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7719 effect(KILL cr, KILL oldval); 7720 7721 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7722 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7723 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7724 ins_encode %{ 7725 __ lock(); 7726 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7727 __ setcc(Assembler::equal, $res$$Register); 7728 %} 7729 ins_pipe( pipe_cmpxchg ); 7730 %} 7731 7732 instruct compareAndSwapI(rRegI res, 7733 memory mem_ptr, 7734 rax_RegI oldval, rRegI newval, 7735 rFlagsReg cr) 7736 %{ 7737 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7738 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7739 effect(KILL cr, KILL oldval); 7740 7741 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7742 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7743 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7744 ins_encode %{ 7745 __ lock(); 7746 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7747 __ setcc(Assembler::equal, $res$$Register); 7748 %} 7749 ins_pipe( pipe_cmpxchg ); 7750 %} 7751 7752 instruct compareAndSwapB(rRegI res, 7753 memory mem_ptr, 7754 rax_RegI oldval, rRegI newval, 7755 rFlagsReg cr) 7756 %{ 7757 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7758 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7759 effect(KILL cr, KILL oldval); 7760 7761 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7762 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7763 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7764 ins_encode %{ 7765 __ lock(); 7766 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7767 __ setcc(Assembler::equal, $res$$Register); 7768 %} 7769 ins_pipe( pipe_cmpxchg ); 7770 %} 7771 7772 instruct compareAndSwapS(rRegI res, 7773 memory mem_ptr, 7774 rax_RegI oldval, rRegI newval, 7775 rFlagsReg cr) 7776 %{ 7777 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7778 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7779 effect(KILL cr, KILL oldval); 7780 7781 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7782 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7783 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7784 ins_encode %{ 7785 __ lock(); 7786 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7787 __ setcc(Assembler::equal, $res$$Register); 7788 %} 7789 ins_pipe( pipe_cmpxchg ); 7790 %} 7791 7792 instruct compareAndSwapN(rRegI res, 7793 memory mem_ptr, 7794 rax_RegN oldval, rRegN newval, 7795 rFlagsReg cr) %{ 7796 predicate(n->as_LoadStore()->barrier_data() == 0); 7797 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7798 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7799 effect(KILL cr, KILL oldval); 7800 7801 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7802 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7803 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7804 ins_encode %{ 7805 __ lock(); 7806 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7807 __ setcc(Assembler::equal, $res$$Register); 7808 %} 7809 ins_pipe( pipe_cmpxchg ); 7810 %} 7811 7812 instruct compareAndExchangeB( 7813 memory mem_ptr, 7814 rax_RegI oldval, rRegI newval, 7815 rFlagsReg cr) 7816 %{ 7817 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7818 effect(KILL cr); 7819 7820 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7821 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7822 ins_encode %{ 7823 __ lock(); 7824 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7825 %} 7826 ins_pipe( pipe_cmpxchg ); 7827 %} 7828 7829 instruct compareAndExchangeS( 7830 memory mem_ptr, 7831 rax_RegI oldval, rRegI newval, 7832 rFlagsReg cr) 7833 %{ 7834 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7835 effect(KILL cr); 7836 7837 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7838 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7839 ins_encode %{ 7840 __ lock(); 7841 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7842 %} 7843 ins_pipe( pipe_cmpxchg ); 7844 %} 7845 7846 instruct compareAndExchangeI( 7847 memory mem_ptr, 7848 rax_RegI oldval, rRegI newval, 7849 rFlagsReg cr) 7850 %{ 7851 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7852 effect(KILL cr); 7853 7854 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7855 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7856 ins_encode %{ 7857 __ lock(); 7858 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7859 %} 7860 ins_pipe( pipe_cmpxchg ); 7861 %} 7862 7863 instruct compareAndExchangeL( 7864 memory mem_ptr, 7865 rax_RegL oldval, rRegL newval, 7866 rFlagsReg cr) 7867 %{ 7868 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7869 effect(KILL cr); 7870 7871 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7872 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7873 ins_encode %{ 7874 __ lock(); 7875 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7876 %} 7877 ins_pipe( pipe_cmpxchg ); 7878 %} 7879 7880 instruct compareAndExchangeN( 7881 memory mem_ptr, 7882 rax_RegN oldval, rRegN newval, 7883 rFlagsReg cr) %{ 7884 predicate(n->as_LoadStore()->barrier_data() == 0); 7885 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7886 effect(KILL cr); 7887 7888 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7889 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7890 ins_encode %{ 7891 __ lock(); 7892 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7893 %} 7894 ins_pipe( pipe_cmpxchg ); 7895 %} 7896 7897 instruct compareAndExchangeP( 7898 memory mem_ptr, 7899 rax_RegP oldval, rRegP newval, 7900 rFlagsReg cr) 7901 %{ 7902 predicate(n->as_LoadStore()->barrier_data() == 0); 7903 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7904 effect(KILL cr); 7905 7906 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7907 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7908 ins_encode %{ 7909 __ lock(); 7910 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7911 %} 7912 ins_pipe( pipe_cmpxchg ); 7913 %} 7914 7915 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7916 predicate(n->as_LoadStore()->result_not_used()); 7917 match(Set dummy (GetAndAddB mem add)); 7918 effect(KILL cr); 7919 format %{ "addb_lock $mem, $add" %} 7920 ins_encode %{ 7921 __ lock(); 7922 __ addb($mem$$Address, $add$$Register); 7923 %} 7924 ins_pipe(pipe_cmpxchg); 7925 %} 7926 7927 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7928 predicate(n->as_LoadStore()->result_not_used()); 7929 match(Set dummy (GetAndAddB mem add)); 7930 effect(KILL cr); 7931 format %{ "addb_lock $mem, $add" %} 7932 ins_encode %{ 7933 __ lock(); 7934 __ addb($mem$$Address, $add$$constant); 7935 %} 7936 ins_pipe(pipe_cmpxchg); 7937 %} 7938 7939 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7940 predicate(!n->as_LoadStore()->result_not_used()); 7941 match(Set newval (GetAndAddB mem newval)); 7942 effect(KILL cr); 7943 format %{ "xaddb_lock $mem, $newval" %} 7944 ins_encode %{ 7945 __ lock(); 7946 __ xaddb($mem$$Address, $newval$$Register); 7947 %} 7948 ins_pipe(pipe_cmpxchg); 7949 %} 7950 7951 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7952 predicate(n->as_LoadStore()->result_not_used()); 7953 match(Set dummy (GetAndAddS mem add)); 7954 effect(KILL cr); 7955 format %{ "addw_lock $mem, $add" %} 7956 ins_encode %{ 7957 __ lock(); 7958 __ addw($mem$$Address, $add$$Register); 7959 %} 7960 ins_pipe(pipe_cmpxchg); 7961 %} 7962 7963 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7964 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7965 match(Set dummy (GetAndAddS mem add)); 7966 effect(KILL cr); 7967 format %{ "addw_lock $mem, $add" %} 7968 ins_encode %{ 7969 __ lock(); 7970 __ addw($mem$$Address, $add$$constant); 7971 %} 7972 ins_pipe(pipe_cmpxchg); 7973 %} 7974 7975 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7976 predicate(!n->as_LoadStore()->result_not_used()); 7977 match(Set newval (GetAndAddS mem newval)); 7978 effect(KILL cr); 7979 format %{ "xaddw_lock $mem, $newval" %} 7980 ins_encode %{ 7981 __ lock(); 7982 __ xaddw($mem$$Address, $newval$$Register); 7983 %} 7984 ins_pipe(pipe_cmpxchg); 7985 %} 7986 7987 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7988 predicate(n->as_LoadStore()->result_not_used()); 7989 match(Set dummy (GetAndAddI mem add)); 7990 effect(KILL cr); 7991 format %{ "addl_lock $mem, $add" %} 7992 ins_encode %{ 7993 __ lock(); 7994 __ addl($mem$$Address, $add$$Register); 7995 %} 7996 ins_pipe(pipe_cmpxchg); 7997 %} 7998 7999 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8000 predicate(n->as_LoadStore()->result_not_used()); 8001 match(Set dummy (GetAndAddI mem add)); 8002 effect(KILL cr); 8003 format %{ "addl_lock $mem, $add" %} 8004 ins_encode %{ 8005 __ lock(); 8006 __ addl($mem$$Address, $add$$constant); 8007 %} 8008 ins_pipe(pipe_cmpxchg); 8009 %} 8010 8011 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 8012 predicate(!n->as_LoadStore()->result_not_used()); 8013 match(Set newval (GetAndAddI mem newval)); 8014 effect(KILL cr); 8015 format %{ "xaddl_lock $mem, $newval" %} 8016 ins_encode %{ 8017 __ lock(); 8018 __ xaddl($mem$$Address, $newval$$Register); 8019 %} 8020 ins_pipe(pipe_cmpxchg); 8021 %} 8022 8023 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 8024 predicate(n->as_LoadStore()->result_not_used()); 8025 match(Set dummy (GetAndAddL mem add)); 8026 effect(KILL cr); 8027 format %{ "addq_lock $mem, $add" %} 8028 ins_encode %{ 8029 __ lock(); 8030 __ addq($mem$$Address, $add$$Register); 8031 %} 8032 ins_pipe(pipe_cmpxchg); 8033 %} 8034 8035 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8036 predicate(n->as_LoadStore()->result_not_used()); 8037 match(Set dummy (GetAndAddL mem add)); 8038 effect(KILL cr); 8039 format %{ "addq_lock $mem, $add" %} 8040 ins_encode %{ 8041 __ lock(); 8042 __ addq($mem$$Address, $add$$constant); 8043 %} 8044 ins_pipe(pipe_cmpxchg); 8045 %} 8046 8047 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 8048 predicate(!n->as_LoadStore()->result_not_used()); 8049 match(Set newval (GetAndAddL mem newval)); 8050 effect(KILL cr); 8051 format %{ "xaddq_lock $mem, $newval" %} 8052 ins_encode %{ 8053 __ lock(); 8054 __ xaddq($mem$$Address, $newval$$Register); 8055 %} 8056 ins_pipe(pipe_cmpxchg); 8057 %} 8058 8059 instruct xchgB( memory mem, rRegI newval) %{ 8060 match(Set newval (GetAndSetB mem newval)); 8061 format %{ "XCHGB $newval,[$mem]" %} 8062 ins_encode %{ 8063 __ xchgb($newval$$Register, $mem$$Address); 8064 %} 8065 ins_pipe( pipe_cmpxchg ); 8066 %} 8067 8068 instruct xchgS( memory mem, rRegI newval) %{ 8069 match(Set newval (GetAndSetS mem newval)); 8070 format %{ "XCHGW $newval,[$mem]" %} 8071 ins_encode %{ 8072 __ xchgw($newval$$Register, $mem$$Address); 8073 %} 8074 ins_pipe( pipe_cmpxchg ); 8075 %} 8076 8077 instruct xchgI( memory mem, rRegI newval) %{ 8078 match(Set newval (GetAndSetI mem newval)); 8079 format %{ "XCHGL $newval,[$mem]" %} 8080 ins_encode %{ 8081 __ xchgl($newval$$Register, $mem$$Address); 8082 %} 8083 ins_pipe( pipe_cmpxchg ); 8084 %} 8085 8086 instruct xchgL( memory mem, rRegL newval) %{ 8087 match(Set newval (GetAndSetL mem newval)); 8088 format %{ "XCHGL $newval,[$mem]" %} 8089 ins_encode %{ 8090 __ xchgq($newval$$Register, $mem$$Address); 8091 %} 8092 ins_pipe( pipe_cmpxchg ); 8093 %} 8094 8095 instruct xchgP( memory mem, rRegP newval) %{ 8096 match(Set newval (GetAndSetP mem newval)); 8097 predicate(n->as_LoadStore()->barrier_data() == 0); 8098 format %{ "XCHGQ $newval,[$mem]" %} 8099 ins_encode %{ 8100 __ xchgq($newval$$Register, $mem$$Address); 8101 %} 8102 ins_pipe( pipe_cmpxchg ); 8103 %} 8104 8105 instruct xchgN( memory mem, rRegN newval) %{ 8106 predicate(n->as_LoadStore()->barrier_data() == 0); 8107 match(Set newval (GetAndSetN mem newval)); 8108 format %{ "XCHGL $newval,$mem]" %} 8109 ins_encode %{ 8110 __ xchgl($newval$$Register, $mem$$Address); 8111 %} 8112 ins_pipe( pipe_cmpxchg ); 8113 %} 8114 8115 //----------Abs Instructions------------------------------------------- 8116 8117 // Integer Absolute Instructions 8118 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8119 %{ 8120 match(Set dst (AbsI src)); 8121 effect(TEMP dst, KILL cr); 8122 format %{ "xorl $dst, $dst\t# abs int\n\t" 8123 "subl $dst, $src\n\t" 8124 "cmovll $dst, $src" %} 8125 ins_encode %{ 8126 __ xorl($dst$$Register, $dst$$Register); 8127 __ subl($dst$$Register, $src$$Register); 8128 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 8129 %} 8130 8131 ins_pipe(ialu_reg_reg); 8132 %} 8133 8134 // Long Absolute Instructions 8135 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8136 %{ 8137 match(Set dst (AbsL src)); 8138 effect(TEMP dst, KILL cr); 8139 format %{ "xorl $dst, $dst\t# abs long\n\t" 8140 "subq $dst, $src\n\t" 8141 "cmovlq $dst, $src" %} 8142 ins_encode %{ 8143 __ xorl($dst$$Register, $dst$$Register); 8144 __ subq($dst$$Register, $src$$Register); 8145 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 8146 %} 8147 8148 ins_pipe(ialu_reg_reg); 8149 %} 8150 8151 //----------Subtraction Instructions------------------------------------------- 8152 8153 // Integer Subtraction Instructions 8154 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8155 %{ 8156 predicate(!UseAPX); 8157 match(Set dst (SubI dst src)); 8158 effect(KILL cr); 8159 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); 8160 8161 format %{ "subl $dst, $src\t# int" %} 8162 ins_encode %{ 8163 __ subl($dst$$Register, $src$$Register); 8164 %} 8165 ins_pipe(ialu_reg_reg); 8166 %} 8167 8168 instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8169 %{ 8170 predicate(UseAPX); 8171 match(Set dst (SubI src1 src2)); 8172 effect(KILL cr); 8173 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); 8174 8175 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8176 ins_encode %{ 8177 __ esubl($dst$$Register, $src1$$Register, $src2$$Register, false); 8178 %} 8179 ins_pipe(ialu_reg_reg); 8180 %} 8181 8182 instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8183 %{ 8184 predicate(UseAPX); 8185 match(Set dst (SubI src1 src2)); 8186 effect(KILL cr); 8187 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); 8188 8189 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8190 ins_encode %{ 8191 __ esubl($dst$$Register, $src1$$Register, $src2$$constant, false); 8192 %} 8193 ins_pipe(ialu_reg_reg); 8194 %} 8195 8196 instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8197 %{ 8198 predicate(UseAPX); 8199 match(Set dst (SubI (LoadI src1) src2)); 8200 effect(KILL cr); 8201 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); 8202 8203 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8204 ins_encode %{ 8205 __ esubl($dst$$Register, $src1$$Address, $src2$$constant, false); 8206 %} 8207 ins_pipe(ialu_reg_reg); 8208 %} 8209 8210 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8211 %{ 8212 predicate(!UseAPX); 8213 match(Set dst (SubI dst (LoadI src))); 8214 effect(KILL cr); 8215 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); 8216 8217 ins_cost(150); 8218 format %{ "subl $dst, $src\t# int" %} 8219 ins_encode %{ 8220 __ subl($dst$$Register, $src$$Address); 8221 %} 8222 ins_pipe(ialu_reg_mem); 8223 %} 8224 8225 instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8226 %{ 8227 predicate(UseAPX); 8228 match(Set dst (SubI src1 (LoadI src2))); 8229 effect(KILL cr); 8230 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); 8231 8232 ins_cost(150); 8233 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8234 ins_encode %{ 8235 __ esubl($dst$$Register, $src1$$Register, $src2$$Address, false); 8236 %} 8237 ins_pipe(ialu_reg_mem); 8238 %} 8239 8240 instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 8241 %{ 8242 predicate(UseAPX); 8243 match(Set dst (SubI (LoadI src1) src2)); 8244 effect(KILL cr); 8245 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); 8246 8247 ins_cost(150); 8248 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8249 ins_encode %{ 8250 __ esubl($dst$$Register, $src1$$Address, $src2$$Register, false); 8251 %} 8252 ins_pipe(ialu_reg_mem); 8253 %} 8254 8255 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8256 %{ 8257 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8258 effect(KILL cr); 8259 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); 8260 8261 ins_cost(150); 8262 format %{ "subl $dst, $src\t# int" %} 8263 ins_encode %{ 8264 __ subl($dst$$Address, $src$$Register); 8265 %} 8266 ins_pipe(ialu_mem_reg); 8267 %} 8268 8269 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8270 %{ 8271 predicate(!UseAPX); 8272 match(Set dst (SubL dst src)); 8273 effect(KILL cr); 8274 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); 8275 8276 format %{ "subq $dst, $src\t# long" %} 8277 ins_encode %{ 8278 __ subq($dst$$Register, $src$$Register); 8279 %} 8280 ins_pipe(ialu_reg_reg); 8281 %} 8282 8283 instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8284 %{ 8285 predicate(UseAPX); 8286 match(Set dst (SubL src1 src2)); 8287 effect(KILL cr); 8288 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); 8289 8290 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8291 ins_encode %{ 8292 __ esubq($dst$$Register, $src1$$Register, $src2$$Register, false); 8293 %} 8294 ins_pipe(ialu_reg_reg); 8295 %} 8296 8297 instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8298 %{ 8299 predicate(UseAPX); 8300 match(Set dst (SubL src1 src2)); 8301 effect(KILL cr); 8302 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); 8303 8304 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8305 ins_encode %{ 8306 __ esubq($dst$$Register, $src1$$Register, $src2$$constant, false); 8307 %} 8308 ins_pipe(ialu_reg_reg); 8309 %} 8310 8311 instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8312 %{ 8313 predicate(UseAPX); 8314 match(Set dst (SubL (LoadL src1) src2)); 8315 effect(KILL cr); 8316 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); 8317 8318 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8319 ins_encode %{ 8320 __ esubq($dst$$Register, $src1$$Address, $src2$$constant, false); 8321 %} 8322 ins_pipe(ialu_reg_reg); 8323 %} 8324 8325 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8326 %{ 8327 predicate(!UseAPX); 8328 match(Set dst (SubL dst (LoadL src))); 8329 effect(KILL cr); 8330 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); 8331 8332 ins_cost(150); 8333 format %{ "subq $dst, $src\t# long" %} 8334 ins_encode %{ 8335 __ subq($dst$$Register, $src$$Address); 8336 %} 8337 ins_pipe(ialu_reg_mem); 8338 %} 8339 8340 instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8341 %{ 8342 predicate(UseAPX); 8343 match(Set dst (SubL src1 (LoadL src2))); 8344 effect(KILL cr); 8345 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); 8346 8347 ins_cost(150); 8348 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8349 ins_encode %{ 8350 __ esubq($dst$$Register, $src1$$Register, $src2$$Address, false); 8351 %} 8352 ins_pipe(ialu_reg_mem); 8353 %} 8354 8355 instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 8356 %{ 8357 predicate(UseAPX); 8358 match(Set dst (SubL (LoadL src1) src2)); 8359 effect(KILL cr); 8360 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); 8361 8362 ins_cost(150); 8363 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8364 ins_encode %{ 8365 __ esubq($dst$$Register, $src1$$Address, $src2$$Register, false); 8366 %} 8367 ins_pipe(ialu_reg_mem); 8368 %} 8369 8370 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8371 %{ 8372 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8373 effect(KILL cr); 8374 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); 8375 8376 ins_cost(150); 8377 format %{ "subq $dst, $src\t# long" %} 8378 ins_encode %{ 8379 __ subq($dst$$Address, $src$$Register); 8380 %} 8381 ins_pipe(ialu_mem_reg); 8382 %} 8383 8384 // Subtract from a pointer 8385 // XXX hmpf??? 8386 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 8387 %{ 8388 match(Set dst (AddP dst (SubI zero src))); 8389 effect(KILL cr); 8390 8391 format %{ "subq $dst, $src\t# ptr - int" %} 8392 ins_encode %{ 8393 __ subq($dst$$Register, $src$$Register); 8394 %} 8395 ins_pipe(ialu_reg_reg); 8396 %} 8397 8398 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 8399 %{ 8400 predicate(!UseAPX); 8401 match(Set dst (SubI zero dst)); 8402 effect(KILL cr); 8403 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8404 8405 format %{ "negl $dst\t# int" %} 8406 ins_encode %{ 8407 __ negl($dst$$Register); 8408 %} 8409 ins_pipe(ialu_reg); 8410 %} 8411 8412 instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr) 8413 %{ 8414 predicate(UseAPX); 8415 match(Set dst (SubI zero src)); 8416 effect(KILL cr); 8417 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8418 8419 format %{ "enegl $dst, $src\t# int ndd" %} 8420 ins_encode %{ 8421 __ enegl($dst$$Register, $src$$Register, false); 8422 %} 8423 ins_pipe(ialu_reg); 8424 %} 8425 8426 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 8427 %{ 8428 predicate(!UseAPX); 8429 match(Set dst (NegI dst)); 8430 effect(KILL cr); 8431 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8432 8433 format %{ "negl $dst\t# int" %} 8434 ins_encode %{ 8435 __ negl($dst$$Register); 8436 %} 8437 ins_pipe(ialu_reg); 8438 %} 8439 8440 instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr) 8441 %{ 8442 predicate(UseAPX); 8443 match(Set dst (NegI src)); 8444 effect(KILL cr); 8445 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8446 8447 format %{ "enegl $dst, $src\t# int ndd" %} 8448 ins_encode %{ 8449 __ enegl($dst$$Register, $src$$Register, false); 8450 %} 8451 ins_pipe(ialu_reg); 8452 %} 8453 8454 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 8455 %{ 8456 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8457 effect(KILL cr); 8458 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8459 8460 format %{ "negl $dst\t# int" %} 8461 ins_encode %{ 8462 __ negl($dst$$Address); 8463 %} 8464 ins_pipe(ialu_reg); 8465 %} 8466 8467 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8468 %{ 8469 predicate(!UseAPX); 8470 match(Set dst (SubL zero dst)); 8471 effect(KILL cr); 8472 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8473 8474 format %{ "negq $dst\t# long" %} 8475 ins_encode %{ 8476 __ negq($dst$$Register); 8477 %} 8478 ins_pipe(ialu_reg); 8479 %} 8480 8481 instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr) 8482 %{ 8483 predicate(UseAPX); 8484 match(Set dst (SubL zero src)); 8485 effect(KILL cr); 8486 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8487 8488 format %{ "enegq $dst, $src\t# long ndd" %} 8489 ins_encode %{ 8490 __ enegq($dst$$Register, $src$$Register, false); 8491 %} 8492 ins_pipe(ialu_reg); 8493 %} 8494 8495 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 8496 %{ 8497 predicate(!UseAPX); 8498 match(Set dst (NegL dst)); 8499 effect(KILL cr); 8500 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8501 8502 format %{ "negq $dst\t# int" %} 8503 ins_encode %{ 8504 __ negq($dst$$Register); 8505 %} 8506 ins_pipe(ialu_reg); 8507 %} 8508 8509 instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr) 8510 %{ 8511 predicate(UseAPX); 8512 match(Set dst (NegL src)); 8513 effect(KILL cr); 8514 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8515 8516 format %{ "enegq $dst, $src\t# long ndd" %} 8517 ins_encode %{ 8518 __ enegq($dst$$Register, $src$$Register, false); 8519 %} 8520 ins_pipe(ialu_reg); 8521 %} 8522 8523 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8524 %{ 8525 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8526 effect(KILL cr); 8527 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8528 8529 format %{ "negq $dst\t# long" %} 8530 ins_encode %{ 8531 __ negq($dst$$Address); 8532 %} 8533 ins_pipe(ialu_reg); 8534 %} 8535 8536 //----------Multiplication/Division Instructions------------------------------- 8537 // Integer Multiplication Instructions 8538 // Multiply Register 8539 8540 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8541 %{ 8542 predicate(!UseAPX); 8543 match(Set dst (MulI dst src)); 8544 effect(KILL cr); 8545 8546 ins_cost(300); 8547 format %{ "imull $dst, $src\t# int" %} 8548 ins_encode %{ 8549 __ imull($dst$$Register, $src$$Register); 8550 %} 8551 ins_pipe(ialu_reg_reg_alu0); 8552 %} 8553 8554 instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8555 %{ 8556 predicate(UseAPX); 8557 match(Set dst (MulI src1 src2)); 8558 effect(KILL cr); 8559 8560 ins_cost(300); 8561 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8562 ins_encode %{ 8563 __ eimull($dst$$Register, $src1$$Register, $src2$$Register, false); 8564 %} 8565 ins_pipe(ialu_reg_reg_alu0); 8566 %} 8567 8568 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8569 %{ 8570 predicate(!UseAPX); 8571 match(Set dst (MulI src imm)); 8572 effect(KILL cr); 8573 8574 ins_cost(300); 8575 format %{ "imull $dst, $src, $imm\t# int" %} 8576 ins_encode %{ 8577 __ imull($dst$$Register, $src$$Register, $imm$$constant); 8578 %} 8579 ins_pipe(ialu_reg_reg_alu0); 8580 %} 8581 8582 instruct mulI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8583 %{ 8584 predicate(UseAPX); 8585 match(Set dst (MulI src1 src2)); 8586 effect(KILL cr); 8587 8588 ins_cost(300); 8589 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8590 ins_encode %{ 8591 __ eimull($dst$$Register, $src1$$Register, $src2$$constant, false); 8592 %} 8593 ins_pipe(ialu_reg_reg_alu0); 8594 %} 8595 8596 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8597 %{ 8598 predicate(!UseAPX); 8599 match(Set dst (MulI dst (LoadI src))); 8600 effect(KILL cr); 8601 8602 ins_cost(350); 8603 format %{ "imull $dst, $src\t# int" %} 8604 ins_encode %{ 8605 __ imull($dst$$Register, $src$$Address); 8606 %} 8607 ins_pipe(ialu_reg_mem_alu0); 8608 %} 8609 8610 instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8611 %{ 8612 predicate(UseAPX); 8613 match(Set dst (MulI src1 (LoadI src2))); 8614 effect(KILL cr); 8615 8616 ins_cost(350); 8617 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8618 ins_encode %{ 8619 __ eimull($dst$$Register, $src1$$Register, $src2$$Address, false); 8620 %} 8621 ins_pipe(ialu_reg_mem_alu0); 8622 %} 8623 8624 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8625 %{ 8626 predicate(!UseAPX); 8627 match(Set dst (MulI (LoadI src) imm)); 8628 effect(KILL cr); 8629 8630 ins_cost(300); 8631 format %{ "imull $dst, $src, $imm\t# int" %} 8632 ins_encode %{ 8633 __ imull($dst$$Register, $src$$Address, $imm$$constant); 8634 %} 8635 ins_pipe(ialu_reg_mem_alu0); 8636 %} 8637 8638 instruct mulI_rReg_mem_imm(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8639 %{ 8640 predicate(UseAPX); 8641 match(Set dst (MulI (LoadI src1) src2)); 8642 effect(KILL cr); 8643 8644 ins_cost(300); 8645 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8646 ins_encode %{ 8647 __ eimull($dst$$Register, $src1$$Address, $src2$$constant, false); 8648 %} 8649 ins_pipe(ialu_reg_mem_alu0); 8650 %} 8651 8652 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8653 %{ 8654 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8655 effect(KILL cr, KILL src2); 8656 8657 expand %{ mulI_rReg(dst, src1, cr); 8658 mulI_rReg(src2, src3, cr); 8659 addI_rReg(dst, src2, cr); %} 8660 %} 8661 8662 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8663 %{ 8664 predicate(!UseAPX); 8665 match(Set dst (MulL dst src)); 8666 effect(KILL cr); 8667 8668 ins_cost(300); 8669 format %{ "imulq $dst, $src\t# long" %} 8670 ins_encode %{ 8671 __ imulq($dst$$Register, $src$$Register); 8672 %} 8673 ins_pipe(ialu_reg_reg_alu0); 8674 %} 8675 8676 instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8677 %{ 8678 predicate(UseAPX); 8679 match(Set dst (MulL src1 src2)); 8680 effect(KILL cr); 8681 8682 ins_cost(300); 8683 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8684 ins_encode %{ 8685 __ eimulq($dst$$Register, $src1$$Register, $src2$$Register, false); 8686 %} 8687 ins_pipe(ialu_reg_reg_alu0); 8688 %} 8689 8690 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8691 %{ 8692 predicate(!UseAPX); 8693 match(Set dst (MulL src imm)); 8694 effect(KILL cr); 8695 8696 ins_cost(300); 8697 format %{ "imulq $dst, $src, $imm\t# long" %} 8698 ins_encode %{ 8699 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8700 %} 8701 ins_pipe(ialu_reg_reg_alu0); 8702 %} 8703 8704 instruct mulL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8705 %{ 8706 predicate(UseAPX); 8707 match(Set dst (MulL src1 src2)); 8708 effect(KILL cr); 8709 8710 ins_cost(300); 8711 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8712 ins_encode %{ 8713 __ eimulq($dst$$Register, $src1$$Register, $src2$$constant, false); 8714 %} 8715 ins_pipe(ialu_reg_reg_alu0); 8716 %} 8717 8718 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8719 %{ 8720 predicate(!UseAPX); 8721 match(Set dst (MulL dst (LoadL src))); 8722 effect(KILL cr); 8723 8724 ins_cost(350); 8725 format %{ "imulq $dst, $src\t# long" %} 8726 ins_encode %{ 8727 __ imulq($dst$$Register, $src$$Address); 8728 %} 8729 ins_pipe(ialu_reg_mem_alu0); 8730 %} 8731 8732 instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8733 %{ 8734 predicate(UseAPX); 8735 match(Set dst (MulL src1 (LoadL src2))); 8736 effect(KILL cr); 8737 8738 ins_cost(350); 8739 format %{ "eimulq $dst, $src1, $src2 \t# long" %} 8740 ins_encode %{ 8741 __ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false); 8742 %} 8743 ins_pipe(ialu_reg_mem_alu0); 8744 %} 8745 8746 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8747 %{ 8748 predicate(!UseAPX); 8749 match(Set dst (MulL (LoadL src) imm)); 8750 effect(KILL cr); 8751 8752 ins_cost(300); 8753 format %{ "imulq $dst, $src, $imm\t# long" %} 8754 ins_encode %{ 8755 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 8756 %} 8757 ins_pipe(ialu_reg_mem_alu0); 8758 %} 8759 8760 instruct mulL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8761 %{ 8762 predicate(UseAPX); 8763 match(Set dst (MulL (LoadL src1) src2)); 8764 effect(KILL cr); 8765 8766 ins_cost(300); 8767 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8768 ins_encode %{ 8769 __ eimulq($dst$$Register, $src1$$Address, $src2$$constant, false); 8770 %} 8771 ins_pipe(ialu_reg_mem_alu0); 8772 %} 8773 8774 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8775 %{ 8776 match(Set dst (MulHiL src rax)); 8777 effect(USE_KILL rax, KILL cr); 8778 8779 ins_cost(300); 8780 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8781 ins_encode %{ 8782 __ imulq($src$$Register); 8783 %} 8784 ins_pipe(ialu_reg_reg_alu0); 8785 %} 8786 8787 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8788 %{ 8789 match(Set dst (UMulHiL src rax)); 8790 effect(USE_KILL rax, KILL cr); 8791 8792 ins_cost(300); 8793 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8794 ins_encode %{ 8795 __ mulq($src$$Register); 8796 %} 8797 ins_pipe(ialu_reg_reg_alu0); 8798 %} 8799 8800 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8801 rFlagsReg cr) 8802 %{ 8803 match(Set rax (DivI rax div)); 8804 effect(KILL rdx, KILL cr); 8805 8806 ins_cost(30*100+10*100); // XXX 8807 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8808 "jne,s normal\n\t" 8809 "xorl rdx, rdx\n\t" 8810 "cmpl $div, -1\n\t" 8811 "je,s done\n" 8812 "normal: cdql\n\t" 8813 "idivl $div\n" 8814 "done:" %} 8815 ins_encode(cdql_enc(div)); 8816 ins_pipe(ialu_reg_reg_alu0); 8817 %} 8818 8819 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8820 rFlagsReg cr) 8821 %{ 8822 match(Set rax (DivL rax div)); 8823 effect(KILL rdx, KILL cr); 8824 8825 ins_cost(30*100+10*100); // XXX 8826 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8827 "cmpq rax, rdx\n\t" 8828 "jne,s normal\n\t" 8829 "xorl rdx, rdx\n\t" 8830 "cmpq $div, -1\n\t" 8831 "je,s done\n" 8832 "normal: cdqq\n\t" 8833 "idivq $div\n" 8834 "done:" %} 8835 ins_encode(cdqq_enc(div)); 8836 ins_pipe(ialu_reg_reg_alu0); 8837 %} 8838 8839 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8840 %{ 8841 match(Set rax (UDivI rax div)); 8842 effect(KILL rdx, KILL cr); 8843 8844 ins_cost(300); 8845 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8846 ins_encode %{ 8847 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8848 %} 8849 ins_pipe(ialu_reg_reg_alu0); 8850 %} 8851 8852 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8853 %{ 8854 match(Set rax (UDivL rax div)); 8855 effect(KILL rdx, KILL cr); 8856 8857 ins_cost(300); 8858 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8859 ins_encode %{ 8860 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8861 %} 8862 ins_pipe(ialu_reg_reg_alu0); 8863 %} 8864 8865 // Integer DIVMOD with Register, both quotient and mod results 8866 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8867 rFlagsReg cr) 8868 %{ 8869 match(DivModI rax div); 8870 effect(KILL cr); 8871 8872 ins_cost(30*100+10*100); // XXX 8873 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8874 "jne,s normal\n\t" 8875 "xorl rdx, rdx\n\t" 8876 "cmpl $div, -1\n\t" 8877 "je,s done\n" 8878 "normal: cdql\n\t" 8879 "idivl $div\n" 8880 "done:" %} 8881 ins_encode(cdql_enc(div)); 8882 ins_pipe(pipe_slow); 8883 %} 8884 8885 // Long DIVMOD with Register, both quotient and mod results 8886 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8887 rFlagsReg cr) 8888 %{ 8889 match(DivModL rax div); 8890 effect(KILL cr); 8891 8892 ins_cost(30*100+10*100); // XXX 8893 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8894 "cmpq rax, rdx\n\t" 8895 "jne,s normal\n\t" 8896 "xorl rdx, rdx\n\t" 8897 "cmpq $div, -1\n\t" 8898 "je,s done\n" 8899 "normal: cdqq\n\t" 8900 "idivq $div\n" 8901 "done:" %} 8902 ins_encode(cdqq_enc(div)); 8903 ins_pipe(pipe_slow); 8904 %} 8905 8906 // Unsigned integer DIVMOD with Register, both quotient and mod results 8907 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8908 no_rax_rdx_RegI div, rFlagsReg cr) 8909 %{ 8910 match(UDivModI rax div); 8911 effect(TEMP tmp, KILL cr); 8912 8913 ins_cost(300); 8914 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8915 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8916 %} 8917 ins_encode %{ 8918 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8919 %} 8920 ins_pipe(pipe_slow); 8921 %} 8922 8923 // Unsigned long DIVMOD with Register, both quotient and mod results 8924 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8925 no_rax_rdx_RegL div, rFlagsReg cr) 8926 %{ 8927 match(UDivModL rax div); 8928 effect(TEMP tmp, KILL cr); 8929 8930 ins_cost(300); 8931 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8932 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8933 %} 8934 ins_encode %{ 8935 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8936 %} 8937 ins_pipe(pipe_slow); 8938 %} 8939 8940 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8941 rFlagsReg cr) 8942 %{ 8943 match(Set rdx (ModI rax div)); 8944 effect(KILL rax, KILL cr); 8945 8946 ins_cost(300); // XXX 8947 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8948 "jne,s normal\n\t" 8949 "xorl rdx, rdx\n\t" 8950 "cmpl $div, -1\n\t" 8951 "je,s done\n" 8952 "normal: cdql\n\t" 8953 "idivl $div\n" 8954 "done:" %} 8955 ins_encode(cdql_enc(div)); 8956 ins_pipe(ialu_reg_reg_alu0); 8957 %} 8958 8959 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8960 rFlagsReg cr) 8961 %{ 8962 match(Set rdx (ModL rax div)); 8963 effect(KILL rax, KILL cr); 8964 8965 ins_cost(300); // XXX 8966 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8967 "cmpq rax, rdx\n\t" 8968 "jne,s normal\n\t" 8969 "xorl rdx, rdx\n\t" 8970 "cmpq $div, -1\n\t" 8971 "je,s done\n" 8972 "normal: cdqq\n\t" 8973 "idivq $div\n" 8974 "done:" %} 8975 ins_encode(cdqq_enc(div)); 8976 ins_pipe(ialu_reg_reg_alu0); 8977 %} 8978 8979 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8980 %{ 8981 match(Set rdx (UModI rax div)); 8982 effect(KILL rax, KILL cr); 8983 8984 ins_cost(300); 8985 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8986 ins_encode %{ 8987 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8988 %} 8989 ins_pipe(ialu_reg_reg_alu0); 8990 %} 8991 8992 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8993 %{ 8994 match(Set rdx (UModL rax div)); 8995 effect(KILL rax, KILL cr); 8996 8997 ins_cost(300); 8998 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8999 ins_encode %{ 9000 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 9001 %} 9002 ins_pipe(ialu_reg_reg_alu0); 9003 %} 9004 9005 // Integer Shift Instructions 9006 // Shift Left by one, two, three 9007 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 9008 %{ 9009 predicate(!UseAPX); 9010 match(Set dst (LShiftI dst shift)); 9011 effect(KILL cr); 9012 9013 format %{ "sall $dst, $shift" %} 9014 ins_encode %{ 9015 __ sall($dst$$Register, $shift$$constant); 9016 %} 9017 ins_pipe(ialu_reg); 9018 %} 9019 9020 // Shift Left by one, two, three 9021 instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr) 9022 %{ 9023 predicate(UseAPX); 9024 match(Set dst (LShiftI src shift)); 9025 effect(KILL cr); 9026 9027 format %{ "esall $dst, $src, $shift\t# int(ndd)" %} 9028 ins_encode %{ 9029 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9030 %} 9031 ins_pipe(ialu_reg); 9032 %} 9033 9034 // Shift Left by 8-bit immediate 9035 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9036 %{ 9037 predicate(!UseAPX); 9038 match(Set dst (LShiftI dst shift)); 9039 effect(KILL cr); 9040 9041 format %{ "sall $dst, $shift" %} 9042 ins_encode %{ 9043 __ sall($dst$$Register, $shift$$constant); 9044 %} 9045 ins_pipe(ialu_reg); 9046 %} 9047 9048 // Shift Left by 8-bit immediate 9049 instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9050 %{ 9051 predicate(UseAPX); 9052 match(Set dst (LShiftI src shift)); 9053 effect(KILL cr); 9054 9055 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9056 ins_encode %{ 9057 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9058 %} 9059 ins_pipe(ialu_reg); 9060 %} 9061 9062 instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9063 %{ 9064 predicate(UseAPX); 9065 match(Set dst (LShiftI (LoadI src) shift)); 9066 effect(KILL cr); 9067 9068 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9069 ins_encode %{ 9070 __ esall($dst$$Register, $src$$Address, $shift$$constant, false); 9071 %} 9072 ins_pipe(ialu_reg); 9073 %} 9074 9075 // Shift Left by 8-bit immediate 9076 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9077 %{ 9078 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9079 effect(KILL cr); 9080 9081 format %{ "sall $dst, $shift" %} 9082 ins_encode %{ 9083 __ sall($dst$$Address, $shift$$constant); 9084 %} 9085 ins_pipe(ialu_mem_imm); 9086 %} 9087 9088 // Shift Left by variable 9089 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9090 %{ 9091 predicate(!VM_Version::supports_bmi2()); 9092 match(Set dst (LShiftI dst shift)); 9093 effect(KILL cr); 9094 9095 format %{ "sall $dst, $shift" %} 9096 ins_encode %{ 9097 __ sall($dst$$Register); 9098 %} 9099 ins_pipe(ialu_reg_reg); 9100 %} 9101 9102 // Shift Left by variable 9103 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9104 %{ 9105 predicate(!VM_Version::supports_bmi2()); 9106 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9107 effect(KILL cr); 9108 9109 format %{ "sall $dst, $shift" %} 9110 ins_encode %{ 9111 __ sall($dst$$Address); 9112 %} 9113 ins_pipe(ialu_mem_reg); 9114 %} 9115 9116 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9117 %{ 9118 predicate(VM_Version::supports_bmi2()); 9119 match(Set dst (LShiftI src shift)); 9120 9121 format %{ "shlxl $dst, $src, $shift" %} 9122 ins_encode %{ 9123 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 9124 %} 9125 ins_pipe(ialu_reg_reg); 9126 %} 9127 9128 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 9129 %{ 9130 predicate(VM_Version::supports_bmi2()); 9131 match(Set dst (LShiftI (LoadI src) shift)); 9132 ins_cost(175); 9133 format %{ "shlxl $dst, $src, $shift" %} 9134 ins_encode %{ 9135 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 9136 %} 9137 ins_pipe(ialu_reg_mem); 9138 %} 9139 9140 // Arithmetic Shift Right by 8-bit immediate 9141 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9142 %{ 9143 predicate(!UseAPX); 9144 match(Set dst (RShiftI dst shift)); 9145 effect(KILL cr); 9146 9147 format %{ "sarl $dst, $shift" %} 9148 ins_encode %{ 9149 __ sarl($dst$$Register, $shift$$constant); 9150 %} 9151 ins_pipe(ialu_mem_imm); 9152 %} 9153 9154 // Arithmetic Shift Right by 8-bit immediate 9155 instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9156 %{ 9157 predicate(UseAPX); 9158 match(Set dst (RShiftI src shift)); 9159 effect(KILL cr); 9160 9161 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9162 ins_encode %{ 9163 __ esarl($dst$$Register, $src$$Register, $shift$$constant, false); 9164 %} 9165 ins_pipe(ialu_mem_imm); 9166 %} 9167 9168 instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9169 %{ 9170 predicate(UseAPX); 9171 match(Set dst (RShiftI (LoadI src) shift)); 9172 effect(KILL cr); 9173 9174 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9175 ins_encode %{ 9176 __ esarl($dst$$Register, $src$$Address, $shift$$constant, false); 9177 %} 9178 ins_pipe(ialu_mem_imm); 9179 %} 9180 9181 // Arithmetic Shift Right by 8-bit immediate 9182 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9183 %{ 9184 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9185 effect(KILL cr); 9186 9187 format %{ "sarl $dst, $shift" %} 9188 ins_encode %{ 9189 __ sarl($dst$$Address, $shift$$constant); 9190 %} 9191 ins_pipe(ialu_mem_imm); 9192 %} 9193 9194 // Arithmetic Shift Right by variable 9195 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9196 %{ 9197 predicate(!VM_Version::supports_bmi2()); 9198 match(Set dst (RShiftI dst shift)); 9199 effect(KILL cr); 9200 9201 format %{ "sarl $dst, $shift" %} 9202 ins_encode %{ 9203 __ sarl($dst$$Register); 9204 %} 9205 ins_pipe(ialu_reg_reg); 9206 %} 9207 9208 // Arithmetic Shift Right by variable 9209 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9210 %{ 9211 predicate(!VM_Version::supports_bmi2()); 9212 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9213 effect(KILL cr); 9214 9215 format %{ "sarl $dst, $shift" %} 9216 ins_encode %{ 9217 __ sarl($dst$$Address); 9218 %} 9219 ins_pipe(ialu_mem_reg); 9220 %} 9221 9222 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9223 %{ 9224 predicate(VM_Version::supports_bmi2()); 9225 match(Set dst (RShiftI src shift)); 9226 9227 format %{ "sarxl $dst, $src, $shift" %} 9228 ins_encode %{ 9229 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 9230 %} 9231 ins_pipe(ialu_reg_reg); 9232 %} 9233 9234 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 9235 %{ 9236 predicate(VM_Version::supports_bmi2()); 9237 match(Set dst (RShiftI (LoadI src) shift)); 9238 ins_cost(175); 9239 format %{ "sarxl $dst, $src, $shift" %} 9240 ins_encode %{ 9241 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 9242 %} 9243 ins_pipe(ialu_reg_mem); 9244 %} 9245 9246 // Logical Shift Right by 8-bit immediate 9247 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9248 %{ 9249 predicate(!UseAPX); 9250 match(Set dst (URShiftI dst shift)); 9251 effect(KILL cr); 9252 9253 format %{ "shrl $dst, $shift" %} 9254 ins_encode %{ 9255 __ shrl($dst$$Register, $shift$$constant); 9256 %} 9257 ins_pipe(ialu_reg); 9258 %} 9259 9260 // Logical Shift Right by 8-bit immediate 9261 instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9262 %{ 9263 predicate(UseAPX); 9264 match(Set dst (URShiftI src shift)); 9265 effect(KILL cr); 9266 9267 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9268 ins_encode %{ 9269 __ eshrl($dst$$Register, $src$$Register, $shift$$constant, false); 9270 %} 9271 ins_pipe(ialu_reg); 9272 %} 9273 9274 instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9275 %{ 9276 predicate(UseAPX); 9277 match(Set dst (URShiftI (LoadI src) shift)); 9278 effect(KILL cr); 9279 9280 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9281 ins_encode %{ 9282 __ eshrl($dst$$Register, $src$$Address, $shift$$constant, false); 9283 %} 9284 ins_pipe(ialu_reg); 9285 %} 9286 9287 // Logical Shift Right by 8-bit immediate 9288 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9289 %{ 9290 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9291 effect(KILL cr); 9292 9293 format %{ "shrl $dst, $shift" %} 9294 ins_encode %{ 9295 __ shrl($dst$$Address, $shift$$constant); 9296 %} 9297 ins_pipe(ialu_mem_imm); 9298 %} 9299 9300 // Logical Shift Right by variable 9301 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9302 %{ 9303 predicate(!VM_Version::supports_bmi2()); 9304 match(Set dst (URShiftI dst shift)); 9305 effect(KILL cr); 9306 9307 format %{ "shrl $dst, $shift" %} 9308 ins_encode %{ 9309 __ shrl($dst$$Register); 9310 %} 9311 ins_pipe(ialu_reg_reg); 9312 %} 9313 9314 // Logical Shift Right by variable 9315 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9316 %{ 9317 predicate(!VM_Version::supports_bmi2()); 9318 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9319 effect(KILL cr); 9320 9321 format %{ "shrl $dst, $shift" %} 9322 ins_encode %{ 9323 __ shrl($dst$$Address); 9324 %} 9325 ins_pipe(ialu_mem_reg); 9326 %} 9327 9328 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9329 %{ 9330 predicate(VM_Version::supports_bmi2()); 9331 match(Set dst (URShiftI src shift)); 9332 9333 format %{ "shrxl $dst, $src, $shift" %} 9334 ins_encode %{ 9335 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 9336 %} 9337 ins_pipe(ialu_reg_reg); 9338 %} 9339 9340 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 9341 %{ 9342 predicate(VM_Version::supports_bmi2()); 9343 match(Set dst (URShiftI (LoadI src) shift)); 9344 ins_cost(175); 9345 format %{ "shrxl $dst, $src, $shift" %} 9346 ins_encode %{ 9347 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 9348 %} 9349 ins_pipe(ialu_reg_mem); 9350 %} 9351 9352 // Long Shift Instructions 9353 // Shift Left by one, two, three 9354 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 9355 %{ 9356 predicate(!UseAPX); 9357 match(Set dst (LShiftL dst shift)); 9358 effect(KILL cr); 9359 9360 format %{ "salq $dst, $shift" %} 9361 ins_encode %{ 9362 __ salq($dst$$Register, $shift$$constant); 9363 %} 9364 ins_pipe(ialu_reg); 9365 %} 9366 9367 // Shift Left by one, two, three 9368 instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr) 9369 %{ 9370 predicate(UseAPX); 9371 match(Set dst (LShiftL src shift)); 9372 effect(KILL cr); 9373 9374 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9375 ins_encode %{ 9376 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9377 %} 9378 ins_pipe(ialu_reg); 9379 %} 9380 9381 // Shift Left by 8-bit immediate 9382 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9383 %{ 9384 predicate(!UseAPX); 9385 match(Set dst (LShiftL dst shift)); 9386 effect(KILL cr); 9387 9388 format %{ "salq $dst, $shift" %} 9389 ins_encode %{ 9390 __ salq($dst$$Register, $shift$$constant); 9391 %} 9392 ins_pipe(ialu_reg); 9393 %} 9394 9395 // Shift Left by 8-bit immediate 9396 instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9397 %{ 9398 predicate(UseAPX); 9399 match(Set dst (LShiftL src shift)); 9400 effect(KILL cr); 9401 9402 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9403 ins_encode %{ 9404 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9405 %} 9406 ins_pipe(ialu_reg); 9407 %} 9408 9409 instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9410 %{ 9411 predicate(UseAPX); 9412 match(Set dst (LShiftL (LoadL src) shift)); 9413 effect(KILL cr); 9414 9415 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9416 ins_encode %{ 9417 __ esalq($dst$$Register, $src$$Address, $shift$$constant, false); 9418 %} 9419 ins_pipe(ialu_reg); 9420 %} 9421 9422 // Shift Left by 8-bit immediate 9423 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9424 %{ 9425 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9426 effect(KILL cr); 9427 9428 format %{ "salq $dst, $shift" %} 9429 ins_encode %{ 9430 __ salq($dst$$Address, $shift$$constant); 9431 %} 9432 ins_pipe(ialu_mem_imm); 9433 %} 9434 9435 // Shift Left by variable 9436 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9437 %{ 9438 predicate(!VM_Version::supports_bmi2()); 9439 match(Set dst (LShiftL dst shift)); 9440 effect(KILL cr); 9441 9442 format %{ "salq $dst, $shift" %} 9443 ins_encode %{ 9444 __ salq($dst$$Register); 9445 %} 9446 ins_pipe(ialu_reg_reg); 9447 %} 9448 9449 // Shift Left by variable 9450 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9451 %{ 9452 predicate(!VM_Version::supports_bmi2()); 9453 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9454 effect(KILL cr); 9455 9456 format %{ "salq $dst, $shift" %} 9457 ins_encode %{ 9458 __ salq($dst$$Address); 9459 %} 9460 ins_pipe(ialu_mem_reg); 9461 %} 9462 9463 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9464 %{ 9465 predicate(VM_Version::supports_bmi2()); 9466 match(Set dst (LShiftL src shift)); 9467 9468 format %{ "shlxq $dst, $src, $shift" %} 9469 ins_encode %{ 9470 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 9471 %} 9472 ins_pipe(ialu_reg_reg); 9473 %} 9474 9475 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 9476 %{ 9477 predicate(VM_Version::supports_bmi2()); 9478 match(Set dst (LShiftL (LoadL src) shift)); 9479 ins_cost(175); 9480 format %{ "shlxq $dst, $src, $shift" %} 9481 ins_encode %{ 9482 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 9483 %} 9484 ins_pipe(ialu_reg_mem); 9485 %} 9486 9487 // Arithmetic Shift Right by 8-bit immediate 9488 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 9489 %{ 9490 predicate(!UseAPX); 9491 match(Set dst (RShiftL dst shift)); 9492 effect(KILL cr); 9493 9494 format %{ "sarq $dst, $shift" %} 9495 ins_encode %{ 9496 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 9497 %} 9498 ins_pipe(ialu_mem_imm); 9499 %} 9500 9501 // Arithmetic Shift Right by 8-bit immediate 9502 instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr) 9503 %{ 9504 predicate(UseAPX); 9505 match(Set dst (RShiftL src shift)); 9506 effect(KILL cr); 9507 9508 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9509 ins_encode %{ 9510 __ esarq($dst$$Register, $src$$Register, (unsigned char)($shift$$constant & 0x3F), false); 9511 %} 9512 ins_pipe(ialu_mem_imm); 9513 %} 9514 9515 instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr) 9516 %{ 9517 predicate(UseAPX); 9518 match(Set dst (RShiftL (LoadL src) shift)); 9519 effect(KILL cr); 9520 9521 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9522 ins_encode %{ 9523 __ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false); 9524 %} 9525 ins_pipe(ialu_mem_imm); 9526 %} 9527 9528 // Arithmetic Shift Right by 8-bit immediate 9529 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 9530 %{ 9531 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9532 effect(KILL cr); 9533 9534 format %{ "sarq $dst, $shift" %} 9535 ins_encode %{ 9536 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 9537 %} 9538 ins_pipe(ialu_mem_imm); 9539 %} 9540 9541 // Arithmetic Shift Right by variable 9542 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9543 %{ 9544 predicate(!VM_Version::supports_bmi2()); 9545 match(Set dst (RShiftL dst shift)); 9546 effect(KILL cr); 9547 9548 format %{ "sarq $dst, $shift" %} 9549 ins_encode %{ 9550 __ sarq($dst$$Register); 9551 %} 9552 ins_pipe(ialu_reg_reg); 9553 %} 9554 9555 // Arithmetic Shift Right by variable 9556 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9557 %{ 9558 predicate(!VM_Version::supports_bmi2()); 9559 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9560 effect(KILL cr); 9561 9562 format %{ "sarq $dst, $shift" %} 9563 ins_encode %{ 9564 __ sarq($dst$$Address); 9565 %} 9566 ins_pipe(ialu_mem_reg); 9567 %} 9568 9569 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9570 %{ 9571 predicate(VM_Version::supports_bmi2()); 9572 match(Set dst (RShiftL src shift)); 9573 9574 format %{ "sarxq $dst, $src, $shift" %} 9575 ins_encode %{ 9576 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 9577 %} 9578 ins_pipe(ialu_reg_reg); 9579 %} 9580 9581 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 9582 %{ 9583 predicate(VM_Version::supports_bmi2()); 9584 match(Set dst (RShiftL (LoadL src) shift)); 9585 ins_cost(175); 9586 format %{ "sarxq $dst, $src, $shift" %} 9587 ins_encode %{ 9588 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 9589 %} 9590 ins_pipe(ialu_reg_mem); 9591 %} 9592 9593 // Logical Shift Right by 8-bit immediate 9594 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9595 %{ 9596 predicate(!UseAPX); 9597 match(Set dst (URShiftL dst shift)); 9598 effect(KILL cr); 9599 9600 format %{ "shrq $dst, $shift" %} 9601 ins_encode %{ 9602 __ shrq($dst$$Register, $shift$$constant); 9603 %} 9604 ins_pipe(ialu_reg); 9605 %} 9606 9607 // Logical Shift Right by 8-bit immediate 9608 instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9609 %{ 9610 predicate(UseAPX); 9611 match(Set dst (URShiftL src shift)); 9612 effect(KILL cr); 9613 9614 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9615 ins_encode %{ 9616 __ eshrq($dst$$Register, $src$$Register, $shift$$constant, false); 9617 %} 9618 ins_pipe(ialu_reg); 9619 %} 9620 9621 instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9622 %{ 9623 predicate(UseAPX); 9624 match(Set dst (URShiftL (LoadL src) shift)); 9625 effect(KILL cr); 9626 9627 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9628 ins_encode %{ 9629 __ eshrq($dst$$Register, $src$$Address, $shift$$constant, false); 9630 %} 9631 ins_pipe(ialu_reg); 9632 %} 9633 9634 // Logical Shift Right by 8-bit immediate 9635 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9636 %{ 9637 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9638 effect(KILL cr); 9639 9640 format %{ "shrq $dst, $shift" %} 9641 ins_encode %{ 9642 __ shrq($dst$$Address, $shift$$constant); 9643 %} 9644 ins_pipe(ialu_mem_imm); 9645 %} 9646 9647 // Logical Shift Right by variable 9648 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9649 %{ 9650 predicate(!VM_Version::supports_bmi2()); 9651 match(Set dst (URShiftL dst shift)); 9652 effect(KILL cr); 9653 9654 format %{ "shrq $dst, $shift" %} 9655 ins_encode %{ 9656 __ shrq($dst$$Register); 9657 %} 9658 ins_pipe(ialu_reg_reg); 9659 %} 9660 9661 // Logical Shift Right by variable 9662 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9663 %{ 9664 predicate(!VM_Version::supports_bmi2()); 9665 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9666 effect(KILL cr); 9667 9668 format %{ "shrq $dst, $shift" %} 9669 ins_encode %{ 9670 __ shrq($dst$$Address); 9671 %} 9672 ins_pipe(ialu_mem_reg); 9673 %} 9674 9675 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9676 %{ 9677 predicate(VM_Version::supports_bmi2()); 9678 match(Set dst (URShiftL src shift)); 9679 9680 format %{ "shrxq $dst, $src, $shift" %} 9681 ins_encode %{ 9682 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 9683 %} 9684 ins_pipe(ialu_reg_reg); 9685 %} 9686 9687 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 9688 %{ 9689 predicate(VM_Version::supports_bmi2()); 9690 match(Set dst (URShiftL (LoadL src) shift)); 9691 ins_cost(175); 9692 format %{ "shrxq $dst, $src, $shift" %} 9693 ins_encode %{ 9694 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 9695 %} 9696 ins_pipe(ialu_reg_mem); 9697 %} 9698 9699 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9700 // This idiom is used by the compiler for the i2b bytecode. 9701 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9702 %{ 9703 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9704 9705 format %{ "movsbl $dst, $src\t# i2b" %} 9706 ins_encode %{ 9707 __ movsbl($dst$$Register, $src$$Register); 9708 %} 9709 ins_pipe(ialu_reg_reg); 9710 %} 9711 9712 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9713 // This idiom is used by the compiler the i2s bytecode. 9714 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9715 %{ 9716 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9717 9718 format %{ "movswl $dst, $src\t# i2s" %} 9719 ins_encode %{ 9720 __ movswl($dst$$Register, $src$$Register); 9721 %} 9722 ins_pipe(ialu_reg_reg); 9723 %} 9724 9725 // ROL/ROR instructions 9726 9727 // Rotate left by constant. 9728 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9729 %{ 9730 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9731 match(Set dst (RotateLeft dst shift)); 9732 effect(KILL cr); 9733 format %{ "roll $dst, $shift" %} 9734 ins_encode %{ 9735 __ roll($dst$$Register, $shift$$constant); 9736 %} 9737 ins_pipe(ialu_reg); 9738 %} 9739 9740 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 9741 %{ 9742 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9743 match(Set dst (RotateLeft src shift)); 9744 format %{ "rolxl $dst, $src, $shift" %} 9745 ins_encode %{ 9746 int shift = 32 - ($shift$$constant & 31); 9747 __ rorxl($dst$$Register, $src$$Register, shift); 9748 %} 9749 ins_pipe(ialu_reg_reg); 9750 %} 9751 9752 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 9753 %{ 9754 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9755 match(Set dst (RotateLeft (LoadI src) shift)); 9756 ins_cost(175); 9757 format %{ "rolxl $dst, $src, $shift" %} 9758 ins_encode %{ 9759 int shift = 32 - ($shift$$constant & 31); 9760 __ rorxl($dst$$Register, $src$$Address, shift); 9761 %} 9762 ins_pipe(ialu_reg_mem); 9763 %} 9764 9765 // Rotate Left by variable 9766 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9767 %{ 9768 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9769 match(Set dst (RotateLeft dst shift)); 9770 effect(KILL cr); 9771 format %{ "roll $dst, $shift" %} 9772 ins_encode %{ 9773 __ roll($dst$$Register); 9774 %} 9775 ins_pipe(ialu_reg_reg); 9776 %} 9777 9778 // Rotate Left by variable 9779 instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9780 %{ 9781 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9782 match(Set dst (RotateLeft src shift)); 9783 effect(KILL cr); 9784 9785 format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %} 9786 ins_encode %{ 9787 __ eroll($dst$$Register, $src$$Register, false); 9788 %} 9789 ins_pipe(ialu_reg_reg); 9790 %} 9791 9792 // Rotate Right by constant. 9793 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9794 %{ 9795 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9796 match(Set dst (RotateRight dst shift)); 9797 effect(KILL cr); 9798 format %{ "rorl $dst, $shift" %} 9799 ins_encode %{ 9800 __ rorl($dst$$Register, $shift$$constant); 9801 %} 9802 ins_pipe(ialu_reg); 9803 %} 9804 9805 // Rotate Right by constant. 9806 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 9807 %{ 9808 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9809 match(Set dst (RotateRight src shift)); 9810 format %{ "rorxl $dst, $src, $shift" %} 9811 ins_encode %{ 9812 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 9813 %} 9814 ins_pipe(ialu_reg_reg); 9815 %} 9816 9817 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 9818 %{ 9819 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9820 match(Set dst (RotateRight (LoadI src) shift)); 9821 ins_cost(175); 9822 format %{ "rorxl $dst, $src, $shift" %} 9823 ins_encode %{ 9824 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 9825 %} 9826 ins_pipe(ialu_reg_mem); 9827 %} 9828 9829 // Rotate Right by variable 9830 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9831 %{ 9832 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9833 match(Set dst (RotateRight dst shift)); 9834 effect(KILL cr); 9835 format %{ "rorl $dst, $shift" %} 9836 ins_encode %{ 9837 __ rorl($dst$$Register); 9838 %} 9839 ins_pipe(ialu_reg_reg); 9840 %} 9841 9842 // Rotate Right by variable 9843 instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9844 %{ 9845 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9846 match(Set dst (RotateRight src shift)); 9847 effect(KILL cr); 9848 9849 format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %} 9850 ins_encode %{ 9851 __ erorl($dst$$Register, $src$$Register, false); 9852 %} 9853 ins_pipe(ialu_reg_reg); 9854 %} 9855 9856 // Rotate Left by constant. 9857 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9858 %{ 9859 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9860 match(Set dst (RotateLeft dst shift)); 9861 effect(KILL cr); 9862 format %{ "rolq $dst, $shift" %} 9863 ins_encode %{ 9864 __ rolq($dst$$Register, $shift$$constant); 9865 %} 9866 ins_pipe(ialu_reg); 9867 %} 9868 9869 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 9870 %{ 9871 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9872 match(Set dst (RotateLeft src shift)); 9873 format %{ "rolxq $dst, $src, $shift" %} 9874 ins_encode %{ 9875 int shift = 64 - ($shift$$constant & 63); 9876 __ rorxq($dst$$Register, $src$$Register, shift); 9877 %} 9878 ins_pipe(ialu_reg_reg); 9879 %} 9880 9881 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 9882 %{ 9883 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9884 match(Set dst (RotateLeft (LoadL src) shift)); 9885 ins_cost(175); 9886 format %{ "rolxq $dst, $src, $shift" %} 9887 ins_encode %{ 9888 int shift = 64 - ($shift$$constant & 63); 9889 __ rorxq($dst$$Register, $src$$Address, shift); 9890 %} 9891 ins_pipe(ialu_reg_mem); 9892 %} 9893 9894 // Rotate Left by variable 9895 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9896 %{ 9897 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9898 match(Set dst (RotateLeft dst shift)); 9899 effect(KILL cr); 9900 format %{ "rolq $dst, $shift" %} 9901 ins_encode %{ 9902 __ rolq($dst$$Register); 9903 %} 9904 ins_pipe(ialu_reg_reg); 9905 %} 9906 9907 // Rotate Left by variable 9908 instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9909 %{ 9910 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9911 match(Set dst (RotateLeft src shift)); 9912 effect(KILL cr); 9913 9914 format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %} 9915 ins_encode %{ 9916 __ erolq($dst$$Register, $src$$Register, false); 9917 %} 9918 ins_pipe(ialu_reg_reg); 9919 %} 9920 9921 // Rotate Right by constant. 9922 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9923 %{ 9924 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9925 match(Set dst (RotateRight dst shift)); 9926 effect(KILL cr); 9927 format %{ "rorq $dst, $shift" %} 9928 ins_encode %{ 9929 __ rorq($dst$$Register, $shift$$constant); 9930 %} 9931 ins_pipe(ialu_reg); 9932 %} 9933 9934 // Rotate Right by constant 9935 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 9936 %{ 9937 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9938 match(Set dst (RotateRight src shift)); 9939 format %{ "rorxq $dst, $src, $shift" %} 9940 ins_encode %{ 9941 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 9942 %} 9943 ins_pipe(ialu_reg_reg); 9944 %} 9945 9946 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 9947 %{ 9948 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9949 match(Set dst (RotateRight (LoadL src) shift)); 9950 ins_cost(175); 9951 format %{ "rorxq $dst, $src, $shift" %} 9952 ins_encode %{ 9953 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 9954 %} 9955 ins_pipe(ialu_reg_mem); 9956 %} 9957 9958 // Rotate Right by variable 9959 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9960 %{ 9961 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9962 match(Set dst (RotateRight dst shift)); 9963 effect(KILL cr); 9964 format %{ "rorq $dst, $shift" %} 9965 ins_encode %{ 9966 __ rorq($dst$$Register); 9967 %} 9968 ins_pipe(ialu_reg_reg); 9969 %} 9970 9971 // Rotate Right by variable 9972 instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9973 %{ 9974 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9975 match(Set dst (RotateRight src shift)); 9976 effect(KILL cr); 9977 9978 format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %} 9979 ins_encode %{ 9980 __ erorq($dst$$Register, $src$$Register, false); 9981 %} 9982 ins_pipe(ialu_reg_reg); 9983 %} 9984 9985 //----------------------------- CompressBits/ExpandBits ------------------------ 9986 9987 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 9988 predicate(n->bottom_type()->isa_long()); 9989 match(Set dst (CompressBits src mask)); 9990 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 9991 ins_encode %{ 9992 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 9993 %} 9994 ins_pipe( pipe_slow ); 9995 %} 9996 9997 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 9998 predicate(n->bottom_type()->isa_long()); 9999 match(Set dst (ExpandBits src mask)); 10000 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10001 ins_encode %{ 10002 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 10003 %} 10004 ins_pipe( pipe_slow ); 10005 %} 10006 10007 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10008 predicate(n->bottom_type()->isa_long()); 10009 match(Set dst (CompressBits src (LoadL mask))); 10010 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10011 ins_encode %{ 10012 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 10013 %} 10014 ins_pipe( pipe_slow ); 10015 %} 10016 10017 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10018 predicate(n->bottom_type()->isa_long()); 10019 match(Set dst (ExpandBits src (LoadL mask))); 10020 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10021 ins_encode %{ 10022 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 10023 %} 10024 ins_pipe( pipe_slow ); 10025 %} 10026 10027 10028 // Logical Instructions 10029 10030 // Integer Logical Instructions 10031 10032 // And Instructions 10033 // And Register with Register 10034 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10035 %{ 10036 predicate(!UseAPX); 10037 match(Set dst (AndI dst src)); 10038 effect(KILL cr); 10039 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); 10040 10041 format %{ "andl $dst, $src\t# int" %} 10042 ins_encode %{ 10043 __ andl($dst$$Register, $src$$Register); 10044 %} 10045 ins_pipe(ialu_reg_reg); 10046 %} 10047 10048 // And Register with Register using New Data Destination (NDD) 10049 instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10050 %{ 10051 predicate(UseAPX); 10052 match(Set dst (AndI src1 src2)); 10053 effect(KILL cr); 10054 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); 10055 10056 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10057 ins_encode %{ 10058 __ eandl($dst$$Register, $src1$$Register, $src2$$Register, false); 10059 10060 %} 10061 ins_pipe(ialu_reg_reg); 10062 %} 10063 10064 // And Register with Immediate 255 10065 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 10066 %{ 10067 match(Set dst (AndI src mask)); 10068 10069 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 10070 ins_encode %{ 10071 __ movzbl($dst$$Register, $src$$Register); 10072 %} 10073 ins_pipe(ialu_reg); 10074 %} 10075 10076 // And Register with Immediate 255 and promote to long 10077 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 10078 %{ 10079 match(Set dst (ConvI2L (AndI src mask))); 10080 10081 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 10082 ins_encode %{ 10083 __ movzbl($dst$$Register, $src$$Register); 10084 %} 10085 ins_pipe(ialu_reg); 10086 %} 10087 10088 // And Register with Immediate 65535 10089 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 10090 %{ 10091 match(Set dst (AndI src mask)); 10092 10093 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 10094 ins_encode %{ 10095 __ movzwl($dst$$Register, $src$$Register); 10096 %} 10097 ins_pipe(ialu_reg); 10098 %} 10099 10100 // And Register with Immediate 65535 and promote to long 10101 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 10102 %{ 10103 match(Set dst (ConvI2L (AndI src mask))); 10104 10105 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 10106 ins_encode %{ 10107 __ movzwl($dst$$Register, $src$$Register); 10108 %} 10109 ins_pipe(ialu_reg); 10110 %} 10111 10112 // Can skip int2long conversions after AND with small bitmask 10113 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 10114 %{ 10115 predicate(VM_Version::supports_bmi2()); 10116 ins_cost(125); 10117 effect(TEMP tmp, KILL cr); 10118 match(Set dst (ConvI2L (AndI src mask))); 10119 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 10120 ins_encode %{ 10121 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 10122 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 10123 %} 10124 ins_pipe(ialu_reg_reg); 10125 %} 10126 10127 // And Register with Immediate 10128 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10129 %{ 10130 predicate(!UseAPX); 10131 match(Set dst (AndI dst src)); 10132 effect(KILL cr); 10133 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); 10134 10135 format %{ "andl $dst, $src\t# int" %} 10136 ins_encode %{ 10137 __ andl($dst$$Register, $src$$constant); 10138 %} 10139 ins_pipe(ialu_reg); 10140 %} 10141 10142 instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10143 %{ 10144 predicate(UseAPX); 10145 match(Set dst (AndI src1 src2)); 10146 effect(KILL cr); 10147 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); 10148 10149 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10150 ins_encode %{ 10151 __ eandl($dst$$Register, $src1$$Register, $src2$$constant, false); 10152 %} 10153 ins_pipe(ialu_reg); 10154 %} 10155 10156 instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10157 %{ 10158 predicate(UseAPX); 10159 match(Set dst (AndI (LoadI src1) src2)); 10160 effect(KILL cr); 10161 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); 10162 10163 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10164 ins_encode %{ 10165 __ eandl($dst$$Register, $src1$$Address, $src2$$constant, false); 10166 %} 10167 ins_pipe(ialu_reg); 10168 %} 10169 10170 // And Register with Memory 10171 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10172 %{ 10173 predicate(!UseAPX); 10174 match(Set dst (AndI dst (LoadI src))); 10175 effect(KILL cr); 10176 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); 10177 10178 ins_cost(150); 10179 format %{ "andl $dst, $src\t# int" %} 10180 ins_encode %{ 10181 __ andl($dst$$Register, $src$$Address); 10182 %} 10183 ins_pipe(ialu_reg_mem); 10184 %} 10185 10186 instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10187 %{ 10188 predicate(UseAPX); 10189 match(Set dst (AndI src1 (LoadI src2))); 10190 effect(KILL cr); 10191 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); 10192 10193 ins_cost(150); 10194 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10195 ins_encode %{ 10196 __ eandl($dst$$Register, $src1$$Register, $src2$$Address, false); 10197 %} 10198 ins_pipe(ialu_reg_mem); 10199 %} 10200 10201 // And Memory with Register 10202 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10203 %{ 10204 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 10205 effect(KILL cr); 10206 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); 10207 10208 ins_cost(150); 10209 format %{ "andb $dst, $src\t# byte" %} 10210 ins_encode %{ 10211 __ andb($dst$$Address, $src$$Register); 10212 %} 10213 ins_pipe(ialu_mem_reg); 10214 %} 10215 10216 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10217 %{ 10218 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10219 effect(KILL cr); 10220 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); 10221 10222 ins_cost(150); 10223 format %{ "andl $dst, $src\t# int" %} 10224 ins_encode %{ 10225 __ andl($dst$$Address, $src$$Register); 10226 %} 10227 ins_pipe(ialu_mem_reg); 10228 %} 10229 10230 // And Memory with Immediate 10231 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 10232 %{ 10233 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10234 effect(KILL cr); 10235 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); 10236 10237 ins_cost(125); 10238 format %{ "andl $dst, $src\t# int" %} 10239 ins_encode %{ 10240 __ andl($dst$$Address, $src$$constant); 10241 %} 10242 ins_pipe(ialu_mem_imm); 10243 %} 10244 10245 // BMI1 instructions 10246 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 10247 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 10248 predicate(UseBMI1Instructions); 10249 effect(KILL cr); 10250 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10251 10252 ins_cost(125); 10253 format %{ "andnl $dst, $src1, $src2" %} 10254 10255 ins_encode %{ 10256 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 10257 %} 10258 ins_pipe(ialu_reg_mem); 10259 %} 10260 10261 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 10262 match(Set dst (AndI (XorI src1 minus_1) src2)); 10263 predicate(UseBMI1Instructions); 10264 effect(KILL cr); 10265 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10266 10267 format %{ "andnl $dst, $src1, $src2" %} 10268 10269 ins_encode %{ 10270 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 10271 %} 10272 ins_pipe(ialu_reg); 10273 %} 10274 10275 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 10276 match(Set dst (AndI (SubI imm_zero src) src)); 10277 predicate(UseBMI1Instructions); 10278 effect(KILL cr); 10279 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10280 10281 format %{ "blsil $dst, $src" %} 10282 10283 ins_encode %{ 10284 __ blsil($dst$$Register, $src$$Register); 10285 %} 10286 ins_pipe(ialu_reg); 10287 %} 10288 10289 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 10290 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 10291 predicate(UseBMI1Instructions); 10292 effect(KILL cr); 10293 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10294 10295 ins_cost(125); 10296 format %{ "blsil $dst, $src" %} 10297 10298 ins_encode %{ 10299 __ blsil($dst$$Register, $src$$Address); 10300 %} 10301 ins_pipe(ialu_reg_mem); 10302 %} 10303 10304 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10305 %{ 10306 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10307 predicate(UseBMI1Instructions); 10308 effect(KILL cr); 10309 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10310 10311 ins_cost(125); 10312 format %{ "blsmskl $dst, $src" %} 10313 10314 ins_encode %{ 10315 __ blsmskl($dst$$Register, $src$$Address); 10316 %} 10317 ins_pipe(ialu_reg_mem); 10318 %} 10319 10320 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10321 %{ 10322 match(Set dst (XorI (AddI src minus_1) src)); 10323 predicate(UseBMI1Instructions); 10324 effect(KILL cr); 10325 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10326 10327 format %{ "blsmskl $dst, $src" %} 10328 10329 ins_encode %{ 10330 __ blsmskl($dst$$Register, $src$$Register); 10331 %} 10332 10333 ins_pipe(ialu_reg); 10334 %} 10335 10336 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10337 %{ 10338 match(Set dst (AndI (AddI src minus_1) src) ); 10339 predicate(UseBMI1Instructions); 10340 effect(KILL cr); 10341 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10342 10343 format %{ "blsrl $dst, $src" %} 10344 10345 ins_encode %{ 10346 __ blsrl($dst$$Register, $src$$Register); 10347 %} 10348 10349 ins_pipe(ialu_reg_mem); 10350 %} 10351 10352 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10353 %{ 10354 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10355 predicate(UseBMI1Instructions); 10356 effect(KILL cr); 10357 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10358 10359 ins_cost(125); 10360 format %{ "blsrl $dst, $src" %} 10361 10362 ins_encode %{ 10363 __ blsrl($dst$$Register, $src$$Address); 10364 %} 10365 10366 ins_pipe(ialu_reg); 10367 %} 10368 10369 // Or Instructions 10370 // Or Register with Register 10371 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10372 %{ 10373 predicate(!UseAPX); 10374 match(Set dst (OrI dst src)); 10375 effect(KILL cr); 10376 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); 10377 10378 format %{ "orl $dst, $src\t# int" %} 10379 ins_encode %{ 10380 __ orl($dst$$Register, $src$$Register); 10381 %} 10382 ins_pipe(ialu_reg_reg); 10383 %} 10384 10385 // Or Register with Register using New Data Destination (NDD) 10386 instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10387 %{ 10388 predicate(UseAPX); 10389 match(Set dst (OrI src1 src2)); 10390 effect(KILL cr); 10391 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); 10392 10393 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10394 ins_encode %{ 10395 __ eorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10396 %} 10397 ins_pipe(ialu_reg_reg); 10398 %} 10399 10400 // Or Register with Immediate 10401 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10402 %{ 10403 predicate(!UseAPX); 10404 match(Set dst (OrI dst src)); 10405 effect(KILL cr); 10406 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); 10407 10408 format %{ "orl $dst, $src\t# int" %} 10409 ins_encode %{ 10410 __ orl($dst$$Register, $src$$constant); 10411 %} 10412 ins_pipe(ialu_reg); 10413 %} 10414 10415 instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10416 %{ 10417 predicate(UseAPX); 10418 match(Set dst (OrI src1 src2)); 10419 effect(KILL cr); 10420 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); 10421 10422 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10423 ins_encode %{ 10424 __ eorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10425 %} 10426 ins_pipe(ialu_reg); 10427 %} 10428 10429 instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr) 10430 %{ 10431 predicate(UseAPX); 10432 match(Set dst (OrI src1 src2)); 10433 effect(KILL cr); 10434 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); 10435 10436 format %{ "eorl $dst, $src2, $src1\t# int ndd" %} 10437 ins_encode %{ 10438 __ eorl($dst$$Register, $src2$$Register, $src1$$constant, false); 10439 %} 10440 ins_pipe(ialu_reg); 10441 %} 10442 10443 instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10444 %{ 10445 predicate(UseAPX); 10446 match(Set dst (OrI (LoadI src1) src2)); 10447 effect(KILL cr); 10448 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); 10449 10450 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10451 ins_encode %{ 10452 __ eorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10453 %} 10454 ins_pipe(ialu_reg); 10455 %} 10456 10457 // Or Register with Memory 10458 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10459 %{ 10460 predicate(!UseAPX); 10461 match(Set dst (OrI dst (LoadI src))); 10462 effect(KILL cr); 10463 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); 10464 10465 ins_cost(150); 10466 format %{ "orl $dst, $src\t# int" %} 10467 ins_encode %{ 10468 __ orl($dst$$Register, $src$$Address); 10469 %} 10470 ins_pipe(ialu_reg_mem); 10471 %} 10472 10473 instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10474 %{ 10475 predicate(UseAPX); 10476 match(Set dst (OrI src1 (LoadI src2))); 10477 effect(KILL cr); 10478 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); 10479 10480 ins_cost(150); 10481 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10482 ins_encode %{ 10483 __ eorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10484 %} 10485 ins_pipe(ialu_reg_mem); 10486 %} 10487 10488 // Or Memory with Register 10489 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10490 %{ 10491 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 10492 effect(KILL cr); 10493 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); 10494 10495 ins_cost(150); 10496 format %{ "orb $dst, $src\t# byte" %} 10497 ins_encode %{ 10498 __ orb($dst$$Address, $src$$Register); 10499 %} 10500 ins_pipe(ialu_mem_reg); 10501 %} 10502 10503 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10504 %{ 10505 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10506 effect(KILL cr); 10507 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); 10508 10509 ins_cost(150); 10510 format %{ "orl $dst, $src\t# int" %} 10511 ins_encode %{ 10512 __ orl($dst$$Address, $src$$Register); 10513 %} 10514 ins_pipe(ialu_mem_reg); 10515 %} 10516 10517 // Or Memory with Immediate 10518 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 10519 %{ 10520 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10521 effect(KILL cr); 10522 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); 10523 10524 ins_cost(125); 10525 format %{ "orl $dst, $src\t# int" %} 10526 ins_encode %{ 10527 __ orl($dst$$Address, $src$$constant); 10528 %} 10529 ins_pipe(ialu_mem_imm); 10530 %} 10531 10532 // Xor Instructions 10533 // Xor Register with Register 10534 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10535 %{ 10536 predicate(!UseAPX); 10537 match(Set dst (XorI dst src)); 10538 effect(KILL cr); 10539 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); 10540 10541 format %{ "xorl $dst, $src\t# int" %} 10542 ins_encode %{ 10543 __ xorl($dst$$Register, $src$$Register); 10544 %} 10545 ins_pipe(ialu_reg_reg); 10546 %} 10547 10548 // Xor Register with Register using New Data Destination (NDD) 10549 instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10550 %{ 10551 predicate(UseAPX); 10552 match(Set dst (XorI src1 src2)); 10553 effect(KILL cr); 10554 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); 10555 10556 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10557 ins_encode %{ 10558 __ exorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10559 %} 10560 ins_pipe(ialu_reg_reg); 10561 %} 10562 10563 // Xor Register with Immediate -1 10564 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) 10565 %{ 10566 predicate(!UseAPX); 10567 match(Set dst (XorI dst imm)); 10568 10569 format %{ "notl $dst" %} 10570 ins_encode %{ 10571 __ notl($dst$$Register); 10572 %} 10573 ins_pipe(ialu_reg); 10574 %} 10575 10576 instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm) 10577 %{ 10578 match(Set dst (XorI src imm)); 10579 predicate(UseAPX); 10580 10581 format %{ "enotl $dst, $src" %} 10582 ins_encode %{ 10583 __ enotl($dst$$Register, $src$$Register); 10584 %} 10585 ins_pipe(ialu_reg); 10586 %} 10587 10588 // Xor Register with Immediate 10589 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10590 %{ 10591 predicate(!UseAPX); 10592 match(Set dst (XorI dst src)); 10593 effect(KILL cr); 10594 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); 10595 10596 format %{ "xorl $dst, $src\t# int" %} 10597 ins_encode %{ 10598 __ xorl($dst$$Register, $src$$constant); 10599 %} 10600 ins_pipe(ialu_reg); 10601 %} 10602 10603 instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10604 %{ 10605 predicate(UseAPX); 10606 match(Set dst (XorI src1 src2)); 10607 effect(KILL cr); 10608 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); 10609 10610 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10611 ins_encode %{ 10612 __ exorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10613 %} 10614 ins_pipe(ialu_reg); 10615 %} 10616 10617 // Xor Memory with Immediate 10618 instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10619 %{ 10620 predicate(UseAPX); 10621 match(Set dst (XorI (LoadI src1) src2)); 10622 effect(KILL cr); 10623 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); 10624 10625 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10626 ins_encode %{ 10627 __ exorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10628 %} 10629 ins_pipe(ialu_reg); 10630 %} 10631 10632 // Xor Register with Memory 10633 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10634 %{ 10635 predicate(!UseAPX); 10636 match(Set dst (XorI dst (LoadI src))); 10637 effect(KILL cr); 10638 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); 10639 10640 ins_cost(150); 10641 format %{ "xorl $dst, $src\t# int" %} 10642 ins_encode %{ 10643 __ xorl($dst$$Register, $src$$Address); 10644 %} 10645 ins_pipe(ialu_reg_mem); 10646 %} 10647 10648 instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10649 %{ 10650 predicate(UseAPX); 10651 match(Set dst (XorI src1 (LoadI src2))); 10652 effect(KILL cr); 10653 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); 10654 10655 ins_cost(150); 10656 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10657 ins_encode %{ 10658 __ exorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10659 %} 10660 ins_pipe(ialu_reg_mem); 10661 %} 10662 10663 instruct xorI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 10664 %{ 10665 predicate(UseAPX); 10666 match(Set dst (XorI (LoadI src1) src2)); 10667 effect(KILL cr); 10668 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); 10669 10670 ins_cost(150); 10671 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10672 ins_encode %{ 10673 __ exorl($dst$$Register, $src1$$Address, $src2$$Register, false); 10674 %} 10675 ins_pipe(ialu_reg_mem); 10676 %} 10677 10678 // Xor Memory with Register 10679 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10680 %{ 10681 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 10682 effect(KILL cr); 10683 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); 10684 10685 ins_cost(150); 10686 format %{ "xorb $dst, $src\t# byte" %} 10687 ins_encode %{ 10688 __ xorb($dst$$Address, $src$$Register); 10689 %} 10690 ins_pipe(ialu_mem_reg); 10691 %} 10692 10693 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10694 %{ 10695 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10696 effect(KILL cr); 10697 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); 10698 10699 ins_cost(150); 10700 format %{ "xorl $dst, $src\t# int" %} 10701 ins_encode %{ 10702 __ xorl($dst$$Address, $src$$Register); 10703 %} 10704 ins_pipe(ialu_mem_reg); 10705 %} 10706 10707 // Xor Memory with Immediate 10708 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 10709 %{ 10710 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10711 effect(KILL cr); 10712 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); 10713 10714 ins_cost(125); 10715 format %{ "xorl $dst, $src\t# int" %} 10716 ins_encode %{ 10717 __ xorl($dst$$Address, $src$$constant); 10718 %} 10719 ins_pipe(ialu_mem_imm); 10720 %} 10721 10722 10723 // Long Logical Instructions 10724 10725 // And Instructions 10726 // And Register with Register 10727 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10728 %{ 10729 predicate(!UseAPX); 10730 match(Set dst (AndL dst src)); 10731 effect(KILL cr); 10732 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); 10733 10734 format %{ "andq $dst, $src\t# long" %} 10735 ins_encode %{ 10736 __ andq($dst$$Register, $src$$Register); 10737 %} 10738 ins_pipe(ialu_reg_reg); 10739 %} 10740 10741 // And Register with Register using New Data Destination (NDD) 10742 instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 10743 %{ 10744 predicate(UseAPX); 10745 match(Set dst (AndL src1 src2)); 10746 effect(KILL cr); 10747 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); 10748 10749 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10750 ins_encode %{ 10751 __ eandq($dst$$Register, $src1$$Register, $src2$$Register, false); 10752 10753 %} 10754 ins_pipe(ialu_reg_reg); 10755 %} 10756 10757 // And Register with Immediate 255 10758 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 10759 %{ 10760 match(Set dst (AndL src mask)); 10761 10762 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 10763 ins_encode %{ 10764 // movzbl zeroes out the upper 32-bit and does not need REX.W 10765 __ movzbl($dst$$Register, $src$$Register); 10766 %} 10767 ins_pipe(ialu_reg); 10768 %} 10769 10770 // And Register with Immediate 65535 10771 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 10772 %{ 10773 match(Set dst (AndL src mask)); 10774 10775 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 10776 ins_encode %{ 10777 // movzwl zeroes out the upper 32-bit and does not need REX.W 10778 __ movzwl($dst$$Register, $src$$Register); 10779 %} 10780 ins_pipe(ialu_reg); 10781 %} 10782 10783 // And Register with Immediate 10784 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10785 %{ 10786 predicate(!UseAPX); 10787 match(Set dst (AndL dst src)); 10788 effect(KILL cr); 10789 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); 10790 10791 format %{ "andq $dst, $src\t# long" %} 10792 ins_encode %{ 10793 __ andq($dst$$Register, $src$$constant); 10794 %} 10795 ins_pipe(ialu_reg); 10796 %} 10797 10798 instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 10799 %{ 10800 predicate(UseAPX); 10801 match(Set dst (AndL src1 src2)); 10802 effect(KILL cr); 10803 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); 10804 10805 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10806 ins_encode %{ 10807 __ eandq($dst$$Register, $src1$$Register, $src2$$constant, false); 10808 %} 10809 ins_pipe(ialu_reg); 10810 %} 10811 10812 instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 10813 %{ 10814 predicate(UseAPX); 10815 match(Set dst (AndL (LoadL src1) src2)); 10816 effect(KILL cr); 10817 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); 10818 10819 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10820 ins_encode %{ 10821 __ eandq($dst$$Register, $src1$$Address, $src2$$constant, false); 10822 %} 10823 ins_pipe(ialu_reg); 10824 %} 10825 10826 // And Register with Memory 10827 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10828 %{ 10829 predicate(!UseAPX); 10830 match(Set dst (AndL dst (LoadL src))); 10831 effect(KILL cr); 10832 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); 10833 10834 ins_cost(150); 10835 format %{ "andq $dst, $src\t# long" %} 10836 ins_encode %{ 10837 __ andq($dst$$Register, $src$$Address); 10838 %} 10839 ins_pipe(ialu_reg_mem); 10840 %} 10841 10842 instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 10843 %{ 10844 predicate(UseAPX); 10845 match(Set dst (AndL src1 (LoadL src2))); 10846 effect(KILL cr); 10847 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); 10848 10849 ins_cost(150); 10850 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10851 ins_encode %{ 10852 __ eandq($dst$$Register, $src1$$Register, $src2$$Address, false); 10853 %} 10854 ins_pipe(ialu_reg_mem); 10855 %} 10856 10857 instruct andL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 10858 %{ 10859 predicate(UseAPX); 10860 match(Set dst (AndL (LoadL src1) src2)); 10861 effect(KILL cr); 10862 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); 10863 10864 ins_cost(150); 10865 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10866 ins_encode %{ 10867 __ eandq($dst$$Register, $src1$$Address, $src2$$Register, false); 10868 %} 10869 ins_pipe(ialu_reg_mem); 10870 %} 10871 10872 // And Memory with Register 10873 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10874 %{ 10875 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10876 effect(KILL cr); 10877 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); 10878 10879 ins_cost(150); 10880 format %{ "andq $dst, $src\t# long" %} 10881 ins_encode %{ 10882 __ andq($dst$$Address, $src$$Register); 10883 %} 10884 ins_pipe(ialu_mem_reg); 10885 %} 10886 10887 // And Memory with Immediate 10888 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10889 %{ 10890 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10891 effect(KILL cr); 10892 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); 10893 10894 ins_cost(125); 10895 format %{ "andq $dst, $src\t# long" %} 10896 ins_encode %{ 10897 __ andq($dst$$Address, $src$$constant); 10898 %} 10899 ins_pipe(ialu_mem_imm); 10900 %} 10901 10902 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 10903 %{ 10904 // con should be a pure 64-bit immediate given that not(con) is a power of 2 10905 // because AND/OR works well enough for 8/32-bit values. 10906 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 10907 10908 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 10909 effect(KILL cr); 10910 10911 ins_cost(125); 10912 format %{ "btrq $dst, log2(not($con))\t# long" %} 10913 ins_encode %{ 10914 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 10915 %} 10916 ins_pipe(ialu_mem_imm); 10917 %} 10918 10919 // BMI1 instructions 10920 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10921 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10922 predicate(UseBMI1Instructions); 10923 effect(KILL cr); 10924 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10925 10926 ins_cost(125); 10927 format %{ "andnq $dst, $src1, $src2" %} 10928 10929 ins_encode %{ 10930 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10931 %} 10932 ins_pipe(ialu_reg_mem); 10933 %} 10934 10935 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10936 match(Set dst (AndL (XorL src1 minus_1) src2)); 10937 predicate(UseBMI1Instructions); 10938 effect(KILL cr); 10939 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10940 10941 format %{ "andnq $dst, $src1, $src2" %} 10942 10943 ins_encode %{ 10944 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10945 %} 10946 ins_pipe(ialu_reg_mem); 10947 %} 10948 10949 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10950 match(Set dst (AndL (SubL imm_zero src) src)); 10951 predicate(UseBMI1Instructions); 10952 effect(KILL cr); 10953 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10954 10955 format %{ "blsiq $dst, $src" %} 10956 10957 ins_encode %{ 10958 __ blsiq($dst$$Register, $src$$Register); 10959 %} 10960 ins_pipe(ialu_reg); 10961 %} 10962 10963 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10964 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10965 predicate(UseBMI1Instructions); 10966 effect(KILL cr); 10967 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10968 10969 ins_cost(125); 10970 format %{ "blsiq $dst, $src" %} 10971 10972 ins_encode %{ 10973 __ blsiq($dst$$Register, $src$$Address); 10974 %} 10975 ins_pipe(ialu_reg_mem); 10976 %} 10977 10978 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10979 %{ 10980 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 10981 predicate(UseBMI1Instructions); 10982 effect(KILL cr); 10983 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10984 10985 ins_cost(125); 10986 format %{ "blsmskq $dst, $src" %} 10987 10988 ins_encode %{ 10989 __ blsmskq($dst$$Register, $src$$Address); 10990 %} 10991 ins_pipe(ialu_reg_mem); 10992 %} 10993 10994 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10995 %{ 10996 match(Set dst (XorL (AddL src minus_1) src)); 10997 predicate(UseBMI1Instructions); 10998 effect(KILL cr); 10999 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11000 11001 format %{ "blsmskq $dst, $src" %} 11002 11003 ins_encode %{ 11004 __ blsmskq($dst$$Register, $src$$Register); 11005 %} 11006 11007 ins_pipe(ialu_reg); 11008 %} 11009 11010 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11011 %{ 11012 match(Set dst (AndL (AddL src minus_1) src) ); 11013 predicate(UseBMI1Instructions); 11014 effect(KILL cr); 11015 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11016 11017 format %{ "blsrq $dst, $src" %} 11018 11019 ins_encode %{ 11020 __ blsrq($dst$$Register, $src$$Register); 11021 %} 11022 11023 ins_pipe(ialu_reg); 11024 %} 11025 11026 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11027 %{ 11028 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 11029 predicate(UseBMI1Instructions); 11030 effect(KILL cr); 11031 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11032 11033 ins_cost(125); 11034 format %{ "blsrq $dst, $src" %} 11035 11036 ins_encode %{ 11037 __ blsrq($dst$$Register, $src$$Address); 11038 %} 11039 11040 ins_pipe(ialu_reg); 11041 %} 11042 11043 // Or Instructions 11044 // Or Register with Register 11045 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11046 %{ 11047 predicate(!UseAPX); 11048 match(Set dst (OrL dst src)); 11049 effect(KILL cr); 11050 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); 11051 11052 format %{ "orq $dst, $src\t# long" %} 11053 ins_encode %{ 11054 __ orq($dst$$Register, $src$$Register); 11055 %} 11056 ins_pipe(ialu_reg_reg); 11057 %} 11058 11059 // Or Register with Register using New Data Destination (NDD) 11060 instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11061 %{ 11062 predicate(UseAPX); 11063 match(Set dst (OrL src1 src2)); 11064 effect(KILL cr); 11065 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); 11066 11067 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11068 ins_encode %{ 11069 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11070 11071 %} 11072 ins_pipe(ialu_reg_reg); 11073 %} 11074 11075 // Use any_RegP to match R15 (TLS register) without spilling. 11076 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 11077 match(Set dst (OrL dst (CastP2X src))); 11078 effect(KILL cr); 11079 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); 11080 11081 format %{ "orq $dst, $src\t# long" %} 11082 ins_encode %{ 11083 __ orq($dst$$Register, $src$$Register); 11084 %} 11085 ins_pipe(ialu_reg_reg); 11086 %} 11087 11088 instruct orL_rReg_castP2X_ndd(rRegL dst, any_RegP src1, any_RegP src2, rFlagsReg cr) %{ 11089 match(Set dst (OrL src1 (CastP2X src2))); 11090 effect(KILL cr); 11091 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); 11092 11093 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11094 ins_encode %{ 11095 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11096 %} 11097 ins_pipe(ialu_reg_reg); 11098 %} 11099 11100 // Or Register with Immediate 11101 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11102 %{ 11103 predicate(!UseAPX); 11104 match(Set dst (OrL dst src)); 11105 effect(KILL cr); 11106 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); 11107 11108 format %{ "orq $dst, $src\t# long" %} 11109 ins_encode %{ 11110 __ orq($dst$$Register, $src$$constant); 11111 %} 11112 ins_pipe(ialu_reg); 11113 %} 11114 11115 instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11116 %{ 11117 predicate(UseAPX); 11118 match(Set dst (OrL src1 src2)); 11119 effect(KILL cr); 11120 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); 11121 11122 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11123 ins_encode %{ 11124 __ eorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11125 %} 11126 ins_pipe(ialu_reg); 11127 %} 11128 11129 instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr) 11130 %{ 11131 predicate(UseAPX); 11132 match(Set dst (OrL src1 src2)); 11133 effect(KILL cr); 11134 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); 11135 11136 format %{ "eorq $dst, $src2, $src1\t# long ndd" %} 11137 ins_encode %{ 11138 __ eorq($dst$$Register, $src2$$Register, $src1$$constant, false); 11139 %} 11140 ins_pipe(ialu_reg); 11141 %} 11142 11143 // Or Memory with Immediate 11144 instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11145 %{ 11146 predicate(UseAPX); 11147 match(Set dst (OrL (LoadL src1) src2)); 11148 effect(KILL cr); 11149 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); 11150 11151 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11152 ins_encode %{ 11153 __ eorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11154 %} 11155 ins_pipe(ialu_reg); 11156 %} 11157 11158 // Or Register with Memory 11159 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11160 %{ 11161 predicate(!UseAPX); 11162 match(Set dst (OrL dst (LoadL src))); 11163 effect(KILL cr); 11164 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); 11165 11166 ins_cost(150); 11167 format %{ "orq $dst, $src\t# long" %} 11168 ins_encode %{ 11169 __ orq($dst$$Register, $src$$Address); 11170 %} 11171 ins_pipe(ialu_reg_mem); 11172 %} 11173 11174 instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11175 %{ 11176 predicate(UseAPX); 11177 match(Set dst (OrL src1 (LoadL src2))); 11178 effect(KILL cr); 11179 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); 11180 11181 ins_cost(150); 11182 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11183 ins_encode %{ 11184 __ eorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11185 %} 11186 ins_pipe(ialu_reg_mem); 11187 %} 11188 11189 // Or Memory with Register 11190 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11191 %{ 11192 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11193 effect(KILL cr); 11194 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); 11195 11196 ins_cost(150); 11197 format %{ "orq $dst, $src\t# long" %} 11198 ins_encode %{ 11199 __ orq($dst$$Address, $src$$Register); 11200 %} 11201 ins_pipe(ialu_mem_reg); 11202 %} 11203 11204 // Or Memory with Immediate 11205 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11206 %{ 11207 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11208 effect(KILL cr); 11209 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); 11210 11211 ins_cost(125); 11212 format %{ "orq $dst, $src\t# long" %} 11213 ins_encode %{ 11214 __ orq($dst$$Address, $src$$constant); 11215 %} 11216 ins_pipe(ialu_mem_imm); 11217 %} 11218 11219 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 11220 %{ 11221 // con should be a pure 64-bit power of 2 immediate 11222 // because AND/OR works well enough for 8/32-bit values. 11223 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 11224 11225 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 11226 effect(KILL cr); 11227 11228 ins_cost(125); 11229 format %{ "btsq $dst, log2($con)\t# long" %} 11230 ins_encode %{ 11231 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 11232 %} 11233 ins_pipe(ialu_mem_imm); 11234 %} 11235 11236 // Xor Instructions 11237 // Xor Register with Register 11238 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11239 %{ 11240 predicate(!UseAPX); 11241 match(Set dst (XorL dst src)); 11242 effect(KILL cr); 11243 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); 11244 11245 format %{ "xorq $dst, $src\t# long" %} 11246 ins_encode %{ 11247 __ xorq($dst$$Register, $src$$Register); 11248 %} 11249 ins_pipe(ialu_reg_reg); 11250 %} 11251 11252 // Xor Register with Register using New Data Destination (NDD) 11253 instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11254 %{ 11255 predicate(UseAPX); 11256 match(Set dst (XorL src1 src2)); 11257 effect(KILL cr); 11258 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); 11259 11260 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11261 ins_encode %{ 11262 __ exorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11263 %} 11264 ins_pipe(ialu_reg_reg); 11265 %} 11266 11267 // Xor Register with Immediate -1 11268 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) 11269 %{ 11270 predicate(!UseAPX); 11271 match(Set dst (XorL dst imm)); 11272 11273 format %{ "notq $dst" %} 11274 ins_encode %{ 11275 __ notq($dst$$Register); 11276 %} 11277 ins_pipe(ialu_reg); 11278 %} 11279 11280 instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm) 11281 %{ 11282 predicate(UseAPX); 11283 match(Set dst (XorL src imm)); 11284 11285 format %{ "enotq $dst, $src" %} 11286 ins_encode %{ 11287 __ enotq($dst$$Register, $src$$Register); 11288 %} 11289 ins_pipe(ialu_reg); 11290 %} 11291 11292 // Xor Register with Immediate 11293 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11294 %{ 11295 predicate(!UseAPX); 11296 match(Set dst (XorL dst src)); 11297 effect(KILL cr); 11298 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); 11299 11300 format %{ "xorq $dst, $src\t# long" %} 11301 ins_encode %{ 11302 __ xorq($dst$$Register, $src$$constant); 11303 %} 11304 ins_pipe(ialu_reg); 11305 %} 11306 11307 instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11308 %{ 11309 predicate(UseAPX); 11310 match(Set dst (XorL src1 src2)); 11311 effect(KILL cr); 11312 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); 11313 11314 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11315 ins_encode %{ 11316 __ exorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11317 %} 11318 ins_pipe(ialu_reg); 11319 %} 11320 11321 // Xor Memory with Immediate 11322 instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11323 %{ 11324 predicate(UseAPX); 11325 match(Set dst (XorL (LoadL src1) src2)); 11326 effect(KILL cr); 11327 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); 11328 11329 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11330 ins_encode %{ 11331 __ exorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11332 %} 11333 ins_pipe(ialu_reg); 11334 %} 11335 11336 // Xor Register with Memory 11337 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11338 %{ 11339 predicate(!UseAPX); 11340 match(Set dst (XorL dst (LoadL src))); 11341 effect(KILL cr); 11342 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); 11343 11344 ins_cost(150); 11345 format %{ "xorq $dst, $src\t# long" %} 11346 ins_encode %{ 11347 __ xorq($dst$$Register, $src$$Address); 11348 %} 11349 ins_pipe(ialu_reg_mem); 11350 %} 11351 11352 instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11353 %{ 11354 predicate(UseAPX); 11355 match(Set dst (XorL src1 (LoadL src2))); 11356 effect(KILL cr); 11357 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); 11358 11359 ins_cost(150); 11360 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11361 ins_encode %{ 11362 __ exorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11363 %} 11364 ins_pipe(ialu_reg_mem); 11365 %} 11366 11367 instruct xorL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 11368 %{ 11369 predicate(UseAPX); 11370 match(Set dst (XorL (LoadL src1) src2)); 11371 effect(KILL cr); 11372 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); 11373 11374 ins_cost(150); 11375 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11376 ins_encode %{ 11377 __ exorq($dst$$Register, $src1$$Address, $src1$$Register, false); 11378 %} 11379 ins_pipe(ialu_reg_mem); 11380 %} 11381 11382 // Xor Memory with Register 11383 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11384 %{ 11385 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11386 effect(KILL cr); 11387 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); 11388 11389 ins_cost(150); 11390 format %{ "xorq $dst, $src\t# long" %} 11391 ins_encode %{ 11392 __ xorq($dst$$Address, $src$$Register); 11393 %} 11394 ins_pipe(ialu_mem_reg); 11395 %} 11396 11397 // Xor Memory with Immediate 11398 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11399 %{ 11400 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11401 effect(KILL cr); 11402 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); 11403 11404 ins_cost(125); 11405 format %{ "xorq $dst, $src\t# long" %} 11406 ins_encode %{ 11407 __ xorq($dst$$Address, $src$$constant); 11408 %} 11409 ins_pipe(ialu_mem_imm); 11410 %} 11411 11412 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 11413 %{ 11414 match(Set dst (CmpLTMask p q)); 11415 effect(KILL cr); 11416 11417 ins_cost(400); 11418 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 11419 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 11420 "negl $dst" %} 11421 ins_encode %{ 11422 __ cmpl($p$$Register, $q$$Register); 11423 __ setcc(Assembler::less, $dst$$Register); 11424 __ negl($dst$$Register); 11425 %} 11426 ins_pipe(pipe_slow); 11427 %} 11428 11429 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 11430 %{ 11431 match(Set dst (CmpLTMask dst zero)); 11432 effect(KILL cr); 11433 11434 ins_cost(100); 11435 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 11436 ins_encode %{ 11437 __ sarl($dst$$Register, 31); 11438 %} 11439 ins_pipe(ialu_reg); 11440 %} 11441 11442 /* Better to save a register than avoid a branch */ 11443 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11444 %{ 11445 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 11446 effect(KILL cr); 11447 ins_cost(300); 11448 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 11449 "jge done\n\t" 11450 "addl $p,$y\n" 11451 "done: " %} 11452 ins_encode %{ 11453 Register Rp = $p$$Register; 11454 Register Rq = $q$$Register; 11455 Register Ry = $y$$Register; 11456 Label done; 11457 __ subl(Rp, Rq); 11458 __ jccb(Assembler::greaterEqual, done); 11459 __ addl(Rp, Ry); 11460 __ bind(done); 11461 %} 11462 ins_pipe(pipe_cmplt); 11463 %} 11464 11465 /* Better to save a register than avoid a branch */ 11466 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11467 %{ 11468 match(Set y (AndI (CmpLTMask p q) y)); 11469 effect(KILL cr); 11470 11471 ins_cost(300); 11472 11473 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 11474 "jlt done\n\t" 11475 "xorl $y, $y\n" 11476 "done: " %} 11477 ins_encode %{ 11478 Register Rp = $p$$Register; 11479 Register Rq = $q$$Register; 11480 Register Ry = $y$$Register; 11481 Label done; 11482 __ cmpl(Rp, Rq); 11483 __ jccb(Assembler::less, done); 11484 __ xorl(Ry, Ry); 11485 __ bind(done); 11486 %} 11487 ins_pipe(pipe_cmplt); 11488 %} 11489 11490 11491 //---------- FP Instructions------------------------------------------------ 11492 11493 // Really expensive, avoid 11494 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 11495 %{ 11496 match(Set cr (CmpF src1 src2)); 11497 11498 ins_cost(500); 11499 format %{ "ucomiss $src1, $src2\n\t" 11500 "jnp,s exit\n\t" 11501 "pushfq\t# saw NaN, set CF\n\t" 11502 "andq [rsp], #0xffffff2b\n\t" 11503 "popfq\n" 11504 "exit:" %} 11505 ins_encode %{ 11506 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11507 emit_cmpfp_fixup(masm); 11508 %} 11509 ins_pipe(pipe_slow); 11510 %} 11511 11512 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 11513 match(Set cr (CmpF src1 src2)); 11514 11515 ins_cost(100); 11516 format %{ "ucomiss $src1, $src2" %} 11517 ins_encode %{ 11518 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11519 %} 11520 ins_pipe(pipe_slow); 11521 %} 11522 11523 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 11524 match(Set cr (CmpF src1 (LoadF src2))); 11525 11526 ins_cost(100); 11527 format %{ "ucomiss $src1, $src2" %} 11528 ins_encode %{ 11529 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11530 %} 11531 ins_pipe(pipe_slow); 11532 %} 11533 11534 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 11535 match(Set cr (CmpF src con)); 11536 ins_cost(100); 11537 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 11538 ins_encode %{ 11539 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11540 %} 11541 ins_pipe(pipe_slow); 11542 %} 11543 11544 // Really expensive, avoid 11545 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 11546 %{ 11547 match(Set cr (CmpD src1 src2)); 11548 11549 ins_cost(500); 11550 format %{ "ucomisd $src1, $src2\n\t" 11551 "jnp,s exit\n\t" 11552 "pushfq\t# saw NaN, set CF\n\t" 11553 "andq [rsp], #0xffffff2b\n\t" 11554 "popfq\n" 11555 "exit:" %} 11556 ins_encode %{ 11557 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11558 emit_cmpfp_fixup(masm); 11559 %} 11560 ins_pipe(pipe_slow); 11561 %} 11562 11563 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 11564 match(Set cr (CmpD src1 src2)); 11565 11566 ins_cost(100); 11567 format %{ "ucomisd $src1, $src2 test" %} 11568 ins_encode %{ 11569 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11570 %} 11571 ins_pipe(pipe_slow); 11572 %} 11573 11574 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 11575 match(Set cr (CmpD src1 (LoadD src2))); 11576 11577 ins_cost(100); 11578 format %{ "ucomisd $src1, $src2" %} 11579 ins_encode %{ 11580 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11581 %} 11582 ins_pipe(pipe_slow); 11583 %} 11584 11585 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 11586 match(Set cr (CmpD src con)); 11587 ins_cost(100); 11588 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 11589 ins_encode %{ 11590 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11591 %} 11592 ins_pipe(pipe_slow); 11593 %} 11594 11595 // Compare into -1,0,1 11596 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 11597 %{ 11598 match(Set dst (CmpF3 src1 src2)); 11599 effect(KILL cr); 11600 11601 ins_cost(275); 11602 format %{ "ucomiss $src1, $src2\n\t" 11603 "movl $dst, #-1\n\t" 11604 "jp,s done\n\t" 11605 "jb,s done\n\t" 11606 "setne $dst\n\t" 11607 "movzbl $dst, $dst\n" 11608 "done:" %} 11609 ins_encode %{ 11610 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11611 emit_cmpfp3(masm, $dst$$Register); 11612 %} 11613 ins_pipe(pipe_slow); 11614 %} 11615 11616 // Compare into -1,0,1 11617 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 11618 %{ 11619 match(Set dst (CmpF3 src1 (LoadF src2))); 11620 effect(KILL cr); 11621 11622 ins_cost(275); 11623 format %{ "ucomiss $src1, $src2\n\t" 11624 "movl $dst, #-1\n\t" 11625 "jp,s done\n\t" 11626 "jb,s done\n\t" 11627 "setne $dst\n\t" 11628 "movzbl $dst, $dst\n" 11629 "done:" %} 11630 ins_encode %{ 11631 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11632 emit_cmpfp3(masm, $dst$$Register); 11633 %} 11634 ins_pipe(pipe_slow); 11635 %} 11636 11637 // Compare into -1,0,1 11638 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 11639 match(Set dst (CmpF3 src con)); 11640 effect(KILL cr); 11641 11642 ins_cost(275); 11643 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 11644 "movl $dst, #-1\n\t" 11645 "jp,s done\n\t" 11646 "jb,s done\n\t" 11647 "setne $dst\n\t" 11648 "movzbl $dst, $dst\n" 11649 "done:" %} 11650 ins_encode %{ 11651 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11652 emit_cmpfp3(masm, $dst$$Register); 11653 %} 11654 ins_pipe(pipe_slow); 11655 %} 11656 11657 // Compare into -1,0,1 11658 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 11659 %{ 11660 match(Set dst (CmpD3 src1 src2)); 11661 effect(KILL cr); 11662 11663 ins_cost(275); 11664 format %{ "ucomisd $src1, $src2\n\t" 11665 "movl $dst, #-1\n\t" 11666 "jp,s done\n\t" 11667 "jb,s done\n\t" 11668 "setne $dst\n\t" 11669 "movzbl $dst, $dst\n" 11670 "done:" %} 11671 ins_encode %{ 11672 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11673 emit_cmpfp3(masm, $dst$$Register); 11674 %} 11675 ins_pipe(pipe_slow); 11676 %} 11677 11678 // Compare into -1,0,1 11679 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 11680 %{ 11681 match(Set dst (CmpD3 src1 (LoadD src2))); 11682 effect(KILL cr); 11683 11684 ins_cost(275); 11685 format %{ "ucomisd $src1, $src2\n\t" 11686 "movl $dst, #-1\n\t" 11687 "jp,s done\n\t" 11688 "jb,s done\n\t" 11689 "setne $dst\n\t" 11690 "movzbl $dst, $dst\n" 11691 "done:" %} 11692 ins_encode %{ 11693 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11694 emit_cmpfp3(masm, $dst$$Register); 11695 %} 11696 ins_pipe(pipe_slow); 11697 %} 11698 11699 // Compare into -1,0,1 11700 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 11701 match(Set dst (CmpD3 src con)); 11702 effect(KILL cr); 11703 11704 ins_cost(275); 11705 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 11706 "movl $dst, #-1\n\t" 11707 "jp,s done\n\t" 11708 "jb,s done\n\t" 11709 "setne $dst\n\t" 11710 "movzbl $dst, $dst\n" 11711 "done:" %} 11712 ins_encode %{ 11713 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11714 emit_cmpfp3(masm, $dst$$Register); 11715 %} 11716 ins_pipe(pipe_slow); 11717 %} 11718 11719 //----------Arithmetic Conversion Instructions--------------------------------- 11720 11721 instruct convF2D_reg_reg(regD dst, regF src) 11722 %{ 11723 match(Set dst (ConvF2D src)); 11724 11725 format %{ "cvtss2sd $dst, $src" %} 11726 ins_encode %{ 11727 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 11728 %} 11729 ins_pipe(pipe_slow); // XXX 11730 %} 11731 11732 instruct convF2D_reg_mem(regD dst, memory src) 11733 %{ 11734 predicate(UseAVX == 0); 11735 match(Set dst (ConvF2D (LoadF src))); 11736 11737 format %{ "cvtss2sd $dst, $src" %} 11738 ins_encode %{ 11739 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 11740 %} 11741 ins_pipe(pipe_slow); // XXX 11742 %} 11743 11744 instruct convD2F_reg_reg(regF dst, regD src) 11745 %{ 11746 match(Set dst (ConvD2F src)); 11747 11748 format %{ "cvtsd2ss $dst, $src" %} 11749 ins_encode %{ 11750 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 11751 %} 11752 ins_pipe(pipe_slow); // XXX 11753 %} 11754 11755 instruct convD2F_reg_mem(regF dst, memory src) 11756 %{ 11757 predicate(UseAVX == 0); 11758 match(Set dst (ConvD2F (LoadD src))); 11759 11760 format %{ "cvtsd2ss $dst, $src" %} 11761 ins_encode %{ 11762 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 11763 %} 11764 ins_pipe(pipe_slow); // XXX 11765 %} 11766 11767 // XXX do mem variants 11768 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 11769 %{ 11770 match(Set dst (ConvF2I src)); 11771 effect(KILL cr); 11772 format %{ "convert_f2i $dst, $src" %} 11773 ins_encode %{ 11774 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11775 %} 11776 ins_pipe(pipe_slow); 11777 %} 11778 11779 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11780 %{ 11781 match(Set dst (ConvF2L src)); 11782 effect(KILL cr); 11783 format %{ "convert_f2l $dst, $src"%} 11784 ins_encode %{ 11785 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11786 %} 11787 ins_pipe(pipe_slow); 11788 %} 11789 11790 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11791 %{ 11792 match(Set dst (ConvD2I src)); 11793 effect(KILL cr); 11794 format %{ "convert_d2i $dst, $src"%} 11795 ins_encode %{ 11796 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11797 %} 11798 ins_pipe(pipe_slow); 11799 %} 11800 11801 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11802 %{ 11803 match(Set dst (ConvD2L src)); 11804 effect(KILL cr); 11805 format %{ "convert_d2l $dst, $src"%} 11806 ins_encode %{ 11807 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11808 %} 11809 ins_pipe(pipe_slow); 11810 %} 11811 11812 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11813 %{ 11814 match(Set dst (RoundD src)); 11815 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11816 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 11817 ins_encode %{ 11818 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11819 %} 11820 ins_pipe(pipe_slow); 11821 %} 11822 11823 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11824 %{ 11825 match(Set dst (RoundF src)); 11826 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11827 format %{ "round_float $dst,$src" %} 11828 ins_encode %{ 11829 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11830 %} 11831 ins_pipe(pipe_slow); 11832 %} 11833 11834 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 11835 %{ 11836 predicate(!UseXmmI2F); 11837 match(Set dst (ConvI2F src)); 11838 11839 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11840 ins_encode %{ 11841 if (UseAVX > 0) { 11842 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11843 } 11844 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11845 %} 11846 ins_pipe(pipe_slow); // XXX 11847 %} 11848 11849 instruct convI2F_reg_mem(regF dst, memory src) 11850 %{ 11851 predicate(UseAVX == 0); 11852 match(Set dst (ConvI2F (LoadI src))); 11853 11854 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11855 ins_encode %{ 11856 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 11857 %} 11858 ins_pipe(pipe_slow); // XXX 11859 %} 11860 11861 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 11862 %{ 11863 predicate(!UseXmmI2D); 11864 match(Set dst (ConvI2D src)); 11865 11866 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11867 ins_encode %{ 11868 if (UseAVX > 0) { 11869 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11870 } 11871 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11872 %} 11873 ins_pipe(pipe_slow); // XXX 11874 %} 11875 11876 instruct convI2D_reg_mem(regD dst, memory src) 11877 %{ 11878 predicate(UseAVX == 0); 11879 match(Set dst (ConvI2D (LoadI src))); 11880 11881 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11882 ins_encode %{ 11883 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 11884 %} 11885 ins_pipe(pipe_slow); // XXX 11886 %} 11887 11888 instruct convXI2F_reg(regF dst, rRegI src) 11889 %{ 11890 predicate(UseXmmI2F); 11891 match(Set dst (ConvI2F src)); 11892 11893 format %{ "movdl $dst, $src\n\t" 11894 "cvtdq2psl $dst, $dst\t# i2f" %} 11895 ins_encode %{ 11896 __ movdl($dst$$XMMRegister, $src$$Register); 11897 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11898 %} 11899 ins_pipe(pipe_slow); // XXX 11900 %} 11901 11902 instruct convXI2D_reg(regD dst, rRegI src) 11903 %{ 11904 predicate(UseXmmI2D); 11905 match(Set dst (ConvI2D src)); 11906 11907 format %{ "movdl $dst, $src\n\t" 11908 "cvtdq2pdl $dst, $dst\t# i2d" %} 11909 ins_encode %{ 11910 __ movdl($dst$$XMMRegister, $src$$Register); 11911 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11912 %} 11913 ins_pipe(pipe_slow); // XXX 11914 %} 11915 11916 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 11917 %{ 11918 match(Set dst (ConvL2F src)); 11919 11920 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11921 ins_encode %{ 11922 if (UseAVX > 0) { 11923 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11924 } 11925 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 11926 %} 11927 ins_pipe(pipe_slow); // XXX 11928 %} 11929 11930 instruct convL2F_reg_mem(regF dst, memory src) 11931 %{ 11932 predicate(UseAVX == 0); 11933 match(Set dst (ConvL2F (LoadL src))); 11934 11935 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11936 ins_encode %{ 11937 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 11938 %} 11939 ins_pipe(pipe_slow); // XXX 11940 %} 11941 11942 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 11943 %{ 11944 match(Set dst (ConvL2D src)); 11945 11946 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11947 ins_encode %{ 11948 if (UseAVX > 0) { 11949 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11950 } 11951 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 11952 %} 11953 ins_pipe(pipe_slow); // XXX 11954 %} 11955 11956 instruct convL2D_reg_mem(regD dst, memory src) 11957 %{ 11958 predicate(UseAVX == 0); 11959 match(Set dst (ConvL2D (LoadL src))); 11960 11961 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11962 ins_encode %{ 11963 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 11964 %} 11965 ins_pipe(pipe_slow); // XXX 11966 %} 11967 11968 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11969 %{ 11970 match(Set dst (ConvI2L src)); 11971 11972 ins_cost(125); 11973 format %{ "movslq $dst, $src\t# i2l" %} 11974 ins_encode %{ 11975 __ movslq($dst$$Register, $src$$Register); 11976 %} 11977 ins_pipe(ialu_reg_reg); 11978 %} 11979 11980 // Zero-extend convert int to long 11981 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 11982 %{ 11983 match(Set dst (AndL (ConvI2L src) mask)); 11984 11985 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11986 ins_encode %{ 11987 if ($dst$$reg != $src$$reg) { 11988 __ movl($dst$$Register, $src$$Register); 11989 } 11990 %} 11991 ins_pipe(ialu_reg_reg); 11992 %} 11993 11994 // Zero-extend convert int to long 11995 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11996 %{ 11997 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11998 11999 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12000 ins_encode %{ 12001 __ movl($dst$$Register, $src$$Address); 12002 %} 12003 ins_pipe(ialu_reg_mem); 12004 %} 12005 12006 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 12007 %{ 12008 match(Set dst (AndL src mask)); 12009 12010 format %{ "movl $dst, $src\t# zero-extend long" %} 12011 ins_encode %{ 12012 __ movl($dst$$Register, $src$$Register); 12013 %} 12014 ins_pipe(ialu_reg_reg); 12015 %} 12016 12017 instruct convL2I_reg_reg(rRegI dst, rRegL src) 12018 %{ 12019 match(Set dst (ConvL2I src)); 12020 12021 format %{ "movl $dst, $src\t# l2i" %} 12022 ins_encode %{ 12023 __ movl($dst$$Register, $src$$Register); 12024 %} 12025 ins_pipe(ialu_reg_reg); 12026 %} 12027 12028 12029 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 12030 match(Set dst (MoveF2I src)); 12031 effect(DEF dst, USE src); 12032 12033 ins_cost(125); 12034 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 12035 ins_encode %{ 12036 __ movl($dst$$Register, Address(rsp, $src$$disp)); 12037 %} 12038 ins_pipe(ialu_reg_mem); 12039 %} 12040 12041 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12042 match(Set dst (MoveI2F src)); 12043 effect(DEF dst, USE src); 12044 12045 ins_cost(125); 12046 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 12047 ins_encode %{ 12048 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 12049 %} 12050 ins_pipe(pipe_slow); 12051 %} 12052 12053 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 12054 match(Set dst (MoveD2L src)); 12055 effect(DEF dst, USE src); 12056 12057 ins_cost(125); 12058 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 12059 ins_encode %{ 12060 __ movq($dst$$Register, Address(rsp, $src$$disp)); 12061 %} 12062 ins_pipe(ialu_reg_mem); 12063 %} 12064 12065 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 12066 predicate(!UseXmmLoadAndClearUpper); 12067 match(Set dst (MoveL2D src)); 12068 effect(DEF dst, USE src); 12069 12070 ins_cost(125); 12071 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 12072 ins_encode %{ 12073 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12074 %} 12075 ins_pipe(pipe_slow); 12076 %} 12077 12078 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12079 predicate(UseXmmLoadAndClearUpper); 12080 match(Set dst (MoveL2D src)); 12081 effect(DEF dst, USE src); 12082 12083 ins_cost(125); 12084 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 12085 ins_encode %{ 12086 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12087 %} 12088 ins_pipe(pipe_slow); 12089 %} 12090 12091 12092 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12093 match(Set dst (MoveF2I src)); 12094 effect(DEF dst, USE src); 12095 12096 ins_cost(95); // XXX 12097 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 12098 ins_encode %{ 12099 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 12100 %} 12101 ins_pipe(pipe_slow); 12102 %} 12103 12104 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 12105 match(Set dst (MoveI2F src)); 12106 effect(DEF dst, USE src); 12107 12108 ins_cost(100); 12109 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 12110 ins_encode %{ 12111 __ movl(Address(rsp, $dst$$disp), $src$$Register); 12112 %} 12113 ins_pipe( ialu_mem_reg ); 12114 %} 12115 12116 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12117 match(Set dst (MoveD2L src)); 12118 effect(DEF dst, USE src); 12119 12120 ins_cost(95); // XXX 12121 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 12122 ins_encode %{ 12123 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 12124 %} 12125 ins_pipe(pipe_slow); 12126 %} 12127 12128 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 12129 match(Set dst (MoveL2D src)); 12130 effect(DEF dst, USE src); 12131 12132 ins_cost(100); 12133 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 12134 ins_encode %{ 12135 __ movq(Address(rsp, $dst$$disp), $src$$Register); 12136 %} 12137 ins_pipe(ialu_mem_reg); 12138 %} 12139 12140 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 12141 match(Set dst (MoveF2I src)); 12142 effect(DEF dst, USE src); 12143 ins_cost(85); 12144 format %{ "movd $dst,$src\t# MoveF2I" %} 12145 ins_encode %{ 12146 __ movdl($dst$$Register, $src$$XMMRegister); 12147 %} 12148 ins_pipe( pipe_slow ); 12149 %} 12150 12151 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 12152 match(Set dst (MoveD2L src)); 12153 effect(DEF dst, USE src); 12154 ins_cost(85); 12155 format %{ "movd $dst,$src\t# MoveD2L" %} 12156 ins_encode %{ 12157 __ movdq($dst$$Register, $src$$XMMRegister); 12158 %} 12159 ins_pipe( pipe_slow ); 12160 %} 12161 12162 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 12163 match(Set dst (MoveI2F src)); 12164 effect(DEF dst, USE src); 12165 ins_cost(100); 12166 format %{ "movd $dst,$src\t# MoveI2F" %} 12167 ins_encode %{ 12168 __ movdl($dst$$XMMRegister, $src$$Register); 12169 %} 12170 ins_pipe( pipe_slow ); 12171 %} 12172 12173 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 12174 match(Set dst (MoveL2D src)); 12175 effect(DEF dst, USE src); 12176 ins_cost(100); 12177 format %{ "movd $dst,$src\t# MoveL2D" %} 12178 ins_encode %{ 12179 __ movdq($dst$$XMMRegister, $src$$Register); 12180 %} 12181 ins_pipe( pipe_slow ); 12182 %} 12183 12184 // Fast clearing of an array 12185 // Small non-constant lenght ClearArray for non-AVX512 targets. 12186 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12187 Universe dummy, rFlagsReg cr) 12188 %{ 12189 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 12190 match(Set dummy (ClearArray cnt base)); 12191 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12192 12193 format %{ $$template 12194 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12195 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12196 $$emit$$"jg LARGE\n\t" 12197 $$emit$$"dec rcx\n\t" 12198 $$emit$$"js DONE\t# Zero length\n\t" 12199 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12200 $$emit$$"dec rcx\n\t" 12201 $$emit$$"jge LOOP\n\t" 12202 $$emit$$"jmp DONE\n\t" 12203 $$emit$$"# LARGE:\n\t" 12204 if (UseFastStosb) { 12205 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12206 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12207 } else if (UseXMMForObjInit) { 12208 $$emit$$"mov rdi,rax\n\t" 12209 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12210 $$emit$$"jmpq L_zero_64_bytes\n\t" 12211 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12212 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12213 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12214 $$emit$$"add 0x40,rax\n\t" 12215 $$emit$$"# L_zero_64_bytes:\n\t" 12216 $$emit$$"sub 0x8,rcx\n\t" 12217 $$emit$$"jge L_loop\n\t" 12218 $$emit$$"add 0x4,rcx\n\t" 12219 $$emit$$"jl L_tail\n\t" 12220 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12221 $$emit$$"add 0x20,rax\n\t" 12222 $$emit$$"sub 0x4,rcx\n\t" 12223 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12224 $$emit$$"add 0x4,rcx\n\t" 12225 $$emit$$"jle L_end\n\t" 12226 $$emit$$"dec rcx\n\t" 12227 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12228 $$emit$$"vmovq xmm0,(rax)\n\t" 12229 $$emit$$"add 0x8,rax\n\t" 12230 $$emit$$"dec rcx\n\t" 12231 $$emit$$"jge L_sloop\n\t" 12232 $$emit$$"# L_end:\n\t" 12233 } else { 12234 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12235 } 12236 $$emit$$"# DONE" 12237 %} 12238 ins_encode %{ 12239 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12240 $tmp$$XMMRegister, false, knoreg); 12241 %} 12242 ins_pipe(pipe_slow); 12243 %} 12244 12245 // Small non-constant length ClearArray for AVX512 targets. 12246 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12247 Universe dummy, rFlagsReg cr) 12248 %{ 12249 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 12250 match(Set dummy (ClearArray cnt base)); 12251 ins_cost(125); 12252 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12253 12254 format %{ $$template 12255 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12256 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12257 $$emit$$"jg LARGE\n\t" 12258 $$emit$$"dec rcx\n\t" 12259 $$emit$$"js DONE\t# Zero length\n\t" 12260 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12261 $$emit$$"dec rcx\n\t" 12262 $$emit$$"jge LOOP\n\t" 12263 $$emit$$"jmp DONE\n\t" 12264 $$emit$$"# LARGE:\n\t" 12265 if (UseFastStosb) { 12266 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12267 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12268 } else if (UseXMMForObjInit) { 12269 $$emit$$"mov rdi,rax\n\t" 12270 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12271 $$emit$$"jmpq L_zero_64_bytes\n\t" 12272 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12273 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12274 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12275 $$emit$$"add 0x40,rax\n\t" 12276 $$emit$$"# L_zero_64_bytes:\n\t" 12277 $$emit$$"sub 0x8,rcx\n\t" 12278 $$emit$$"jge L_loop\n\t" 12279 $$emit$$"add 0x4,rcx\n\t" 12280 $$emit$$"jl L_tail\n\t" 12281 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12282 $$emit$$"add 0x20,rax\n\t" 12283 $$emit$$"sub 0x4,rcx\n\t" 12284 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12285 $$emit$$"add 0x4,rcx\n\t" 12286 $$emit$$"jle L_end\n\t" 12287 $$emit$$"dec rcx\n\t" 12288 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12289 $$emit$$"vmovq xmm0,(rax)\n\t" 12290 $$emit$$"add 0x8,rax\n\t" 12291 $$emit$$"dec rcx\n\t" 12292 $$emit$$"jge L_sloop\n\t" 12293 $$emit$$"# L_end:\n\t" 12294 } else { 12295 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12296 } 12297 $$emit$$"# DONE" 12298 %} 12299 ins_encode %{ 12300 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12301 $tmp$$XMMRegister, false, $ktmp$$KRegister); 12302 %} 12303 ins_pipe(pipe_slow); 12304 %} 12305 12306 // Large non-constant length ClearArray for non-AVX512 targets. 12307 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12308 Universe dummy, rFlagsReg cr) 12309 %{ 12310 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 12311 match(Set dummy (ClearArray cnt base)); 12312 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12313 12314 format %{ $$template 12315 if (UseFastStosb) { 12316 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12317 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12318 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12319 } else if (UseXMMForObjInit) { 12320 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12321 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12322 $$emit$$"jmpq L_zero_64_bytes\n\t" 12323 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12324 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12325 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12326 $$emit$$"add 0x40,rax\n\t" 12327 $$emit$$"# L_zero_64_bytes:\n\t" 12328 $$emit$$"sub 0x8,rcx\n\t" 12329 $$emit$$"jge L_loop\n\t" 12330 $$emit$$"add 0x4,rcx\n\t" 12331 $$emit$$"jl L_tail\n\t" 12332 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12333 $$emit$$"add 0x20,rax\n\t" 12334 $$emit$$"sub 0x4,rcx\n\t" 12335 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12336 $$emit$$"add 0x4,rcx\n\t" 12337 $$emit$$"jle L_end\n\t" 12338 $$emit$$"dec rcx\n\t" 12339 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12340 $$emit$$"vmovq xmm0,(rax)\n\t" 12341 $$emit$$"add 0x8,rax\n\t" 12342 $$emit$$"dec rcx\n\t" 12343 $$emit$$"jge L_sloop\n\t" 12344 $$emit$$"# L_end:\n\t" 12345 } else { 12346 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12347 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12348 } 12349 %} 12350 ins_encode %{ 12351 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12352 $tmp$$XMMRegister, true, knoreg); 12353 %} 12354 ins_pipe(pipe_slow); 12355 %} 12356 12357 // Large non-constant length ClearArray for AVX512 targets. 12358 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12359 Universe dummy, rFlagsReg cr) 12360 %{ 12361 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 12362 match(Set dummy (ClearArray cnt base)); 12363 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12364 12365 format %{ $$template 12366 if (UseFastStosb) { 12367 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12368 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12369 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12370 } else if (UseXMMForObjInit) { 12371 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12372 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12373 $$emit$$"jmpq L_zero_64_bytes\n\t" 12374 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12375 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12376 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12377 $$emit$$"add 0x40,rax\n\t" 12378 $$emit$$"# L_zero_64_bytes:\n\t" 12379 $$emit$$"sub 0x8,rcx\n\t" 12380 $$emit$$"jge L_loop\n\t" 12381 $$emit$$"add 0x4,rcx\n\t" 12382 $$emit$$"jl L_tail\n\t" 12383 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12384 $$emit$$"add 0x20,rax\n\t" 12385 $$emit$$"sub 0x4,rcx\n\t" 12386 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12387 $$emit$$"add 0x4,rcx\n\t" 12388 $$emit$$"jle L_end\n\t" 12389 $$emit$$"dec rcx\n\t" 12390 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12391 $$emit$$"vmovq xmm0,(rax)\n\t" 12392 $$emit$$"add 0x8,rax\n\t" 12393 $$emit$$"dec rcx\n\t" 12394 $$emit$$"jge L_sloop\n\t" 12395 $$emit$$"# L_end:\n\t" 12396 } else { 12397 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12398 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12399 } 12400 %} 12401 ins_encode %{ 12402 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12403 $tmp$$XMMRegister, true, $ktmp$$KRegister); 12404 %} 12405 ins_pipe(pipe_slow); 12406 %} 12407 12408 // Small constant length ClearArray for AVX512 targets. 12409 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 12410 %{ 12411 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 12412 match(Set dummy (ClearArray cnt base)); 12413 ins_cost(100); 12414 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 12415 format %{ "clear_mem_imm $base , $cnt \n\t" %} 12416 ins_encode %{ 12417 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 12418 %} 12419 ins_pipe(pipe_slow); 12420 %} 12421 12422 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12423 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12424 %{ 12425 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12426 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12427 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12428 12429 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12430 ins_encode %{ 12431 __ string_compare($str1$$Register, $str2$$Register, 12432 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12433 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 12434 %} 12435 ins_pipe( pipe_slow ); 12436 %} 12437 12438 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12439 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12440 %{ 12441 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12442 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12443 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12444 12445 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12446 ins_encode %{ 12447 __ string_compare($str1$$Register, $str2$$Register, 12448 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12449 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 12450 %} 12451 ins_pipe( pipe_slow ); 12452 %} 12453 12454 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12455 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12456 %{ 12457 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12458 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12459 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12460 12461 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12462 ins_encode %{ 12463 __ string_compare($str1$$Register, $str2$$Register, 12464 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12465 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 12466 %} 12467 ins_pipe( pipe_slow ); 12468 %} 12469 12470 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12471 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12472 %{ 12473 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12474 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12475 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12476 12477 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12478 ins_encode %{ 12479 __ string_compare($str1$$Register, $str2$$Register, 12480 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12481 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 12482 %} 12483 ins_pipe( pipe_slow ); 12484 %} 12485 12486 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12487 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12488 %{ 12489 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12490 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12491 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12492 12493 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12494 ins_encode %{ 12495 __ string_compare($str1$$Register, $str2$$Register, 12496 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12497 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 12498 %} 12499 ins_pipe( pipe_slow ); 12500 %} 12501 12502 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12503 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12504 %{ 12505 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12506 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12507 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12508 12509 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12510 ins_encode %{ 12511 __ string_compare($str1$$Register, $str2$$Register, 12512 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12513 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 12514 %} 12515 ins_pipe( pipe_slow ); 12516 %} 12517 12518 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12519 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12520 %{ 12521 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12522 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12523 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12524 12525 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12526 ins_encode %{ 12527 __ string_compare($str2$$Register, $str1$$Register, 12528 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12529 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 12530 %} 12531 ins_pipe( pipe_slow ); 12532 %} 12533 12534 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12535 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12536 %{ 12537 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12538 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12539 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12540 12541 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12542 ins_encode %{ 12543 __ string_compare($str2$$Register, $str1$$Register, 12544 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12545 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 12546 %} 12547 ins_pipe( pipe_slow ); 12548 %} 12549 12550 // fast search of substring with known size. 12551 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12552 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12553 %{ 12554 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12555 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12556 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12557 12558 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12559 ins_encode %{ 12560 int icnt2 = (int)$int_cnt2$$constant; 12561 if (icnt2 >= 16) { 12562 // IndexOf for constant substrings with size >= 16 elements 12563 // which don't need to be loaded through stack. 12564 __ string_indexofC8($str1$$Register, $str2$$Register, 12565 $cnt1$$Register, $cnt2$$Register, 12566 icnt2, $result$$Register, 12567 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12568 } else { 12569 // Small strings are loaded through stack if they cross page boundary. 12570 __ string_indexof($str1$$Register, $str2$$Register, 12571 $cnt1$$Register, $cnt2$$Register, 12572 icnt2, $result$$Register, 12573 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12574 } 12575 %} 12576 ins_pipe( pipe_slow ); 12577 %} 12578 12579 // fast search of substring with known size. 12580 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12581 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12582 %{ 12583 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12584 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12585 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12586 12587 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12588 ins_encode %{ 12589 int icnt2 = (int)$int_cnt2$$constant; 12590 if (icnt2 >= 8) { 12591 // IndexOf for constant substrings with size >= 8 elements 12592 // which don't need to be loaded through stack. 12593 __ string_indexofC8($str1$$Register, $str2$$Register, 12594 $cnt1$$Register, $cnt2$$Register, 12595 icnt2, $result$$Register, 12596 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12597 } else { 12598 // Small strings are loaded through stack if they cross page boundary. 12599 __ string_indexof($str1$$Register, $str2$$Register, 12600 $cnt1$$Register, $cnt2$$Register, 12601 icnt2, $result$$Register, 12602 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12603 } 12604 %} 12605 ins_pipe( pipe_slow ); 12606 %} 12607 12608 // fast search of substring with known size. 12609 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12610 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12611 %{ 12612 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12613 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12614 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12615 12616 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12617 ins_encode %{ 12618 int icnt2 = (int)$int_cnt2$$constant; 12619 if (icnt2 >= 8) { 12620 // IndexOf for constant substrings with size >= 8 elements 12621 // which don't need to be loaded through stack. 12622 __ string_indexofC8($str1$$Register, $str2$$Register, 12623 $cnt1$$Register, $cnt2$$Register, 12624 icnt2, $result$$Register, 12625 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12626 } else { 12627 // Small strings are loaded through stack if they cross page boundary. 12628 __ string_indexof($str1$$Register, $str2$$Register, 12629 $cnt1$$Register, $cnt2$$Register, 12630 icnt2, $result$$Register, 12631 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12632 } 12633 %} 12634 ins_pipe( pipe_slow ); 12635 %} 12636 12637 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12638 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12639 %{ 12640 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12641 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12642 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12643 12644 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12645 ins_encode %{ 12646 __ string_indexof($str1$$Register, $str2$$Register, 12647 $cnt1$$Register, $cnt2$$Register, 12648 (-1), $result$$Register, 12649 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12650 %} 12651 ins_pipe( pipe_slow ); 12652 %} 12653 12654 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12655 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12656 %{ 12657 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12658 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12659 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12660 12661 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12662 ins_encode %{ 12663 __ string_indexof($str1$$Register, $str2$$Register, 12664 $cnt1$$Register, $cnt2$$Register, 12665 (-1), $result$$Register, 12666 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12667 %} 12668 ins_pipe( pipe_slow ); 12669 %} 12670 12671 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12672 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12673 %{ 12674 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12675 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12676 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12677 12678 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12679 ins_encode %{ 12680 __ string_indexof($str1$$Register, $str2$$Register, 12681 $cnt1$$Register, $cnt2$$Register, 12682 (-1), $result$$Register, 12683 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12684 %} 12685 ins_pipe( pipe_slow ); 12686 %} 12687 12688 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12689 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12690 %{ 12691 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 12692 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12693 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12694 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12695 ins_encode %{ 12696 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12697 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12698 %} 12699 ins_pipe( pipe_slow ); 12700 %} 12701 12702 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12703 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12704 %{ 12705 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 12706 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12707 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12708 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12709 ins_encode %{ 12710 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12711 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12712 %} 12713 ins_pipe( pipe_slow ); 12714 %} 12715 12716 // fast string equals 12717 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12718 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 12719 %{ 12720 predicate(!VM_Version::supports_avx512vlbw()); 12721 match(Set result (StrEquals (Binary str1 str2) cnt)); 12722 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12723 12724 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12725 ins_encode %{ 12726 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12727 $cnt$$Register, $result$$Register, $tmp3$$Register, 12728 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12729 %} 12730 ins_pipe( pipe_slow ); 12731 %} 12732 12733 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12734 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 12735 %{ 12736 predicate(VM_Version::supports_avx512vlbw()); 12737 match(Set result (StrEquals (Binary str1 str2) cnt)); 12738 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12739 12740 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12741 ins_encode %{ 12742 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12743 $cnt$$Register, $result$$Register, $tmp3$$Register, 12744 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12745 %} 12746 ins_pipe( pipe_slow ); 12747 %} 12748 12749 // fast array equals 12750 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12751 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12752 %{ 12753 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12754 match(Set result (AryEq ary1 ary2)); 12755 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12756 12757 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12758 ins_encode %{ 12759 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12760 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12761 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12762 %} 12763 ins_pipe( pipe_slow ); 12764 %} 12765 12766 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12767 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12768 %{ 12769 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12770 match(Set result (AryEq ary1 ary2)); 12771 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12772 12773 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12774 ins_encode %{ 12775 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12776 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12777 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12778 %} 12779 ins_pipe( pipe_slow ); 12780 %} 12781 12782 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12783 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12784 %{ 12785 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12786 match(Set result (AryEq ary1 ary2)); 12787 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12788 12789 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12790 ins_encode %{ 12791 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12792 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12793 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 12794 %} 12795 ins_pipe( pipe_slow ); 12796 %} 12797 12798 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12799 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12800 %{ 12801 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12802 match(Set result (AryEq ary1 ary2)); 12803 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12804 12805 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12806 ins_encode %{ 12807 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12808 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12809 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 12810 %} 12811 ins_pipe( pipe_slow ); 12812 %} 12813 12814 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 12815 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 12816 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 12817 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 12818 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 12819 %{ 12820 predicate(UseAVX >= 2); 12821 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 12822 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 12823 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 12824 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 12825 USE basic_type, KILL cr); 12826 12827 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 12828 ins_encode %{ 12829 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 12830 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12831 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 12832 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 12833 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 12834 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 12835 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 12836 %} 12837 ins_pipe( pipe_slow ); 12838 %} 12839 12840 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12841 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 12842 %{ 12843 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12844 match(Set result (CountPositives ary1 len)); 12845 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12846 12847 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12848 ins_encode %{ 12849 __ count_positives($ary1$$Register, $len$$Register, 12850 $result$$Register, $tmp3$$Register, 12851 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 12852 %} 12853 ins_pipe( pipe_slow ); 12854 %} 12855 12856 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12857 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 12858 %{ 12859 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12860 match(Set result (CountPositives ary1 len)); 12861 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12862 12863 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12864 ins_encode %{ 12865 __ count_positives($ary1$$Register, $len$$Register, 12866 $result$$Register, $tmp3$$Register, 12867 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 12868 %} 12869 ins_pipe( pipe_slow ); 12870 %} 12871 12872 // fast char[] to byte[] compression 12873 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12874 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12875 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12876 match(Set result (StrCompressedCopy src (Binary dst len))); 12877 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 12878 USE_KILL len, KILL tmp5, KILL cr); 12879 12880 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12881 ins_encode %{ 12882 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12883 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12884 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12885 knoreg, knoreg); 12886 %} 12887 ins_pipe( pipe_slow ); 12888 %} 12889 12890 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12891 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12892 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12893 match(Set result (StrCompressedCopy src (Binary dst len))); 12894 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 12895 USE_KILL len, KILL tmp5, KILL cr); 12896 12897 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12898 ins_encode %{ 12899 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12900 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12901 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12902 $ktmp1$$KRegister, $ktmp2$$KRegister); 12903 %} 12904 ins_pipe( pipe_slow ); 12905 %} 12906 // fast byte[] to char[] inflation 12907 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12908 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 12909 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12910 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12911 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12912 12913 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12914 ins_encode %{ 12915 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12916 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 12917 %} 12918 ins_pipe( pipe_slow ); 12919 %} 12920 12921 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12922 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 12923 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12924 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12925 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12926 12927 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12928 ins_encode %{ 12929 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12930 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 12931 %} 12932 ins_pipe( pipe_slow ); 12933 %} 12934 12935 // encode char[] to byte[] in ISO_8859_1 12936 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12937 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12938 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12939 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12940 match(Set result (EncodeISOArray src (Binary dst len))); 12941 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12942 12943 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12944 ins_encode %{ 12945 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12946 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12947 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 12948 %} 12949 ins_pipe( pipe_slow ); 12950 %} 12951 12952 // encode char[] to byte[] in ASCII 12953 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12954 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12955 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12956 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 12957 match(Set result (EncodeISOArray src (Binary dst len))); 12958 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12959 12960 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12961 ins_encode %{ 12962 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12963 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12964 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 12965 %} 12966 ins_pipe( pipe_slow ); 12967 %} 12968 12969 //----------Overflow Math Instructions----------------------------------------- 12970 12971 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 12972 %{ 12973 match(Set cr (OverflowAddI op1 op2)); 12974 effect(DEF cr, USE_KILL op1, USE op2); 12975 12976 format %{ "addl $op1, $op2\t# overflow check int" %} 12977 12978 ins_encode %{ 12979 __ addl($op1$$Register, $op2$$Register); 12980 %} 12981 ins_pipe(ialu_reg_reg); 12982 %} 12983 12984 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 12985 %{ 12986 match(Set cr (OverflowAddI op1 op2)); 12987 effect(DEF cr, USE_KILL op1, USE op2); 12988 12989 format %{ "addl $op1, $op2\t# overflow check int" %} 12990 12991 ins_encode %{ 12992 __ addl($op1$$Register, $op2$$constant); 12993 %} 12994 ins_pipe(ialu_reg_reg); 12995 %} 12996 12997 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 12998 %{ 12999 match(Set cr (OverflowAddL op1 op2)); 13000 effect(DEF cr, USE_KILL op1, USE op2); 13001 13002 format %{ "addq $op1, $op2\t# overflow check long" %} 13003 ins_encode %{ 13004 __ addq($op1$$Register, $op2$$Register); 13005 %} 13006 ins_pipe(ialu_reg_reg); 13007 %} 13008 13009 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 13010 %{ 13011 match(Set cr (OverflowAddL op1 op2)); 13012 effect(DEF cr, USE_KILL op1, USE op2); 13013 13014 format %{ "addq $op1, $op2\t# overflow check long" %} 13015 ins_encode %{ 13016 __ addq($op1$$Register, $op2$$constant); 13017 %} 13018 ins_pipe(ialu_reg_reg); 13019 %} 13020 13021 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13022 %{ 13023 match(Set cr (OverflowSubI op1 op2)); 13024 13025 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13026 ins_encode %{ 13027 __ cmpl($op1$$Register, $op2$$Register); 13028 %} 13029 ins_pipe(ialu_reg_reg); 13030 %} 13031 13032 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13033 %{ 13034 match(Set cr (OverflowSubI op1 op2)); 13035 13036 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13037 ins_encode %{ 13038 __ cmpl($op1$$Register, $op2$$constant); 13039 %} 13040 ins_pipe(ialu_reg_reg); 13041 %} 13042 13043 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13044 %{ 13045 match(Set cr (OverflowSubL op1 op2)); 13046 13047 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13048 ins_encode %{ 13049 __ cmpq($op1$$Register, $op2$$Register); 13050 %} 13051 ins_pipe(ialu_reg_reg); 13052 %} 13053 13054 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13055 %{ 13056 match(Set cr (OverflowSubL op1 op2)); 13057 13058 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13059 ins_encode %{ 13060 __ cmpq($op1$$Register, $op2$$constant); 13061 %} 13062 ins_pipe(ialu_reg_reg); 13063 %} 13064 13065 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 13066 %{ 13067 match(Set cr (OverflowSubI zero op2)); 13068 effect(DEF cr, USE_KILL op2); 13069 13070 format %{ "negl $op2\t# overflow check int" %} 13071 ins_encode %{ 13072 __ negl($op2$$Register); 13073 %} 13074 ins_pipe(ialu_reg_reg); 13075 %} 13076 13077 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 13078 %{ 13079 match(Set cr (OverflowSubL zero op2)); 13080 effect(DEF cr, USE_KILL op2); 13081 13082 format %{ "negq $op2\t# overflow check long" %} 13083 ins_encode %{ 13084 __ negq($op2$$Register); 13085 %} 13086 ins_pipe(ialu_reg_reg); 13087 %} 13088 13089 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13090 %{ 13091 match(Set cr (OverflowMulI op1 op2)); 13092 effect(DEF cr, USE_KILL op1, USE op2); 13093 13094 format %{ "imull $op1, $op2\t# overflow check int" %} 13095 ins_encode %{ 13096 __ imull($op1$$Register, $op2$$Register); 13097 %} 13098 ins_pipe(ialu_reg_reg_alu0); 13099 %} 13100 13101 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 13102 %{ 13103 match(Set cr (OverflowMulI op1 op2)); 13104 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13105 13106 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 13107 ins_encode %{ 13108 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 13109 %} 13110 ins_pipe(ialu_reg_reg_alu0); 13111 %} 13112 13113 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13114 %{ 13115 match(Set cr (OverflowMulL op1 op2)); 13116 effect(DEF cr, USE_KILL op1, USE op2); 13117 13118 format %{ "imulq $op1, $op2\t# overflow check long" %} 13119 ins_encode %{ 13120 __ imulq($op1$$Register, $op2$$Register); 13121 %} 13122 ins_pipe(ialu_reg_reg_alu0); 13123 %} 13124 13125 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 13126 %{ 13127 match(Set cr (OverflowMulL op1 op2)); 13128 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13129 13130 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 13131 ins_encode %{ 13132 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 13133 %} 13134 ins_pipe(ialu_reg_reg_alu0); 13135 %} 13136 13137 13138 //----------Control Flow Instructions------------------------------------------ 13139 // Signed compare Instructions 13140 13141 // XXX more variants!! 13142 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13143 %{ 13144 match(Set cr (CmpI op1 op2)); 13145 effect(DEF cr, USE op1, USE op2); 13146 13147 format %{ "cmpl $op1, $op2" %} 13148 ins_encode %{ 13149 __ cmpl($op1$$Register, $op2$$Register); 13150 %} 13151 ins_pipe(ialu_cr_reg_reg); 13152 %} 13153 13154 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13155 %{ 13156 match(Set cr (CmpI op1 op2)); 13157 13158 format %{ "cmpl $op1, $op2" %} 13159 ins_encode %{ 13160 __ cmpl($op1$$Register, $op2$$constant); 13161 %} 13162 ins_pipe(ialu_cr_reg_imm); 13163 %} 13164 13165 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 13166 %{ 13167 match(Set cr (CmpI op1 (LoadI op2))); 13168 13169 ins_cost(500); // XXX 13170 format %{ "cmpl $op1, $op2" %} 13171 ins_encode %{ 13172 __ cmpl($op1$$Register, $op2$$Address); 13173 %} 13174 ins_pipe(ialu_cr_reg_mem); 13175 %} 13176 13177 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 13178 %{ 13179 match(Set cr (CmpI src zero)); 13180 13181 format %{ "testl $src, $src" %} 13182 ins_encode %{ 13183 __ testl($src$$Register, $src$$Register); 13184 %} 13185 ins_pipe(ialu_cr_reg_imm); 13186 %} 13187 13188 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 13189 %{ 13190 match(Set cr (CmpI (AndI src con) zero)); 13191 13192 format %{ "testl $src, $con" %} 13193 ins_encode %{ 13194 __ testl($src$$Register, $con$$constant); 13195 %} 13196 ins_pipe(ialu_cr_reg_imm); 13197 %} 13198 13199 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 13200 %{ 13201 match(Set cr (CmpI (AndI src1 src2) zero)); 13202 13203 format %{ "testl $src1, $src2" %} 13204 ins_encode %{ 13205 __ testl($src1$$Register, $src2$$Register); 13206 %} 13207 ins_pipe(ialu_cr_reg_imm); 13208 %} 13209 13210 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 13211 %{ 13212 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 13213 13214 format %{ "testl $src, $mem" %} 13215 ins_encode %{ 13216 __ testl($src$$Register, $mem$$Address); 13217 %} 13218 ins_pipe(ialu_cr_reg_mem); 13219 %} 13220 13221 // Unsigned compare Instructions; really, same as signed except they 13222 // produce an rFlagsRegU instead of rFlagsReg. 13223 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 13224 %{ 13225 match(Set cr (CmpU op1 op2)); 13226 13227 format %{ "cmpl $op1, $op2\t# unsigned" %} 13228 ins_encode %{ 13229 __ cmpl($op1$$Register, $op2$$Register); 13230 %} 13231 ins_pipe(ialu_cr_reg_reg); 13232 %} 13233 13234 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 13235 %{ 13236 match(Set cr (CmpU op1 op2)); 13237 13238 format %{ "cmpl $op1, $op2\t# unsigned" %} 13239 ins_encode %{ 13240 __ cmpl($op1$$Register, $op2$$constant); 13241 %} 13242 ins_pipe(ialu_cr_reg_imm); 13243 %} 13244 13245 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 13246 %{ 13247 match(Set cr (CmpU op1 (LoadI op2))); 13248 13249 ins_cost(500); // XXX 13250 format %{ "cmpl $op1, $op2\t# unsigned" %} 13251 ins_encode %{ 13252 __ cmpl($op1$$Register, $op2$$Address); 13253 %} 13254 ins_pipe(ialu_cr_reg_mem); 13255 %} 13256 13257 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 13258 %{ 13259 match(Set cr (CmpU src zero)); 13260 13261 format %{ "testl $src, $src\t# unsigned" %} 13262 ins_encode %{ 13263 __ testl($src$$Register, $src$$Register); 13264 %} 13265 ins_pipe(ialu_cr_reg_imm); 13266 %} 13267 13268 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 13269 %{ 13270 match(Set cr (CmpP op1 op2)); 13271 13272 format %{ "cmpq $op1, $op2\t# ptr" %} 13273 ins_encode %{ 13274 __ cmpq($op1$$Register, $op2$$Register); 13275 %} 13276 ins_pipe(ialu_cr_reg_reg); 13277 %} 13278 13279 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 13280 %{ 13281 match(Set cr (CmpP op1 (LoadP op2))); 13282 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13283 13284 ins_cost(500); // XXX 13285 format %{ "cmpq $op1, $op2\t# ptr" %} 13286 ins_encode %{ 13287 __ cmpq($op1$$Register, $op2$$Address); 13288 %} 13289 ins_pipe(ialu_cr_reg_mem); 13290 %} 13291 13292 // XXX this is generalized by compP_rReg_mem??? 13293 // Compare raw pointer (used in out-of-heap check). 13294 // Only works because non-oop pointers must be raw pointers 13295 // and raw pointers have no anti-dependencies. 13296 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 13297 %{ 13298 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 13299 n->in(2)->as_Load()->barrier_data() == 0); 13300 match(Set cr (CmpP op1 (LoadP op2))); 13301 13302 format %{ "cmpq $op1, $op2\t# raw ptr" %} 13303 ins_encode %{ 13304 __ cmpq($op1$$Register, $op2$$Address); 13305 %} 13306 ins_pipe(ialu_cr_reg_mem); 13307 %} 13308 13309 // This will generate a signed flags result. This should be OK since 13310 // any compare to a zero should be eq/neq. 13311 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 13312 %{ 13313 match(Set cr (CmpP src zero)); 13314 13315 format %{ "testq $src, $src\t# ptr" %} 13316 ins_encode %{ 13317 __ testq($src$$Register, $src$$Register); 13318 %} 13319 ins_pipe(ialu_cr_reg_imm); 13320 %} 13321 13322 // This will generate a signed flags result. This should be OK since 13323 // any compare to a zero should be eq/neq. 13324 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 13325 %{ 13326 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 13327 n->in(1)->as_Load()->barrier_data() == 0); 13328 match(Set cr (CmpP (LoadP op) zero)); 13329 13330 ins_cost(500); // XXX 13331 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 13332 ins_encode %{ 13333 __ testq($op$$Address, 0xFFFFFFFF); 13334 %} 13335 ins_pipe(ialu_cr_reg_imm); 13336 %} 13337 13338 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 13339 %{ 13340 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 13341 n->in(1)->as_Load()->barrier_data() == 0); 13342 match(Set cr (CmpP (LoadP mem) zero)); 13343 13344 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 13345 ins_encode %{ 13346 __ cmpq(r12, $mem$$Address); 13347 %} 13348 ins_pipe(ialu_cr_reg_mem); 13349 %} 13350 13351 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 13352 %{ 13353 match(Set cr (CmpN op1 op2)); 13354 13355 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13356 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 13357 ins_pipe(ialu_cr_reg_reg); 13358 %} 13359 13360 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 13361 %{ 13362 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13363 match(Set cr (CmpN src (LoadN mem))); 13364 13365 format %{ "cmpl $src, $mem\t# compressed ptr" %} 13366 ins_encode %{ 13367 __ cmpl($src$$Register, $mem$$Address); 13368 %} 13369 ins_pipe(ialu_cr_reg_mem); 13370 %} 13371 13372 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 13373 match(Set cr (CmpN op1 op2)); 13374 13375 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13376 ins_encode %{ 13377 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 13378 %} 13379 ins_pipe(ialu_cr_reg_imm); 13380 %} 13381 13382 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 13383 %{ 13384 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13385 match(Set cr (CmpN src (LoadN mem))); 13386 13387 format %{ "cmpl $mem, $src\t# compressed ptr" %} 13388 ins_encode %{ 13389 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 13390 %} 13391 ins_pipe(ialu_cr_reg_mem); 13392 %} 13393 13394 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 13395 match(Set cr (CmpN op1 op2)); 13396 13397 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 13398 ins_encode %{ 13399 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 13400 %} 13401 ins_pipe(ialu_cr_reg_imm); 13402 %} 13403 13404 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 13405 %{ 13406 predicate(!UseCompactObjectHeaders); 13407 match(Set cr (CmpN src (LoadNKlass mem))); 13408 13409 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 13410 ins_encode %{ 13411 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 13412 %} 13413 ins_pipe(ialu_cr_reg_mem); 13414 %} 13415 13416 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 13417 match(Set cr (CmpN src zero)); 13418 13419 format %{ "testl $src, $src\t# compressed ptr" %} 13420 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 13421 ins_pipe(ialu_cr_reg_imm); 13422 %} 13423 13424 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 13425 %{ 13426 predicate(CompressedOops::base() != nullptr && 13427 n->in(1)->as_Load()->barrier_data() == 0); 13428 match(Set cr (CmpN (LoadN mem) zero)); 13429 13430 ins_cost(500); // XXX 13431 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 13432 ins_encode %{ 13433 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 13434 %} 13435 ins_pipe(ialu_cr_reg_mem); 13436 %} 13437 13438 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 13439 %{ 13440 predicate(CompressedOops::base() == nullptr && 13441 n->in(1)->as_Load()->barrier_data() == 0); 13442 match(Set cr (CmpN (LoadN mem) zero)); 13443 13444 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 13445 ins_encode %{ 13446 __ cmpl(r12, $mem$$Address); 13447 %} 13448 ins_pipe(ialu_cr_reg_mem); 13449 %} 13450 13451 // Yanked all unsigned pointer compare operations. 13452 // Pointer compares are done with CmpP which is already unsigned. 13453 13454 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13455 %{ 13456 match(Set cr (CmpL op1 op2)); 13457 13458 format %{ "cmpq $op1, $op2" %} 13459 ins_encode %{ 13460 __ cmpq($op1$$Register, $op2$$Register); 13461 %} 13462 ins_pipe(ialu_cr_reg_reg); 13463 %} 13464 13465 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13466 %{ 13467 match(Set cr (CmpL op1 op2)); 13468 13469 format %{ "cmpq $op1, $op2" %} 13470 ins_encode %{ 13471 __ cmpq($op1$$Register, $op2$$constant); 13472 %} 13473 ins_pipe(ialu_cr_reg_imm); 13474 %} 13475 13476 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 13477 %{ 13478 match(Set cr (CmpL op1 (LoadL op2))); 13479 13480 format %{ "cmpq $op1, $op2" %} 13481 ins_encode %{ 13482 __ cmpq($op1$$Register, $op2$$Address); 13483 %} 13484 ins_pipe(ialu_cr_reg_mem); 13485 %} 13486 13487 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 13488 %{ 13489 match(Set cr (CmpL src zero)); 13490 13491 format %{ "testq $src, $src" %} 13492 ins_encode %{ 13493 __ testq($src$$Register, $src$$Register); 13494 %} 13495 ins_pipe(ialu_cr_reg_imm); 13496 %} 13497 13498 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 13499 %{ 13500 match(Set cr (CmpL (AndL src con) zero)); 13501 13502 format %{ "testq $src, $con\t# long" %} 13503 ins_encode %{ 13504 __ testq($src$$Register, $con$$constant); 13505 %} 13506 ins_pipe(ialu_cr_reg_imm); 13507 %} 13508 13509 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 13510 %{ 13511 match(Set cr (CmpL (AndL src1 src2) zero)); 13512 13513 format %{ "testq $src1, $src2\t# long" %} 13514 ins_encode %{ 13515 __ testq($src1$$Register, $src2$$Register); 13516 %} 13517 ins_pipe(ialu_cr_reg_imm); 13518 %} 13519 13520 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 13521 %{ 13522 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 13523 13524 format %{ "testq $src, $mem" %} 13525 ins_encode %{ 13526 __ testq($src$$Register, $mem$$Address); 13527 %} 13528 ins_pipe(ialu_cr_reg_mem); 13529 %} 13530 13531 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 13532 %{ 13533 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 13534 13535 format %{ "testq $src, $mem" %} 13536 ins_encode %{ 13537 __ testq($src$$Register, $mem$$Address); 13538 %} 13539 ins_pipe(ialu_cr_reg_mem); 13540 %} 13541 13542 // Manifest a CmpU result in an integer register. Very painful. 13543 // This is the test to avoid. 13544 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 13545 %{ 13546 match(Set dst (CmpU3 src1 src2)); 13547 effect(KILL flags); 13548 13549 ins_cost(275); // XXX 13550 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 13551 "movl $dst, -1\n\t" 13552 "jb,u done\n\t" 13553 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13554 "done:" %} 13555 ins_encode %{ 13556 Label done; 13557 __ cmpl($src1$$Register, $src2$$Register); 13558 __ movl($dst$$Register, -1); 13559 __ jccb(Assembler::below, done); 13560 __ setcc(Assembler::notZero, $dst$$Register); 13561 __ bind(done); 13562 %} 13563 ins_pipe(pipe_slow); 13564 %} 13565 13566 // Manifest a CmpL result in an integer register. Very painful. 13567 // This is the test to avoid. 13568 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13569 %{ 13570 match(Set dst (CmpL3 src1 src2)); 13571 effect(KILL flags); 13572 13573 ins_cost(275); // XXX 13574 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13575 "movl $dst, -1\n\t" 13576 "jl,s done\n\t" 13577 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13578 "done:" %} 13579 ins_encode %{ 13580 Label done; 13581 __ cmpq($src1$$Register, $src2$$Register); 13582 __ movl($dst$$Register, -1); 13583 __ jccb(Assembler::less, done); 13584 __ setcc(Assembler::notZero, $dst$$Register); 13585 __ bind(done); 13586 %} 13587 ins_pipe(pipe_slow); 13588 %} 13589 13590 // Manifest a CmpUL result in an integer register. Very painful. 13591 // This is the test to avoid. 13592 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13593 %{ 13594 match(Set dst (CmpUL3 src1 src2)); 13595 effect(KILL flags); 13596 13597 ins_cost(275); // XXX 13598 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13599 "movl $dst, -1\n\t" 13600 "jb,u done\n\t" 13601 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13602 "done:" %} 13603 ins_encode %{ 13604 Label done; 13605 __ cmpq($src1$$Register, $src2$$Register); 13606 __ movl($dst$$Register, -1); 13607 __ jccb(Assembler::below, done); 13608 __ setcc(Assembler::notZero, $dst$$Register); 13609 __ bind(done); 13610 %} 13611 ins_pipe(pipe_slow); 13612 %} 13613 13614 // Unsigned long compare Instructions; really, same as signed long except they 13615 // produce an rFlagsRegU instead of rFlagsReg. 13616 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 13617 %{ 13618 match(Set cr (CmpUL op1 op2)); 13619 13620 format %{ "cmpq $op1, $op2\t# unsigned" %} 13621 ins_encode %{ 13622 __ cmpq($op1$$Register, $op2$$Register); 13623 %} 13624 ins_pipe(ialu_cr_reg_reg); 13625 %} 13626 13627 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 13628 %{ 13629 match(Set cr (CmpUL op1 op2)); 13630 13631 format %{ "cmpq $op1, $op2\t# unsigned" %} 13632 ins_encode %{ 13633 __ cmpq($op1$$Register, $op2$$constant); 13634 %} 13635 ins_pipe(ialu_cr_reg_imm); 13636 %} 13637 13638 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 13639 %{ 13640 match(Set cr (CmpUL op1 (LoadL op2))); 13641 13642 format %{ "cmpq $op1, $op2\t# unsigned" %} 13643 ins_encode %{ 13644 __ cmpq($op1$$Register, $op2$$Address); 13645 %} 13646 ins_pipe(ialu_cr_reg_mem); 13647 %} 13648 13649 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 13650 %{ 13651 match(Set cr (CmpUL src zero)); 13652 13653 format %{ "testq $src, $src\t# unsigned" %} 13654 ins_encode %{ 13655 __ testq($src$$Register, $src$$Register); 13656 %} 13657 ins_pipe(ialu_cr_reg_imm); 13658 %} 13659 13660 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 13661 %{ 13662 match(Set cr (CmpI (LoadB mem) imm)); 13663 13664 ins_cost(125); 13665 format %{ "cmpb $mem, $imm" %} 13666 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 13667 ins_pipe(ialu_cr_reg_mem); 13668 %} 13669 13670 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 13671 %{ 13672 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 13673 13674 ins_cost(125); 13675 format %{ "testb $mem, $imm\t# ubyte" %} 13676 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13677 ins_pipe(ialu_cr_reg_mem); 13678 %} 13679 13680 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 13681 %{ 13682 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 13683 13684 ins_cost(125); 13685 format %{ "testb $mem, $imm\t# byte" %} 13686 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13687 ins_pipe(ialu_cr_reg_mem); 13688 %} 13689 13690 //----------Max and Min-------------------------------------------------------- 13691 // Min Instructions 13692 13693 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 13694 %{ 13695 predicate(!UseAPX); 13696 effect(USE_DEF dst, USE src, USE cr); 13697 13698 format %{ "cmovlgt $dst, $src\t# min" %} 13699 ins_encode %{ 13700 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 13701 %} 13702 ins_pipe(pipe_cmov_reg); 13703 %} 13704 13705 instruct cmovI_reg_g_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13706 %{ 13707 predicate(UseAPX); 13708 effect(DEF dst, USE src1, USE src2, USE cr); 13709 13710 format %{ "ecmovlgt $dst, $src1, $src2\t# min ndd" %} 13711 ins_encode %{ 13712 __ ecmovl(Assembler::greater, $dst$$Register, $src1$$Register, $src2$$Register); 13713 %} 13714 ins_pipe(pipe_cmov_reg); 13715 %} 13716 13717 instruct minI_rReg(rRegI dst, rRegI src) 13718 %{ 13719 predicate(!UseAPX); 13720 match(Set dst (MinI dst src)); 13721 13722 ins_cost(200); 13723 expand %{ 13724 rFlagsReg cr; 13725 compI_rReg(cr, dst, src); 13726 cmovI_reg_g(dst, src, cr); 13727 %} 13728 %} 13729 13730 instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13731 %{ 13732 predicate(UseAPX); 13733 match(Set dst (MinI src1 src2)); 13734 effect(DEF dst, USE src1, USE src2); 13735 13736 ins_cost(200); 13737 expand %{ 13738 rFlagsReg cr; 13739 compI_rReg(cr, src1, src2); 13740 cmovI_reg_g_ndd(dst, src1, src2, cr); 13741 %} 13742 %} 13743 13744 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 13745 %{ 13746 predicate(!UseAPX); 13747 effect(USE_DEF dst, USE src, USE cr); 13748 13749 format %{ "cmovllt $dst, $src\t# max" %} 13750 ins_encode %{ 13751 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 13752 %} 13753 ins_pipe(pipe_cmov_reg); 13754 %} 13755 13756 instruct cmovI_reg_l_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13757 %{ 13758 predicate(UseAPX); 13759 effect(DEF dst, USE src1, USE src2, USE cr); 13760 13761 format %{ "ecmovllt $dst, $src1, $src2\t# max ndd" %} 13762 ins_encode %{ 13763 __ ecmovl(Assembler::less, $dst$$Register, $src1$$Register, $src2$$Register); 13764 %} 13765 ins_pipe(pipe_cmov_reg); 13766 %} 13767 13768 instruct maxI_rReg(rRegI dst, rRegI src) 13769 %{ 13770 predicate(!UseAPX); 13771 match(Set dst (MaxI dst src)); 13772 13773 ins_cost(200); 13774 expand %{ 13775 rFlagsReg cr; 13776 compI_rReg(cr, dst, src); 13777 cmovI_reg_l(dst, src, cr); 13778 %} 13779 %} 13780 13781 instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13782 %{ 13783 predicate(UseAPX); 13784 match(Set dst (MaxI src1 src2)); 13785 effect(DEF dst, USE src1, USE src2); 13786 13787 ins_cost(200); 13788 expand %{ 13789 rFlagsReg cr; 13790 compI_rReg(cr, src1, src2); 13791 cmovI_reg_l_ndd(dst, src1, src2, cr); 13792 %} 13793 %} 13794 13795 // ============================================================================ 13796 // Branch Instructions 13797 13798 // Jump Direct - Label defines a relative address from JMP+1 13799 instruct jmpDir(label labl) 13800 %{ 13801 match(Goto); 13802 effect(USE labl); 13803 13804 ins_cost(300); 13805 format %{ "jmp $labl" %} 13806 size(5); 13807 ins_encode %{ 13808 Label* L = $labl$$label; 13809 __ jmp(*L, false); // Always long jump 13810 %} 13811 ins_pipe(pipe_jmp); 13812 %} 13813 13814 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13815 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 13816 %{ 13817 match(If cop cr); 13818 effect(USE labl); 13819 13820 ins_cost(300); 13821 format %{ "j$cop $labl" %} 13822 size(6); 13823 ins_encode %{ 13824 Label* L = $labl$$label; 13825 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13826 %} 13827 ins_pipe(pipe_jcc); 13828 %} 13829 13830 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13831 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 13832 %{ 13833 match(CountedLoopEnd cop cr); 13834 effect(USE labl); 13835 13836 ins_cost(300); 13837 format %{ "j$cop $labl\t# loop end" %} 13838 size(6); 13839 ins_encode %{ 13840 Label* L = $labl$$label; 13841 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13842 %} 13843 ins_pipe(pipe_jcc); 13844 %} 13845 13846 // Jump Direct Conditional - using unsigned comparison 13847 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 13848 match(If cop cmp); 13849 effect(USE labl); 13850 13851 ins_cost(300); 13852 format %{ "j$cop,u $labl" %} 13853 size(6); 13854 ins_encode %{ 13855 Label* L = $labl$$label; 13856 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13857 %} 13858 ins_pipe(pipe_jcc); 13859 %} 13860 13861 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 13862 match(If cop cmp); 13863 effect(USE labl); 13864 13865 ins_cost(200); 13866 format %{ "j$cop,u $labl" %} 13867 size(6); 13868 ins_encode %{ 13869 Label* L = $labl$$label; 13870 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13871 %} 13872 ins_pipe(pipe_jcc); 13873 %} 13874 13875 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 13876 match(If cop cmp); 13877 effect(USE labl); 13878 13879 ins_cost(200); 13880 format %{ $$template 13881 if ($cop$$cmpcode == Assembler::notEqual) { 13882 $$emit$$"jp,u $labl\n\t" 13883 $$emit$$"j$cop,u $labl" 13884 } else { 13885 $$emit$$"jp,u done\n\t" 13886 $$emit$$"j$cop,u $labl\n\t" 13887 $$emit$$"done:" 13888 } 13889 %} 13890 ins_encode %{ 13891 Label* l = $labl$$label; 13892 if ($cop$$cmpcode == Assembler::notEqual) { 13893 __ jcc(Assembler::parity, *l, false); 13894 __ jcc(Assembler::notEqual, *l, false); 13895 } else if ($cop$$cmpcode == Assembler::equal) { 13896 Label done; 13897 __ jccb(Assembler::parity, done); 13898 __ jcc(Assembler::equal, *l, false); 13899 __ bind(done); 13900 } else { 13901 ShouldNotReachHere(); 13902 } 13903 %} 13904 ins_pipe(pipe_jcc); 13905 %} 13906 13907 // ============================================================================ 13908 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 13909 // superklass array for an instance of the superklass. Set a hidden 13910 // internal cache on a hit (cache is checked with exposed code in 13911 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 13912 // encoding ALSO sets flags. 13913 13914 instruct partialSubtypeCheck(rdi_RegP result, 13915 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 13916 rFlagsReg cr) 13917 %{ 13918 match(Set result (PartialSubtypeCheck sub super)); 13919 predicate(!UseSecondarySupersTable); 13920 effect(KILL rcx, KILL cr); 13921 13922 ins_cost(1100); // slightly larger than the next version 13923 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 13924 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 13925 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 13926 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 13927 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 13928 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 13929 "xorq $result, $result\t\t Hit: rdi zero\n\t" 13930 "miss:\t" %} 13931 13932 ins_encode %{ 13933 Label miss; 13934 // NB: Callers may assume that, when $result is a valid register, 13935 // check_klass_subtype_slow_path_linear sets it to a nonzero 13936 // value. 13937 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 13938 $rcx$$Register, $result$$Register, 13939 nullptr, &miss, 13940 /*set_cond_codes:*/ true); 13941 __ xorptr($result$$Register, $result$$Register); 13942 __ bind(miss); 13943 %} 13944 13945 ins_pipe(pipe_slow); 13946 %} 13947 13948 // ============================================================================ 13949 // Two versions of hashtable-based partialSubtypeCheck, both used when 13950 // we need to search for a super class in the secondary supers array. 13951 // The first is used when we don't know _a priori_ the class being 13952 // searched for. The second, far more common, is used when we do know: 13953 // this is used for instanceof, checkcast, and any case where C2 can 13954 // determine it by constant propagation. 13955 13956 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 13957 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13958 rFlagsReg cr) 13959 %{ 13960 match(Set result (PartialSubtypeCheck sub super)); 13961 predicate(UseSecondarySupersTable); 13962 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 13963 13964 ins_cost(1000); 13965 format %{ "partialSubtypeCheck $result, $sub, $super" %} 13966 13967 ins_encode %{ 13968 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 13969 $temp3$$Register, $temp4$$Register, $result$$Register); 13970 %} 13971 13972 ins_pipe(pipe_slow); 13973 %} 13974 13975 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 13976 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13977 rFlagsReg cr) 13978 %{ 13979 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 13980 predicate(UseSecondarySupersTable); 13981 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 13982 13983 ins_cost(700); // smaller than the next version 13984 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 13985 13986 ins_encode %{ 13987 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 13988 if (InlineSecondarySupersTest) { 13989 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 13990 $temp3$$Register, $temp4$$Register, $result$$Register, 13991 super_klass_slot); 13992 } else { 13993 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 13994 } 13995 %} 13996 13997 ins_pipe(pipe_slow); 13998 %} 13999 14000 // ============================================================================ 14001 // Branch Instructions -- short offset versions 14002 // 14003 // These instructions are used to replace jumps of a long offset (the default 14004 // match) with jumps of a shorter offset. These instructions are all tagged 14005 // with the ins_short_branch attribute, which causes the ADLC to suppress the 14006 // match rules in general matching. Instead, the ADLC generates a conversion 14007 // method in the MachNode which can be used to do in-place replacement of the 14008 // long variant with the shorter variant. The compiler will determine if a 14009 // branch can be taken by the is_short_branch_offset() predicate in the machine 14010 // specific code section of the file. 14011 14012 // Jump Direct - Label defines a relative address from JMP+1 14013 instruct jmpDir_short(label labl) %{ 14014 match(Goto); 14015 effect(USE labl); 14016 14017 ins_cost(300); 14018 format %{ "jmp,s $labl" %} 14019 size(2); 14020 ins_encode %{ 14021 Label* L = $labl$$label; 14022 __ jmpb(*L); 14023 %} 14024 ins_pipe(pipe_jmp); 14025 ins_short_branch(1); 14026 %} 14027 14028 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14029 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14030 match(If cop cr); 14031 effect(USE labl); 14032 14033 ins_cost(300); 14034 format %{ "j$cop,s $labl" %} 14035 size(2); 14036 ins_encode %{ 14037 Label* L = $labl$$label; 14038 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14039 %} 14040 ins_pipe(pipe_jcc); 14041 ins_short_branch(1); 14042 %} 14043 14044 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14045 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14046 match(CountedLoopEnd cop cr); 14047 effect(USE labl); 14048 14049 ins_cost(300); 14050 format %{ "j$cop,s $labl\t# loop end" %} 14051 size(2); 14052 ins_encode %{ 14053 Label* L = $labl$$label; 14054 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14055 %} 14056 ins_pipe(pipe_jcc); 14057 ins_short_branch(1); 14058 %} 14059 14060 // Jump Direct Conditional - using unsigned comparison 14061 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14062 match(If cop cmp); 14063 effect(USE labl); 14064 14065 ins_cost(300); 14066 format %{ "j$cop,us $labl" %} 14067 size(2); 14068 ins_encode %{ 14069 Label* L = $labl$$label; 14070 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14071 %} 14072 ins_pipe(pipe_jcc); 14073 ins_short_branch(1); 14074 %} 14075 14076 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14077 match(If cop cmp); 14078 effect(USE labl); 14079 14080 ins_cost(300); 14081 format %{ "j$cop,us $labl" %} 14082 size(2); 14083 ins_encode %{ 14084 Label* L = $labl$$label; 14085 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14086 %} 14087 ins_pipe(pipe_jcc); 14088 ins_short_branch(1); 14089 %} 14090 14091 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14092 match(If cop cmp); 14093 effect(USE labl); 14094 14095 ins_cost(300); 14096 format %{ $$template 14097 if ($cop$$cmpcode == Assembler::notEqual) { 14098 $$emit$$"jp,u,s $labl\n\t" 14099 $$emit$$"j$cop,u,s $labl" 14100 } else { 14101 $$emit$$"jp,u,s done\n\t" 14102 $$emit$$"j$cop,u,s $labl\n\t" 14103 $$emit$$"done:" 14104 } 14105 %} 14106 size(4); 14107 ins_encode %{ 14108 Label* l = $labl$$label; 14109 if ($cop$$cmpcode == Assembler::notEqual) { 14110 __ jccb(Assembler::parity, *l); 14111 __ jccb(Assembler::notEqual, *l); 14112 } else if ($cop$$cmpcode == Assembler::equal) { 14113 Label done; 14114 __ jccb(Assembler::parity, done); 14115 __ jccb(Assembler::equal, *l); 14116 __ bind(done); 14117 } else { 14118 ShouldNotReachHere(); 14119 } 14120 %} 14121 ins_pipe(pipe_jcc); 14122 ins_short_branch(1); 14123 %} 14124 14125 // ============================================================================ 14126 // inlined locking and unlocking 14127 14128 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 14129 predicate(LockingMode != LM_LIGHTWEIGHT); 14130 match(Set cr (FastLock object box)); 14131 effect(TEMP tmp, TEMP scr, USE_KILL box); 14132 ins_cost(300); 14133 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 14134 ins_encode %{ 14135 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 14136 $scr$$Register, noreg, noreg, r15_thread, nullptr); 14137 %} 14138 ins_pipe(pipe_slow); 14139 %} 14140 14141 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 14142 predicate(LockingMode != LM_LIGHTWEIGHT); 14143 match(Set cr (FastUnlock object box)); 14144 effect(TEMP tmp, USE_KILL box); 14145 ins_cost(300); 14146 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 14147 ins_encode %{ 14148 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 14149 %} 14150 ins_pipe(pipe_slow); 14151 %} 14152 14153 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 14154 predicate(LockingMode == LM_LIGHTWEIGHT); 14155 match(Set cr (FastLock object box)); 14156 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 14157 ins_cost(300); 14158 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 14159 ins_encode %{ 14160 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14161 %} 14162 ins_pipe(pipe_slow); 14163 %} 14164 14165 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 14166 predicate(LockingMode == LM_LIGHTWEIGHT); 14167 match(Set cr (FastUnlock object rax_reg)); 14168 effect(TEMP tmp, USE_KILL rax_reg); 14169 ins_cost(300); 14170 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 14171 ins_encode %{ 14172 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14173 %} 14174 ins_pipe(pipe_slow); 14175 %} 14176 14177 14178 // ============================================================================ 14179 // Safepoint Instructions 14180 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 14181 %{ 14182 match(SafePoint poll); 14183 effect(KILL cr, USE poll); 14184 14185 format %{ "testl rax, [$poll]\t" 14186 "# Safepoint: poll for GC" %} 14187 ins_cost(125); 14188 ins_encode %{ 14189 __ relocate(relocInfo::poll_type); 14190 address pre_pc = __ pc(); 14191 __ testl(rax, Address($poll$$Register, 0)); 14192 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 14193 %} 14194 ins_pipe(ialu_reg_mem); 14195 %} 14196 14197 instruct mask_all_evexL(kReg dst, rRegL src) %{ 14198 match(Set dst (MaskAll src)); 14199 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 14200 ins_encode %{ 14201 int mask_len = Matcher::vector_length(this); 14202 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 14203 %} 14204 ins_pipe( pipe_slow ); 14205 %} 14206 14207 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 14208 predicate(Matcher::vector_length(n) > 32); 14209 match(Set dst (MaskAll src)); 14210 effect(TEMP tmp); 14211 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 14212 ins_encode %{ 14213 int mask_len = Matcher::vector_length(this); 14214 __ movslq($tmp$$Register, $src$$Register); 14215 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 14216 %} 14217 ins_pipe( pipe_slow ); 14218 %} 14219 14220 // ============================================================================ 14221 // Procedure Call/Return Instructions 14222 // Call Java Static Instruction 14223 // Note: If this code changes, the corresponding ret_addr_offset() and 14224 // compute_padding() functions will have to be adjusted. 14225 instruct CallStaticJavaDirect(method meth) %{ 14226 match(CallStaticJava); 14227 effect(USE meth); 14228 14229 ins_cost(300); 14230 format %{ "call,static " %} 14231 opcode(0xE8); /* E8 cd */ 14232 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 14233 ins_pipe(pipe_slow); 14234 ins_alignment(4); 14235 %} 14236 14237 // Call Java Dynamic Instruction 14238 // Note: If this code changes, the corresponding ret_addr_offset() and 14239 // compute_padding() functions will have to be adjusted. 14240 instruct CallDynamicJavaDirect(method meth) 14241 %{ 14242 match(CallDynamicJava); 14243 effect(USE meth); 14244 14245 ins_cost(300); 14246 format %{ "movq rax, #Universe::non_oop_word()\n\t" 14247 "call,dynamic " %} 14248 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 14249 ins_pipe(pipe_slow); 14250 ins_alignment(4); 14251 %} 14252 14253 // Call Runtime Instruction 14254 instruct CallRuntimeDirect(method meth) 14255 %{ 14256 match(CallRuntime); 14257 effect(USE meth); 14258 14259 ins_cost(300); 14260 format %{ "call,runtime " %} 14261 ins_encode(clear_avx, Java_To_Runtime(meth)); 14262 ins_pipe(pipe_slow); 14263 %} 14264 14265 // Call runtime without safepoint 14266 instruct CallLeafDirect(method meth) 14267 %{ 14268 match(CallLeaf); 14269 effect(USE meth); 14270 14271 ins_cost(300); 14272 format %{ "call_leaf,runtime " %} 14273 ins_encode(clear_avx, Java_To_Runtime(meth)); 14274 ins_pipe(pipe_slow); 14275 %} 14276 14277 // Call runtime without safepoint and with vector arguments 14278 instruct CallLeafDirectVector(method meth) 14279 %{ 14280 match(CallLeafVector); 14281 effect(USE meth); 14282 14283 ins_cost(300); 14284 format %{ "call_leaf,vector " %} 14285 ins_encode(Java_To_Runtime(meth)); 14286 ins_pipe(pipe_slow); 14287 %} 14288 14289 // Call runtime without safepoint 14290 instruct CallLeafNoFPDirect(method meth) 14291 %{ 14292 match(CallLeafNoFP); 14293 effect(USE meth); 14294 14295 ins_cost(300); 14296 format %{ "call_leaf_nofp,runtime " %} 14297 ins_encode(clear_avx, Java_To_Runtime(meth)); 14298 ins_pipe(pipe_slow); 14299 %} 14300 14301 // Return Instruction 14302 // Remove the return address & jump to it. 14303 // Notice: We always emit a nop after a ret to make sure there is room 14304 // for safepoint patching 14305 instruct Ret() 14306 %{ 14307 match(Return); 14308 14309 format %{ "ret" %} 14310 ins_encode %{ 14311 __ ret(0); 14312 %} 14313 ins_pipe(pipe_jmp); 14314 %} 14315 14316 // Tail Call; Jump from runtime stub to Java code. 14317 // Also known as an 'interprocedural jump'. 14318 // Target of jump will eventually return to caller. 14319 // TailJump below removes the return address. 14320 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 14321 // emitted just above the TailCall which has reset rbp to the caller state. 14322 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 14323 %{ 14324 match(TailCall jump_target method_ptr); 14325 14326 ins_cost(300); 14327 format %{ "jmp $jump_target\t# rbx holds method" %} 14328 ins_encode %{ 14329 __ jmp($jump_target$$Register); 14330 %} 14331 ins_pipe(pipe_jmp); 14332 %} 14333 14334 // Tail Jump; remove the return address; jump to target. 14335 // TailCall above leaves the return address around. 14336 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 14337 %{ 14338 match(TailJump jump_target ex_oop); 14339 14340 ins_cost(300); 14341 format %{ "popq rdx\t# pop return address\n\t" 14342 "jmp $jump_target" %} 14343 ins_encode %{ 14344 __ popq(as_Register(RDX_enc)); 14345 __ jmp($jump_target$$Register); 14346 %} 14347 ins_pipe(pipe_jmp); 14348 %} 14349 14350 // Forward exception. 14351 instruct ForwardExceptionjmp() 14352 %{ 14353 match(ForwardException); 14354 14355 format %{ "jmp forward_exception_stub" %} 14356 ins_encode %{ 14357 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 14358 %} 14359 ins_pipe(pipe_jmp); 14360 %} 14361 14362 // Create exception oop: created by stack-crawling runtime code. 14363 // Created exception is now available to this handler, and is setup 14364 // just prior to jumping to this handler. No code emitted. 14365 instruct CreateException(rax_RegP ex_oop) 14366 %{ 14367 match(Set ex_oop (CreateEx)); 14368 14369 size(0); 14370 // use the following format syntax 14371 format %{ "# exception oop is in rax; no code emitted" %} 14372 ins_encode(); 14373 ins_pipe(empty); 14374 %} 14375 14376 // Rethrow exception: 14377 // The exception oop will come in the first argument position. 14378 // Then JUMP (not call) to the rethrow stub code. 14379 instruct RethrowException() 14380 %{ 14381 match(Rethrow); 14382 14383 // use the following format syntax 14384 format %{ "jmp rethrow_stub" %} 14385 ins_encode %{ 14386 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 14387 %} 14388 ins_pipe(pipe_jmp); 14389 %} 14390 14391 // ============================================================================ 14392 // This name is KNOWN by the ADLC and cannot be changed. 14393 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14394 // for this guy. 14395 instruct tlsLoadP(r15_RegP dst) %{ 14396 match(Set dst (ThreadLocal)); 14397 effect(DEF dst); 14398 14399 size(0); 14400 format %{ "# TLS is in R15" %} 14401 ins_encode( /*empty encoding*/ ); 14402 ins_pipe(ialu_reg_reg); 14403 %} 14404 14405 14406 //----------PEEPHOLE RULES----------------------------------------------------- 14407 // These must follow all instruction definitions as they use the names 14408 // defined in the instructions definitions. 14409 // 14410 // peeppredicate ( rule_predicate ); 14411 // // the predicate unless which the peephole rule will be ignored 14412 // 14413 // peepmatch ( root_instr_name [preceding_instruction]* ); 14414 // 14415 // peepprocedure ( procedure_name ); 14416 // // provide a procedure name to perform the optimization, the procedure should 14417 // // reside in the architecture dependent peephole file, the method has the 14418 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 14419 // // with the arguments being the basic block, the current node index inside the 14420 // // block, the register allocator, the functions upon invoked return a new node 14421 // // defined in peepreplace, and the rules of the nodes appearing in the 14422 // // corresponding peepmatch, the function return true if successful, else 14423 // // return false 14424 // 14425 // peepconstraint %{ 14426 // (instruction_number.operand_name relational_op instruction_number.operand_name 14427 // [, ...] ); 14428 // // instruction numbers are zero-based using left to right order in peepmatch 14429 // 14430 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14431 // // provide an instruction_number.operand_name for each operand that appears 14432 // // in the replacement instruction's match rule 14433 // 14434 // ---------VM FLAGS--------------------------------------------------------- 14435 // 14436 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14437 // 14438 // Each peephole rule is given an identifying number starting with zero and 14439 // increasing by one in the order seen by the parser. An individual peephole 14440 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14441 // on the command-line. 14442 // 14443 // ---------CURRENT LIMITATIONS---------------------------------------------- 14444 // 14445 // Only transformations inside a basic block (do we need more for peephole) 14446 // 14447 // ---------EXAMPLE---------------------------------------------------------- 14448 // 14449 // // pertinent parts of existing instructions in architecture description 14450 // instruct movI(rRegI dst, rRegI src) 14451 // %{ 14452 // match(Set dst (CopyI src)); 14453 // %} 14454 // 14455 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 14456 // %{ 14457 // match(Set dst (AddI dst src)); 14458 // effect(KILL cr); 14459 // %} 14460 // 14461 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 14462 // %{ 14463 // match(Set dst (AddI dst src)); 14464 // %} 14465 // 14466 // 1. Simple replacement 14467 // - Only match adjacent instructions in same basic block 14468 // - Only equality constraints 14469 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 14470 // - Only one replacement instruction 14471 // 14472 // // Change (inc mov) to lea 14473 // peephole %{ 14474 // // lea should only be emitted when beneficial 14475 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14476 // // increment preceded by register-register move 14477 // peepmatch ( incI_rReg movI ); 14478 // // require that the destination register of the increment 14479 // // match the destination register of the move 14480 // peepconstraint ( 0.dst == 1.dst ); 14481 // // construct a replacement instruction that sets 14482 // // the destination to ( move's source register + one ) 14483 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 14484 // %} 14485 // 14486 // 2. Procedural replacement 14487 // - More flexible finding relevent nodes 14488 // - More flexible constraints 14489 // - More flexible transformations 14490 // - May utilise architecture-dependent API more effectively 14491 // - Currently only one replacement instruction due to adlc parsing capabilities 14492 // 14493 // // Change (inc mov) to lea 14494 // peephole %{ 14495 // // lea should only be emitted when beneficial 14496 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14497 // // the rule numbers of these nodes inside are passed into the function below 14498 // peepmatch ( incI_rReg movI ); 14499 // // the method that takes the responsibility of transformation 14500 // peepprocedure ( inc_mov_to_lea ); 14501 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 14502 // // node is passed into the function above 14503 // peepreplace ( leaI_rReg_immI() ); 14504 // %} 14505 14506 // These instructions is not matched by the matcher but used by the peephole 14507 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 14508 %{ 14509 predicate(false); 14510 match(Set dst (AddI src1 src2)); 14511 format %{ "leal $dst, [$src1 + $src2]" %} 14512 ins_encode %{ 14513 Register dst = $dst$$Register; 14514 Register src1 = $src1$$Register; 14515 Register src2 = $src2$$Register; 14516 if (src1 != rbp && src1 != r13) { 14517 __ leal(dst, Address(src1, src2, Address::times_1)); 14518 } else { 14519 assert(src2 != rbp && src2 != r13, ""); 14520 __ leal(dst, Address(src2, src1, Address::times_1)); 14521 } 14522 %} 14523 ins_pipe(ialu_reg_reg); 14524 %} 14525 14526 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 14527 %{ 14528 predicate(false); 14529 match(Set dst (AddI src1 src2)); 14530 format %{ "leal $dst, [$src1 + $src2]" %} 14531 ins_encode %{ 14532 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 14533 %} 14534 ins_pipe(ialu_reg_reg); 14535 %} 14536 14537 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 14538 %{ 14539 predicate(false); 14540 match(Set dst (LShiftI src shift)); 14541 format %{ "leal $dst, [$src << $shift]" %} 14542 ins_encode %{ 14543 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14544 Register src = $src$$Register; 14545 if (scale == Address::times_2 && src != rbp && src != r13) { 14546 __ leal($dst$$Register, Address(src, src, Address::times_1)); 14547 } else { 14548 __ leal($dst$$Register, Address(noreg, src, scale)); 14549 } 14550 %} 14551 ins_pipe(ialu_reg_reg); 14552 %} 14553 14554 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 14555 %{ 14556 predicate(false); 14557 match(Set dst (AddL src1 src2)); 14558 format %{ "leaq $dst, [$src1 + $src2]" %} 14559 ins_encode %{ 14560 Register dst = $dst$$Register; 14561 Register src1 = $src1$$Register; 14562 Register src2 = $src2$$Register; 14563 if (src1 != rbp && src1 != r13) { 14564 __ leaq(dst, Address(src1, src2, Address::times_1)); 14565 } else { 14566 assert(src2 != rbp && src2 != r13, ""); 14567 __ leaq(dst, Address(src2, src1, Address::times_1)); 14568 } 14569 %} 14570 ins_pipe(ialu_reg_reg); 14571 %} 14572 14573 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 14574 %{ 14575 predicate(false); 14576 match(Set dst (AddL src1 src2)); 14577 format %{ "leaq $dst, [$src1 + $src2]" %} 14578 ins_encode %{ 14579 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 14580 %} 14581 ins_pipe(ialu_reg_reg); 14582 %} 14583 14584 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 14585 %{ 14586 predicate(false); 14587 match(Set dst (LShiftL src shift)); 14588 format %{ "leaq $dst, [$src << $shift]" %} 14589 ins_encode %{ 14590 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14591 Register src = $src$$Register; 14592 if (scale == Address::times_2 && src != rbp && src != r13) { 14593 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 14594 } else { 14595 __ leaq($dst$$Register, Address(noreg, src, scale)); 14596 } 14597 %} 14598 ins_pipe(ialu_reg_reg); 14599 %} 14600 14601 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 14602 // sal}) with lea instructions. The {add, sal} rules are beneficial in 14603 // processors with at least partial ALU support for lea 14604 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 14605 // beneficial for processors with full ALU support 14606 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 14607 14608 peephole 14609 %{ 14610 peeppredicate(VM_Version::supports_fast_2op_lea()); 14611 peepmatch (addI_rReg); 14612 peepprocedure (lea_coalesce_reg); 14613 peepreplace (leaI_rReg_rReg_peep()); 14614 %} 14615 14616 peephole 14617 %{ 14618 peeppredicate(VM_Version::supports_fast_2op_lea()); 14619 peepmatch (addI_rReg_imm); 14620 peepprocedure (lea_coalesce_imm); 14621 peepreplace (leaI_rReg_immI_peep()); 14622 %} 14623 14624 peephole 14625 %{ 14626 peeppredicate(VM_Version::supports_fast_3op_lea() || 14627 VM_Version::is_intel_cascade_lake()); 14628 peepmatch (incI_rReg); 14629 peepprocedure (lea_coalesce_imm); 14630 peepreplace (leaI_rReg_immI_peep()); 14631 %} 14632 14633 peephole 14634 %{ 14635 peeppredicate(VM_Version::supports_fast_3op_lea() || 14636 VM_Version::is_intel_cascade_lake()); 14637 peepmatch (decI_rReg); 14638 peepprocedure (lea_coalesce_imm); 14639 peepreplace (leaI_rReg_immI_peep()); 14640 %} 14641 14642 peephole 14643 %{ 14644 peeppredicate(VM_Version::supports_fast_2op_lea()); 14645 peepmatch (salI_rReg_immI2); 14646 peepprocedure (lea_coalesce_imm); 14647 peepreplace (leaI_rReg_immI2_peep()); 14648 %} 14649 14650 peephole 14651 %{ 14652 peeppredicate(VM_Version::supports_fast_2op_lea()); 14653 peepmatch (addL_rReg); 14654 peepprocedure (lea_coalesce_reg); 14655 peepreplace (leaL_rReg_rReg_peep()); 14656 %} 14657 14658 peephole 14659 %{ 14660 peeppredicate(VM_Version::supports_fast_2op_lea()); 14661 peepmatch (addL_rReg_imm); 14662 peepprocedure (lea_coalesce_imm); 14663 peepreplace (leaL_rReg_immL32_peep()); 14664 %} 14665 14666 peephole 14667 %{ 14668 peeppredicate(VM_Version::supports_fast_3op_lea() || 14669 VM_Version::is_intel_cascade_lake()); 14670 peepmatch (incL_rReg); 14671 peepprocedure (lea_coalesce_imm); 14672 peepreplace (leaL_rReg_immL32_peep()); 14673 %} 14674 14675 peephole 14676 %{ 14677 peeppredicate(VM_Version::supports_fast_3op_lea() || 14678 VM_Version::is_intel_cascade_lake()); 14679 peepmatch (decL_rReg); 14680 peepprocedure (lea_coalesce_imm); 14681 peepreplace (leaL_rReg_immL32_peep()); 14682 %} 14683 14684 peephole 14685 %{ 14686 peeppredicate(VM_Version::supports_fast_2op_lea()); 14687 peepmatch (salL_rReg_immI2); 14688 peepprocedure (lea_coalesce_imm); 14689 peepreplace (leaL_rReg_immI2_peep()); 14690 %} 14691 14692 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 14693 // 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 14694 14695 //int variant 14696 peephole 14697 %{ 14698 peepmatch (testI_reg); 14699 peepprocedure (test_may_remove); 14700 %} 14701 14702 //long variant 14703 peephole 14704 %{ 14705 peepmatch (testL_reg); 14706 peepprocedure (test_may_remove); 14707 %} 14708 14709 14710 //----------SMARTSPILL RULES--------------------------------------------------- 14711 // These must follow all instruction definitions as they use the names 14712 // defined in the instructions definitions.